Java貪吃蛇游戲完善版
很認(rèn)真的寫的一個(gè)java版的貪吃蛇游戲,圖形界面,支持菜單操作,鍵盤監(jiān)聽,可加速,減速,統(tǒng)計(jì)得分,設(shè)定運(yùn)動(dòng)速度,設(shè)定游戲背景顏色等!應(yīng)該沒有Bug了,因?yàn)槿晃倚薷臎]了。
下面是項(xiàng)目各包及類的層次關(guān)系:

游戲的主要運(yùn)行界面截圖如下:


下面是部分代碼,詳細(xì)源碼見此鏈接:貪吃蛇源碼下載
Snake類:
package com.huowolf.entities;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import com.huowolf.listener.SnakeListener;
import com.huowolf.util.Global;
public class Snake {
//代表方向的常量
public static final int UP = 1;
public static final int DOWN = -1;
public static final int LEFT = 2;
public static final int RIGHT = -2;
//監(jiān)聽器組
private Set<SnakeListener> listeners = new HashSet<SnakeListener>();
//存儲蛇的鏈表結(jié)構(gòu)
private LinkedList<Point> body = new LinkedList<Point>();
private boolean life; //是否活著
private boolean pause; //是否暫停游戲
private int oldDirection,newDirection; //新,舊方向的引入(避免一次移動(dòng)時(shí)間內(nèi)的無效方向)
private Point oldTail; //舊的尾巴(在吃掉食物的時(shí)候使用)
private int foodCount = 0; //吃掉食物的數(shù)量
private Color headColor;
private Color bodyColor;
private int sleepTime;
public boolean isLife() {
return life;
}
public int getSleepTime() {
return sleepTime;
}
public void setSleepTime(int sleepTime) {
this.sleepTime = sleepTime;
}
public void setHeadColor(Color headColor) {
this.headColor = headColor;
}
public void setBodyColor(Color bodyColor) {
this.bodyColor = bodyColor;
}
public void init() {
int x = Global.WIDTH/2;
int y = Global.HEIGHT/2;
for(int i=0;i<3;i++) {
body.addLast(new Point(x--,y));
}
oldDirection = newDirection = RIGHT;
foodCount = 0;
life = true;
pause = false;
if(sleepTime==0) {
sleepTime = 300;
}
}
//清空蛇的節(jié)點(diǎn)的方法(用來開始一次新的游戲)
public void clear() {
body.clear();
}
public void setLife(boolean life) {
this.life = life;
}
public boolean getPause() {
return pause;
}
public void setPause(boolean pause) {
this.pause = pause;
}
//用來改變pause常量的狀態(tài)
public void changePause() {
pause = !pause;
}
//蛇死掉的方法
public void die() {
life = false;
}
//蛇移動(dòng)的方法
public void move() {
if(!(oldDirection + newDirection==0)) {
oldDirection = newDirection ;
}
//去尾
oldTail = body.removeLast();
int x = body.getFirst().x;
int y = body.getFirst().y;
switch(oldDirection) {
case UP:
y--;
if(y<0) {
y = Global.HEIGHT -1 ;
}
break;
case DOWN:
y++;
if(y >= Global.HEIGHT) {
y = 0;
}
break;
case LEFT:
x--;
if(x<0) {
x = Global.WIDTH-1;
}
break;
case RIGHT:
x++;
if(x >= Global.WIDTH) {
x = 0;
}
break;
}
Point newHead = new Point(x, y);
//加頭
body.addFirst(newHead);
}
//改變方向
public void changeDirection(int direction) {
newDirection = direction;
}
//吃食物
public void eatFood() {
body.addLast(oldTail);
foodCount++;
}
//獲取吃到的食物數(shù)量
public int getFoodCount() {
return foodCount;
}
//蛇是否吃到了自己的身體
public boolean isEatBody() {
for(int i=1;i<body.size();i++) {
if(body.get(i).equals(this.getHead()))
return true;
}
return false;
}
//獲取代表蛇頭的節(jié)點(diǎn)
public Point getHead() {
return body.getFirst();
}
//顯示自己
public void drawMe(Graphics g) {
if(bodyColor==null) {
g.setColor(new Color(0x3333FF));
} else {
g.setColor(bodyColor);
}
for(Point p : body) {
g.fillRoundRect(p.x*Global.CELL_SIZE, p.y*Global.CELL_SIZE,
Global.CELL_SIZE, Global.CELL_SIZE, 15,12 );
}
drawHead(g);
}
//畫蛇頭
public void drawHead(Graphics g) {
if(headColor==null)
g.setColor(Color.YELLOW);
else {
g.setColor(headColor);
}
g.fillRoundRect(getHead().x * Global.CELL_SIZE, getHead().y* Global.CELL_SIZE,
Global.CELL_SIZE, Global.CELL_SIZE, 15,12);
}
//控制蛇移動(dòng)的線程內(nèi)部類
private class SnakeDriver implements Runnable {
public void run() {
while(life) {
if(pause==false) {
move();
for(SnakeListener l : listeners)
l.snakeMoved(Snake.this);
}
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//啟動(dòng)線程的方法
public void begin() {
new Thread(new SnakeDriver()).start();
}
//添加監(jiān)聽器
public void addSnakeListener(SnakeListener l) {
if(l != null) {
listeners.add(l);
}
}
//加速
public void speedUp() {
if(sleepTime>50) {
sleepTime-=20;
}
}
//減速
public void speedDown() {
if(sleepTime<700) {
sleepTime+=20;
}
}
}
Food類:
package com.huowolf.entities;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import com.huowolf.util.Global;
public class Food extends Point{
private static final long serialVersionUID = 1L;
private Color foodColor;
public void setFoodColor(Color foodColor) {
this.foodColor = foodColor;
}
public Color getFoodColor() {
return foodColor;
}
public void newFood(Point p) {
setLocation(p);
}
public boolean isFoodEated(Snake snake) {
return this.equals(snake.getHead());
}
public void drawMe(Graphics g) {
if(foodColor==null) {
g.setColor(Color.RED);
}else {
g.setColor(foodColor);
}
g.fill3DRect(x*Global.CELL_SIZE, y*Global.CELL_SIZE, Global.CELL_SIZE, Global.CELL_SIZE, true);
}
}
Ground類
package com.huowolf.entities;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Random;
import com.huowolf.util.Global;
public class Ground {
private boolean [][] rocks = new boolean[Global.WIDTH][Global.HEIGHT];
private int mapType = 1;
public int getMapType() {
return mapType;
}
public void setMapType(int mapType) {
this.mapType = mapType;
}
//初始化地面(清空石頭)
public void clear() {
for (int x = 0; x < Global.WIDTH; x++)
for (int y = 0; y < Global.HEIGHT; y++)
rocks[x][y] = false;
}
/**
* 產(chǎn)生石頭
*/
public void generateRocks1() {
for (int x = 0; x < Global.WIDTH; x++)
rocks[x][0] = rocks[x][Global.HEIGHT - 1] = true;
for (int y = 0; y < Global.HEIGHT; y++)
rocks[0][y] = rocks[Global.WIDTH - 1][y] = true;
}
public void generateRocks2() {
for (int y = 0; y < 6; y++) {
rocks[0][y] = true;
rocks[Global.WIDTH - 1][y] = true;
rocks[0][Global.HEIGHT - 1 - y] = true;
rocks[Global.WIDTH - 1][Global.HEIGHT - 1 - y] = true;
}
for (int y = 6; y < Global.HEIGHT - 6; y++) {
rocks[6][y] = true;
rocks[Global.WIDTH - 7][y] = true;
}
}
public void generateRocks3() {
for(int x=4;x<14;x++)
rocks[x][5] = true;
for(int j=5;j<15;j++)
rocks[21][j] = true;
for(int y=13;y<20;y++)
rocks[14][y] = true;
for(int x=2;x<10;x++)
rocks[x][17] = true;
for(int i=10;i<Global.WIDTH-3;i++)
rocks[i][Global.HEIGHT-3] = true;
}
//蛇是否吃到了石頭
public boolean isGroundEated(Snake snake) {
for(int x=0; x<Global.WIDTH;x++) {
for(int y=0; y<Global.HEIGHT;y++) {
if(rocks[x][y] == true &&
(x==snake.getHead().x &&y==snake.getHead().y)) {
return true;
}
}
}
return false;
}
public Point getPoint() {
Random random = new Random();
int x=0,y=0;
do {
x = random.nextInt(Global.WIDTH);
y = random.nextInt(Global.HEIGHT);
} while (rocks[x][y]==true);
return new Point(x,y);
}
//顯示方法
public void drawMe(Graphics g) {
g.setColor(Color.DARK_GRAY);
for(int x=0; x<Global.WIDTH;x++) {
for(int y=0; y<Global.HEIGHT;y++) {
if(rocks[x][y] == true) {
g.fill3DRect(x*Global.CELL_SIZE, y*Global.CELL_SIZE,
Global.CELL_SIZE,Global.CELL_SIZE, true);
}
}
}
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解IntelliJ IDEA2020.1和JDK14體驗(yàn)
這篇文章主要介紹了詳解IntelliJ IDEA2020.1和JDK14體驗(yàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
mybatis高級映射一對多查詢實(shí)現(xiàn)代碼
本篇文章主要介紹了mybatis高級映射一對多查詢實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04
Java實(shí)現(xiàn)生成JSON字符串的三種方式分享
這篇文章主要來和大家分享一下Java實(shí)現(xiàn)生成JSON字符串的常見三種方式,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,需要的可以參考一下2023-05-05
修改SpringBoot 中MyBatis的mapper.xml文件位置的過程詳解
由于MyBatis默認(rèn)的mapper.xml的掃描位置是resource文件下,但是不可能整個(gè)項(xiàng)目的mapper.xml文件都放在resource下,如果文件較少還行,但是如果文件比較多,太麻煩了,所以本文給大家介紹了修改SpringBoot 中MyBatis的mapper.xml文件位置的過程,需要的朋友可以參考下2024-08-08
SpringBoot整合Elasticsearch實(shí)現(xiàn)索引和文檔的操作方法
Elasticsearch 基于 Apache Lucene 構(gòu)建,采用 Java 編寫,并使用 Lucene 構(gòu)建索引、提供搜索功能,本文分步驟通過綜合案例給大家分享SpringBoot整合Elasticsearch的相關(guān)知識,感興趣的朋友跟隨小編一起看看吧2021-05-05

