java可视化,实现走迷宫小游戏(包含随机迷宫生成、BFS自动寻找迷宫解)

if (!inArea(i, j))

throw new IllegalArgumentException(“i or j is out of index in getMaze!”);

return maze[i][j];

}

}

同样将迷宫的各个位置封装成一个类 Position.java,便于操作,这里不做赘述。详情

视图层


AlgoFrame.java 是绘制界面的核心代码,使用java的JFrame控件,在上面添加JPanel画板,在JFrame中定义渲染方法render来调用画板的 paintComponent 方法实现绘制,其中需要用到自己定义的绘制辅助类 AlgoVisHelper.java,在里面封装了绘制矩形,设置画笔颜色,停顿等方法,也定义了一些颜色,也可以不用定义该辅助类而直接在 AlgoFrame.java 中使用awt包中的各种方法直接实现,如有需要可自行下载代码。

import java.awt.*;

import javax.swing.*;

public class AlgoFrame extends JFrame{

private int canvasWidth;

private int canvasHeight;

public AlgoFrame(String title, int canvasWidth, int canvasHeight){

super(title);

this.canvasWidth = canvasWidth;

this.canvasHeight = canvasHeight;

AlgoCanvas canvas = new AlgoCanvas();

setContentPane(canvas);

pack();

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setResizable(false);

setVisible(true);

}

public AlgoFrame(String title){

this(title, 1024, 768);

}

public int getCanvasWidth(){return canvasWidth;}

public int getCanvasHeight(){return canvasHeight;}

// data

private MazeData data;

public void render(MazeData data){

this.data = data;

repaint();

}

private class AlgoCanvas extends JPanel{

public AlgoCanvas(){

// 双缓存

super(true);

}

@Override

public void paintComponent(Graphics g) {

super.paintComponent(g);

Graphics2D g2d = (Graphics2D)g;

// 抗锯齿

RenderingHints hints = new RenderingHints(

RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

g2d.addRenderingHints(hints);

// 具体绘制

int w = canvasWidth/data.M();

int h = canvasHeight/data.N();

for(int i = 0 ; i < data.N() ; i ++ )

for(int j = 0 ; j < data.M() ; j ++){

if(data.maze[i][j] == MazeData.WALL)

AlgoVisHelper.setColor(g2d, AlgoVisHelper.LightBlue);

else

AlgoVisHelper.setColor(g2d, AlgoVisHelper.White);

if(data.path[i][j] && data.showPath == true)

AlgoVisHelper.setColor(g2d, AlgoVisHelper.Yellow);

if (data.player.getX() == i && data.player.getY() == j)

AlgoVisHelper.setColor(g2d, AlgoVisHelper.Red);

AlgoVisHelper.fillRectangle(g2d, j * w, i * h, w, h);

}

}

@Override

public Dimension getPreferredSize(){

return new Dimension(canvasWidth, canvasHeight);

}

}

}

控制层


主函数 AlgoVisualizer.java ,初始化过程封装在 initial 函数中,主要完成随机迷宫的生成以及通过基于递归的DFS算法将迷宫的解事先求出,用户按下空格则可以实现提示功能,红色表示玩家,键盘上下左右控制四个方向的移动。run()方法实现了所有的动画逻辑。

import java.awt.*;

import java.awt.event.*;

public class AlgoVisualizer {

private static int DELAY = 5;

private static int blockSide = 8;

private MazeData data;

private AlgoFrame frame;

private static final int d[][] = {{-1,0},{0,1},{1,0},{0,-1}};

public AlgoVisualizer(int N, int M){

// 初始化数据

data = new MazeData(N, M);

int sceneHeight = data.N() * blockSide;

int sceneWidth = data.M() * blockSide;

// 初始化视图

EventQueue.invokeLater(() -> {

frame = new AlgoFrame(“Random Maze Generation Visualization”, sceneWidth, sceneHeight);

frame.addKeyListener(new AlgoKeyListener());

new Thread(() -> {

run();

}).start();

});

}

private void run(){

setRoadData(-1, -1);

if (initial())

System.out.println(“初始化已完成”);

while (true){

frame.render(data);

AlgoVisHelper.pause(DELAY);

}

}

private boolean initial(){

data.player = new Position(data.getEntranceX(), data.getEntranceY());

RandomQueue queue = new RandomQueue();

Position first = new Position(data.getEntranceX(), data.getEntranceY()+1);

queue.add(first);

data.visited[first.getX()][first.getY()] = true;

while(queue.size() != 0){

Position curPos = queue.remove();

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

int newX = curPos.getX() + d[i][0]*2;

int newY = curPos.getY() + d[i][1]*2;

if(data.inArea(newX, newY) && !data.visited[newX][newY]){

queue.add(new Position(newX, newY));

data.visited[newX][newY] = true;

setRoadData(curPos.getX() + d[i][0], curPos.getY() + d[i][1]);

}

}

}

for(int i = 0 ; i < data.N() ; i ++)

for(int j = 0 ; j < data.M() ; j ++)

data.visited[i][j] = false;

new Thread(() -> {

go(data.getEntranceX(), data.getEntranceY());

}).start();

return true;

}

private boolean go(int x, int y){

if(!data.inArea(x,y))

throw new IllegalArgumentException(“x,y are out of index in go function!”);

data.visited[x][y] = true;

setPathData(x, y, true);

if(x == data.getExitX() && y == data.getExitY())

return true;

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

int newX = x + d[i][0];

int newY = y + d[i][1];

if(data.inArea(newX, newY) &&

data.maze[newX][newY] == MazeData.ROAD &&

!data.visited[newX][newY])

if(go(newX, newY))

return true;

}

// 回溯

setPathData(x, y, false);

return false;

}

private void setRoadData(int x, int y){

if(data.inArea(x, y))

data.maze[x][y] = MazeData.ROAD;

}

private void setPathData(int x, int y, boolean isPath){

if(data.inArea(x, y))

data.path[x][y] = isPath;

}

private class AlgoKeyListener extends KeyAdapter{

@Override

public void keyPressed(KeyEvent event){

if (event.getKeyCode() == KeyEvent.VK_LEFT){

System.out.println(“go left”);

最后

由于篇幅原因,就不多做展示了

lass AlgoKeyListener extends KeyAdapter{

@Override

public void keyPressed(KeyEvent event){

if (event.getKeyCode() == KeyEvent.VK_LEFT){

System.out.println(“go left”);

最后

[外链图片转存中…(img-umrF91DW-1714345249259)]

[外链图片转存中…(img-IXcKFq92-1714345249260)]

[外链图片转存中…(img-zobrlycF-1714345249260)]

[外链图片转存中…(img-OpJVCvPe-1714345249260)]

[外链图片转存中…(img-RPHMn966-1714345249260)]

[外链图片转存中…(img-ocv5Ezpt-1714345249261)]

由于篇幅原因,就不多做展示了

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 29
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值