推箱子游戏(黄臻,潘方舟)

本文详细介绍了经典的推箱子游戏的实现,包括游戏规则、程序设计思路和关键代码实现。游戏采用Java编程,通过二维数组表示地图,利用枚举类型表示地图元素,实现了移动逻辑。文章还分享了作者在团队合作和游戏编程学习过程中的体验和反思。
摘要由CSDN通过智能技术生成
经典的推箱子是一个来自日本的古老游戏,目的是在训练你的逻辑思考能力。在一个狭小的仓库中,要求把木箱放到指定的位置,稍不小心就会出现箱子无法移动或者通道被堵住的情况,所以需要巧妙的利用有限的空间和通道,合理安排移动的次序和位置,才能顺利的完成任务。
推箱子游戏界面


性能测试:








程序设计的思路
 
我们把地图想象成一个网格,每个格子就是工人每次移动的步长(这里为30像素),也是箱子移动的距离,这样问题就简化多了。首先我们设计一个mapRow *mapColumn的二维数组map。按照这样的框架来思考。对于格子的(X,Y)两个屏幕像素坐标,可以由二维数组下标(i,j)换算。
换算公式为:leftX + j * 30, leftY + i* 30
每个格子状态值分别用枚举类型值:
    // 定义一些常量,对应地图的元素
    final byte WALL = 1, BOX = 2, BOXONEND = 3, END = 4, MANDOWN = 5,
    MANLEFT = 6, MANRIGHT = 7, MANUP = 8, GRASS = 9,
    MANDOWNONEND = 10,MANLEFTONEND = 11,
    MANRIGHTONEND = 12, MANUPONEND = 13;
 
每个格子状态值分别用枚举类型值:
    // 定义一些常量,对应地图的元素
    final byte WALL = 1, BOX = 2, BOXONEND = 3, END = 4, MANDOWN = 5,
    MANLEFT = 6, MANRIGHT = 7, MANUP = 8, GRASS = 9,
    MANDOWNONEND = 10,MANLEFTONEND = 11,
    MANRIGHTONEND = 12, MANUPONEND = 13;
Wall(1)代表墙,Box(2)代表箱子,BOXONEND(3)代表放到目的地的箱子,
END(4)代表目的地;
MANDOWN(5)向下的人,MANLEFT(6)向左的人MANRIGHT(7)向右的人, MANUP(8)向上的人;GRASS(9)代表通道。
MANDOWNONEND(10)站在目的地向下的人,MANLEFTONEND(11)站在目的地向左的人,MANRIGHTONEND(12)站在目的地向右的人,MANUPONEND(13)站在目的地向上的人。
存储的原始地图中格子的状态值数组采用相应的整数形式存放。
 
游戏规则
 
可以假设工人移动趋势方向向右,其他方向原理是一致的。P1,P2分别代表工人移动趋势方向前两个方格。
 
1.前方P1是围墙
如果工人前方是围墙(即阻挡工人的路线)
{
    退出规则判断,布局不做任何改变;
}
2.前方P1是通道(GRASS)或目的地(END)
如果工人前方是通道或目的地
{
    工人可以进到P1方格;修改相关位置格子的状态值。
}




程序设计的步骤:
1.设计地图数据类(MapFactory.java)地图数据类保存所有关卡的原始地图数据,每关数据类保存所有关卡的原始地图数据,每关数据为一个二维数组。所以此处map是三维数组。
2.设计地图类(Map.java)由于每移动一步,需要保存当前的游戏状态,所以此处定义此地图类,保存人的位置和游戏地图的当前状态。撤销移动时,恢复地图是通过此类获取需要人的位置,地图当前状态,关卡数。
3.设计游戏面板类(GameFrame.java)
游戏面板类完成游戏的界面刷新显示,以及相应鼠标键盘相关事件。
事后总结:在这次与黄臻的合作中,我体会到了团队合作的重要性。同时,也对Java游戏编程有了更深的了解,此次编程借鉴的是其他人的代码,由于刚刚接触游戏编程,还没有能力在此基础上进行创新(仅仅做到看懂并运行测试),望老师谅解。
提出过程改进计划:在下一次团队合作中,一定要注意分工明确这一点。同时,应提高自身的编程能力,及思考视野。
整个游戏的源文件说明:
GameFrame.java:游戏界面视图。
//6-18完成
//推箱子带音乐版
//右键单击--悔棋功能
//用时1:40分钟
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.util.ArrayList;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class GameFrame extends JFrame implements ActionListener, MouseListener// 主面板类
  , KeyListener {
 private int grade = 0;
 // row,column记载人的行号 列号
 // leftX,leftY 记载左上角图片的位置 避免图片从(0,0)坐标开始
 private int row = 7, column = 7, leftX = 0, leftY = 0;
 // 记载地图的行列数
 private int mapRow = 0, mapColumn = 0;
 // width,height 记载屏幕的大小
 private int width = 0, height = 0;
 private boolean acceptKey = true;
 // 程序所用到的图片
 private Image pic[] = null;
 // 定义一些常量,对应地图的元素
 final byte WALL = 1, BOX = 2, BOXONEND = 3, END = 4, MANDOWN = 5,
   MANLEFT = 6, MANRIGHT = 7, MANUP = 8, GRASS = 9, MANDOWNONEND = 10,
   MANLEFTONEND = 11, MANRIGHTONEND = 12, MANUPONEND = 13;
 private byte[][] map = null;
 private ArrayList list = new ArrayList();
 Sound sound;
 public void getManPosition() {
  for (int i = 0; i < map.length; i++)
   for (int j = 0; j < map[0].length; j++)
    if (map[i][j] == MANDOWN || map[i][j] == MANDOWNONEND
      || map[i][j] == MANUP || map[i][j] == MANUPONEND
      || map[i][j] == MANLEFT || map[i][j] == MANLEFTONEND
      || map[i][j] == MANRIGHT || map[i][j] == MANRIGHTONEND) {
     row = i;
     column = j;
     break;
    }
 }
 
 public void DisplayToast(String str) {
  JOptionPane.showMessageDialog(null, str, "提示",
    JOptionPane.ERROR_MESSAGE);
 }
 // 撤销移动
 public void undo() {
  if (acceptKey) {
   // 撤销
   if (list.size() > 0) {
    // 若要撤销 必须走过
    Map priorMap = (Map) list.get(list.size() - 1);
    map = priorMap.getMap();
    row = priorMap.getManX();
    column = priorMap.getManY();
    repaint();
    list.remove(list.size() - 1);
   } else
    DisplayToast("不能再撤销!");
  } else {
   DisplayToast("此关已完成,不能撤销!");
  }
 }
 public void nextGrade() {
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值