java中使用雙向鏈表實(shí)現(xiàn)貪吃蛇程序源碼分享
使用雙向鏈表實(shí)現(xiàn)貪吃蛇程序
1.鏈表節(jié)點(diǎn)定義:
package snake;
public class SnakeNode {
private int x;
private int y;
private SnakeNode next;
private SnakeNode ahead;
public SnakeNode() {
}
public SnakeNode(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public SnakeNode getNext() {
return next;
}
public void setNext(SnakeNode next) {
this.next = next;
}
public SnakeNode getAhead() {
return ahead;
}
public void setAhead(SnakeNode ahead) {
this.ahead = ahead;
}
}
主程序:
package snake;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.KeyEventPostProcessor;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
/**
* Created by hackcoder on 15-3-11.
*/
public class Snake extends JFrame {
private static final int rows = 60;
private static final int columns = 80;
// 方向
private static final int UP = 1;
private static final int RIGHT = 2;
private static final int DOWN = 3;
private static final int LEFT = 4;
private static int DRIECTION_NOW = RIGHT;
private static boolean isEat = false;
private static int TAILX;
private static int TAILY;
private static SnakeNode snakeHeader = new SnakeNode();
private static SnakeNode snakeTailer = snakeHeader;
private static SnakeNode food = new SnakeNode();
private static JLabel[] images = new JLabel[rows * columns];
public static void main(String args[]) {
snakeHeader.setX(new Random().nextInt(rows - 1));
snakeHeader.setY(new Random().nextInt(columns - 1));
Snake snake = new Snake();
food = getFood();
while (true) {
try {
next();
// 吃到了食物
if (food.getX() == snakeHeader.getX()
&& food.getY() == snakeHeader.getY()) {
addTail();
isEat = true;
}
//吃到食物,重新生成一個(gè)食物
if (isEat) {
food = getFood();
}
// 判斷是否結(jié)束游戲
if (judgeEND()) {
JOptionPane.showMessageDialog(null, "游戲結(jié)束!", "游戲結(jié)束!",
JOptionPane.ERROR_MESSAGE);
break;
}
SnakeNode pNow = snakeHeader;
while (pNow != null) {
images[columns * pNow.getX() + pNow.getY()]
.setIcon(new ImageIcon("image/black.jpg", ""));
pNow = pNow.getNext();
}
images[columns * food.getX() + food.getY()]
.setIcon(new ImageIcon("image/black.jpg", ""));
Thread.sleep(100);
// 清理
pNow = snakeHeader;
while (pNow != null) {
images[columns * pNow.getX() + pNow.getY()]
.setIcon(new ImageIcon("image/white.jpg", ""));
pNow = pNow.getNext();
}
images[columns * food.getX() + food.getY()]
.setIcon(new ImageIcon("image/white.jpg", ""));
isEat = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public Snake() {
init();
this.setBounds(80, 80, 400, 400);
this.setVisible(true);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
// 添加全局鍵盤監(jiān)聽
KeyboardFocusManager manager = KeyboardFocusManager
.getCurrentKeyboardFocusManager();
manager.addKeyEventPostProcessor((KeyEventPostProcessor) this
.getMyKeyEventHandler());
}
/**
* 初始化地圖
*/
public void init() {
JPanel p = new JPanel(new GridLayout(rows, columns, 1, 1));
setLayout(new BorderLayout());
for (int x = 0; x < rows; x++) {
for (int y = 0; y < columns; y++) {
ImageIcon imageIcon;
if (x == 0 || x == rows - 1 || y == 0 || y == columns - 1) {
imageIcon = new ImageIcon("image/red.jpg", "");
} else {
imageIcon = new ImageIcon("image/white.jpg", "");
}
images[columns * x + y] = new JLabel(imageIcon);
p.add(images[columns * x + y]);
}
}
getContentPane().add(p, BorderLayout.CENTER);
}
/**
* 鍵盤監(jiān)聽
*
* @return
*/
public KeyEventPostProcessor getMyKeyEventHandler() {
return new KeyEventPostProcessor() {
public boolean postProcessKeyEvent(KeyEvent e) {
if (e.getID() != KeyEvent.KEY_PRESSED) {
return false;
}
int keycode = e.getKeyCode();
if (keycode == KeyEvent.VK_UP) {
if (snakeHeader.getNext() != null) {
// 判斷方向是否可轉(zhuǎn)
int x1 = snakeHeader.getX();
int y1 = snakeHeader.getY();
int x2 = snakeHeader.getNext().getX();
int y2 = snakeHeader.getNext().getY();
if (y1 == y2 && x1 - x2 == 1) {
return true;
}
}
DRIECTION_NOW = UP;
} else if (keycode == KeyEvent.VK_RIGHT) {
if (snakeHeader.getNext() != null) {
int x1 = snakeHeader.getX();
int y1 = snakeHeader.getY();
int x2 = snakeHeader.getNext().getX();
int y2 = snakeHeader.getNext().getY();
if (x1 == x2 && y2 - y1 == 1) {
return true;
}
}
DRIECTION_NOW = RIGHT;
} else if (keycode == KeyEvent.VK_DOWN) {
if (snakeHeader.getNext() != null) {
int x1 = snakeHeader.getX();
int y1 = snakeHeader.getY();
int x2 = snakeHeader.getNext().getX();
int y2 = snakeHeader.getNext().getY();
if (y1 == y2 && x2 - x1 == 1) {
return true;
}
}
DRIECTION_NOW = DOWN;
} else if (keycode == KeyEvent.VK_LEFT) {
if (snakeHeader.getNext() != null) {
int x1 = snakeHeader.getX();
int y1 = snakeHeader.getY();
int x2 = snakeHeader.getNext().getX();
int y2 = snakeHeader.getNext().getY();
if (x1 == x2 && y1 - y2 == 1) {
return true;
}
}
DRIECTION_NOW = LEFT;
}
return true;
}
};
}
/**
* 計(jì)算貪吃蛇的方向及位移
*
* @param header
*/
public static void next() {
if (snakeHeader == null)
return;
TAILX = snakeTailer.getX();
TAILY = snakeTailer.getY();
SnakeNode pNow = snakeTailer;
while (pNow != null) {
if (pNow == snakeHeader) {
break;
}
pNow.setX(pNow.getAhead().getX());
pNow.setY(pNow.getAhead().getY());
pNow = pNow.getAhead();
}
if (DRIECTION_NOW == RIGHT) {
snakeHeader.setY(snakeHeader.getY() + 1);
} else if (DRIECTION_NOW == LEFT) {
snakeHeader.setY(snakeHeader.getY() - 1);
} else if (DRIECTION_NOW == UP) {
snakeHeader.setX(snakeHeader.getX() - 1);
} else if (DRIECTION_NOW == DOWN) {
snakeHeader.setX(snakeHeader.getX() + 1);
}
}
public static void addTail() {
SnakeNode tail = new SnakeNode(TAILX, TAILY);
snakeTailer.setNext(tail);
tail.setAhead(snakeTailer);
snakeTailer = snakeTailer.getNext();
}
public static SnakeNode getFood() {
SnakeNode food = new SnakeNode();
boolean flag = true;
while (true) {
int x = new Random().nextInt(rows);
int y = new Random().nextInt(columns);
if (x == 0 || x == rows - 1 || y == 0 || y == columns - 1) {
continue;
}
SnakeNode pNow = snakeHeader;
while (pNow != null) {
if (x == pNow.getX() && y == pNow.getY()) {
flag = false;
}
pNow = pNow.getNext();
}
if (flag) {
food = new SnakeNode(x, y);
break;
}
}
return food;
}
public static boolean judgeEND() {
//碰墻判斷
if (snakeHeader.getX() == 0 || snakeHeader.getX() == rows - 1
|| snakeHeader.getY() == 0 || snakeHeader.getY() == columns - 1) {
return true;
}
//碰身體判斷
SnakeNode pNow = snakeHeader.getNext();
while (pNow != null) {
if (snakeHeader.getX() == pNow.getX()
&& snakeHeader.getY() == pNow.getY()) {
System.out.println("=========碰到身體===========");
return true;
}
pNow = pNow.getNext();
}
return false;
}
}
相關(guān)文章
使用Mybatis遇到的there is no getter異常
這篇文章主要介紹了使用Mybatis遇到的there is no getter異常,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09
SpringBoot整合RabbitMQ消息隊(duì)列的完整步驟
這篇文章主要給大家介紹了關(guān)于SpringBoot整合RabbitMQ消息隊(duì)列的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
idea項(xiàng)目代碼打包為jar包的超詳細(xì)步驟
因?yàn)闃I(yè)務(wù)開發(fā)場景需要,將開發(fā)項(xiàng)目中的Java類打成一個(gè)jar包引入到外部工具中,下面這篇文章主要給大家介紹了關(guān)于idea項(xiàng)目代碼打包為jar包的相關(guān)資料,需要的朋友可以參考下2023-01-01
springboot + rabbitmq 如何實(shí)現(xiàn)消息確認(rèn)機(jī)制(踩坑經(jīng)驗(yàn))
這篇文章主要介紹了springboot + rabbitmq 如何實(shí)現(xiàn)消息確認(rèn)機(jī)制,本文給大家分享小編實(shí)際開發(fā)中的一點(diǎn)踩坑經(jīng)驗(yàn),內(nèi)容簡單易懂,需要的朋友可以參考下2020-07-07
Java+opencv3.2.0實(shí)現(xiàn)hough直線檢測
這篇文章主要為大家詳細(xì)介紹了Java+opencv3.2.0之hough直線檢測,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02
解決mybatis 執(zhí)行mapper的方法時(shí)報(bào)空指針問題
這篇文章主要介紹了解決mybatis 執(zhí)行mapper的方法時(shí)報(bào)空指針問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Java中float類型的范圍及其與十六進(jìn)制的轉(zhuǎn)換例子
這篇文章主要介紹了Java中float類型的范圍及其與十六進(jìn)制的轉(zhuǎn)換例子,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-10-10
Java方法遞歸的形式和常見遞歸算法(方法遞歸結(jié)合File類查找文件)
方法遞歸方法直接調(diào)用自己或者間接調(diào)用自己的形式稱為方法遞歸( recursion),遞歸做為一種算法在程序設(shè)計(jì)語言中廣泛應(yīng)用,這篇文章主要介紹了Java方法遞歸的形式和常見遞歸算法-方法遞歸結(jié)合File類查找文件,需要的朋友可以參考下2023-02-02

