0


JAVA 实现《简易迷宫》游戏|CSDN创作打卡

前言

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

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

主要需求

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

主要设计

1、构建游戏地图面板

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

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

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

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

功能截图

游戏开始页面

image-20220129172502756

移动界面

image-20220129172549752

通关的界面

image-20220129172624040

代码实现

窗口布局

publicclassMainAppextendsJFrame{publicMainApp(){// 设置窗体名称setTitle("简易迷宫游戏");// 获取自定义的游戏地图面板的实例对象MapPanel panel=newMapPanel();Container contentPane =getContentPane();
        contentPane.add(panel);// 执行并构建窗体设定pack();}publicstaticvoidmain(String[] args){MainApp app=newMainApp();// 允许窗体关闭操作
        app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 显示窗体
        app.setVisible(true);}}

核心算法

publicclassMapPanelextendsJPanelimplementsKeyListener{// 窗体的宽和高privatestaticfinalint WIDTH =450;privatestaticfinalint HEIGHT =450;// 设定背景方格默认行数和列数privatestaticfinalint ROW =15;privatestaticfinalint COLUMN =15;// 设置窗体单个图像,采用30x30大小的图形,一行设置15个,即450像素,即窗体默认大小privatestaticfinalint SIZE =30;// 设定迷宫地图privatestaticfinalbyte FLOOR =0;// 0表示通道地板privatestaticfinalbyte WALL =1;// 1表示墙privatestaticfinalbyte END =2;// 2表示终点privatebyte[][] 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}};// 设定显示的图像对象privateImage floorImage;privateImage wallImage;privateImage heroImage;privateImage endImage;// 角色坐标privateint x, y;// 区分上下左右按键的移动privatestaticfinalbyte LEFT =0;privatestaticfinalbyte RIGHT =1;privatestaticfinalbyte UP =2;privatestaticfinalbyte DOWN =3;publicMapPanel(){// 设定面板大小setPreferredSize(newDimension(WIDTH, HEIGHT));// 加载图片loadImage();// 初始化角色坐标this.x =1;this.y =1;// 设定焦点在本窗体并且监听键盘事件setFocusable(true);addKeyListener(this);}/**
     * 画地图和角色
     *
     * @param g 画笔
     */publicvoidpaintComponent(Graphics g){drawMap(g);drawRole(g);}/**
     * 画角色(英雄)
     *
     * @param g 画笔
     */privatevoiddrawRole(Graphics g){
        g.drawImage(heroImage, x * SIZE, y * SIZE, SIZE, SIZE,this);}privatevoidloadImage(){// 获取当前类对应相对位置image文件夹下的地板图像ImageIcon icon =newImageIcon(getClass().getResource("images/floor.png"));// 将地板图像实例赋给floorImage变量
        floorImage = icon.getImage();// 获取墙体图像
        icon =newImageIcon(getClass().getResource("images/wall.gif"));
        wallImage = icon.getImage();// 获取英雄图像
        icon =newImageIcon(getClass().getResource("images/hero.png"));
        heroImage = icon.getImage();// 获取终点图像
        icon =newImageIcon(getClass().getResource("images/end.png"));
        endImage = icon.getImage();}/**
     * 根据map[i][j]中记录的地图信息绘制图案画出地图
     * 标记0为地板,标记1为墙
     *
     * @param g
     */privatevoiddrawMap(Graphics g){for(int i =0; i < ROW; i++){for(int j =0; j < COLUMN; j++){switch(map[i][j]){case0:// 标记为0时画出地板,在指定位置加载图像
                        g.drawImage(floorImage, j * SIZE, i * SIZE,this);break;case1:// 标记为1时画出城墙
                        g.drawImage(wallImage, j * SIZE, i * SIZE,this);break;case2:// 标记为2时画出终点
                        g.drawImage(endImage, j * SIZE, i * SIZE, SIZE, SIZE,this);default:break;}}}}@OverridepublicvoidkeyTyped(KeyEvent e){}@OverridepublicvoidkeyPressed(KeyEvent e){// 根据按键进行移动int keyCode = e.getKeyCode();// 获取按键编码switch(keyCode){// 左方向键或'A'键,都可以左移caseKeyEvent.VK_LEFT:move(LEFT);break;caseKeyEvent.VK_A:move(LEFT);break;// 右方向键或'D'键,都可以右移caseKeyEvent.VK_RIGHT:move(RIGHT);break;caseKeyEvent.VK_D:move(RIGHT);break;// 上方向键或'W'键,都可以上移caseKeyEvent.VK_UP:move(UP);break;caseKeyEvent.VK_W:move(UP);break;// 下方向键或'S'键,都可以下移caseKeyEvent.VK_DOWN:move(DOWN);break;caseKeyEvent.VK_S:move(DOWN);break;default:break;}// 重新绘制窗体图像repaint();if(isFinish(x, y)){// 移动到出口JOptionPane.showMessageDialog(this,"恭喜通关!");}}@OverridepublicvoidkeyReleased(KeyEvent e){}/**
     * 判断是否允许移动,如果传入的坐标不是墙则可以移动
     *
     * @param x
     * @param y
     * @return 允许移动则返回true,否则返回false
     */privatebooleanisAllowMove(int x,int y){// 以判断(x,y)是WALL还是FLOOR来作为是否能移动的根据// 1表示墙,不能移动;0表示地板,可以移动if(x < COLUMN && y < ROW){// 进行参数校验,不能超过数组的长度return map[y][x]!=1;}returnfalse;}/**
     * 移动角色人物
     *
     * @param event 传入移动方向,分别可以是LEFT、RIGHT、UP、DOWN
     */privatevoidmove(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
     */privatebooleanisFinish(int x,int y){// 2表示终点图像// 注意:x坐标表示第几列,y坐标表示第几行,所以是map[y][x]而不是map[x][y]return map[y][x]== END;}}

总结

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

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

源码获取

源码下载地址:传送门------->

可关注博主后,私聊博主免费获取

今天是持续写作的第 5 / 100 天。
可以关注我,点赞我、评论我、收藏我啦。


本文转载自: https://blog.csdn.net/qq_40869977/article/details/122790690
版权归原作者 毅慎 所有, 如有侵权,请联系我们删除。

“JAVA 实现《简易迷宫》游戏|CSDN创作打卡”的评论:

还没有评论