java graduation project - fortress game design and implementation based on java+J2ME (graduation thesis + program source code) - fortress game

Design and implementation of fortress game based on java+J2ME (graduate thesis + program source code)

Hello everyone, today I will introduce the design and implementation of the fortress game based on java+J2ME. The thesis and source code download address of this graduation project are attached at the end of the article.

Article directory:

1. Project introduction

  1. The fortress game is a mobile RPG game developed based on J2ME. It uses midp2.0 technology to realize menu, map, protagonist action, monster action and AI, etc. It mainly triggers events through collision detection between elves. The main process of the game is that the player uses the mobile phone keyboard to operate the protagonist to pick up props in the fort to solve the maze, and as the number of levels increases, the difficulty of the game gradually increases. In addition, the game also includes leaderboards, sound settings, help and other additional functions. It is full of fun and excitement, and is a puzzle adventure game suitable for all ages.
  2. This paper introduces the related technology of J2ME, the structure analysis of the fortress game program and the realization of its specific functions.

2. Resource details

Project Difficulty: Medium Difficulty
Applicable scenarios: Graduation projects for related topics
The number of words in supporting thesis: 9848 words and 26 pages
Included content: complete set of source code + complete graduation thesis + defense PPT

3. Keywords

J2ME; Mobile Games; Fortress

4. Introduction

Reminder: The following is a brief introduction to the graduation thesis. The project source code and the download address of the complete graduation thesis are at the end of the article.

Introduction
omit

2 Current Situation of Mobile Games and Overview of J2ME
2.1 Software Status
omit

2.2 Overview of J2ME
2.2.1 The origin of J2ME
The biggest goal and feature of Java is "write once, run anywhere" platform independence. However, one set of standards cannot accommodate a variety of different needs. Therefore, there are currently three sets of Java technology, which are aimed at different platforms and applications.
omit

2.2.2 J2ME's 3-layer Architecture and Introduction to MIDP
The 3-layer architecture of J2ME divides the J2ME technical framework into three layers: Profile, Configuration and Java Virtual Machine (JVM) according to the resource characteristics of various devices, and then further subdivides them, which enables J2ME to Works within the constraints of each type of device while providing minimal Java language functionality.

Regarding the architecture of J2ME, it can be summarized as follows: The classification of Configuration is divided according to the different computing capabilities, and the computing capabilities of similar devices are similar. Configuration is a specification that defines a common Java platform for such devices, defines a device-independent Java virtual machine and core library, and is the basis for platform compatibility. The classification of profiles is based on device functions, and other hardware conditions and requirements of devices with similar functions are also similar. Profile is a set of APIs that extend the APIs for device-specific functions on the basis of a Configuration, so that the standard can fully adapt to special devices and fully utilize the functions of the device.

The general structure of the J2ME system is: the Java virtual machine defined by Configuration runs on the host operating system of the device and forms the basis of the entire platform. Configuration provides basic language features, and Profile provides device-specific API s and extended class libraries. The running environment of the application requires a Configuration and at least one Profile. Multiple Profiles can coexist or overlap.

omit

2.2.3 Configuration and Profiles
omit

2.3 Current Situation and Prospects of J2ME
omit

2.4 Mobile game business
Mobile games are the most valuable applications in the era of mobile multimedia. This is because games are the most integrated business in multimedia applications. Images, music, and interaction can all be implemented in games, which can fully meet the needs of users in all aspects.

Although the current mobile games can not be compared with PC games, its display function, keyboard input, and sound processing capabilities also form certain constraints. However, the features that can be operated anytime and anywhere and can be connected to the Internet have greatly expanded the time and space for people's entertainment and leisure. Mobile terminals with game functions are gradually recognized in the market, and multimedia functions are evolving to the standard functions of mobile phones, restricting the development of mobile games. The technical bottleneck will be broken. Although there are still many bottlenecks restricting its development in the current mobile game industry, mobile games have shown an extraordinary development speed, and their market potential is huge, and will become a new growth point in the mobile value-added service market.

3 Introduction to the development environment
3.1 Development environment
Operating System: Microsoft Windows
Programming language: Java
Development platform: Java Micro Edition
Development tools: Wireless Tool Kit + UltraEdit

3.2 About SonyEricsson Wireless Tool Kit
omit

4 Development of Mobile Game (Fortress)
4.1 The idea and concept of the game
4.1.1 Generation of game ideas
I believe that everyone must have played the game "Adventure Island" on an 8-bit computer, which is very interesting.

In the game, players rescue the princess by constantly breaking through the levels. There are many monsters blocking you in each level, so you need to use various traps or cheats to kill them. While killing them, you can also get various rewards, such as life, blood, etc., which increases the fun of the game.

as shown in picture 2:

Figure 2 Screenshot of the game
The implementation of this "Adventure Island" game is slightly simpler than other RPG or online mobile games, and it is suitable for beginners as an exercise, so I decided to write a similar mobile game.

Since we only had a preliminary understanding of the programming knowledge of mobile games and the design of the game, we have gone through several stages in the structure and thinking of the game.

4.1.2 Preliminary understanding of game design
At the beginning we only had a preliminary understanding of J2ME. At this time, we just imitated the game we saw on the PC before, and described the implementation of the game in language into several parts:
Game interface system: including game start interface; game start interface; game running interface; game end interface.
Game elements: menu class; canvas class; character class; leaderboard class.

4.1.3 Module forming stage
After further familiar with the knowledge of J2ME, some modifications were made to the framework, and the basic functions of the game were gradually determined. The game enters the loading interface in turn; the main menu; the game running interface; the game ending interface.

The specific functions are:
1. The main menu has the following options:
(1) Start the game - enter the game interface.
(2) Sound - set the option of sound.
(3) Help - Introduce the gameplay of the game.
(4) Leaderboards - Leaderboards of player scores.
(5) About - used to display description information and background pictures.
2. Game running interface, including:
Game interface; current game score; game level; number of lives;
3. Game over interface: After the game is over, display a line of description information, and then return to the menu.

The main modules of the game are:
1. The main game MIDlet (GameMIDlet) - judgment of the game life cycle; calls to the canvas class; management of the transition between the various screens in the game program.
2. Game Canvas (MyGame) - setting of variables and constants used in the game; initialization of the game; control of the sprite movement trajectory in the game; collision detection between sprites and bricks and control of brick status; basic settings of each level in the game Set; the processing of the button state in the game.
3. Menu class - the handling of menu events in the game.
4. GameOgre class - The class of the monster in the game.
5. GamePlayer class - the sprite class controlled by the player.
6. GameRMS class - used to implement score leaderboards.
7. PlayMusic class - used to implement music playback.
8. MySet class - the setting of the volume of the sound.

4.2 The class structure of the program
The program has a total of 8 main classes, among which the menu class is responsible for the switching of each screen. The class structure of the program is shown in Figure 3:

Figure 3 Class structure

4.3 The flow chart of the game
Enter the game menu. Initially, the game menu has 5 options, they are start game, game description and leaderboard, settings, about. Choose to start a new game to enter the game. If you press a non-game key during the game, you will interrupt the game and return to the menu. At this time, an option to continue the game is added to the menu. You can return to the game or start a new game again. Select game description or high score record in the menu to enter the corresponding screen, and they can all use the "back" soft key to return to the menu. The Exit option in the menu is used to exit the program.

4.4 Implementation of the game
The game implements several classes in total, including the menu class, the leaderboard screen class, the sound setting screen class, the end screen class, and the game canvas class and sound effect class used for the game itself.

4.4.1 Implementation of the main class GameMIDlet
MIDlet is the core class. A MIDlet program has three states:
1. suspended state
2. Operating status
3. Destroyed state
J2ME programs are executed from the MIDlet class. When the system executes a MIDlet program, it first constructs a MIDlet type object, and then makes the program enter the suspended state. According to the provisions of the life cycle, the system will automatically call the startApp method of the MIDlet object to make the program Enter the running state and start the execution of the program.

The following image is the canvas object displayed at runtime:

Figure 5 Switching between screens
First of all, we need to create an object of MIDlet type. Let's look at the construction method of the object:

//Main program construction method
        public GameMIDlet()
        {
        		rs = null;
        		RecordName = "GameRMS ";
        		GameMenu.display = Display.getDisplay(this) ;
        		GameMenu.midlet = this;
        }

In this constructor, a Display object is created for display, and then a reference to the current program is passed to a static variable in the menu class.

The Display class has two main functions:
1. Get the properties of the screen. Information such as whether the screen is colored, and the number of supported colors.
2. Control the display of the screen. For example, make the screen display a specified interface or obtain the current display interface.
Among them, especially the second role is used more frequently.

When the program starts, the startApp method of the program is called to display the screen:

   public void startApp()
        {
        	//The program starts, open the database, add 10 blank data if the database has no data, and finally close the database
        	try {
				rs = RecordStore.openRecordStore(RecordName,true);
			} catch (Exception e) 
			{
				System.out.println("Failed to create database");
			}
			GameRMS rd = new GameRMS("player ",0);
			byte tem[] = rd.encode();
			try 
			{
				if(rs.getNumRecords()==0)
				{	
					for(int i=1;i<=11;i++)
					   	  {
						   	  try
							  {
							  rs.addRecord(tem,0,tem.length);
							  }catch(Exception e)
							  {
							  	System.out.println("Failed to add data"); 
							  }
				   	      }
				}	
			} 
			catch (Exception e1) 
			{
				System.out.println("Failed to get database size");
			}	   
				
			try
			{
			    rs.closeRecordStore();
			}catch(Exception e)
			{
			 	System.out.println("Failed to close database");
			}
        	   //Set the screen as the main screen MAIN SCREEN
			new Thread(this).start(); 
        }

The program starts, opens the database, adds 10 blank data if the database has no data, and finally closes the database, then starts a new thread and starts the menu.
The storage system in MIDP is actually a database-like system, not a simple file system. This system is called Record Management System (RMS). RMS realizes the persistent management of data, provides the function of data storage, and can be used again when the program is started next time.

A record store is a record-oriented database. A record store can be viewed as a database file composed of many records that will persist and support requests across multiple MIDlet s. During the entire regular application period of the system platform, including restarting, replacing the battery, etc., the MIDlet record storage is maintained by the system platform, and the system will try to maintain the integrity of the record as much as possible.

When the destroyApp method is called, the program is exited.

public void destroyApp(boolean unconditional) 
{
        exit();
 }
public void exit() 
{
        System.gc();
        notifyDestroyed();
 }

When you exit the program, garbage collection is performed to release memory that is no longer used.
2. Screen switching, as shown in Figure 6:

Figure 6 Screen switching
The graphic switching of the menu adopts the process controller, which is very convenient and succinctly realizes the switching of the screen image. The following is the key implementation code:

//Navigator
	//Set 4 constants to represent the main screen, game screen, help screen and leaderboard screen
	final public static int MY_MENU = 1;
	final public static int MY_GAME = 2;
	final public static int MY_HELP = 3;
	final public static int MY_RMS = 4;
	final public static int MY_ABOUT = 5;
	final public static int MY_SET = 6;
Use static variables to identify the screen.
//Process execution, get the object that needs the screen, and display it on the screen
	public static void show()
	{
		switch(current)
		{
			case MY_MENU:
				display.setCurrent(MyMenu.getInstance());
				break;
			case MY_GAME:
				display.setCurrent(MyGame.getInstance());
				break;
			case MY_SET:
				display.setCurrent(MySet.getInstance());
				break;
			case MY_HELP:
				display.setCurrent(MyHelp.getInstance());
				break;
			case MY_RMS:
				display.setCurrent(MyRms.getInstance());
				break;
			case MY_ABOUT:
				display.setCurrent(MyAbout.getInstance());
				break;
		}
	}

In this way, using the above function, it is very convenient to realize the conversion of the process. Realize screen switching.

4.4.2 Implementation of the game canvas MyGame class
In J2ME game programming, the Canvas class is one of the most commonly used classes. This class provides many useful functions such as obtaining mobile phone screen properties, drawing interface and event processing.
The Canvas class is a subclass of Displayable, which is mainly used to handle low-level events, such as keyboard key events, and programs that need to draw the screen. In the actual use process, the functions provided by this class are generally used by inheriting Canvas. The Canvas class is an abstract class, and the paint method must be overridden when inheriting this class.
The GameCanvas class provides the basic game user interface. In addition to the features inherited from Canvas (commands, input events, etc.), it also provides game-specific features, such as back-screen buffering and the ability to query keyboard state. This is also the two advantages that GameCanvas has compared with Canvas. Look at the game screen:
When the process controller goes to the game running interface, the game canvas MyGame class is used.

Here is a screenshot of the game:

Figure 7 Game screenshot
Let's look at the class declaration:

public class MyGame extends GameCanvas implements Runnable
{
}
The canvas program we use is inherited from GameCanvas This class, which also derives Runnable Interface to implement the function of generating a new thread.
procedural run method:
public void run() 
	{
		long st = 0;
        long et = 0;
        Graphics g = getGraphics();
        for(stage = 2;stage <= 4;stage++)
        {
        	flag = true;
        	g.setColor(0,0,0);
        	g.fillRect(0,0,getWidth(),getHeight());
        	g.setColor(255,255,0);        	g.setFont(Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_BOLD,Font.SIZE_LARGE));
g.drawString("No. ” + (stage -1)+ " close",getWidth()/2-30,getHeight()/2-10,Graphics.TOP|Graphics.LEFT);
        	flushGraphics();		
        	try { Thread.sleep(1000);} 
catch (InterruptedException e1) {}
			CREAT_STAGE();   //	Call the method that creates the level
        	try {Thread.sleep(500);} 
        	catch (InterruptedException e1) {}
			mpaint(g);
			isKey = true;
	        while(flag)   //The game officially starts
	        {
	        	while(ispause)  //Determine whether to press pause
	        	{
	        		try{ Thread.sleep(100); }
	        		catch(Exception e){}
	        	}
	            st = System.currentTimeMillis();
	            StartGameTime = System.currentTimeMillis();
	       	            INPUT_KEY();       //call button method

	   	            PENG_ZHUANG();    //methods that invoke various judgments and actions
	   	    	movMing();    //Call the method to refresh the screen
	            mpaint(g);
	            et = System.currentTimeMillis();
	            if((et-st)<rest)
	            {
                try { Thread.sleep(rest-(et-st)); }
catch(Exception e){}
	            }}
	        if(isEndGame)      //Determine whether to lose the game
	        {
		        if(islose)
		        {
		        	EedGameTime = System.currentTimeMillis();
		        	g.setColor(0,0,0);
		        	g.fillRect(0,0,getWidth(),getHeight());
		        	g.setColor(255,255,0);		        	g.setFont(Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_PLAIN,Font.SIZE_LARGE));
		        	g.drawString("you failed! ",getWidth()/2-40,getHeight()/2-20,Graphics.TOP|Graphics.LEFT);
		        	flushGraphics();
		        	try { Thread.sleep(3000); }
catch(Exception e){}
//	                init_Game();
	                break;
		        }}} 
        if(isEndGame)      //Determine whether to win the game
        {
	        if(!islose)
	        {
	        	EedGameTime = System.currentTimeMillis();
	        	g.setColor(0,0,0);
	        	g.fillRect(0,0,getWidth(),getHeight());
	        	g.setColor(255,255,0);
	g.setFont(Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_PLAIN,Font.SIZE_LARGE));
	        	g.drawString("You are victorious! ",getWidth()/2-40,getHeight()/2-20,Graphics.TOP|Graphics.LEFT);
	        	flushGraphics();
	        	try {Thread.sleep(3000); }
catch(Exception e){}
//	            init_Game();
	        } 
//	        GetScore();
	        if (score > 0)
	        {
		        GameName in = new GameName();
		        GameMenu.display.setCurrent(in);
		        in.start();
	        }
	        else
	        {
		        GameMenu.current = GameMenu.MY_MENU;
		        GameMenu.show();
	        }} } }

in the thread, via
1. Call the method CREAT_STAGE() to create a level;
2. Determine whether to press the pause while(ispause)
3. Call the key method INPUT_KEY();
4. Call various judgment and action methods PENG_ZHUANG();
5. Call the method movMing() to refresh the screen;
6. Determine whether to lose the game if(isEndGame)
7. Determine whether to win the game if(isEndGame)
to continuously monitor the game.

4.4.3 Implementation of the GamePlayer class of the player sprite
The Sprite class is a basic visual element that inherits from Layer and is used to store multiple frames. Different frame s can be displayed alternately to form dynamic effects. The picture can be flipped and reversed, and the display status of all directions can be easily obtained from a single protagonist image. Compared with the original Canvas drawing, it is much simpler to draw the protagonist images in all directions in the png image. Sprite can also read the image from the integrated image. When reading the image, the large image will be decomposed into several small images of equal width and height. Each small picture has a corresponding serial number according to its arrangement order, and the corresponding picture can be drawn by calling its serial number in the program. Players and monsters in this program are inherited by Sprite. In some cases, to control the flip of the protagonist, especially the process of displaying multiple images together, if the shared anchor point of multiple images is set at the usual upper left corner, it will be difficult to control, because many flips are based on other points. Reference electrical (eg, center point). Thus, the concept of reference point is introduced. The reference point is determined by the defineReferencePixel function to determine the coordinates when the picture state is not flipped. The default is the (0,0) point, if desired, the reference point can be set outside the frame boundaries.
In this program, due to the limited functions of the Sprite class provided in J2ME, I wrote a GamePlayer class to inherit the Sprite class and expanded more functions.

public class GamePlayer extends Sprite
{
}
Collision detection in the game and in the background is always difficult. In this program, it is implemented like this:
public void isPeng(int x,int y,int Array[][],int N)
{
for(int i = 0; i < 20; i++)
{			
for(int j = 0; j< 18; j++)
	{			
		if(Array[i][j] == N)
		{	
			if (!MyGame.isU)
			{
				if( Length * j <= x + this.getWidth() /2 && Length *(j + 1) >= x + this.getWidth() /2  && 10 + Length * i <= y  && 10 + Length *(i + 1) >= y)
				{
					this.setPosition(this.getX(),  20 + Length *(i + 1));
						System.out.println("UP: "+getY());
				}
//left
				if( Length * j <= x + 1 && Length *(j + 1) >= x + 1 && 10 + Length * i <= y + this.getHeight()/2 && 10 + Length *(i + 1) >= y + this.getHeight()/2)
				{
					this.setPosition( Length * (j + 1),this.getY());
					}
					if( Length * j <=x + this.getWidth() - 1 && Length *(j + 1) >= x + this.getWidth() –1 && 10 + Length * i <= y + this.getHeight()/2 && 10 + Length *(i + 1) >= y + this.getHeight()/2)
				{
				this.setPosition(Length * j - this.getWidth() ,this.getY());
}
				}
				//lower left
			if( Length * j <= x + 3&& Length *(j + 1) >= x + 3 && 10 + Length * i <= y + this.getHeight() && 10 + Length *(i + 1) >= y + this.getHeight())
			{
				this.setPosition(this.getX(),  Length * (i -1));
}
			//lower right
			if( Length * j <= x +this.getWidth() -3 && Length *(j + 1) >= x + this.getWidth() -3  && 10 + Length * i <= y + this.getHeight() && 10 + Length *(i + 1) >= y + this.getHeight())
			{
this.setPosition(this.getX(),  Length * (i - 1));
Length * i:+Length * (i-1));
			}
	
		}		
}		

Collision detection with the background is achieved by looking at the background array and player coordinates.

4.4.5 Implementation of the SoundEffects class
Sound effects are an essential part of a game, without the vivid music effects, the game experience will be greatly reduced. And of course we can't live without sound in our game.
The PlayMusic class in our game program is the sound effect class in the game. The main function of this class is to use the MIDP2.0 Media API to play the sound effects in the game: background music and the prompt sound for the end of the game.
We create the player with private Player createPlayer(String filename, String f, int i). The filename in this method is the relative path of the sound file to be played, f is the format of the music file to be played, and i is used to control the number of times the music is played. Before playing a sound, we all need to call the stop method to stop the sound (if the sound is not playing, this method has no effect). The sound in the game we use the startPlayer method to play. When we need to play the sound in the game, we call the corresponding method in this class.

5 Some important problems encountered in the process of programming
5.1 Questions about collisions
The first and most important problem to be solved in the game is the realization of collision detection and the effect of collision. There are two types of collision detection in pinball games: collision detection between sprites and sprites and collision detection between sprites and block layers.

The collision detection between the sprite and the sprite can directly call the collidesWith() method in the Sprite class or re-create the collidesWith() method in the Sprite class and call for collision detection. In this game program we use the latter. This performance is still very good.

Then there is the collision detection between the sprite and the layer, that is, the collision detection between the protagonist and the brick. The collidesWith() method rewritten in our sprite detects the collision between them. At this time, we have a problem of how to judge which brick collided with the ball. What I use is to achieve collision detection with the background by looking at the background array and player coordinates, but the effect is not very satisfactory. So far, in the many tests we have passed, there have been no errors such as misjudgment and inability to judge. However, the effect is not ideal, and I will continue to explore more refined and efficient algorithms.

5.2 About the display problem of the game screen
In the later test, it was found that when the game resumed the game after being suspended, the game screen returned to the screen at the beginning of the game, not the game screen when the game was suspended. After many debuggings, it was found that the problem was in the MyGameCanvas class.

After carefully reading the relevant information, it is found that the creation and operation of the thread is started by calling its own function start() to mobilize the run() function to start running. When the run() method is executed, the thread ends. Once a thread finishes executing, the instance cannot be restarted, only a new instance can be regenerated and a thread is started again. In view of this, we decided to set a pause flag pause in the run() of the MyGameCanvas class.

This implements the pause (suspend) function of the game. When the game is resumed, the game screen is the screen when we paused.

in conclusion
This program design realizes the development of the fortress game on the mobile phone with J2ME as the platform, which has certain playability and complexity. After careful debugging and troubleshooting, most of the problems have been solved.

Through the conception, design, code writing and debugging of the mobile game "Dune Castle", I further learned the J2ME platform and gained a new understanding of mobile game programming. As far as the modules I have done, I have a better understanding of the technology in J2ME such as menu, sound, canvas, etc. A simple menu has different writing and some complex technology behind it. What I have made now is the 1.0 version of the game, which has realized the basic functions of the game, and is still a long way from a mobile game in the full sense:
1. The game only runs on the emulator and has not been debugged on the real machine;
2. The option interface of the game has not been beautified with any effect;
3. Can adjust the volume of the sound and switch the background music.
This game is a small casual game. If you can continue to improve the menu functions of the game and increase the playability of the game, then this game will be a relatively popular mobile game.

references
[1] Hu Xuhuai, Yang Zhihe, Li Huan. J2ME Mobile Device Programming [M]. Beijing: Tsinghua University Press, 2005.
[2] Li Zhenpeng, Gong Jian. Detailed Explanation of J2ME Mobile Game Development Technology [M]. Beijing: Tsinghua University Press, 2006.
[3] Zhan Jianfei. J2ME Development Refinement [M]. Beijing: Electronic Industry Press, 2006.
[4] Shi Zheng. J2ME Technical Reference Manual [M]. Beijing: Electronic Industry Press, 2004.
[5] Micro Java. JAVA mobile phone development [M]. Beijing: China Railway Press, 2003.
[6] Wen Yiyang. J2ME MIDP 1.0/2.0 Wireless Device Programming Guide [M]. Beijing: Peking University Press, 2004.

Thanks
omit

5. Resource download

The source code and complete paper of this project are as follows. Friends who need it can click to download. If the link is invalid, you can click the card below to scan the code for self-service download.

serial numberA full set of resources for graduation design (click to download)
The source code of this projectDesign and implementation of fortress game based on java+J2ME (source code + documentation)_java_J2ME_fortress game

Tags: Java jvm Game Development

Posted by jswash on Thu, 06 Oct 2022 06:08:35 +1030