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);
 }
}

 

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值