欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

老程序員教你一天時(shí)間完成Java迷宮小游戲

 更新時(shí)間:2021年08月12日 09:55:03   投稿:BJT  
最近經(jīng)常在機(jī)房看同學(xué)在玩一個(gè)走迷宮的游戲,比較有趣,自己也用java寫一個(gè)實(shí)現(xiàn)隨機(jī)生成迷宮的算法,其實(shí)就是一個(gè)圖的深度優(yōu)先遍歷算法.

效果圖

在這里插入圖片描述

實(shí)現(xiàn)思路

1.創(chuàng)建運(yùn)行窗口。
2.創(chuàng)建菜單。
3.繪制迷宮的每個(gè)單元。
4.通過算法計(jì)算迷宮路徑,并打通路徑,形成迷宮。
5.繪制起點(diǎn)終點(diǎn)。
6.添加鍵盤事件控制起點(diǎn)方塊移動(dòng)。
7.收尾。

迷宮算法(網(wǎng)上參考的)

1.將起點(diǎn)作為當(dāng)前迷宮單元并標(biāo)記為已訪問

2.當(dāng)還存在未標(biāo)記的迷宮單元,進(jìn)行循環(huán)

1).如果當(dāng)前迷宮單元有未被訪問過的的相鄰的迷宮單元

(1).隨機(jī)選擇一個(gè)未訪問的相鄰迷宮單元

(2).將當(dāng)前迷宮單元入棧

(3).移除當(dāng)前迷宮單元與相鄰迷宮單元的墻

(4).標(biāo)記相鄰迷宮單元并用它作為當(dāng)前迷宮單元

2).如果當(dāng)前迷宮單元不存在未訪問的相鄰迷宮單元,并且棧不空

(1).棧頂?shù)拿詫m單元出棧

(2).令其成為當(dāng)前迷宮單元

**這個(gè)算法叫做“深度優(yōu)先”,簡單來說,就是從起點(diǎn)開始走,尋找它的上下左右4個(gè)鄰居,然后隨機(jī)一個(gè)走,到走不通的時(shí)候就返回上一步繼續(xù)走,直到全部單元都走完。 **

相關(guān)圖示說明

每個(gè)單元的墻,分為上墻、右墻、下墻、左墻,把這些墻用長度為4的數(shù)組表示,元素的值為true則表示墻存在,否則墻不存在,代碼里數(shù)組的下標(biāo)方式來確定墻是否存在。

單元是根據(jù)行列來創(chuàng)建的,會用到雙循環(huán),類似表格,比如第二行用 i 來表示的話就是 1,第3列用 j 來表示就是2,那第二行第3列的元素組合起來就是(1,2)

那同理它的上鄰居就是(0,2),右鄰居(1,3),下鄰居(2,2),左鄰居(1,1),也就是上下鄰居是 i 減加1,左右鄰居是 j 減加1。

正方形4個(gè)點(diǎn)的坐標(biāo)分別為(x1,y1)(x2,y2)(x3,y3)(x4,y4),計(jì)算坐標(biāo)的公式為(其中start為相對偏移量,為了讓迷宮兩邊有些空隙):

//i代表行 j代表列 h為單元高度
//左上角坐標(biāo)
this.x1=start+j*h;
this.y1=start+i*h;
//右上角坐標(biāo)
this.x2=start+(j+1)*h;
this.y2=start+i*h;
//右下角坐標(biāo)
this.x3=start+(j+1)*h;
this.y3=start+(i+1)*h;
//左下角坐標(biāo)
this.x4=start+j*h;
this.y4=start+(i+1)*h;	

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


5. 墻的處理,之前說到墻是以一個(gè)4個(gè)元素的數(shù)組來表示的,比如數(shù)組為:[true,true,true,true],則圖為:


如果數(shù)組為[false,true,true,true],則圖為:


6. 如果要聯(lián)通右邊的鄰居要怎么做呢?當(dāng)前單元去除右墻,右邊單元去除左墻,這樣就聯(lián)通了。


去除后就這樣,以此類推

代碼實(shí)現(xiàn)

創(chuàng)建窗口

首先創(chuàng)建一個(gè)游戲窗體類GameFrame,繼承至JFrame,用來顯示在屏幕上(window的對象),每個(gè)游戲都有一個(gè)窗口,設(shè)置好窗口標(biāo)題、尺寸、布局等就可以。

import javax.swing.JFrame;
/**
 *窗體類
 */
public class GameFrame extends JFrame {
	//構(gòu)造方法
	public GameFrame(){
		setTitle("迷宮");//設(shè)置標(biāo)題
		setSize(420, 470);//設(shè)置窗體大小
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//關(guān)閉后進(jìn)程退出
		setLocationRelativeTo(null);//居中
		setResizable(false);//不允許變大
		//setVisible(true);//設(shè)置顯示窗體
	}
}

創(chuàng)建面板容器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";//游戲狀態(tài)
	//構(gòu)造方法
	public GamePanel(GameFrame mainFrame){
		this.setLayout(null);
		this.setOpaque(false);
		this.mainFrame=mainFrame;
		this.panel =this;
	}
}

再創(chuàng)建一個(gè)Main類,來啟動(dòng)這個(gè)窗口。

//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);
	}
}

右鍵執(zhí)行這個(gè)Main類,窗口建出來了

在這里插入圖片描述

創(chuàng)建菜單及菜單選項(xiàng)

創(chuàng)建菜單

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

實(shí)現(xiàn)ActionListener并重寫方法actionPerformed

在這里插入圖片描述

此時(shí)GamePanel是報(bào)錯(cuò)的,需重寫actionPerformed方法。

actionPerformed方法的實(shí)現(xiàn)

@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, "您確認(rèn)要退出嗎", "",
				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, "通過鍵盤的上下左右來移動(dòng)",
				"提示!", JOptionPane.INFORMATION_MESSAGE);
	}else if("win".equals(command)){
		JOptionPane.showMessageDialog(null, "移動(dòng)到終點(diǎn)獲得勝利",
				"提示!", JOptionPane.INFORMATION_MESSAGE);
	}	
}

此時(shí)的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";//游戲狀態(tài)
	//構(gòu)造方法
	public GamePanel(GameFrame mainFrame){
		this.setLayout(null);
		this.setOpaque(false);
		this.mainFrame=mainFrame;
		this.panel =this;
		//創(chuàng)建菜單
		createMenu();
	}
	private Font createFont(){
		return new Font("思源宋體",Font.BOLD,18);
	}
	//創(chuàng)建菜單
	private void createMenu() {
		//創(chuàng)建JMenuBar
		jmb = new JMenuBar();
		//取得字體
		Font tFont = createFont(); 
		//創(chuàng)建游戲選項(xiàng)
		JMenu jMenu1 = new JMenu("游戲");
		jMenu1.setFont(tFont);
		//創(chuàng)建幫助選項(xiàng)
		JMenu jMenu2 = new JMenu("幫助");
		jMenu2.setFont(tFont);
		JMenuItem jmi1 = new JMenuItem("新游戲");
		jmi1.setFont(tFont);
		JMenuItem jmi2 = new JMenuItem("退出");
		jmi2.setFont(tFont);
		//jmi1 jmi2添加到菜單項(xiàng)“游戲”中
		jMenu1.add(jmi1);
		jMenu1.add(jmi2);
		JMenuItem jmi3 = new JMenuItem("操作幫助");
		jmi3.setFont(tFont);
		JMenuItem jmi4 = new JMenuItem("勝利條件");
		jmi4.setFont(tFont);
		//jmi13 jmi4添加到菜單項(xiàng)“游戲”中
		jMenu2.add(jmi3);
		jMenu2.add(jmi4);
		
		jmb.add(jMenu1);
		jmb.add(jMenu2);
		mainFrame.setJMenuBar(jmb);
		//添加監(jiān)聽
		jmi1.addActionListener(this);
		jmi2.addActionListener(this);
		jmi3.addActionListener(this);
		jmi4.addActionListener(this);
		//設(shè)置指令
		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, "您確認(rèn)要退出嗎", "",
					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, "通過鍵盤的上下左右來移動(dòng)",
					"提示!", JOptionPane.INFORMATION_MESSAGE);
		}else if("win".equals(command)){
			JOptionPane.showMessageDialog(null, "移動(dòng)到終點(diǎn)獲得勝利",
					"提示!", JOptionPane.INFORMATION_MESSAGE);
		}	
	}
	void restart(){
	}
}

運(yùn)行它

在這里插入圖片描述

繪制迷宮的每個(gè)單元

初始化相關(guān)參數(shù)

public final int ROWS=20;//行
public final int COLS=20;//列
public final int H=20;//每一塊的寬高
Block[][] blocks = null;//存儲每個(gè)單元的二維數(shù)組

創(chuàng)建迷宮單元類(如果對坐標(biāo)計(jì)算不明白,可以往上翻,有圖示說明解釋)

import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
/*
 * 迷宮單元類
 */
public class Block {
	private GamePanel panel = null;
	private int i=0;//二維數(shù)組的下標(biāo)i
	private int j=0;//二維數(shù)組的下標(biāo)j
	private int h=0;//寬高
	private int start=6;//偏移像素
	//4個(gè)頂點(diǎn)坐標(biāo)
	private int x1=0;//x1坐標(biāo)
	private int y1=0;//y1坐標(biāo)
	private int x2=0;//x2坐標(biāo)
	private int y2=0;//y2坐標(biāo)
	private int x3=0;//x3坐標(biāo)
	private int y3=0;//y3坐標(biāo)
	private int x4=0;//x4坐標(biāo)
	private int y4=0;//y4坐標(biāo)
	//上下左右4個(gè)墻是否顯示,true:顯示,false:隱藏
	boolean[] walls=new boolean[4];
	private boolean visited=false;//是否被訪問
	//構(gòu)造
	public Block(int i,int j,int h,GamePanel panel){
		this.i=i;
		this.j=j;
		this.h=h;
		this.panel=panel;
		//計(jì)算4個(gè)頂點(diǎn)的坐標(biāo)
		init();
	}
	//計(jì)算4個(gè)頂點(diǎn)的坐標(biāo)
	private void init() {
		//i代表行 j代表列
		//左上角坐標(biāo)
		this.x1=start+j*h;
		this.y1=start+i*h;
		//右上角坐標(biāo)
		this.x2=start+(j+1)*h;
		this.y2=start+i*h;
		//右下角坐標(biāo)
		this.x3=start+(j+1)*h;
		this.y3=start+(i+1)*h;
		//左下角坐標(biāo)
		this.x4=start+j*h;
		this.y4=start+(i+1)*h;	
		//默認(rèn)上下左右4個(gè)墻都顯示
		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);	
		}
	}
}

在GamePanel類中創(chuàng)建方法createBlocks

//創(chuàng)建數(shù)組內(nèi)容
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;
		}
	}
}

在構(gòu)造函數(shù)中調(diào)用此方法

//構(gòu)造方法
public GamePanel(GameFrame mainFrame){
	this.setLayout(null);
	this.setOpaque(false);
	this.mainFrame=mainFrame;
	this.panel =this;
	//創(chuàng)建菜單
	createMenu();
	//創(chuàng)建數(shù)組內(nèi)容
	createBlocks();
}

在GamePanel中重新paint方法,繪制這些方塊

public void paint(Graphics g) {
	super.paint(g);
	//繪制網(wǎng)格
	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);
			}
		}
	}
}

運(yùn)行可以看到一個(gè)個(gè)的方形繪制出來了

在這里插入圖片描述

計(jì)算并打通迷宮

給每個(gè)單元都增加鄰居查找方法(Block類中)

//查找當(dāng)前單元是否有未被訪問的鄰居單元
public List<Block> findNeighbors() {
	//鄰居分為上下左右
	List<Block> res= new ArrayList<Block>();//返回的數(shù)組
	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;//返回鄰居數(shù)組
}
//根據(jù)方向,獲得鄰居
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{
		//首先找到這個(gè)鄰居
		neighbor = blocks[ti][tj];
		//判斷是否被訪問,如果被訪問了返回null
		if(neighbor.visited && !lose_visited){//lose_visited等于true表示忽略訪問
			neighbor = null;
		}
	}
	return neighbor;
}

計(jì)算

跟著算法來寫的代碼,唯一要注意的是我設(shè)置了一個(gè)值unVisitedCount,初始值為所有單元的數(shù)量,每當(dāng)一個(gè)單元被標(biāo)記為已訪問后,這個(gè)值就遞減1,當(dāng)值為0后就終止循環(huán),結(jié)束算法。

//線路的計(jì)算處理
private void computed(){
	/*
	1.將起點(diǎn)作為當(dāng)前迷宮單元并標(biāo)記為已訪問
	2.當(dāng)還存在未標(biāo)記的迷宮單元,進(jìn)行循環(huán)
		1).如果當(dāng)前迷宮單元有未被訪問過的的相鄰的迷宮單元
			(1).隨機(jī)選擇一個(gè)未訪問的相鄰迷宮單元
			(2).將當(dāng)前迷宮單元入棧
			(3).移除當(dāng)前迷宮單元與相鄰迷宮單元的墻
			(4).標(biāo)記相鄰迷宮單元并用它作為當(dāng)前迷宮單元
		2).如果當(dāng)前迷宮單元不存在未訪問的相鄰迷宮單元,并且棧不空
			(1).棧頂?shù)拿詫m單元出棧
			(2).令其成為當(dāng)前迷宮單元
	 */
	Random random = new Random();
	Stack<Block> stack = new Stack<Block>();//棧
	Block current = blocks[0][0];//取第一個(gè)為當(dāng)前單元
	current.setVisited(true);//標(biāo)記為已訪問
	int unVisitedCount=ROWS*COLS-1;//因?yàn)榈谝粋€(gè)已經(jīng)設(shè)置為訪問了
	List<Block> neighbors ;//定義鄰居
	Block next;
	while(unVisitedCount>0){
		neighbors = current.findNeighbors();//查找鄰居集合(未被訪問的)
		if(neighbors.size()>0){//如果當(dāng)前迷宮單元有未被訪問過的的相鄰的迷宮單元
			//隨機(jī)選擇一個(gè)未訪問的相鄰迷宮單元
			int index = random.nextInt(neighbors.size()); 
			next = neighbors.get(index);
			//將當(dāng)前迷宮單元入棧
			stack.push(current);
			//移除當(dāng)前迷宮單元與相鄰迷宮單元的墻
			this.removeWall(current,next);
			//標(biāo)記相鄰迷宮單元并用它作為當(dāng)前迷宮單元
			next.setVisited(true);
			//標(biāo)記一個(gè)為訪問,則計(jì)數(shù)器遞減1
			unVisitedCount--;//遞減
			current = next;
		}else if(!stack.isEmpty()){//如果當(dāng)前迷宮單元不存在未訪問的相鄰迷宮單元,并且棧不空
			/*
				1.棧頂?shù)拿詫m單元出棧
				2.令其成為當(dāng)前迷宮單元
			*/
			Block cell = stack.pop();
			current = cell;
		}
	}
}

移除墻

//移除當(dāng)前迷宮單元與相鄰迷宮單元的墻
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;
		}
	}
}

在構(gòu)造函數(shù)中調(diào)用computed方法

//構(gòu)造方法
public GamePanel(GameFrame mainFrame){
	this.setLayout(null);
	this.setOpaque(false);
	this.mainFrame=mainFrame;
	this.panel =this;
	//創(chuàng)建菜單
	createMenu();
	//創(chuàng)建數(shù)組內(nèi)容
	createBlocks();
	//計(jì)算處理線路
	computed();
}

運(yùn)行效果

在這里插入圖片描述

繪制起點(diǎn)終點(diǎn)

創(chuàng)建Rect類

package main;
import java.awt.Color;
import java.awt.Graphics;
//開始結(jié)束方塊
public class Rect {
	private int i=0;//二維數(shù)組的下標(biāo)i
	private int j=0;//二維數(shù)組的下標(biāo)j
	private int x=0;//x坐標(biāo)
	private int y=0;//y坐標(biāo)
	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){
		//計(jì)算x、y坐標(biāo)
		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);
	}
	//移動(dòng)
	public void move(int type, Block[][] blocks,GamePanel panel) {
		//根據(jù)當(dāng)前start方形,獲得對應(yīng)的迷宮單元
		Block cur = blocks[this.i][this.j];
		boolean wall = cur.walls[type];//得到對應(yīng)的那面墻	
		if(!wall){
			//得到移動(dòng)方塊對應(yīng)的單元
			Block next = cur.getNeighbor(type,true);
			if(next!=null){
				this.i = next.getI();
				this.j = next.getJ();
				panel.repaint();
				//判斷如果i,j等于終點(diǎn)的,則表示獲得成功
				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;
	}
}

在GamePanel類中創(chuàng)建方法,并在構(gòu)造中調(diào)用。

//創(chuàng)建開始結(jié)束的方形
private void createRects() {
	start = new Rect(0, 0, H, "start") ;
	end = new Rect(ROWS-1, COLS-1, H, "end") ;
}
//構(gòu)造方法
public GamePanel(GameFrame mainFrame){
	this.setLayout(null);
	this.setOpaque(false);
	this.mainFrame=mainFrame;
	this.panel =this;
	//創(chuàng)建菜單
	createMenu();
	//創(chuàng)建數(shù)組內(nèi)容
	createBlocks();
	//計(jì)算處理線路
	computed();
	//創(chuàng)建開始結(jié)束的方形
	createRects();
}

在paint方法中繪制

@Override
public void paint(Graphics g) {
	super.paint(g);
	//繪制網(wǎng)格
	drawBlock(g);
	//繪制開始結(jié)束方向
	drawRect(g);
}
//繪制開始結(jié)束方塊
private void drawRect(Graphics g) {
	end.draw(g);
	start.draw(g);
}

運(yùn)行一下

在這里插入圖片描述

加入鍵盤移動(dòng)監(jiān)聽

創(chuàng)建監(jiān)聽方法

//添加鍵盤監(jiān)聽
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添加鍵盤監(jiān)聽
	mainFrame.addKeyListener(l);
}

在構(gòu)造中調(diào)用

//構(gòu)造方法
public GamePanel(GameFrame mainFrame){
	this.setLayout(null);
	this.setOpaque(false);
	this.mainFrame=mainFrame;
	this.panel =this;
	//創(chuàng)建菜單
	createMenu();
	//創(chuàng)建數(shù)組內(nèi)容
	createBlocks();
	//計(jì)算處理線路
	computed();
	//創(chuàng)建開始結(jié)束的方形
	createRects();
	//添加鍵盤事件監(jiān)聽
	createKeyListener();
}

運(yùn)行

在這里插入圖片描述

收尾

此時(shí)代碼已經(jīng)基本完成,加入游戲勝利、重新開始等方法即可

//重新開始
void restart() {
	/*參數(shù)重置
	1.游戲狀態(tài)
	2.迷宮單元重置
	3.重新計(jì)算線路
	*/
	//1.游戲狀態(tài)
	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.計(jì)算處理線路
	computed();
	//開始方塊歸零
	start.setI(0);
	start.setJ(0);
	//重繪
	repaint();
}

總結(jié)

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • 使用springboot打包后的文件讀取方式

    使用springboot打包后的文件讀取方式

    這篇文章主要介紹了使用springboot打包后的文件讀取方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • JAVA基于Redis實(shí)現(xiàn)計(jì)數(shù)器限流的使用示例

    JAVA基于Redis實(shí)現(xiàn)計(jì)數(shù)器限流的使用示例

    計(jì)數(shù)器法是限流算法里最簡單也是最容易實(shí)現(xiàn)的一種算法,本文主要介紹了JAVA基于Redis實(shí)現(xiàn)計(jì)數(shù)器限流的使用示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • 深入理解Java設(shè)計(jì)模式之建造者模式

    深入理解Java設(shè)計(jì)模式之建造者模式

    這篇文章主要介紹了JAVA設(shè)計(jì)模式之建造者模式的的相關(guān)資料,文中示例代碼非常詳細(xì),供X大家參考和學(xué)習(xí),感興趣的朋友可以了解下
    2021-11-11
  • 基于java實(shí)現(xiàn)DFA算法代碼實(shí)例

    基于java實(shí)現(xiàn)DFA算法代碼實(shí)例

    這篇文章主要介紹了基于java實(shí)現(xiàn)DFA算法代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 淺談Java中static關(guān)鍵字的作用

    淺談Java中static關(guān)鍵字的作用

    這篇文章主要介紹了Java中static關(guān)鍵字的作用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 自己動(dòng)手用Springboot實(shí)現(xiàn)仿百度網(wǎng)盤的實(shí)踐

    自己動(dòng)手用Springboot實(shí)現(xiàn)仿百度網(wǎng)盤的實(shí)踐

    本項(xiàng)目基于Springboot開發(fā)實(shí)現(xiàn),前端采用BootStrap開發(fā)實(shí)現(xiàn),模仿百度網(wǎng)盤實(shí)現(xiàn)相關(guān)功能,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • IDEA解決src和resource下創(chuàng)建多級目錄的操作

    IDEA解決src和resource下創(chuàng)建多級目錄的操作

    這篇文章主要介紹了IDEA解決src和resource下創(chuàng)建多級目錄的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Java9新特性中的模塊化詳解

    Java9新特性中的模塊化詳解

    今天介紹一個(gè)Java?9的功能,模塊化(Modular),這可能使Java有史以來最大的Feature,對Java9模塊化相關(guān)知識感興趣的朋友一起看看吧
    2022-03-03
  • java根據(jù)圖片中綠色像素點(diǎn)的多少進(jìn)行排序

    java根據(jù)圖片中綠色像素點(diǎn)的多少進(jìn)行排序

    這篇文章主要介紹了java根據(jù)圖片中綠色像素點(diǎn)的多少進(jìn)行排序,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Java中HashSet和LinkedHashSet詳解

    Java中HashSet和LinkedHashSet詳解

    這篇文章主要介紹了Java中HashSet和LinkedHashSet詳解,   HashSet是Set接口的子類,其內(nèi)部采用了HashMap作為數(shù)據(jù)存儲,HashSet其實(shí)就是在操作HashMap的key,HashSet是無序存儲的,不能保證元素的順序;HashSet并沒有進(jìn)行同步處理,因此是線程不安全的,需要的朋友可以參考下
    2023-09-09

最新評論