Big Big Wolf Series - Custom Level Sokoban (source code included)

foreword

insert image description here
"Author's Homepage" : Sprite Youbai Bubbles
"Personal Website" : Sprite's personal website
"Recommendation Column" :

Java one-stop service
Front-end cool code sharing
uniapp-from construction to promotion
From 0 to hero, Vue's road to god
Solving algorithm, one column is enough
Let's talk about architecture from 0
The subtle way of data circulation

Please add a picture description

Summary

Society is progressing, and people's quality of life is also improving day by day. High-intensity pressure also ensued. There is an urgent need for new and effective ways to relieve stress in society. This design meets the needs of the society. The Java Sokoban game allows people to experience the fun of the game in their spare time. It has the characteristics of simple operation and easy use.
The gameplay of the Sokoban game is very simple - control the character to bypass obstacles and reach the destination. This graduation project is based on the Java language. The game map is made into a general level design, and the level is realized by a two-dimensional array. The value range is set in the two-dimensional array to represent different objects, and the traversal algorithm of the two-dimensional array is used to load the corresponding picture to realize the initialization state of the game picture. At the same time, the game map level design is realized by initializing multiple different two-dimensional arrays. The method is ingenious and simple, and effectively solves the problem of image layout. Make full use of class and method calls to realize the initialization of game levels. Use the method of reading the key value to judge that the game character moves, stops, and reaches the destination. The soothing music and interesting steps are sure to arouse the interest of many people. As a game with a long history, it can also arouse people's nostalgia and resonance.

Game overall structure and code analysis

Please add a picture description

Interface frame and button design

The interface of this game is simple and clear, the operation interface is beautiful, and it has a strong ability to bring in. The game operation modules are divided into: "Regret one step", "Restart", "Previous level", "Next level", "First level", "Final level", "Select level" and "Music level". The next level of the current level; "Level 1": The game system defaults to the first level, and this button allows players to jump directly to the first level from other levels; "Final level": You can jump to the last level, which is the default last
level of
the game system .



mainFrame()
	{
    
    
		super("推箱子v2.0");
		setSize(720,720);
		setVisible(true);
		setResizable(false);
		setLocation(300,20);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Container cont=getContentPane();
		cont.setLayout(null);
		cont.setBackground(Color.black);
		Menu choice=new Menu("    选项");
		choice.add(renew);choice.add(last);choice.add(next);choice.add(choose);choice.add(back);
		choice.addSeparator();choice.add(exit);
		renew.addActionListener(this);
		last.addActionListener(this);
		next.addActionListener(this);
		choose.addActionListener(this);
		exit.addActionListener(this);
		back.addActionListener(this);
		Menu setmuc=new Menu("    设置音乐")
		setmuc.add(nor);setmuc.add(qin);setmuc.add(po);setmuc.add(guang);setmuc.add(eye);
		nor.addActionListener(this);
		qin.addActionListener(this);
		po.addActionListener(this);
		guang.addActionListener(this);
		eye.addActionListener(this);
		Menu help=new Menu("    帮助");
		help.add(about);
		about.addActionListener(this);
		MenuBar bar=new MenuBar();
		bar.add(choice);bar.add(setmuc);bar.add(help);
		setMenuBar(bar);                                        
}

Level selection module

"Select Level": Select the level you want to challenge. When game players want to choose a level independently, they can freely enter the level they want to jump into, which saves time. Players can effectively challenge themselves by passing through the selected level and connect to the last game progress.
Among them, part of the code of this part is:

void Tuixiangzi(int i)
	{
    
    
		Levelmap=new Readmap(i);
		Levelmaptmp=new Readmap(i);
		map=Levelmap.getmap();
		manX=Levelmap.getmanX();
		manY=Levelmap.getmanY();
		maptmp=Levelmaptmp.getmap();
		repaint();
	}
	int maxlevel(){
    
    return max;}
	public void paint(Graphics g)
	{
    
    
		for(int i=0; i<20; i++)
			for(int j=0; j<20; j++)
		    {
    
    
			    g.drawImage(myImage[map[j][i]],i*len,j*len,this);
			}		
		g.setColor(new Color(0,0,0));
		g.setFont(new Font("楷体_2312",Font.BOLD,30));
		g.drawString("现在是第",150,40);
		g.drawString(String.valueOf(level),310,40);
		g.drawString("关",360,40);
	}

insert image description here

map making

The map is stored in the form of a two-dimensional array, and different numbers represent different meanings. In the map file of this mini-game, the ten numbers from 0 to 9 are defined as follows:
Number 0: Represents an undefined area; Number 1 : Represents
obstacles (or boundaries); Number 2 : Represents
grass ; For example, as shown in the figure below (the map file of the two-dimensional array is on the left, and the corresponding mini-game interface is on the right): the gameplay of the Sokoban mini-game, its main function is to provide users with a good game interface, and the game includes map files of 50 levels. The map file is written first, and all interface information is stored in a 20*20 two-dimensional array in the form of numbers, and these map files are unified in a map file, which is convenient for the program to call the map file. Then, each level will redraw the map according to these array data, so as to achieve the usability of the mini-game and its corresponding purpose. Part of the code is as follows:








insert image description here

private int[][] mymap=new int[20][20];
	FileReader r;
	BufferedReader br;
	String bb="";
	int[] x;int c=0;
	Readmap(int k)
	{
    
    
		level=k;
		String s;
		
			File f=new File("maps\\"+level+".map");
			r=new FileReader(f);
			br=new BufferedReader(r);
		}
		
			while ((s=br.readLine())!=null)
			{
    
    
				bb=bb+s;
			}
		byte[] d=bb.getBytes();
		int len=bb.length();
		int[] x=new int[len];
		for(int i=0;i<bb.length();i++)x[i]=d[i]-48;
		for(int i=0;i<20;i++)
		{
    
    
			for(int j=0;j<20;j++)
		    {
    
    
				mymap[i][j]=x[c];
		        if(mymap[i][j]==5)
		        {
    
    
					mx=j;my=i;
		        }
		        c++;
		    }
	    }

The Algorithm of Moving the Little Man and the Box

The movement of the villain and the box includes the positive movement and the negative movement of "one step of regret".
Positive movement: The up, down, left, and right movement of the villain is a judgment algorithm, and its judgment is based on judging whether the front of the villain is grass or a box or an obstacle (or boundary). If it is an obstacle or a boundary, it cannot be moved; if there is no box or an obstacle, it can move freely; and if there is a box, it is necessary to judge whether the box can be moved, and finally discuss the position where the box is pushed, the position where the villain moves, and the graphic changes of their original position and the new position that is blocked, etc. It is necessary to use an algorithm to redraw the map and fill in the gaps. After the algorithm is judged, the data is sent out and recorded in a stack for use when "regret one step".
Negative movement: Judging by the data recorded in the stack, the movement direction of the villain in the previous step and the algorithm used in the movement, the code is re-run in reverse, and the map is drawn and refreshed to achieve the state of the previous step.
Among them, part of the code of this part is:

void moveup()
	 {
    
    
		if(map[manY-1][manX]==2||map[manY-1][manX]==4)
		{
    
    
			if(maptmp[manY][manX]==4||maptmp[manY][manX]==9)
				map[manY][manX]=4;
			else map[manY][manX]=2;
			map[manY-1][manX]=8;
			repaint();manY--;mystack.push(10);
		}
		else if(map[manY-1][manX]==3)
		{
    
    
			if(map[manY-2][manX]==4)
			{
    
    
				if(maptmp[manY][manX]==4||maptmp[manY][manX]==9)
					map[manY][manX]=4;
				else map[manY][manX]=2;
				map[manY-1][manX]=8;
				map[manY-2][manX]=9;
				repaint();manY--;mystack.push(11);
			}
			else if(map[manY-2][manX]==2)
			{
    
    
				if(maptmp[manY][manX]==4||maptmp[manY][manX]==9)
					map[manY][manX]=4;
				else map[manY][manX]=2;
				map[manY-1][manX]=8;
				map[manY-2][manX]=3;
				repaint();manY--;mystack.push(11);
			}
			else {
    
    map[manY][manX]=8;repaint();}
		}
		else if(map[manY-1][manX]==9)
		{
    
    
			if(map[manY-2][manX]==4)
			{
    
    
				if(maptmp[manY][manX]==4||maptmp[manY][manX]==9)
					map[manY][manX]=4;
				else map[manY][manX]=2;
				map[manY-1][manX]=8;
				map[manY-2][manX]=9;
				repaint();manY--;mystack.push(11);
			}
			else if(map[manY-2][manX]==2)
			{
    
    
				if(maptmp[manY][manX]==4||maptmp[manY][manX]==9)
					map[manY][manX]=4;
				else map[manY][manX]=2;
				map[manY-1][manX]=8;
				map[manY-2][manX]=3;
				repaint();manY--;mystack.push(11);
			}
			else {
    
    map[manY][manX]=8;repaint();}
		}
		if(map[manY-1][manX]==1)
		{
    
    
			map[manY][manX]=8;repaint();
		}
	}

The villain moves the module up and down

In this mini-game system, the movement of villains and boxes should be able to bring players a more realistic visual experience, so as to reflect the effectiveness and entertainment of the system. The player controls the villain and pushes the box on the grass to avoid obstacles and blind corners to reach the designated end position.
Among them, this part of the code is divided into moving up, down, left, and right. The principle of the code is the same, turning to the judgment of the next step.

void moveleft(){
    
    
……}
void movedown(){
    
    
……}
void moveright(){
    
    
……}

The code for the villain to turn backwards is as follows:

void backup(int t)
	{
    
    
		int n=t;
		if(n==10)
		{
    
    
			if(maptmp[manY][manX]==4||maptmp[manY][manX]==9)
			{
    
    
				map[manY][manX]=4;
			}
			else map[manY][manX]=2;
		}
		else if(n==11)
		{
    
    
			if(maptmp[manY][manX]==4||maptmp[manY][manX]==9)
			{
    
    
				map[manY][manX]=9;
			}
			else map[manY][manX]=3;
			if(maptmp[manY-1][manX]==4||maptmp[manY-1][manX]==9)
			{
    
    
				map[manY-1][manX]=4;
			}
			else map[manY-1][manX]=2;
		}
		map[manY+1][manX]=8;
		repaint();manY++;
	}

insert image description here

Regret module

In the Sokoban mini-game, the storage of data is very important, otherwise the operation of "one step of regret" cannot be performed. This mini-game system uses the stack storage method to store and control the movement of villains and boxes and the transformation of map files. The "one step regret" operation allows the player to regret this step, which can avoid blocking the writing caused by a momentary mistake and save the player time to start over.
Among them, part of the code of this part is:

else if(e.getSource()==btnback||e.getSource()==back)
		{
    
    
			if(panel.isMystackEmpty())JOptionPane.showMessageDialog(this, "您还未移动!!!");
			else
			{
    
    
				switch(panel.back())
				{
    
    
					case 10:panel.backup(10);break;
					case 11:panel.backup(11);break;
					case 20:panel.backdown(20);break;
					case 21:panel.backdown(21);break;
					case 30:panel.backleft(30);break;
					case 31:panel.backleft(31);break;
					case 40:panel.backright(40);break;
					case 41:panel.backright(41);break;
				}
			} 

insert image description here

music control

In the Sokoban mini-game, the choice of music is very important, and the entertainment of the game can be improved through music selection. It allows gamers to play games in an easier and faster environment, and at the same time, the transition of the game with the level is also a major feature of this design. The Sequence class and the Sequencer container in the Java MIDI technology and the getSequence() method therein are used.
Among them, part of the code of this part is:

public void itemStateChanged(ItemEvent ie)
	 {
    
    
		int no=jc.getSelectedIndex();
		switch(no)
		{
    
    
			case 0:sound.setMusic("nor.mid");
					 if(sound.isplay())
					 sound.mystop();
					 sound.loadSound();
					 btnmuc.setLabel("音乐关");
					 nor.setEnabled(false);
					 qin.setEnabled(true);
					 guang.setEnabled(true);
					 eye.setEnabled(true);
					 po.setEnabled(true);
panel.requestFocus();
break;
			case 1:sound.setMusic("qin.mid");
					 if(sound.isplay())
					 sound.mystop();
					 sound.loadSound();
					 btnmuc.setLabel("音乐关");
					 nor.setEnabled(true);
					 qin.setEnabled(false);
					 guang.setEnabled(true);
					 eye.setEnabled(true);
					 po.setEnabled(true);
panel.requestFocus();
break;
			case 2:……
			case 3:……
			case 4:sound.setMusic("eyes on me.mid");
					if(sound.isplay())
					sound.mystop();
					sound.loadSound();
					btnmuc.setLabel("音乐关");
					nor.setEnabled(true);
					qin.setEnabled(true);
					guang.setEnabled(true);
					eye.setEnabled(false);
					po.setEnabled(true);
panel.requestFocus();break;
			}

The effect is as shown in the figure
insert image description here

Game video display and download link

Sokoban

You can leave a message in the comment area for the download link, and I will send a private message.
z
You can download it directly at the top of the article title

Guess you like

Origin blog.csdn.net/Why_does_it_work/article/details/131857925