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).如果當前迷宮單元有未被訪問過的的相鄰的迷宮單元
(1).隨機選擇一個未訪問的相鄰迷宮單元
(2).將當前迷宮單元入堆疊
(3).移除當前迷宮單元與相鄰迷宮單元的墻
(4).標記相鄰迷宮單元并用它作為當前迷宮單元
2).如果當前迷宮單元不存在未訪問的相鄰迷宮單元,并且堆疊不空
(1).堆疊頂的迷宮單元出堆疊
(2).令其成為當前迷宮單元
**這個演算法叫做“深度優先”,簡單來說,就是從起點開始走,尋找它的上下左右4個鄰居,然后隨機一個走,到走不通的時候就回傳上一步繼續走,直到全部單元都走完, **
相關圖示說明
- 每個單元的墻,分為上墻、右墻、下墻、左墻,把這些墻用長度為4的陣串列示,元素的值為true則表示墻存在,否則墻不存在,代碼里陣列的下標方式來確定墻是否存在,

- 單元是根據行列來創建的,會用到雙回圈,類似表格,比如第二行用 i 來表示的話就是 1,第3列用 j 來表示就是2,那第二行第3列的元素組合起來就是(1,2)

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

- 正方形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(){
}
}
運行它

繪制迷宮的每個單元
- 初始化相關引數
public final int ROWS=20;//行
public final int COLS=20;//列
public final int H=20;//每一塊的寬高
Block[][] blocks = null;//存盤每個單元的二維陣列
- 創建迷宮單元類(如果對坐標計算不明白,可以往上翻,有圖示說明解釋)
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);
}
}
}
- 在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;
}
}
}
- 在建構式中呼叫此方法
//構造方法
public GamePanel(GameFrame mainFrame){
this.setLayout(null);
this.setOpaque(false);
this.mainFrame=mainFrame;
this.panel =this;
//創建選單
createMenu();
//創建陣列內容
createBlocks();
}
- 在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);
}
}
}
}
運行可以看到一個個的方形繪制出來了

計算并打通迷宮
- 給每個單元都增加鄰居查找方法(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;
}
- 計算
跟著演算法來寫的代碼,唯一要注意的是我設定了一個值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;
}
}
}
- 移除墻
//移除當前迷宮單元與相鄰迷宮單元的墻
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;
}
}
}
- 在建構式中呼叫computed方法
//構造方法
public GamePanel(GameFrame mainFrame){
this.setLayout(null);
this.setOpaque(false);
this.mainFrame=mainFrame;
this.panel =this;
//創建選單
createMenu();
//創建陣列內容
createBlocks();
//計算處理線路
computed();
}
- 運行效果

繪制起點終點
- 創建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;
}
}
- 在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();
}
- 在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);
}
- 運行一下

加入鍵盤移動監聽
- 創建監聽方法
//添加鍵盤監聽
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);
}
- 在構造中呼叫
//構造方法
public GamePanel(GameFrame mainFrame){
this.setLayout(null);
this.setOpaque(false);
this.mainFrame=mainFrame;
this.panel =this;
//創建選單
createMenu();
//創建陣列內容
createBlocks();
//計算處理線路
computed();
//創建開始結束的方形
createRects();
//添加鍵盤事件監聽
createKeyListener();
}
- 運行

收尾
此時代碼已經基本完成,加入游戲勝利、重新開始等方法即可
//重新開始
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
標籤:其他
