主頁 >  其他 > Java迷宮小游戲,老程式員花一天時間完成,你可以嗎?

Java迷宮小游戲,老程式員花一天時間完成,你可以嗎?

2021-08-11 06:54:14 其他

<iframe id="Dgq4MjGv-1628465767037" src="https://live.csdn.net/v/embed/174822" allowfullscreen="true" data-mediaembed="csdn"></iframe>

Java迷宮,老程式員又來了

作者簡介

作者名:編程界明世隱
簡介:CSDN博客專家,從事軟體開發多年,精通Java、JavaScript,博主也是從零開始一步步把學習成長、深知學習和積累的重要性,喜歡跟廣大ADC一起打野升級,歡迎您關注,期待與您一起學習、成長、起飛!

系列目錄

1. Java俄羅斯方塊
2. Java五子棋小游戲
3. 老Java程式員花一天時間寫了個飛機大戰
4. Java植物大戰僵尸
5. 老Java程式員花2天寫了個連連看
6. Java消消樂(天天愛消除)
7. Java貪吃蛇小游戲
8. Java掃雷小游戲
9. Java坦克大戰

效果圖

在這里插入圖片描述

實作思路

1.創建運行視窗,
2.創建選單,
3.繪制迷宮的每個單元,
4.通過演算法計算迷宮路徑,并打通路徑,形成迷宮,
5.繪制起點終點,
6.添加鍵盤事件控制起點方塊移動,
7.收尾,

迷宮演算法(網上參考的)

  1. 將起點作為當前迷宮單元并標記為已訪問
  2. 當還存在未標記的迷宮單元,進行回圈
    1).如果當前迷宮單元有未被訪問過的的相鄰的迷宮單元
    (1).隨機選擇一個未訪問的相鄰迷宮單元
    (2).將當前迷宮單元入堆疊
    (3).移除當前迷宮單元與相鄰迷宮單元的墻
    (4).標記相鄰迷宮單元并用它作為當前迷宮單元
    2).如果當前迷宮單元不存在未訪問的相鄰迷宮單元,并且堆疊不空
    (1).堆疊頂的迷宮單元出堆疊
    (2).令其成為當前迷宮單元

**這個演算法叫做“深度優先”,簡單來說,就是從起點開始走,尋找它的上下左右4個鄰居,然后隨機一個走,到走不通的時候就回傳上一步繼續走,直到全部單元都走完, **

相關圖示說明

  1. 每個單元的墻,分為上墻、右墻、下墻、左墻,把這些墻用長度為4的陣串列示,元素的值為true則表示墻存在,否則墻不存在,代碼里陣列的下標方式來確定墻是否存在,
  2. 單元是根據行列來創建的,會用到雙回圈,類似表格,比如第二行用 i 來表示的話就是 1,第3列用 j 來表示就是2,那第二行第3列的元素組合起來就是(1,2)
  3. 那同理它的上鄰居就是(0,2),右鄰居(1,3),下鄰居(2,2),左鄰居(1,1),也就是上下鄰居是 i 減加1,左右鄰居是 j 減加1,
  4. 正方形4個點的坐標分別為(x1,y1)(x2,y2)(x3,y3)(x4,y4),計算坐標的公式為(其中start為相對偏移量,為了讓迷宮兩邊有些空隙):
//i代表行 j代表列 h為單元高度
//左上角坐標
this.x1=start+j*h;
this.y1=start+i*h;
//右上角坐標
this.x2=start+(j+1)*h;
this.y2=start+i*h;
//右下角坐標
this.x3=start+(j+1)*h;
this.y3=start+(i+1)*h;
//左下角坐標
this.x4=start+j*h;
this.y4=start+(i+1)*h;	

計算坐標,假如每個正方形的寬高都是40,那么(1,2)這個單元的坐標如下圖:

5. 墻的處理,之前說到墻是以一個4個元素的陣列來表示的,比如陣列為:[true,true,true,true],則圖為:

如果陣列為[false,true,true,true],則圖為:

6. 如果要聯通右邊的鄰居要怎么做呢?當前單元去除右墻,右邊單元去除左墻,這樣就聯通了,

去除后就這樣,以此類推

代碼實作

創建視窗

首先創建一個游戲表單類GameFrame,繼承至JFrame,用來顯示在螢屏上(window的物件),每個游戲都有一個視窗,設定好視窗標題、尺寸、布局等就可以,

import javax.swing.JFrame;
/**
 *表單類
 */
public class GameFrame extends JFrame {
	//構造方法
	public GameFrame(){
		setTitle("迷宮");//設定標題
		setSize(420, 470);//設定表單大小
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//關閉后行程退出
		setLocationRelativeTo(null);//居中
		setResizable(false);//不允許變大
		//setVisible(true);//設定顯示表單
	}
}

創建面板容器GamePanel繼承至JPanel

import javax.swing.JMenuBar;
import javax.swing.JPanel;

/*
 * 畫布類
 */
public class GamePanel extends JPanel{
	private JMenuBar jmb = null;
	private GameFrame mainFrame = null;
	private GamePanel panel = null;
	private String gameFlag="start";//游戲狀態
	//構造方法
	public GamePanel(GameFrame mainFrame){
		this.setLayout(null);
		this.setOpaque(false);
		this.mainFrame=mainFrame;
		this.panel =this;
	}
}

再創建一個Main類,來啟動這個視窗,

//Main類
public class Main {

	public static void main(String[] args) {
		GameFrame frame = new GameFrame();
		GamePanel panel = new GamePanel(frame);
		frame.add(panel);
		frame.setVisible(true);
	}
}

右鍵執行這個Main類,視窗建出來了
在這里插入圖片描述

創建選單及選單選項

創建選單

private Font createFont(){
	return new Font("思源宋體",Font.BOLD,18);
}
//創建選單
private void createMenu() {
	//創建JMenuBar
	jmb = new JMenuBar();
	//取得字體
	Font tFont = createFont(); 
	//創建游戲選項
	JMenu jMenu1 = new JMenu("游戲");
	jMenu1.setFont(tFont);
	//創建幫助選項
	JMenu jMenu2 = new JMenu("幫助");
	jMenu2.setFont(tFont);
	
	JMenuItem jmi1 = new JMenuItem("新游戲");
	jmi1.setFont(tFont);
	JMenuItem jmi2 = new JMenuItem("退出");
	jmi2.setFont(tFont);
	//jmi1 jmi2添加到選單項“游戲”中
	jMenu1.add(jmi1);
	jMenu1.add(jmi2);
	
	JMenuItem jmi3 = new JMenuItem("操作幫助");
	jmi3.setFont(tFont);
	JMenuItem jmi4 = new JMenuItem("勝利條件");
	jmi4.setFont(tFont);
	//jmi13 jmi4添加到選單項“游戲”中
	jMenu2.add(jmi3);
	jMenu2.add(jmi4);
	
	
	jmb.add(jMenu1);
	jmb.add(jMenu2);
	
	mainFrame.setJMenuBar(jmb);
	//添加監聽
	jmi1.addActionListener(this);
	jmi2.addActionListener(this);
	jmi3.addActionListener(this);
	jmi4.addActionListener(this);
	//設定指令
	jmi1.setActionCommand("restart");
	jmi2.setActionCommand("exit");
	jmi3.setActionCommand("help");
	jmi4.setActionCommand("win");
}

實作ActionListener并重寫方法actionPerformed
在這里插入圖片描述
此時GamePanel是報錯的,需重寫actionPerformed方法,
actionPerformed方法的實作

@Override
public void actionPerformed(ActionEvent e) {
	String command = e.getActionCommand();
	System.out.println(command);
	UIManager.put("OptionPane.buttonFont", new FontUIResource(new Font("思源宋體", Font.ITALIC, 18)));
	UIManager.put("OptionPane.messageFont", new FontUIResource(new Font("思源宋體", Font.ITALIC, 18)));
	if ("exit".equals(command)) {
		Object[] options = { "確定", "取消" };
		int response = JOptionPane.showOptionDialog(this, "您確認要退出嗎", "",
				JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
				options, options[0]);
		if (response == 0) {
			System.exit(0);
		} 
	}else if("restart".equals(command)){
		restart();
	}else if("help".equals(command)){
		JOptionPane.showMessageDialog(null, "通過鍵盤的上下左右來移動",
				"提示!", JOptionPane.INFORMATION_MESSAGE);
	}else if("win".equals(command)){
		JOptionPane.showMessageDialog(null, "移動到終點獲得勝利",
				"提示!", JOptionPane.INFORMATION_MESSAGE);
	}	
}

此時的GamePanel代碼如下:

package main;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.plaf.FontUIResource;

/*
 * 畫布類
 */
public class GamePanel extends JPanel implements ActionListener{
	private JMenuBar jmb = null;
	private GameFrame mainFrame = null;
	private GamePanel panel = null;
	private String gameFlag="start";//游戲狀態
	//構造方法
	public GamePanel(GameFrame mainFrame){
		this.setLayout(null);
		this.setOpaque(false);
		this.mainFrame=mainFrame;
		this.panel =this;
		//創建選單
		createMenu();
	}
	private Font createFont(){
		return new Font("思源宋體",Font.BOLD,18);
	}
	//創建選單
	private void createMenu() {
		//創建JMenuBar
		jmb = new JMenuBar();
		//取得字體
		Font tFont = createFont(); 
		//創建游戲選項
		JMenu jMenu1 = new JMenu("游戲");
		jMenu1.setFont(tFont);
		//創建幫助選項
		JMenu jMenu2 = new JMenu("幫助");
		jMenu2.setFont(tFont);
		
		JMenuItem jmi1 = new JMenuItem("新游戲");
		jmi1.setFont(tFont);
		JMenuItem jmi2 = new JMenuItem("退出");
		jmi2.setFont(tFont);
		//jmi1 jmi2添加到選單項“游戲”中
		jMenu1.add(jmi1);
		jMenu1.add(jmi2);
		
		JMenuItem jmi3 = new JMenuItem("操作幫助");
		jmi3.setFont(tFont);
		JMenuItem jmi4 = new JMenuItem("勝利條件");
		jmi4.setFont(tFont);
		//jmi13 jmi4添加到選單項“游戲”中
		jMenu2.add(jmi3);
		jMenu2.add(jmi4);
		
		
		jmb.add(jMenu1);
		jmb.add(jMenu2);
		
		mainFrame.setJMenuBar(jmb);
		//添加監聽
		jmi1.addActionListener(this);
		jmi2.addActionListener(this);
		jmi3.addActionListener(this);
		jmi4.addActionListener(this);
		//設定指令
		jmi1.setActionCommand("restart");
		jmi2.setActionCommand("exit");
		jmi3.setActionCommand("help");
		jmi4.setActionCommand("win");
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();
		System.out.println(command);
		UIManager.put("OptionPane.buttonFont", new FontUIResource(new Font("思源宋體", Font.ITALIC, 18)));
		UIManager.put("OptionPane.messageFont", new FontUIResource(new Font("思源宋體", Font.ITALIC, 18)));
		if ("exit".equals(command)) {
			Object[] options = { "確定", "取消" };
			int response = JOptionPane.showOptionDialog(this, "您確認要退出嗎", "",
					JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
					options, options[0]);
			if (response == 0) {
				System.exit(0);
			} 
		}else if("restart".equals(command)){
			restart();
		}else if("help".equals(command)){
			JOptionPane.showMessageDialog(null, "通過鍵盤的上下左右來移動",
					"提示!", JOptionPane.INFORMATION_MESSAGE);
		}else if("win".equals(command)){
			JOptionPane.showMessageDialog(null, "移動到終點獲得勝利",
					"提示!", JOptionPane.INFORMATION_MESSAGE);
		}	
	}
	
	void restart(){
		
	}
	
}

運行它
在這里插入圖片描述

繪制迷宮的每個單元

  1. 初始化相關引數
public final int ROWS=20;//行
public final int COLS=20;//列
public final int H=20;//每一塊的寬高
Block[][] blocks = null;//存盤每個單元的二維陣列
  1. 創建迷宮單元類(如果對坐標計算不明白,可以往上翻,有圖示說明解釋)
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
/*
 * 迷宮單元類
 */
public class Block {
	private GamePanel panel = null;
	private int i=0;//二維陣列的下標i
	private int j=0;//二維陣列的下標j
	private int h=0;//寬高
	private int start=6;//偏移像素
	//4個頂點坐標
	private int x1=0;//x1坐標
	private int y1=0;//y1坐標
	private int x2=0;//x2坐標
	private int y2=0;//y2坐標
	private int x3=0;//x3坐標
	private int y3=0;//y3坐標
	private int x4=0;//x4坐標
	private int y4=0;//y4坐標
	//上下左右4個墻是否顯示,true:顯示,false:隱藏
	boolean[] walls=new boolean[4];
	
	private boolean visited=false;//是否被訪問
	//構造
	public Block(int i,int j,int h,GamePanel panel){
		this.i=i;
		this.j=j;
		this.h=h;
		this.panel=panel;
		//計算4個頂點的坐標
		init();
	}
	
	//計算4個頂點的坐標
	private void init() {
		//i代表行 j代表列
		//左上角坐標
		this.x1=start+j*h;
		this.y1=start+i*h;
		//右上角坐標
		this.x2=start+(j+1)*h;
		this.y2=start+i*h;
		//右下角坐標
		this.x3=start+(j+1)*h;
		this.y3=start+(i+1)*h;
		//左下角坐標
		this.x4=start+j*h;
		this.y4=start+(i+1)*h;	
		//默認上下左右4個墻都顯示
		walls[0]=true;
		walls[1]=true;
		walls[2]=true;
		walls[3]=true;
	}

	//繪制指示器的方法
	public void draw(Graphics g) {
		//繪制迷宮塊
		drawBlock(g);
	}
	//繪制迷宮塊
	private void drawBlock(Graphics g) {
		//判斷上、右、下、左 的墻,true的話墻就會有,否則墻就沒有
		boolean top    = walls[0];
		boolean right  = walls[1];
		boolean bottom = walls[2];
		boolean left   = walls[3];
		if(top){//繪制上墻
			g.drawLine(x1, y1, x2, y2);
		}
		if(right){//繪制右墻
			g.drawLine(x2, y2, x3, y3);	
		}
		if(bottom){//繪制下墻
			g.drawLine(x3, y3, x4, y4);	
		}
		if(left){//繪制左墻
			g.drawLine(x4, y4, x1, y1);	
		}
	}
}
  1. 在GamePanel類中創建方法createBlocks
//創建陣列內容
private void createBlocks() {
	blocks = new Block[ROWS][COLS];
	Block block ;
	for (int i = 0; i < ROWS; i++) {
		for (int j = 0; j < COLS; j++) {
			block = new Block(i, j,H,this);
			blocks[i][j]=block;
		}
	}
}
  1. 在建構式中呼叫此方法
//構造方法
public GamePanel(GameFrame mainFrame){
	this.setLayout(null);
	this.setOpaque(false);
	this.mainFrame=mainFrame;
	this.panel =this;
	//創建選單
	createMenu();
	//創建陣列內容
	createBlocks();
}
  1. 在GamePanel中重新paint方法,繪制這些方塊
public void paint(Graphics g) {
	super.paint(g);
	//繪制網格
	drawBlock(g);
}

//繪制迷宮塊
private void drawBlock(Graphics g) {
	Block block ;
	for (int i = 0; i < ROWS; i++) {
		for (int j = 0; j < COLS; j++) {
			block = blocks[i][j];
			if(block!=null){
				block.draw(g);
			}
		}
	}
}

運行可以看到一個個的方形繪制出來了
在這里插入圖片描述

計算并打通迷宮

  1. 給每個單元都增加鄰居查找方法(Block類中)
//查找當前單元是否有未被訪問的鄰居單元
public List<Block> findNeighbors() {
	//鄰居分為上下左右
	List<Block> res= new ArrayList<Block>();//回傳的陣列
	
	Block top    = this.getNeighbor(0,false);
	Block right  = this.getNeighbor(1,false);
	Block bottom = this.getNeighbor(2,false);
	Block left   = this.getNeighbor(3,false);
	
	if(top!=null){
		res.add(top);
	}
	if(right!=null){
		res.add(right);
	}
	if(bottom!=null){
		res.add(bottom);
	}
	if(left!=null){
		res.add(left);
	}
	return res;//回傳鄰居陣列
}
//根據方向,獲得鄰居
public Block getNeighbor(int type,boolean lose_visited) {
	Block neighbor;
	int ti=0,tj=0;
	if(type==0){
		ti = this.i-1;
		tj = this.j;
	}else if(type==1){
		ti = this.i;
		tj = this.j+1;
	}else if(type==2){
		ti = this.i+1;
		tj = this.j;
	}else if(type==3){
		ti = this.i;
		tj = this.j-1;
	}
	
	Block[][] blocks = panel.blocks;
	
	if(ti<0 || tj<0 || ti>=panel.ROWS || tj>=panel.COLS){//超出邊界了
		neighbor = null;
	}else{
		//首先找到這個鄰居
		neighbor = blocks[ti][tj];
		//判斷是否被訪問,如果被訪問了回傳null
		if(neighbor.visited && !lose_visited){//lose_visited等于true表示忽略訪問
			neighbor = null;
		}
	}
	return neighbor;
}
  1. 計算
    跟著演算法來寫的代碼,唯一要注意的是我設定了一個值unVisitedCount,初始值為所有單元的數量,每當一個單元被標記為已訪問后,這個值就遞減1,當值為0后就終止回圈,結束演算法,
//線路的計算處理
private void computed(){
	/*
	1.將起點作為當前迷宮單元并標記為已訪問
	2.當還存在未標記的迷宮單元,進行回圈
		1).如果當前迷宮單元有未被訪問過的的相鄰的迷宮單元
			(1).隨機選擇一個未訪問的相鄰迷宮單元
			(2).將當前迷宮單元入堆疊
			(3).移除當前迷宮單元與相鄰迷宮單元的墻
			(4).標記相鄰迷宮單元并用它作為當前迷宮單元
		2).如果當前迷宮單元不存在未訪問的相鄰迷宮單元,并且堆疊不空
			(1).堆疊頂的迷宮單元出堆疊
			(2).令其成為當前迷宮單元
	 */
	Random random = new Random();
	Stack<Block> stack = new Stack<Block>();//堆疊
	Block current = blocks[0][0];//取第一個為當前單元
	current.setVisited(true);//標記為已訪問
	
	int unVisitedCount=ROWS*COLS-1;//因為第一個已經設定為訪問了
	List<Block> neighbors ;//定義鄰居
	Block next;
	while(unVisitedCount>0){
		neighbors = current.findNeighbors();//查找鄰居集合(未被訪問的)
		if(neighbors.size()>0){//如果當前迷宮單元有未被訪問過的的相鄰的迷宮單元
			//隨機選擇一個未訪問的相鄰迷宮單元
			int index = random.nextInt(neighbors.size()); 
			next = neighbors.get(index);
			//將當前迷宮單元入堆疊
			stack.push(current);
			//移除當前迷宮單元與相鄰迷宮單元的墻
			this.removeWall(current,next);
			//標記相鄰迷宮單元并用它作為當前迷宮單元
			next.setVisited(true);
			//標記一個為訪問,則計數器遞減1
			unVisitedCount--;//遞減
			current = next;
		}else if(!stack.isEmpty()){//如果當前迷宮單元不存在未訪問的相鄰迷宮單元,并且堆疊不空
			/*
				1.堆疊頂的迷宮單元出堆疊
				2.令其成為當前迷宮單元
			*/
			Block cell = stack.pop();
			current = cell;
		}
	}
}
  1. 移除墻
//移除當前迷宮單元與相鄰迷宮單元的墻
private void removeWall(Block current, Block next) {
	if(current.getI()==next.getI()){//橫向鄰居
		if(current.getJ()>next.getJ()){//匹配到的是左邊鄰居
			//左邊鄰居的話,要移除自己的左墻和鄰居的右墻
			current.walls[3]=false;
			next.walls[1]=false;
		}else{//匹配到的是右邊鄰居
			//右邊鄰居的話,要移除自己的右墻和鄰居的左墻
			current.walls[1]=false;
			next.walls[3]=false;
		}
	}else if(current.getJ()==next.getJ()){//縱向鄰居
		if(current.getI()>next.getI()){//匹配到的是上邊鄰居
			//上邊鄰居的話,要移除自己的上墻和鄰居的下墻
			current.walls[0]=false;
			next.walls[2]=false;
		}else{//匹配到的是下邊鄰居
			//下邊鄰居的話,要移除自己的下墻和鄰居的上墻
			current.walls[2]=false;
			next.walls[0]=false;
		}
	}
}
  1. 在建構式中呼叫computed方法
//構造方法
public GamePanel(GameFrame mainFrame){
	this.setLayout(null);
	this.setOpaque(false);
	this.mainFrame=mainFrame;
	this.panel =this;
	//創建選單
	createMenu();
	//創建陣列內容
	createBlocks();
	//計算處理線路
	computed();
}
  1. 運行效果
    在這里插入圖片描述

繪制起點終點

  1. 創建Rect類
package main;

import java.awt.Color;
import java.awt.Graphics;

//開始結束方塊
public class Rect {
	private int i=0;//二維陣列的下標i
	private int j=0;//二維陣列的下標j
	private int x=0;//x坐標
	private int y=0;//y坐標
	private int h=0;//寬高
	private int start=6;//偏移像素
	private String type="";//start end 
	
	public Rect(int i,int j,int h,String type){
		this.i=i;
		this.j=j;
		this.h=h;
		this.type=type;
		
	}
	//初始化
	private void init() {
		this.x=start+j*h+2;
		this.y=start+i*h+2;
	}
	//繪制
	void draw(Graphics g){
		//計算x、y坐標
		init();
		
		Color oColor = g.getColor();
		if("start".equals(type)){//紅色
			g.setColor(Color.red);
		}else{
			g.setColor(Color.blue);
		}
		g.fillRect(x, y, h-3, h-3);
		g.setColor(oColor);
	}
	
	//移動
	public void move(int type, Block[][] blocks,GamePanel panel) {
		//根據當前start方形,獲得對應的迷宮單元
		Block cur = blocks[this.i][this.j];
		
		boolean wall = cur.walls[type];//得到對應的那面墻	
		if(!wall){
			//得到移動方塊對應的單元
			Block next = cur.getNeighbor(type,true);
			if(next!=null){
				this.i = next.getI();
				this.j = next.getJ();
				panel.repaint();
				//判斷如果i,j等于終點的,則表示獲得成功
				if(this.i==panel.end.i && this.j==panel.end.j){
					panel.gameWin();
				}
			}
		}
	}
	
	public int getI() {
		return i;
	}
	public void setI(int i) {
		this.i = i;
	}
	public int getJ() {
		return j;
	}
	public void setJ(int j) {
		this.j = j;
	}
}

  1. 在GamePanel類中創建方法,并在構造中呼叫,
//創建開始結束的方形
private void createRects() {
	start = new Rect(0, 0, H, "start") ;
	end = new Rect(ROWS-1, COLS-1, H, "end") ;
}
//構造方法
public GamePanel(GameFrame mainFrame){
	this.setLayout(null);
	this.setOpaque(false);
	this.mainFrame=mainFrame;
	this.panel =this;
	//創建選單
	createMenu();
	//創建陣列內容
	createBlocks();
	//計算處理線路
	computed();
	//創建開始結束的方形
	createRects();
}
  1. 在paint方法中繪制
@Override
public void paint(Graphics g) {
	super.paint(g);
	//繪制網格
	drawBlock(g);
	//繪制開始結束方向
	drawRect(g);
}
//繪制開始結束方塊
private void drawRect(Graphics g) {
	end.draw(g);
	start.draw(g);
}
  1. 運行一下
    在這里插入圖片描述

加入鍵盤移動監聽

  1. 創建監聽方法
//添加鍵盤監聽
private void createKeyListener() {
	KeyAdapter l = new KeyAdapter() {
		//按下
		@Override
		public void keyPressed(KeyEvent e) {
			if(!"start".equals(gameFlag)) return ;
			int key = e.getKeyCode();
			switch (key) {
				//向上
				case KeyEvent.VK_UP:
				case KeyEvent.VK_W:
					if(start!=null) start.move(0,blocks,panel);
					break;
					
				//向右	
				case KeyEvent.VK_RIGHT:
				case KeyEvent.VK_D:
					if(start!=null) start.move(1,blocks,panel);
					break;
					
				//向下
				case KeyEvent.VK_DOWN:
				case KeyEvent.VK_S:
					if(start!=null) start.move(2,blocks,panel);
					break;
					
				//向左
				case KeyEvent.VK_LEFT:
				case KeyEvent.VK_A:
					if(start!=null) start.move(3,blocks,panel);
					break;
			}
		
		}
		//松開
		@Override
		public void keyReleased(KeyEvent e) {
		}
		
	};
	//給主frame添加鍵盤監聽
	mainFrame.addKeyListener(l);
}
  1. 在構造中呼叫
//構造方法
public GamePanel(GameFrame mainFrame){
	this.setLayout(null);
	this.setOpaque(false);
	this.mainFrame=mainFrame;
	this.panel =this;
	//創建選單
	createMenu();
	//創建陣列內容
	createBlocks();
	//計算處理線路
	computed();
	//創建開始結束的方形
	createRects();
	//添加鍵盤事件監聽
	createKeyListener();
}
  1. 運行
    在這里插入圖片描述

收尾

此時代碼已經基本完成,加入游戲勝利、重新開始等方法即可

//重新開始
void restart() {
	/*引數重置
	1.游戲狀態
	2.迷宮單元重置
	3.重新計算線路
	*/
	
	//1.游戲狀態
	gameFlag="start";
	//2.迷宮單元重置
	Block block ;
	for (int i = 0; i < ROWS; i++) {
		for (int j = 0; j < COLS; j++) {
			block = blocks[i][j];
			if(block!=null){
				block.setVisited(false);
				block.walls[0]=true;
				block.walls[1]=true;
				block.walls[2]=true;
				block.walls[3]=true;
			}
		}
	}
	//3.計算處理線路
	computed();
	//開始方塊歸零
	start.setI(0);
	start.setJ(0);
	//重繪
	repaint();
}

看到這里的大佬,動動發財的小手 點贊 + 回復 + 收藏,能【 關注 】一波就更好了,

代碼獲取方式

幫忙文章【點贊】 +【 收藏】+【關注】+【評論】 后,加我主頁微信或者私聊我,我發給你!

更多精彩

1. Java俄羅斯方塊
2. Java五子棋小游戲
3. 老Java程式員花一天時間寫了個飛機大戰
4. Java植物大戰僵尸
5. 老Java程式員花2天寫了個連連看
6. Java消消樂(天天愛消除)
7. Java貪吃蛇小游戲
8. Java掃雷小游戲
9. Java坦克大戰

相關閱讀

1. JavaWeb圖書管理系統
2. JavaWeb學生宿舍管理系統
3. JavaWeb在線考試系統

另外

為了幫助更多小白從零進階 Java 工程師,從CSDN官方那邊搞來了一套 《Java 工程師學習成長知識圖譜》,尺寸 870mm x 560mm,展開后有一張辦公桌大小,也可以折疊成一本書的尺寸,原件129元現價 29 元先到先得,有興趣的小伙伴可以了解一下

在這里插入圖片描述

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/292892.html

標籤:其他

上一篇:Pycharm常用的小技巧匯總,Python新手上路必備,快上車!

下一篇:30.洗掉ZooKeeper—Kerberos環境

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more