Java实现简单的迷宫游戏详解

网友投稿 258 2022-08-29


Java实现简单的迷宫游戏详解

目录前言主要设计功能截图代码实现窗口布局核心算法总结

前言

人类建造迷宫已有5000年的历史。在世界的不同文化发展时期,这些奇特的建筑物始终吸引人们沿着弯弯曲曲、困难重重的小路吃力地行走,寻找真相。迷宫类小游戏应运而生。在游戏中,迷宫被表现为冒险舞台里,藏有各式各样奇妙与谜题或宝藏的危险区域。型态有洞窟、人工建筑物、怪物巢穴、密林或山路等。迷宫内有恶徒或凶猛的生物(真实存在或想像物体都有)徘徊,其中可能会有陷阱、不明设施、遗迹等。

《简单迷宫》游戏是用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想。

主要需求

方向键控制移动,角色走出迷宫,游戏胜利。

主要设计

1、构建游戏地图面板

2、设定迷宫地图,包含可走的通道,不可走的墙体,还有出口位置

3、键盘的上下左右按键,来控制角色的移动

4、角色移动的算法,通道可走,遇到墙体不可走

5、走到终点,有成功通关的提示。

功能截图

游戏开始页面

移动界面

通关的界面

代码实现

窗口布局

public class MainApp extends JFrame {

public MainApp(){

// 设置窗体名称

setTitle("简易迷宫游戏");

// 获取自定义的游戏地图面板的实例对象

MapPanel panel=new MapPanel();

Container contentPane = getContentPane();

contentPane.add(panel);

// 执行并构建窗体设定

pack();

}

public static void main(String[] args) {

MainApp app=new MainApp();

// 允许窗体关闭操作

app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// 显示窗体

app.setVisible(true);

}

}

核心算法

public class MapPanel extends JPanel implements KeyListener {

// 窗体的宽和高

private static final int WIDTH = 450;

private static final int HEIGHT = 450;

// 设定背景方格默认行数和列数

private static final int ROW = 15;

private static final int COLUMN = 15;

// 设置窗体单个图像,采用30x30大小的图形,一行设置15个,即450像素,即窗体默认大小

private static final int SIZE = 30;

// 设定迷宫地图

private static final byte FLOOR = 0;// 0表示通道地板

private static final byte WALL = 1;// 1表示墙

private static final byte END = 2;// 2表示终点

private byte[][] map = {

{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},

{1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1},

{1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},

{1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1},

{1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1},

{1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1},

{1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1},

{1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1},

{1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1},

{1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1},

{1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1},

{1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1},

{1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1},

{1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1},

{1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 2, 1}

};

http:// // 设定显示的图像对象

private Image floorImage;

private Image wallImage;

private Image heroImage;

private Image endImage;

// 角色坐标

private int x, y;

// 区分上下左右按键的移动

private static final byte LEFT = 0;

private static final byte RIGHT = 1;

private static final byte UP = 2;

private static final byte DOWN = 3;

public MapPanel() {

// 设定面板大小

setPreferredSize(new Dimension(WIDTH, HEIGHT));

// 加载图片

loadImage()http://;

// 初始化角色坐标

this.x = 1;

this.y = 1;

// 设定焦点在本窗体并且监听键盘事件

setFocusable(true);

addKeyListener(this);

}

/**

* 画地图和角色

*

* @param g 画笔

*/

public void paintComponent(Graphics g) {

drawMap(g);

drawRole(g);

}

/**

* 画角色(英雄)

*

* @param g 画笔

*/

private void drawRole(Graphics g) {

g.drawImage(heroImage, x * SIZE, y * SIZE, SIZE, SIZE, this);

}

private void loadImage() {

// 获取当前类对应相对位置image文件夹下的地板图像

ImageIcon icon = new ImageIcon(getClass().getResource("images/floor.png"));

// 将地板图像实例赋给floorImage变量

floorImage = icon.getImage();

// 获取墙体图像

icon = new ImageIcon(getClass().getResource("images/wall.gif"));

wallImage = icon.getImage();

// 获取英雄图像

icon = new ImageIcon(getClass().getResource("images/hero.png"));

heroImage = icon.getImage();

// 获取终点图像

icon = new ImageIcon(getClass().getResource("images/end.png"));

endImage = icon.getImage();

}

/**

* 根据map[i][j]中记录的地图信息绘制图案画出地图

* 标记0为地板,标记1为墙

*

* @param g

*/

private void drawMap(Graphics g) {

for (int i = 0; i < ROW; i++) {

for (int j = 0; j < COLUMN; j++) {

switch (map[i][j]) {

case 0:

// 标记为0时画出地板,在指定位置加载图像

g.drawImage(floorImage, j * SIZE, i * SIZE, this);

break;

case 1:

// 标记为1时画出城墙

g.http://drawImage(wallImage, j * SIZE, i * SIZE, this);

break;

case 2:

// 标记为2时画出终点

g.drawImage(endImage, j * SIZE, i * SIZE, SIZE, SIZE, this);

default:

break;

}

}

}

}

@Override

public void keyTyped(KeyEvent e) {

}

@Override

public void keyPressed(KeyEvent e) {

// 根据按键进行移动

int keyCode = e.getKeyCode();// 获取按键编码

switch (keyCode) {

// 左方向键或'A'键,都可以左移

case KeyEvent.VK_LEFT:

move(LEFT);

break;

case KeyEvent.VK_A:

move(LEFT);

break;

// 右方向键或'D'键,都可以右移

case KeyEvent.VK_RIGHT:

move(RIGHT);

break;

case KeyEvent.VK_D:

move(RIGHT);

http:// break;

// 上方向键或'W'键,都可以上移

case KeyEvent.VK_UP:

move(UP);

break;

case KeyEvent.VK_W:

move(UP);

break;

// 下方向键或'S'键,都可以下移

case KeyEvent.VK_DOWN:

move(DOWN);

break;

case KeyEvent.VK_S:

move(DOWN);

break;

default:

break;

}

// 重新绘制窗体图像

repaint();

if (isFinish(x, y)) {

// 移动到出口

JOptionPane.showMessageDialog(this, "恭喜通关!");

}

}

@Override

public void keyReleased(KeyEvent e) {

}

/**

* 判断是否允许移动,如果传入的坐标不是墙则可以移动

*

* @param x

* @param y

* @return 允许移动则返回true,否则返回false

*/

private boolean isAllowMove(int x, int y) {

// 以判断(x,y)是WALL还是FLOOR来作为是否能移动的根据

// 1表示墙,不能移动;0表示地板,可以移动

if (x < COLUMN && y < ROW) {// 进行参数校验,不能超过数组的长度

return map[y][x] != 1;

}

return false;

}

/**

* 移动角色人物

*

* @param event 传入移动方向,分别可以是LEFT、RIGHT、UP、DOWN

*/

private void move(int event) {

switch (event) {

case LEFT:// 左移

if (isAllowMove(x - 1, y)) {// 判断左移一步后的位置是否允许移动(不是墙就可以移动)

x--;

}

break;

case RIGHT:// 右移

if (isAllowMove(x + 1, y)) {

x++;

}

break;

case UP:// 上移

if (isAllowMove(x, y - 1)) {

y--;

}

break;

case DOWN:// 下移

if (isAllowMove(x, y + 1)) {

y++;

}

default:

break;

}

}

/**

* 传入人物的坐标来判断是否到达终点

*

* @param x

* @param y

* @return

*/

private boolean isFinish(int x, int y) {

// 2表示终点图像

// 注意:x坐标表示第几列,y坐标表示第几行,所以是map[y][x]而不是map[x][y]

return map[y][x] == END;

}

}

总结

通过此次的《简易迷宫》游戏实现,让我对swing的相关知识有了进一步的了解,对java这门语言也有了比以前更深刻的认识。

java的一些基本语法,比如数据类型、运算符、程序流程控制和数组等,理解更加透彻。java最核心的核心就是面向对象思想,对于这一个概念,终于悟到了一些。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:又是听歌软件,pc端项目,pc听歌。(pc端好用的听歌软件)
下一篇:flake8多于警告忽略
相关文章

 发表评论

暂时没有评论,来抢沙发吧~