Java實現(xiàn)簡單的迷宮游戲詳解
前言
人類建造迷宮已有5000年的歷史。在世界的不同文化發(fā)展時期,這些奇特的建筑物始終吸引人們沿著彎彎曲曲、困難重重的小路吃力地行走,尋找真相。迷宮類小游戲應運而生。在游戲中,迷宮被表現(xiàn)為冒險舞臺里,藏有各式各樣奇妙與謎題或寶藏的危險區(qū)域。型態(tài)有洞窟、人工建筑物、怪物巢穴、密林或山路等。迷宮內有惡徒或兇猛的生物(真實存在或想像物體都有)徘徊,其中可能會有陷阱、不明設施、遺跡等。
《簡單迷宮》游戲是用java語言實現(xiàn),采用了swing技術進行了界面化處理,設計思路用了面向對象思想。
主要需求
方向鍵控制移動,角色走出迷宮,游戲勝利。
主要設計
1、構建游戲地圖面板
2、設定迷宮地圖,包含可走的通道,不可走的墻體,還有出口位置
3、鍵盤的上下左右按鍵,來控制角色的移動
4、角色移動的算法,通道可走,遇到墻體不可走
5、走到終點,有成功通關的提示。
功能截圖
游戲開始頁面

移動界面

通關的界面

代碼實現(xiàn)
窗口布局
public class MainApp extends JFrame {
public MainApp(){
// 設置窗體名稱
setTitle("簡易迷宮游戲");
// 獲取自定義的游戲地圖面板的實例對象
MapPanel panel=new MapPanel();
Container contentPane = getContentPane();
contentPane.add(panel);
// 執(zhí)行并構建窗體設定
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;
// 設定背景方格默認行數(shù)和列數(shù)
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}
};
// 設定顯示的圖像對象
private Image floorImage;
private Image wallImage;
private Image heroImage;
private Image endImage;
// 角色坐標
private int x, y;
// 區(qū)分上下左右按鍵的移動
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();
// 初始化角色坐標
this.x = 1;
this.y = 1;
// 設定焦點在本窗體并且監(jiān)聽鍵盤事件
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();
}
/**
* 根據(jù)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.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) {
// 根據(jù)按鍵進行移動
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);
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來作為是否能移動的根據(jù)
// 1表示墻,不能移動;0表示地板,可以移動
if (x < COLUMN && y < ROW) {// 進行參數(shù)校驗,不能超過數(shù)組的長度
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;
}
}總結
通過此次的《簡易迷宮》游戲實現(xiàn),讓我對swing的相關知識有了進一步的了解,對java這門語言也有了比以前更深刻的認識。
java的一些基本語法,比如數(shù)據(jù)類型、運算符、程序流程控制和數(shù)組等,理解更加透徹。java最核心的核心就是面向對象思想,對于這一個概念,終于悟到了一些。
到此這篇關于Java實現(xiàn)簡單的迷宮游戲詳解的文章就介紹到這了,更多相關Java迷宮游戲內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringMVC框架實現(xiàn)Handler處理器的三種寫法
這篇文章主要介紹了SpringMVC框架實現(xiàn)Handler處理器的三種寫法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-02-02
java.lang.Runtime.exec() Payload知識點詳解
在本篇文章里小編給大家整理的是一篇關于java.lang.Runtime.exec() Payload知識點相關內容,有興趣的朋友們學習下。2020-03-03
MyBatisPlus+SpringBoot實現(xiàn)樂觀鎖功能詳細流程
樂觀鎖是針對一些特定問題的解決方案,主要解決丟失更新問題,下面這篇文章主要給大家介紹了關于MyBatisPlus+SpringBoot實現(xiàn)樂觀鎖功能的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-03-03
老生常談spring boot 1.5.4 日志管理(必看篇)
下面小編就為大家?guī)硪黄仙U剆pring boot 1.5.4 日志管理(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06
詳解spring boot整合JMS(ActiveMQ實現(xiàn))
本篇文章主要介紹了詳解spring boot整合JMS(ActiveMQ實現(xiàn)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10

