继手把手教你做游戏——JAVA GUI 推箱子(一)做好后,我们就需要做游戏主体了
1.新建MainGame.java并创建窗口
这次我们的大致结构是这样的 (下图),上面一个JMenuBar作为菜单栏,添加菜单(选关,重玩,地图编辑器,关于),下方一个游戏界面。其余的就无关紧要了
package cn.edu.caztc.sokobangame;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
/**
* 游戏主体
*
* @author 莫言情难忘
*
*/
public class MainGame extends JFrame implements MapConfig {
// 游戏面板
JPanel panel;
public static void main(String[] args) {
new MainGame();
}
public MainGame() {
// TODO Auto-generated constructor stub
this.setTitle("推箱子");
this.setSize(900, 950);
this.setLayout(new FlowLayout());
this.setDefaultCloseOperation(3);
// 设置窗体居中
this.setLocationRelativeTo(null);
// 不可拉伸
this.setResizable(false);
JMenuBar menuBar = new JMenuBar();
this.add(menuBar, BorderLayout.NORTH);
JMenu menu = new JMenu("菜单");
menuBar.add(menu);
JMenuItem menuItem = new JMenuItem("选关");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
// System.out.println("选关");
}
});
menu.add(menuItem);
JMenuItem menuItem_1 = new JMenuItem("重新开始");
menuItem_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// 重新开始
}
});
menu.add(menuItem_1);
JMenuItem menuItem_2 = new JMenuItem("关于");
menuItem_2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// System.out.println("关于");
JOptionPane.showMessageDialog(null, "莫言情难忘开发,csdn:莫言情难忘,个人QQ:1179307527", "关于",
JOptionPane.PLAIN_MESSAGE);
}
});
JMenu menu_1 = new JMenu("\u81EA\u5B9A\u4E49");
menuBar.add(menu_1);
JMenuItem menuItem_3 = new JMenuItem("地图编辑器");
menuItem_3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
test demo = new test();
// demo.open();
}
});
menu_1.add(menuItem_3);
menuBar.add(menuItem_2);
panel = new JPanel();
this.add(panel);
this.setVisible(true);
}
}

2.读取地图数据
我们在教程一中是怎么保存的,这次怎么取出来。
其中参数level是关卡的意思,即我们读取的地图是第几关
参数diy是你选关是本人即开发者做的地图还是玩家自己做的地图
/**
* 读取地图数据
* @param level 关卡
* @param diy
*/
void GetMAP(int level,boolean diy) {
String stringdiy = "";
if (diy) {
stringdiy="diy";
}
try {
DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(path+"\\" + stringdiy + level + ".map")));
int i = in.readInt();
int j = in.readInt();
for (int ii = 0; ii < i; ii++) {
for (int jj = 0; jj < j; jj++) {
map1[ii][jj][0] = in.readInt();
if (map1[ii][jj][0] == 5) {
playex = ii;
playey = jj;
map1[ii][jj][0] = 1;
}
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
3.地图实现
和一的部分差不多,我们需要新建一个面板内部类,用于构造地图。
其中的几个值在接口MapConfig中
/**
* 自定义内部游戏面板类
*
* @author 莫言情难忘
*
*/
class MyPanel extends JPanel {
@Override
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i < MapHeight / eleHeight; i++) {
for (int j = 0; j < MapWidth / eleWidth; j++) {
g.drawImage(GetGameImage(map1[i][j][0]), getDrawX(j), getDrawY(i), eleWidth, eleHeight, null);
}
}
g.drawImage(icon106.getImage(), getDrawX(playey), getDrawY(playex), eleWidth, eleHeight, null);
}
// 将数组下标转化成对应的图片左上角坐标
public int getDrawX(int j) {
int x = j * 50;
return x;
}
// 将数组下标转化成对应的图片左上角坐标
public int getDrawY(int i) {
int y = i * 50;
return y;
}
}
4.整合代码
整合上述代码,游戏主体默认读取1.map。将main方法移动到test.java中测试。需要D盘存在文件夹(推箱子),存在地图文件1.map。1.map文件可在XXX下载中获取。
package cn.edu.caztc.sokobangame;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
/**
* 游戏主体
*
* @author 莫言情难忘
*
*/
public class MainGame extends JFrame implements MapConfig {
int[][][] map1 = new int[18][18][1];// 地图数组
int playex = 0;// 玩家坐标
int playey = 0;// 玩家坐标
boolean diy = false;//
int level = 1;// 关卡
// 游戏面板
JPanel panel;
public MainGame() {
// TODO Auto-generated constructor stub
this.setTitle("推箱子");
this.setSize(900, 950);
this.setLayout(new FlowLayout());
this.setDefaultCloseOperation(3);
// 设置窗体居中
this.setLocationRelativeTo(null);
// 不可拉伸
this.setResizable(false);
JMenuBar menuBar = new JMenuBar();
this.add(menuBar, BorderLayout.NORTH);
JMenu menu = new JMenu("菜单");
menuBar.add(menu);
JMenuItem menuItem = new JMenuItem("选关");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
// System.out.println("选关");
}
});
menu.add(menuItem);
JMenuItem menuItem_1 = new JMenuItem("重新开始");
menuItem_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// 重新开始
}
});
menu.add(menuItem_1);
JMenuItem menuItem_2 = new JMenuItem("关于");
menuItem_2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// System.out.println("关于");
JOptionPane.showMessageDialog(null, "莫言情难忘开发,csdn:莫言情难忘,个人QQ:1179307527", "关于",
JOptionPane.PLAIN_MESSAGE);
}
});
JMenu menu_1 = new JMenu("\u81EA\u5B9A\u4E49");
menuBar.add(menu_1);
JMenuItem menuItem_3 = new JMenuItem("地图编辑器");
menuItem_3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
menu_1.add(menuItem_3);
menuBar.add(menuItem_2);
GetMAP(level, diy);
// 创建游戏面板
panel = setpanel();
this.add(panel);
this.setVisible(true);
}
/**
* 读取地图数据
*
* @param level 关卡
* @param diy
*/
void GetMAP(int level, boolean diy) {
String stringdiy = "";
if (diy) {
stringdiy = "diy";
}
try {
DataInputStream in = new DataInputStream(
new BufferedInputStream(new FileInputStream(PATH + "\\" + stringdiy + level + ".map")));
int i = in.readInt();
int j = in.readInt();
for (int ii = 0; ii < i; ii++) {
for (int jj = 0; jj < j; jj++) {
map1[ii][jj][0] = in.readInt();
if (map1[ii][jj][0] == 5) {
playex = ii;
playey = jj;
map1[ii][jj][0] = 1;
}
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
/**
* 自定义内部游戏面板类
*
* @author 莫言情难忘
*
*/
class MyPanel extends JPanel {
@Override
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i < MAP_HEIGHT / SOUREC_HEIGHT; i++) {
for (int j = 0; j < MAP_WIDTH / SOUREC_WIDTH; j++) {
g.drawImage(GetGameImage(map1[i][j][0]), getDrawX(j), getDrawY(i), SOUREC_WIDTH, SOUREC_HEIGHT,
null);
}
}
g.drawImage(icon106.getImage(), getDrawX(playey), getDrawY(playex), SOUREC_WIDTH, SOUREC_HEIGHT, null);
}
// 将数组下标转化成对应的图片左上角坐标
public int getDrawX(int j) {
int x = j * 50;
return x;
}
// 将数组下标转化成对应的图片左上角坐标
public int getDrawY(int i) {
int y = i * 50;
return y;
}
}
/**
* 设置游戏面板
*/
public JPanel setpanel() {
JPanel panel = new MyPanel();
panel.setPreferredSize(new Dimension(MAP_WIDTH, MAP_HEIGHT));
panel.setLayout(null);
panel.setBackground(Color.black);
return panel;
}
/**
* 获取到数字对应的图片
*
* @param i 数字
* @return
*/
Image GetGameImage(int i) {
if (i > 5) {
i = 0;
}
return allicons[i].getImage();
}
}

好了,身为一个理工男写博客还是挺费劲的,还好只是代码多。
莫言情难忘 1179307527
更多请看: