Java游戏程序 - 推箱子

推箱子 游戏界面

 

第一个Java游戏程序  - 推箱子 

本人是写面向过程程序长大的,对游戏程序一窍不通。最初的想法是做一个超级玛丽来自己玩玩,结果完全没思路,遂找CC老师指引人生方向。最终的结论是,推箱子最简单,写出了推箱子在试试写贪食蛇,完成了这两个再考虑超级玛丽。 >_< |

这个推箱子程序功能比较简单,只有一个关卡,还是很弱智的。可以通过文件读取的方式来扩展关卡,暂时就不写了。

 

下面说说第一次做一个游戏程序的思路:

首先,做界面真是一件烦人的事情。若只是考虑核心代码,二三十行就能搞定。做了图形界面,加上几个功能按钮,这么弱智一个程序就快到三百行了……

我把界面分为三块,上、中、下。顶部一个Reset按钮,中部是游戏面板,底部留着暂时没用。中部是一个独立的类,取名GamePanel,继承了JPanel类并实现了KeyListener接口。游戏的基本功能和键盘事件监听都由GamePanel类独立完成。

游戏用两个二维数组表示地图,一个map[][]数组记录基本地形,空格、墙壁或是目标地点;另一个数组box[][]记录箱子所在位置。游戏者的坐标单独用一个Point变量player来记录。

制作过程中遇到一个郁闷的问题,就是中部的GamePanel总是捕捉不到到键盘事件。折腾了好久,发现当我把顶部按钮注释掉以后就能正常捕获,一旦把按钮显示出来就不行了。后来得知问题在于中部的组件没有获得输入焦点。加上this.requestFocusInWindow();强制使中部组件获得输入焦点以后,问题解决。

 

以下是游戏中用到的图片:

Box_box1.gifBox_box1.gif Box_box2.gifBox_box2.gif Box_floor.gifBox_floor.gif Box_wall.gifBox_wall.gif Box_trg.gifBox_trg.gif Box_player.gifBox_player.gif

(注意更改程序中图片的路径)

下面给出源代码:

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.*;

//Class GamePanel
//The main class of the game

class GamePanel extends JPanel implements KeyListener
{
 private static final long serialVersionUID = 1L;
 
 private char[][] map; //Map state
 private char[][] box;
 private int sX,sY;  //Map size
 private Point player,p; //Point of player
 private int Num=0;  //Number of boxs
 private Point[] boxs; //Points of boxs;
 //private Point[] trg; //Points of target
 //private Point[] path;
 //private int steps;
 private Point[] dir;
 
 private int size;
 private Image imgfloor;
 private Image imgwall;
 private Image imgplayer;
 private Image imgbox1;
 private Image imgbox2;
 private Image imgtrg;
 
 //method
 public GamePanel(char b[][],int w,int h,int size)throws Exception
 {
  
  sX = b.length;
  sY = b[0].length;
  Num = 0;
  
  map =   new char[sX][sY];
  box =   new char[sX][sY];
  player= new Point();
  p = new Point();
  boxs= new Point[sX*sY];
  
  dir = new Point[4];
  dir[0]= new Point(0,-1); //left
  dir[1]= new Point(-1,0); //up
  dir[2]= new Point(0, 1); //right
  dir[3]= new Point(1, 0); //down
  
  File parent = new File("E:/My Document/我的大学/JAVA/工作区/Program/src/images/");
  
  imgfloor = ImageIO.read(new File(parent,"Box_floor.gif"));  
  imgwall  = ImageIO.read(new File(parent,"Box_wall.gif"));
  imgplayer= ImageIO.read(new File(parent,"Box_player.gif"));
  imgtrg  = ImageIO.read(new File(parent,"Box_trg.gif"));
  imgbox1  = ImageIO.read(new File(parent,"Box_box1.gif"));
  imgbox2  = ImageIO.read(new File(parent,"Box_box2.gif"));
  
  this.size=size;
  
  //set Map
  for(int i=0;i<sX;i++){ 
   for(int j=0;j<sY;j++){
    switch(b[i][j]){
     case 'P': //Player
      map[i][j]='.';
      p.setLocation(i, j);
      break;
     case 'X': //Target
      map[i][j]='X';
      break;
     case 'B': //Box
      map[i][j]='.';
      boxs[Num++]=new Point(i, j);
      break;
     case '#': //Wall
      map[i][j]='#';
      break;
     case '.': //floor
      map[i][j]='.';
      break;
     default :
      map[i][j]='.';
      break;
    }
   }
  }//end set Map
  
  reset(); //reset Game
 }
 
 public void reset(){
  player.setLocation(p);
  for(int i=0;i<sX;i++)
   for(int j=0;j<sY;j++)
    box[i][j]=' ';
  for(int i=0;i<Num;i++)
   box[boxs[i].x][boxs[i].y]='B';
  //steps=0;
  repaint();
 }
 
 public void undo(){
  
 }
 
 public boolean judge(){
  for(int i=0;i<sX;i++)
   for(int j=0;j<sY;j++)
    if(box[i][j]=='B'&&map[i][j]!='X')
     return false;
  return true;
 }
 
 public void paint(Graphics g){
  //draw map
  for(int i=0;i<sX;i++){
   for(int j=0;j<sY;j++){
    switch(map[i][j]){
     case '.':
      g.drawImage(imgfloor, j*size, i*size, null);
      break;
     case '#':
      g.drawImage(imgwall, j*size, i*size, null);
      break;
     case 'X':
      g.drawImage(imgfloor, j*size, i*size, null);
      break;
    }
    if(box[i][j]=='B'&&map[i][j]=='X') g.drawImage(imgbox2, j*size, i*size, null);
    else if(box[i][j]=='B') g.drawImage(imgbox1, j*size, i*size, null);
    else if(map[i][j]=='X') g.drawImage(imgtrg, j*size, i*size, null);
   }
  }
  //draw player
  g.drawImage(imgplayer, player.y*size, player.x*size, null);
  
  g.drawRect(0, 0, sY*size, sX*size);
  
  //get Focus
  this.requestFocusInWindow(); /* ********* */
 }
 
 
 /* methods of KeyListener */
 
 public void keyPressed(KeyEvent e){
  int x=player.x;
  int y=player.y;
  int k,x0,y0;
  
  k=e.getKeyCode()-37;
  
  if(k<0||k>=4) return;
  
  x+=dir[k].x;
  y+=dir[k].y;

  if(x<0||x>=sX||y<0||y>=sY) return;
  if(map[x][y]=='#') return;
  
  if(box[x][y]!='B'&&(map[x][y]=='.'||map[x][y]=='X')){
   player.x=x;
   player.y=y;
  }
  if(box[x][y]=='B'){
   x0=x+dir[k].x;
   y0=y+dir[k].y;
   if(x0<0||y0<0||x0>=sX||y0>=sY) return;
   if(map[x0][y0]!='#'&&box[x0][y0]!='B'){
    box[x][y]=' ';
    box[x0][y0]='B';
    player.x=x;
    player.y=y;
   }
  }
  
  repaint();
  
  if(judge()){
            JOptionPane.showMessageDialog(null,"You win!");
   reset();
  }
 }
 
 public void keyReleased(KeyEvent e){}
 public void keyTyped(KeyEvent e){}
 
}


 
//Class PushBox
//Creat JFrame to Play the game

public class PushBox extends JFrame
{
 private static final long serialVersionUID = 1L;
 
 private JPanel top;
 private GamePanel center;
 private JPanel bottom;
 
 private JButton breset; //Button of reset
 private JButton bundo; //Button of undo
 
 private int width,height,size;
 private int sX,sY;
 
 //method of constitution
 public PushBox(char[][] b)throws Exception{
  super("PushBox Game");

  //set Window
  size=35;
  sX=b.length;
  sY=b[0].length;
  width=size*sY+10;
  height=size*sX+100;
  
  top     = new JPanel();
  center  = new GamePanel(b,width,height-100,size); //Panel of Game
  bottom  = new JPanel();
  breset = new JButton("Reset");
  bundo = new JButton("←Undo");
  
  //add Listener
  center.addKeyListener(center);
  breset.addActionListener(new ResetListener());
  bundo.addActionListener(new UndoListener());
  
  top.add(breset);
  //top.add(bundo);
  add(top,"North");
  add(center,"Center");
  add(bottom,"South");
  
  setSize(width,height);
  setVisible(true);
 }
 
 //classes of Listener
 class ResetListener implements ActionListener{
  public void actionPerformed(ActionEvent e){
   center.reset();
  }
 }
 class UndoListener implements ActionListener{
  public void actionPerformed(ActionEvent e){
   center.undo();
  }
 }
  
 //method main
 public static void main(String[] args)throws Exception{
  char[][] b=new char[5][6];
  
  b[0]="##X##P".toCharArray();
  b[1]="##.##.".toCharArray();
  b[2]=".B.#..".toCharArray();
  b[3]="X..B..".toCharArray();
  b[4]="##....".toCharArray();
  
  PushBox p=new PushBox(b);
  p.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 }
}

 

 

  • 0
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
基于JAVA推箱子游戏设计软件程序源码+word毕业论文文档. 基于JAVA推箱子游戏系统主要用于实现游戏推箱子功能,提供多种不同难度的关卡。本系统结构如下: (1)初始化模块: 该模块包括屏幕初始化和游戏第一关的初始化。屏幕初始化用于输出欢迎信息和操 (2)画图模块: 该模块主要是被其它模块调用,用于画墙、在空地画箱子、在目的地画箱子、画小人和画目的地。 (3)移动箱子模块: 该模块用于移动箱子,包括目的地之间、空地之间和目的地与空地之间的箱子移动。 (4)移动小人模块: 该模块用于控制小人移动,从而推动箱子到目的地。 (5)功能控制模块: 该模块是几个功能函数的集合,包括屏幕输出功能、指定位置状态判断功能和关卡重置功能。 目 录 摘 要 i Abstract ii 引 言 1 1 系统分析 2 1.1 技术可行性分析 2 1.1.1 可行性目的 2 1.1.2 可行性研究前提 2 1.1.3 算法可行性分析 2 1.1.4 平台选择 6 1.2 需求分析 6 1.2.1 引言 6 1.2.2 游戏需求 6 1.2.3 软硬件需求 9 1.2.4 接口控制 10 1.3 方案论证 10 1.3.1 C++语言的优点 10 1.3.2 Java语言的优点 11 1.3.3 C语言的优点 13 1.3.4 方案选择 14 2 概要设计 16 2.1 游戏设计分析 16 2.1.1 地图文件的引用 18 2.1.2 程序运逻辑 19 2.1.3 绘图 20 2.1.4 显示平台 22 2.2 注意事项 24 2.3 游戏流程图 24 2.4 函数模型 25 3 详细设计 28 3.1 游戏总体结构与代码 28 3.2 选关模块 29 3.3 地图的绘制形成 30 3.4 小人与箱子移动的算法 31 3.5 小人上下移动模块 33 3.6 悔棋模块 34 3.7 音乐控制 35 4 游戏测试 38 4.1 软件测试 38 4.1.1 软件测试简介 38 4.2 测试方法 38 4.3 测试步骤 38 4.4 游戏系统性能分析 41 5 项目经验与总结 42 6 参考文献 44 7 致谢 45 8 外文原文及中文翻译 46 引 言 策略性游戏可以锻炼人的思维能力还能缓解人的压力,使人们暂时忘却生活当中的烦恼,增强人们的逻辑思维能力,游戏的艺术美也吸引着越来越多的玩家和厂商,寓教于乐,在放松人们心情的同时还可以活跃双手。在人类的社会生活当中,游戏占有很大的比重,并且随着社会的发展而不断发展。而且游戏本身具有激发人类潜在行为的特质,是一种能够吸引人们参与其中的活动,其本身具有强烈的吸引力使游戏者卷入其中;再者适当的游戏、合理的时间安排,能够让玩家在娱乐的同时还可以锻炼其反应速度及灵敏程度,亦可让玩家从压力中释放出来。因此游戏逐渐成为人们生活中不可缺少的一部分,游戏产业也正逐步发展成熟。 经典的推箱子游戏是一个来自日本的古老游戏,目的是在训练你的逻辑思考能力。它的玩法也非常简单,在一个狭小的仓库中,要求把木箱放到指定的位置,稍不小心就会出现箱子无法移动或者通道被堵住的情况,所以需要巧妙的利用有限的空间和通道,合理安排移动的次序和位置,控制人物不停的移动将箱子推到目的位置才能顺利的完成任务。难点在于移动的位置,以及箱子到达指定位置的顺序,只有多加思考才能获得游戏的胜利。反复推敲,锻炼了人们的耐性。本次的开发尽量多的设置了关卡数目,增强游戏的耐玩性,同时在画面上有所提高,借鉴了许多达人的经验和技术,引发了我对游戏的热爱,丰富了个人生活,相信推箱子游戏在今后的社会总会越来越引人注目。 1 系统分析 1.1 技术可行性分析 1.1.1 可行性目的 通过推箱子游戏中使用的Java技术,让我能够更加熟练的使用Eclipse。同时了解相关运行环境的配置。将理论知识和实际操作结合起来。达到学以致用的目的。网上资料的查询极大的提高了我的自学能力。希望经过此次设计,锻炼自己的思考,解决问题的能力。对系统开发的流程有更深层次的理解,检验学习成果和实际动手能力,对底层知识有更深的了解。为今后的工作打好基础。 1.1.2 可行性研究前提 基本需求:通过规范的开发流程,采用面向对象的分析设计方法实现游戏美观,易玩,及时等特性。操作性方面主要通过键盘的借口实现,操作键位是上下左右。 主要开发目标:通过此次研究熟练Java的相关知识和技术的应用,界面美化的工作需要同学的帮助,了解团队和合作的重要,熟悉不同领域相关技术

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值