1、用java实现推箱子sokoban游戏推箱子游戏一、功能描述: 可以通过面板上的按钮或是键盘上的pageup,pagedown键选择上下关 可以通过面板上按钮或是键盘上的Backspace键后退,一直后退自己想要的位置,知道游戏开始时的位置。 可以通过面板上的按钮或是键盘上的字母r重新开始当前关卡游戏。 可以在复选框选择想要玩的关卡。二、界面及运行截图 三、源代码(三部分)1、地图类package box;import java.io.BufferedReader;import java.io.File;import java.io.FileNotFoundException;import j
2、ava.io.FileReader;/读取字符文件类FileReaderimport java.io.IOException;public class map int map=new int2020; int manX,manY; public map(int level) String filepath=mapc/+level+.txt; File file = new File(filepath); FileReader fr = null;/利用FileReader流来读取一个文件中的数据 BufferedReader br = null;/字符读到缓存里 try fr = new Fi
3、leReader(file); br = new BufferedReader(fr); for (int i = 0; i 15; i+) String line = br.readLine();/以行为单位,一次读一行 利用BufferedReader的readLine,读取分行文本 byte point = line.getBytes();/将字符串转换为字节数组 for (int j = 0; j 15; j+) mapij = pointj - 48;/ 根据ASCall码表要减掉30H(十进制的48) if (mapij = 5 | mapij = 6 | mapij = 7| m
4、apij = 8) manX = i; manY = j; catch (FileNotFoundException e) e.printStackTrace();/深层次的输出异常调用的流程 catch (IOException e) e.printStackTrace();/深层次的输出异常调用的流程 catch(NullPointerException e) e.printStackTrace();/深层次的输出异常调用的流程 finally if (br = null) try br.close(); catch (IOException e) e.printStackTrace();
5、 br = null; if (fr = null) try fr.close(); catch (IOException e) e.printStackTrace(); fr = null; public int getMap() return map; public int getManX() return manX; public int getManY() return manY; 2、游戏运行类package box;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionList
6、ener;import java.awt.event.ItemEvent;import java.awt.event.ItemListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.*;import javax.swing.*;public class pushbox extends JFrame implements KeyListener,ActionListener map map_level=new map(1); /首次获取地图 int map=new int
7、1515; /地图上每个位置所对应的图片 int map_restart=new int1515; /备用图片 static int manX,manY; /人所处的位置 static int level=1; /所处关卡 static int step=0; Image picture; /地图上的所有图片 ImageIcon image=new ImageIcon10; Stack back_stack = new Stack(); /存储所前行的路径 JButton next,previous,back,restart,exit; /按钮:下一关,上一关,重新开始,退出 String c
8、urrent_level=第+level+关; /当前所处关卡(右上角显示文本) String level_button=new String13; /复选框的容 JComboBox selectBox; /选关复选框 final int Up = 0; final int Down = 1; final int Left = 2; final int Right = 3; int dir_x = -1, 1, 0, 0; int dir_y = 0, 0, -1, 1; public pushbox() super(推箱子); getmap(map); previous=new JButto
9、n(上一关); next=new JButton(下一关); restart=new JButton(重新开始); back=new JButton(后退); exit=new JButton(退出游戏); for(int i=0;i13;i+) level_buttoni=第+Integer.toString(i+1)+关; selectBox=new JComboBox(level_button); FlowLayout layout=new FlowLayout(); /布局模式 Container c=getContentPane(); c.setLayout(layout); lay
10、out.setAlignment(FlowLayout.CENTER); /控件在布局中的位置 c.setBackground(Color.CYAN); /背景色 c.add(previous); c.add(next); c.add(back); c.add(restart); c.add(selectBox); c.add(exit); previous.addActionListener(ActionListener) this); previous.addKeyListener(this); next.addActionListener(ActionListener) this); n
11、ext.addKeyListener(this); back.addActionListener(this); back.addKeyListener(this); restart.addActionListener(ActionListener) this); restart.addKeyListener(this); exit.addActionListener(ActionListener) this); exit.addKeyListener(this); selectBox.addItemListener( /监听复选框点击事件 new ItemListener() public v
12、oid itemStateChanged(ItemEvent e) if(e.getStateChange()=e.SELECTED) step=0; back_stack.clear(); /每次重新选关后都要清空路径栈 level=selectBox.getSelectedIndex()+1; /获取所选的关卡 map_level=new map(level); /重新获取对应关卡的地图 getmap(map); current_level=第+level+关; /右上角提示所处关卡文本的更新 repaint(); /重画地图 requestFocus(); /重新获取焦点(因为按钮事件后
13、键盘事件不起作用) ); for(int k=0;k10;k+) imagek=new ImageIcon(picture/+k+.png); /获取图片 picture=new Image image0.getImage(), image1.getImage(), image2.getImage(), image3.getImage(), image4.getImage(), image5.getImage(), image6.getImage(), image7.getImage(), image8.getImage(), image9.getImage() ; this.setFocus
14、able(true); this.addKeyListener(KeyListener)this); setSize(640,640); setVisible(true); /判断是否通关(方法是,检查地图中是否还有箱子编号4) public Boolean pass() int p=0; for(int i=0;i15;i+) for(int j=0;j15;j+) if(mapij=4) p+; if(p=0) return true; else return false; /获取地图上每个位置所对应的图片编号 public void getmap(int map) for(int i=0
15、;i15;i+) for(int j=0;j15;j+) mapij=map_level.mapij; manX=map_level.manX; manY=map_level.manY; public void paint(Graphics g) super.paint(g); /提示信息 back_stack.push(Down + 5); /这里是一个细节,先将“DOWN”存入栈 g.drawString(current_level,500,90); g.drawString(第+step+步,400,90); g.drawString(用键盘上的R重新开始,Q退出游戏,200,565);
16、 g.drawString(用键盘pageup,pagedown切换关卡,200,580); g.drawString(用键盘上的上下左右键控制人的移动,200,600); g.drawString(用键盘上的Backspace键后退,200,620); /在面板上画地图 for (int i = 0; i 15; i+) for (int j = 0; j 15; j+) g.drawImage(picturemapij,100+30*j,100+30*i, this); public void Step(Graphics g) g.setColor(Color.cyan); g.drawS
17、tring(第+step+步,400,90); step+; g.setColor(Color.BLACK); g.drawString(第+step+步,400,90); public void move(int dir, Graphics g) int man = dir + 5; int dx = dir_xdir; int dy = dir_ydir; int x = manX; int y = manY; manX += dx; manY += dy; int origin_picture = mapmanXmanY; int next_picture = mapmanX + dxm
18、anY + dy; if(mapmanXmanY=4|mapmanXmanY=3)&(mapmanX+dxmanY+dy=2|mapmanX+dxmanY+dy=4|mapmanX+dxmanY+dy=3) /上面是箱子,箱子上面是墙或箱子 manX -= dx; manY -= dy; return ; if(mapmanXmanY=2) /上面是墙 manX -= dx; manY -= dy; return ; if(mapmanXmanY=1|mapmanXmanY=9) /人上面是草地或是目的地 g.drawImage(pictureman,100+30*manY,manX*30+1
19、00,this); /人的朝向变化 if(mapxy=9) /原来位置是目的地 g.drawImage(picture9,100+30*y,100+30*x,this); else /原来位置是草地 g.drawImage(picture1,100+30*y,x*30+100,this); mapxy=1; Step(g); if(mapmanXmanY=4|mapmanXmanY=3)&mapmanX+dxmanY+dy=1) /上面是箱子,箱子上面是草地 g.drawImage(pictureman,100+30*manY,manX*30+100,this); /人的朝向变化 if(map
20、manXmanY=3) /若是移动一大目的地的箱子,原箱子位置值为9 mapmanXmanY=9; if(mapxy=9) /原来位置是目的地 g.drawImage(picture9,100+30*y,100+30*x,this); else /原来位置是草地 g.drawImage(picture1,100+30*y,x*30+100,this); mapxy=1; g.drawImage(picture4,100+30*(manY+dy),(manX+dx)*30+100,this); /草地位置变箱子 mapmanX+dxmanY+dy=4; Step(g); if(mapmanXma
21、nY=4|mapmanXmanY=3)&mapmanX+dxmanY+dy=9) /上面是箱子,箱子上面是目的地 g.drawImage(pictureman,100+30*manY,manX*30+100,this); /人的朝向变化 if(mapmanXmanY=3) /若是移动一大目的地的箱子,原箱子位置值为9 mapmanXmanY=9; else mapmanXmanY=0; if(mapxy=9) /原来位置是目的地 g.drawImage(picture9,100+30*y,100+30*x,this); else /原来位置是草地 g.drawImage(picture1,10
22、0+30*y,x*30+100,this); mapxy=1; g.drawImage(picture3,100+30*(manY+dy),(manX+dx)*30+100,this); /目的地位置变箱子 mapmanX+dxmanY+dy=3; Step(g); back_stack.push(next_picture); back_stack.push(origin_picture); back_stack.push(manY); back_stack.push(manX); back_stack.push(man); if(pass() JOptionPane.showMessageD
23、ialog(null, 恭喜你过关了!); /键盘事件 public void keyPressed(KeyEvent e) Graphics g=getGraphics(); int dir ; switch(e.getKeyCode() case KeyEvent.VK_UP: dir = Up; move(dir, g); break; case KeyEvent.VK_DOWN : dir = Down; move(dir, g); break; case KeyEvent.VK_LEFT: dir = Left; move(dir, g); break; case KeyEvent.
24、VK_RIGHT: dir = Right; move(dir, g); break; case KeyEvent.VK_BACK_SPACE: back.doClick(); break; case KeyEvent.VK_PAGE_DOWN : next.doClick(); break; case KeyEvent.VK_PAGE_UP: previous.doClick(); break; case KeyEvent.VK_R: restart.doClick(); break; case KeyEvent.VK_Q : exit.doClick(); break; public vo
25、id keyReleased(KeyEvent e) public void keyTyped(KeyEvent e) /悔步后退 public void step_back(Graphics g) g.setColor(Color.cyan); g.drawString(第+step+步,400,90); step-; g.setColor(Color.BLACK); g.drawString(第+step+步,400,90); public void Back() if(back_stack.size()=2) return; int dir=back_stack.pop() - 5; /
26、获取上一步的方向 int s = back_stack.pop(); int t = back_stack.pop(); int origin_picture = back_stack.pop(); int netx_picture = back_stack.pop(); int pre_dir = back_stack.lastElement(); Graphics g=getGraphics(); int dx = dir_xdir; int dy = dir_ydir; g.drawImage(pictureorigin_picture,100+30*t,100+30*s,this); g.drawImage(picturenetx_picture,100+30*(t+dy),100+30*(s+dx),this); g.drawImage(picturepre_dir,100+30*(t-dy),100+30*(s-dx),this); manX = s - dx; manY = t - dy; mapst = origin_picture; maps+dxt+dy = netx_picture;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1