课程设计参考别人的推箱子,我也做了一个
先看看效果
下面展示一下代码
如果觉得不过瘾,可以到我的资源里面拿到完整的项目
public class Main {
public static void main(String[] args) {
new MyFrame();
}
}
//定义的区域
//1:代表障碍物
//2:代表草地
//3:代表箱子(未到指定位置)
//4:代表目的地
//5:代表蜗牛向下移动方向; (默认方向)
//6:代表蜗牛向左移动方向
//7:代表蜗牛向右移动方向
//8:代表蜗牛向上移动方向
//9:代表到达指定目的地
import java.awt.Color;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
//ItemListener用于监听带有item的组件产生的事件
//而ActionListener 是所有监听的父类
public class MyFrame extends JFrame implements ActionListener, ItemListener {
private static final long serialVersionUID = 1L;//序列化是为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性
JLabel lb1;// 标签
JLabel lb2;
// 右栏按钮
JButton btnReNew;// 重来
JButton btnLast;// 上一关
JButton btnNext;// 下一关
JButton btnChoose;// 选关
JButton btnFirst;// 第一关
JButton btnOver;// 最终关
JButton btnMusic;// 音乐开关
JButton btnBack;// 悔一步
MainPanel mainPanel;
Sound sound;
JComboBox<String> jComboBox = new JComboBox<String>();// 下拉菜单形式的复选框
// 下面是菜单项定义
MenuItem renew = new MenuItem(" Restar");
MenuItem last = new MenuItem(" Last");
MenuItem back = new MenuItem(" Back");
MenuItem next = new MenuItem(" Next");
MenuItem choose = new MenuItem(" Choose");
MenuItem music = new MenuItem(" Music");
MenuItem exit = new MenuItem(" Exit");
MenuItem about = new MenuItem(" About");
MenuItem defout = new MenuItem("Defout ");
MenuItem loveSong = new MenuItem("LoveSong");
MenuItem kissBye = new MenuItem("KissBye");
public MyFrame() {
super("SOKOBAN");
布局设置///
setBounds(320, 10, 720, 720);// 设置窗口位置,大小
setResizable(false);// 窗口不可更改
setDefaultCloseOperation(EXIT_ON_CLOSE);// 关闭按钮直接退出
java.awt.Container container = getContentPane();// 将面板放到容器container,方便使用
container.setLayout(null);// 空布局
container.setBackground(Color.lightGray);// 设置背景色为浅灰色
/ 菜单设置///
MenuBar bar = new MenuBar();
setMenuBar(bar);// 挂一个菜单栏
Menu option = new Menu(" Option");
// 菜单项添加到菜单--选项
option.add(renew);// 重新开始
option.add(choose);// 选关
option.add(back);// 悔一步
option.add(next);// 下一关
option.add(last);// 最终关
option.addSeparator();// 加一条分割线
option.add(exit);// 退出
// 各菜单项添加监听
renew.addActionListener(this);
choose.addActionListener(this);
back.addActionListener(this);
next.addActionListener(this);
last.addActionListener(this);
exit.addActionListener(this);
Menu musicMenu = new Menu(" Music");
// 菜单项添加到菜单栏--音乐
musicMenu.add(defout);
musicMenu.add(loveSong);
musicMenu.add(kissBye);
// 各菜单项添加监听
defout.addActionListener(this);
loveSong.addActionListener(this);
kissBye.addActionListener(this);
Menu help = new Menu(" Help");
// 菜单项添加到菜单栏--音乐
help.add(about);
// 各菜单项添加监听
about.addActionListener(this);
// 菜单添加到菜单栏
bar.add(option);
bar.add(musicMenu);
bar.add(help);
defout.setEnabled(false);// 设置控件是否可用 这里就是菜单栏里的默认按钮不可用
// 下面是两个标签的设置(lb1,lb2)
lb1 = new JLabel("~~Sokoban~~", JLabel.CENTER);
lb2 = new JLabel("Music", JLabel.CENTER);
lb1.setBounds(100, 20, 450, 20);// 设置位置,大小
lb2.setBounds(625, 500, 55, 20);
add(lb1);
add(lb2);
/ 右侧按钮///
btnReNew = new JButton("Restar");
btnBack = new JButton("Back");
btnLast = new JButton("Last");
btnNext = new JButton("Next");
btnChoose = new JButton("Choose");
btnFirst = new JButton("First");
btnOver = new JButton("Final");
btnMusic = new JButton("MusON");// 默认关闭音乐
// 各个按钮添加监听
btnBack.addActionListener(this);
btnChoose.addActionListener(this);
btnFirst.addActionListener(this);
btnLast.addActionListener(this);
btnMusic.addActionListener(this);
btnNext.addActionListener(this);
btnOver.addActionListener(this);
btnReNew.addActionListener(this);
// 各个按钮的位置
btnReNew.setBounds(625, 100, 80, 30);
btnBack.setBounds(625, 150, 80, 30);
btnFirst.setBounds(625, 200, 80, 30);
btnLast.setBounds(625, 250, 80, 30);
btnNext.setBounds(625, 300, 80, 30);
btnOver.setBounds(625, 350, 80, 30);
btnChoose.setBounds(625, 400, 80, 30);
btnMusic.setBounds(625, 450, 80, 30);
// 添加
add(btnReNew);
add(btnFirst);
add(btnChoose);
add(btnLast);
add(btnNext);
add(btnOver);
add(btnBack);
add(btnMusic);
jComboBox.setBounds(625, 530, 80, 20);// 下拉菜单位置
// 添加三个下拉菜单选项
jComboBox.addItem("Default");
jComboBox.addItem("loveSong");
jComboBox.addItem("kissBye");
jComboBox.addActionListener(this);// 监听下拉菜单
jComboBox.addItemListener(this);
container.add(jComboBox);// 添加
// 游戏进行的主面板设置
mainPanel = new MainPanel();
mainPanel.Sokoban(mainPanel.level);// 调用判断关数(level:MainPanel里定义,起始为1)
mainPanel.requestFocus();// 把输入焦点放在调用这个方法的控件上
add(mainPanel);// 添加
// 加载声音文件
sound = new Sound();
setVisible(true);
}
// 接口ItemListener的实现(监听音乐)
public void itemStateChanged(ItemEvent e) {
int num = jComboBox.getSelectedIndex();//下拉菜单选择了第几个就返回一个整数
switch (num) {
case 0:
sound.setMusic("musics\\def.mid");//设置音乐路径
if (sound.isPlay()) {//如果正在播放,则关掉
sound.stopMusic();
}
sound.loadSound();//加载声音
btnMusic.setText("MusOFF");
//上方菜单项按钮可否选择
defout.setEnabled(false);
loveSong.setEnabled(true);
kissBye.setEnabled(true);
mainPanel.requestFocus();
break;
case 1:
sound.setMusic("musics\\loveSong.mid");
if (sound.isPlay()) {
sound.stopMusic();
}
sound.loadSound();
btnMusic.setText("MusOFF");
defout.setEnabled(true);
loveSong.setEnabled(false);
kissBye.setEnabled(true);
mainPanel.requestFocus();
break;
case 2:
sound.setMusic("musics\\kissBye.mid");
if (sound.isPlay()) {
sound.stopMusic();
}
sound.loadSound();
btnMusic.setText("MusOFF");
defout.setEnabled(true);
loveSong.setEnabled(true);
kissBye.setEnabled(false);
mainPanel.requestFocus();
break;
}
}
// 接口ActionListener的实现(监听菜单栏和侧栏按钮)
public void actionPerformed(ActionEvent e) {
// 按下--重新开始按钮
if (e.getSource() == btnReNew || e.getSource() == renew) {
mainPanel.Sokoban(mainPanel.level);
mainPanel.requestFocus();
mainPanel.mysStack.removeAllElements();
}
// 按下--上一关按钮
else if (e.getSource() == btnLast || e.getSource() == last) {
mainPanel.level--;
if(mainPanel.level < 1){//已经是第一关
mainPanel.level++;
JOptionPane.showMessageDialog(this, "This is the first stage");
mainPanel.requestFocus();
}else {
mainPanel.Sokoban(mainPanel.level);
mainPanel.requestFocus();
}
mainPanel.mysStack.removeAllElements();
mainPanel.requestFocus();
}
// 按下--下一关按钮
else if (e.getSource() == btnNext || e.getSource() == next) {
mainPanel.level++;//关数加一
if(mainPanel.level > mainPanel.max){//达到最后一关
mainPanel.level--;
JOptionPane.showMessageDialog(this, "This is the final stage");
mainPanel.requestFocus();
}else {
mainPanel.Sokoban(mainPanel.level);
mainPanel.requestFocus();
}
mainPanel.mysStack.removeAllElements();
}
// 按下--退出按钮
else if (e.getSource() == exit) {
System.exit(0);
}
// 按下--关于按钮
else if (e.getSource() == about) {
JOptionPane.showMessageDialog(this, " SOKOBAN\nDEVELOPER:柒寸思\nQQ: 1228127092");// \nEmail:
}
// 按下--选择关数按钮
else if (e.getSource() == btnChoose || e.getSource() == choose) {
String le = JOptionPane.showInputDialog(this, "Please input the stage:<0~20>");
try {
int L = Integer.parseInt(le);
mainPanel.mysStack.removeAllElements();
if(L > mainPanel.max || L < 1){
JOptionPane.showMessageDialog(this, "We have no this stage");
mainPanel.requestFocus();
}else {
mainPanel.level = L;
mainPanel.Sokoban(L);
mainPanel.mysStack.removeAllElements();
mainPanel.requestFocus();
}
} catch (Exception e2) {
}
}
// 按下--第一关按钮
else if (e.getSource() == btnFirst) {
mainPanel.level = 1;//将关数重设为1
mainPanel.Sokoban(1);//开始第一关
mainPanel.requestFocus();//窗口固定
mainPanel.mysStack.removeAllElements();
}
// 按下--最终关按钮
else if (e.getSource() == btnOver) {
mainPanel.level = 20;
mainPanel.Sokoban(mainPanel.level);
mainPanel.requestFocus();
mainPanel.mysStack.removeAllElements();
}
// 音乐开关按钮
else if (e.getSource() == btnMusic) {
if (sound.isPlay()) {//如果正在播放
sound.stopMusic();//关闭音乐
btnMusic.setText("musON");//设置标签
}else {//否则
sound.loadSound();//加载音乐
btnMusic.setText("musOFF");//设置标签
}
}
// 悔一步按钮(上菜单或者右栏菜单)
else if (e.getSource() == btnBack || e.getSource() == back) {
if (mainPanel.isMystackEmty()) {//还没移动
JOptionPane.showMessageDialog(this, "You have no move");
}else {
switch (mainPanel.back()) {
case 10:
mainPanel.backUp(10);
break;
case 11:
mainPanel.backUp(11);
break;
case 20:
mainPanel.backDown(20);
break;
case 21:
mainPanel.backDown(21);
break;
case 30:
mainPanel.backLeft(30);
break;
case 31:
mainPanel.backLeft(31);
break;
case 40:
mainPanel.backRight(40);
break;
case 41:
mainPanel.backRight(41);
break;
}
}
mainPanel.requestFocus();//back之后可以继续
}
// 按下--右栏默认按钮
else if (e.getSource() == defout) {
jComboBox.setSelectedIndex(0);//设置下拉菜单默认选择为第(0+1)个(这里就是默认选择第一个)
}
//按下--下拉菜单lovaSong
else if (e.getSource() == loveSong) {
jComboBox.setSelectedIndex(1);
}
else if(e.getSource() == kissBye){
jComboBox.setSelectedIndex(2);
}
}
}
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.FileNotFoundException;
import java.util.Stack;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class MainPanel extends JPanel implements KeyListener {
private static final long serialVersionUID = 1L;
public int level = 1;// 默认通关数是 1
int max = 20;// 最大关数为20关
int snailX, snailY;// snailX代表水平方向上的第几个图片
int[][] map, mapTemp;// 两个二维数组(map是随游戏进行而改变的。mapTemp是不会改变的,用于判断)
Image[] myImage;// 存放图片的数组
int len = 30;// 像素
ReadMap Levelmap;// 类的两个实例
ReadMap Levelmaptmp;
Stack<Integer> mysStack = new Stack<Integer>();//新建一个栈(int)
MainPanel() {
setBounds(15, 50, 600, 600);// 主面板的大小,位置
addKeyListener(this);// 添加键盘监听
myImage = new Image[10];// 一共十个图片
for (int i = 0; i < 10; i++) {
// 将十个图片放到myImage[i]
myImage[i] = java.awt.Toolkit.getDefaultToolkit().getImage("pic\\" + i + ".gif");
}
}
// 进入第几关
void Sokoban(int i) {
try {
Levelmap = new ReadMap(i);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
map = Levelmap.getMap();
snailX = Levelmap.getX();
snailY = Levelmap.getY();
try {
Levelmaptmp = new ReadMap(i);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
mapTemp = Levelmaptmp.getMap();
repaint();
}
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(Color.darkGray);
g.setFont(new Font("楷体",Font.BOLD,28));
g.drawString("Now is "+level+" stage", 210, 40);
}
// // 实现接口KeyListener 的方法
public void keyPressed(KeyEvent e) {// 键被按下(使用这个)
if (e.getKeyCode() == KeyEvent.VK_UP) { // 按下方向键--上
moveUp();
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {// 按下方向键--下
moveDown();
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {// 按下方向键--左
moveLeft();
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {// 按下方向键--右
moveRight();
}
if (isWin()) {// 如果胜出 ,则询问是否进入下一关
if (level == max) {
JOptionPane.showMessageDialog(this, "Congratulations,you had passed all stage!");
}else {
String title = "PASS";
String messageString = "Congratulations,you had passed"+level+"stage";
int type = JOptionPane.YES_NO_OPTION;
int choice = 0;
choice = JOptionPane.showConfirmDialog(null, messageString, title, type);
if (choice == 0) {
level++;
Sokoban(level);
mysStack.removeAllElements();//到下一关,则清空栈
}else if(choice == 1){
System.exit(0);
}
}
}
}
boolean isMystackEmty(){
return mysStack.empty();//返回栈时候空的boolean值
}
public void keyTyped(KeyEvent e) {// 字符被输入
}
public void keyReleased(KeyEvent e) {// 键被弹起
}
int back(){
// return (Integer)mysStack.pop();
return mysStack.pop();//出栈
}
// /// 游戏进行 上下左右四个方法/
// 向前一步,有可能是遇到障碍物(1),草地(2),箱子(3),目的地(4),到达目的地的箱子(9)
// 进栈的10,20,30,40代表蜗牛移动到草地或目的地
// 11,21,31,41代表有推动箱子
void moveUp() {
if(map[snailY-1][snailX] == 2 || map[snailY -1][snailX] == 4){//如果当前位置的上一个是 草地(2)和 目的地(4)可以直接进去
//下面一个if:maptmp是用来存放蜗牛当前位置的背景是多少(当它离开一个目的地的时候需要将其还原为目的地而不是草地)
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY-1][snailX] = 8;//将上面的位置设置为向上 的蜗牛
snailY--;
mysStack.push(10);//进栈
}else if(map[snailY-1][snailX] == 3){//如果是箱子(3)(则需要判断该箱子的前一个是什么)
if(map[snailY-2][snailX] == 4){//如果蜗牛的前两个是目的地--
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//草地
}
map[snailY-2][snailX] = 9;//到达目的地的箱子
map[snailY-1][snailX] = 8;//向上的蜗牛
snailY--;
mysStack.push(11);
}else if(map[snailY-2][snailX] == 2){//如果是草地,将箱子推到草地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//草地
}
map[snailY-2][snailX] = 3;//箱子
map[snailY-1][snailX] = 8;//向上的蜗牛
snailY--;
mysStack.push(11);
}else{//剩下的障碍物,箱子,到达目的地的箱子的情况 都不能动(并且没必要记录到堆栈当中)
map[snailY][snailX] = 8;
}
}else if(map[snailY-1][snailX] == 9){//如果是已经到达指定位置的箱子(9)(则需要判断该箱子的前一个是什么)
if(map[snailY-2][snailX] == 4){//如果是目的地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//草地
}
map[snailY-2][snailX] = 9;
map[snailY-1][snailX] = 8;
snailY--;
mysStack.push(11);
}else if(map[snailY-2][snailX] == 2){//如果是草地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//草地
}
map[snailY-2][snailX] = 3;
map[snailY-1][snailX] = 8;
snailY--;
mysStack.push(11);
}else{//其他情況都不能动
map[snailY][snailX] = 8;
}
}else if(map[snailY-1][snailX] == 1){//如果是障碍物,则不能移动
map[snailY][snailX] = 8;
}
repaint();
}
void moveDown() {
if(map[snailY+1][snailX] == 2 || map[snailY+1][snailX] == 4){//如果是草地或者目的地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY+1][snailX] = 5;
snailY++;
mysStack.push(20);
}else if(map[snailY+1][snailX] == 3){//如果是箱子
if(map[snailY+2][snailX] == 4){//目的地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY+2][snailX] = 9;//到达目的地的箱子
map[snailY+1][snailX] = 5;
snailY++;
mysStack.push(21);
}else if(map[snailY+2][snailX] == 2){//草地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY+2][snailX] = 3;//箱子
map[snailY+1][snailX] = 5;
snailY++;
mysStack.push(21);
}else{//障碍物
map[snailY][snailX] = 5;
}
}else if(map[snailY+1][snailX] == 9){//如果是到达位置的箱子
if(map[snailY+2][snailX] == 4){//目的地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY+2][snailX] = 9;
map[snailY+1][snailX] = 5;
snailY++;
mysStack.push(21);
}else if(map[snailY+2][snailX] == 2){//草地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY+2][snailX] = 3;
map[snailY+1][snailX] = 5;
snailY++;
mysStack.push(21);
}else{//障碍物
map[snailY][snailX] = 5;
}
}else if(map[snailY+1][snailX] == 1){//障碍物
map[snailY][snailX] = 5;
}
repaint();
}
void moveLeft() {
if (map[snailY][snailX-1] == 2 || map[snailY][snailX-1] == 4) {//草地或者是目的地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY][snailX-1] = 6;//向左的蜗牛
snailX--;
mysStack.push(30);
}else if (map[snailY][snailX-1] == 3) {//箱子
if (map[snailY][snailX-2] == 4) {//目的地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY][snailX-2] = 9;
map[snailY][snailX-1] = 6;
snailX--;
mysStack.push(31);
}else if (map[snailY][snailX-2] == 2) {//草地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY][snailX-2] = 3;
map[snailY][snailX-1] = 6;
snailX--;
mysStack.push(31);
}else {
map[snailY][snailX] = 6;
}
}else if (map[snailY][snailX-1] == 9){//到达目的地的箱子
if (map[snailY][snailX-2] == 4) {//目的地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY][snailX-2] = 9;
map[snailY][snailX-1] = 6;
snailX--;
mysStack.push(31);
}else if (map[snailY][snailX-2] == 2) {//草地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY][snailX-2] = 3;
map[snailY][snailX-1] = 6;
snailX--;
mysStack.push(31);
}else {
map[snailY][snailX] = 6;
}
}else if (map[snailY][snailX-1] == 1) {//障碍物
map[snailY][snailX] = 6;
}
repaint();
}
void moveRight() {
if (map[snailY][snailX+1] == 2 || map[snailY][snailX+1] == 4) {//草地或者是目的地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY][snailX+1] = 7;//向右的蜗牛
snailX++;
mysStack.push(40);
}else if (map[snailY][snailX+1] == 3) {//箱子
if (map[snailY][snailX+2] == 4) {//目的地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY][snailX+2] = 9;
map[snailY][snailX+1] = 7;
snailX++;
mysStack.push(41);
}else if (map[snailY][snailX+2] == 2) {//草地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY][snailX+2] = 3;
map[snailY][snailX+1] = 7;
snailX++;
mysStack.push(41);
}else {
map[snailY][snailX] = 7;
}
}else if (map[snailY][snailX+1] == 9){//到达目的地的箱子
if (map[snailY][snailX+2] == 4) {//目的地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY][snailX+2] = 9;
map[snailY][snailX+1] = 7;
snailX++;
mysStack.push(41);
}else if (map[snailY][snailX+2] == 2) {//草地
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){//目的地(4),到达目的地的箱子(9)
map[snailY][snailX] = 4;
}else{
map[snailY][snailX] = 2;//将当前位置设置为草地
}
map[snailY][snailX+2] = 3;
map[snailY][snailX+1] = 7;
snailX++;
mysStack.push(41);
}else {
map[snailY][snailX] = 7;
}
}else if (map[snailY][snailX+1] == 1) {//障碍物
map[snailY][snailX] = 7;
}
repaint();
}
// 游戏悔一步 上下左右四个方法/
void backUp(int t) {
int num = t;
if (num == 10) {//没推动箱子
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9) {//目的地,到达位置的箱子
map[snailY][snailX] = 4;
}else {
map[snailY][snailX] = 2;
}
}else if (num == 11) {//有推动箱子
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9) {//原地图当前位置是目的地或者是到达目的地的箱子
map[snailY][snailX] = 9;
} else{
map[snailY][snailX] = 3;
}
if (mapTemp[snailY - 1][snailX] == 4 || mapTemp[snailY - 1][snailX] == 9) {
map[snailY - 1][snailX] = 4;
} else{
map[snailY - 1][snailX] = 2;
}
}
map[snailY+1][snailX] = 8;//向上的蜗牛
snailY++;//相当于向下了一步
repaint();
}
void backDown(int t) {
int num = t;
if (num == 20) {//如果没推动箱子
if(mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){
map[snailY][snailX] = 4;
}else {
map[snailY][snailX] = 2;
}
}else if (num == 21) {
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9) {
map[snailY][snailX] = 9;
} else{
map[snailY][snailX] = 3;
}
if (mapTemp[snailY + 1][snailX] == 4 || mapTemp[snailY + 1][snailX] == 9) {
map[snailY + 1][snailX] = 4;
} else{
map[snailY + 1][snailX] = 2;
}
}
map[snailY-1][snailX] = 5;
snailY--;//蜗牛向上一步
repaint();
}
void backLeft(int t) {
int num = t;
if (num == 30) {
if(mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){
map[snailY][snailX] = 4;
}else {
map[snailY][snailX] = 2;
}
}else if (num == 31) {
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9) {
map[snailY][snailX] = 9;
} else{
map[snailY][snailX] = 3;
}
if (mapTemp[snailY][snailX - 1] == 4 || mapTemp[snailY][snailX - 1] == 9) {
map[snailY][snailX - 1] = 4;
} else{
map[snailY][snailX - 1] = 2;
}
}
map[snailY][snailX + 1] = 6;
snailX++;
repaint();
}
void backRight(int t) {
int num = t;
if (num == 40) {
if(mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9){
map[snailY][snailX] = 4;
}else {
map[snailY][snailX] = 2;
}
}else if (num == 41) {
if (mapTemp[snailY][snailX] == 4 || mapTemp[snailY][snailX] == 9) {
map[snailY][snailX] = 9;
} else
map[snailY][snailX] = 3;
if (mapTemp[snailY][snailX + 1] == 4 || mapTemp[snailY][snailX + 1] == 9) {
map[snailY][snailX + 1] = 4;
} else
map[snailY][snailX + 1] = 2;
}
map[snailY][snailX - 1] = 7;
snailX--;
repaint();
}
// 是否通过一关
boolean isWin() {
boolean judge = false;
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
if(mapTemp[i][j]==4 || mapTemp[i][j]==9){//如果玩家的地图每一个目的地都有了箱子,就为胜出
if(map[i][j] == 9){
judge = true;
}
else{
return false;
}
}
}
}
return judge;
}
}
/*
* 正移动:小人向上、下、左、右的移动是一个判断算法, 其判断都是通过判断小人前面是否是草地或者是箱子亦或者是障碍物(或者边界)。
* 如果是障碍物或者是边界,就不能够进行移动;如果是没有箱子或者是障碍物,
* 就可以自由移动;又如果是有箱子,就要判断是否可以移动箱子,最后再讨论箱子被推过的位置,小人移动的位置,
* 以及它们的原位置和被遮挡住的新位置的图形变化等等,需要运用算法使其重新绘制地图,填补空白。算法判断完毕后,
* 传出数据并且将其记录在一个堆栈中,以备“Regret step”时使用。
* 负移动:通过记录在堆栈中的数据来判断,前一步小人的移动方向以及移动中使用过的算法, 逆向将代码重新运行,同时绘制并刷新地图以达到前一步的状态。
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ReadMap {
private int leval;// 关数
private int mx, my;
private int myMap[][] = new int[20][20];// 背景20*20个图片
String aString = "";// 空串
int[] x;
private BufferedReader bReader;
ReadMap(int k) throws FileNotFoundException {
leval = k;
String string;
// 读文件字符到aString
try {
File file = new File("maps\\" + leval + ".map");// 文件路径(将文件中的数字转换成对应图片)
FileReader fReader = new FileReader(file);// 读文件file到fRead
bReader = new BufferedReader(fReader);
while ((string = bReader.readLine()) != null) {
aString = aString + string;// 连接起来
}
} catch (IOException e) {
System.out.println(e);
}
byte[] b = aString.getBytes();
int len = aString.length();// 得到长度放到len
int[] x = new int[len];
for (int i = 0; i < len; i++) {
x[i] = b[i] - 48;// 将ASCII,码装换为数字
}
int c = 0;
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
myMap[i][j] = x[c];
if (myMap[i][j] == 5) {//编号5:代表蜗牛向下移动方向(默认方向)
mx = j;
my = i;
}
c++;
}
}
}
int[][] getMap() {
return myMap;
}
int getX() {
return mx;
}
int getY() {
return my;
}
}
import java.io.File;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
public class Sound {
boolean sign;//用于判断是否在播放
String path = new String("musics\\def.mid");// 路径
Sequence sequence;//类 的实例
Sequencer midi;//接口
void loadSound() {
try {
//MidiSystem 类提供了对已安装的 MIDI 系统资源的访问
sequence = MidiSystem.getSequence(new File(path));//将开始路径给sequence(如果没找到,需要抛出异常)
midi = MidiSystem.getSequencer();//获得连接到默认设备上的默认的 Sequencer(音序器)
midi.setSequence(sequence);
midi.open();
midi.start();
//设置循环次数为无限
midi.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);//LOOP_CONTINUOUSLY指示循环应无限继续而不是在执行完特定次数的循环后停止
} catch (Exception e) {
e.printStackTrace();
}
sign = true;//正在播放
}
void stopMusic() {//关闭音乐
midi.close();//关闭
sign = false;
}
boolean isPlay() {//用于判断是否在播放音乐
return sign;
}
void setMusic(String string ) {
path = string;
}
}