这是用Java的Swing工具实现的一个小程序。
与传统的贪吃蛇游戏一样,通过“上、下、左、右”控制方向觅食
死亡条件:①头碰到身体。②头碰到墙壁。
项目主要分为三块
一个是蛇snake
一个是蛋egg
还有一个是界面yard
主要源码可以在我的GItHub仓库中找到
仓库地址
package demo01;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
public class Snake {
Node head = null;
Node tail = null;
int size = 0;
Node node=new Node (20,40,Dir.L);
private Yard y;
//定义一个蛇
public Snake(Yard y) {
head=node;
tail=node;
size=1;
this.y=y;
}
//尾部添加一个节点
public void addToTail() {
Node node = null;
switch(tail.dir) {
case L :
node = new Node (tail.row , tail.col + 1 , tail.dir);
break;
case U :
node = new Node (tail.row + 1 , tail.col , tail.dir);
break;
case R :
node = new Node (tail.row , tail.col - 1 , tail.dir);
break;
case D :
node = new Node (tail.row - 1 , tail.col , tail.dir);
break;
}
tail.next=node;
node.prev=tail;
tail=node;
size++;
}
//头部添加一个节点
public void addToHead() {
Node node = null;
switch(head.dir) {
case L :
node = new Node (head.row , head.col - 1 , head.dir);
break;
case U :
node = new Node (head.row - 1 , head.col , head.dir);
break;
case R :
node = new Node (head.row , head.col + 1 , head.dir);
break;
case D :
node = new Node (head.row + 1 , head.col , head.dir);
break;
}
node.next=head;
head.prev=node;
head=node;
size++;
}
//画出蛇,同时蛇开始移动
public void draw(Graphics g) {
move();
for(Node n = head ; n!=null;n = n.next) {
n.draw(g);
}
}
//蛇开始移动,就是把头部前面加一个,尾部去掉一个别的不变
private void move() {
addToHead();
deleteFromTail();
checkdead();
}
//检验是否死掉
private void checkdead() {
// TODO Auto-generated method stub
if(head.row<3||head.row>Yard.ROWS-2||head.col<1||head.col>Yard.COLS-2) {
y.stop();
}
for(Node n=head.next;n!=null;n=n.next) {
if(head.row==n.row&&head.col==n.col) {
y.stop();
}
}
}
//删除蛇的尾部
private void deleteFromTail() {
if(size==0) {
return;
}
tail=tail.prev;
tail.next=null;
}
//蛇身上的节点
private class Node {
//每个点的深度
int w=Yard.BLOCK_SIZE;
//每个点的宽度
int h=Yard.BLOCK_SIZE;
//点的坐标col是x,row是y
int row , col;
//方向的枚举型
Dir dir=Dir.L;
Node next=null;
Node prev=null;
//初始化
Node(int row , int col , Dir dir) {
this.row = row;
this.col = col;
this.dir = dir;
}
void draw(Graphics g) {
Color c=g.getColor();
//设置颜色
g.setColor(Color.BLACK);
//画出节点
g.fillRect(col*Yard.BLOCK_SIZE ,row*Yard.BLOCK_SIZE , w , h);
g.setColor(c);
}
}
public void eat(Egg e) {
if(this.getRect().intersects(e.getRect())) {
e.reAppear();
addToHead();
y.setScore(y.getScore()+1);
}
}
public Rectangle getRect() {
return new Rectangle(Yard.BLOCK_SIZE*head.col , Yard.BLOCK_SIZE*head.row , head.w , head.h);
}
//根据监听器判断蛇的方向
public void keyPress(KeyEvent e) {
int key =e.getKeyCode();
switch(key){
case KeyEvent.VK_UP:
if(head.dir!=Dir.D)
head.dir=Dir.U;
break;
case KeyEvent.VK_DOWN:
if(head.dir!=Dir.U)
head.dir=Dir.D;
break;
case KeyEvent.VK_LEFT:
if(head.dir!=Dir.R)
head.dir=Dir.L;
break;
case KeyEvent.VK_RIGHT:
if(head.dir!=Dir.L)
head.dir=Dir.R;
break;
}
}
}
package demo01;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
public class Egg {
int row,col;
int w=Yard.BLOCK_SIZE;
int h=Yard.BLOCK_SIZE;
private Color color=Color.GREEN;
private static Random r=new Random();
public Egg(int row, int col) {
super();
this.row = row;
this.col = col;
}
public Egg() {
this(r.nextInt(Yard.ROWS-6)+3,r.nextInt(Yard.COLS-6)+3);
}
public void draw(Graphics g) {
Color c=g.getColor();
g.setColor(color);
g.fillOval(col*Yard.BLOCK_SIZE ,row*Yard.BLOCK_SIZE , w , h);
g.setColor(c);
if(color==Color.GREEN) {
color=Color.RED;
}else {
color=Color.GREEN;
}
}
public Rectangle getRect() {
return new Rectangle(Yard.BLOCK_SIZE*col , Yard.BLOCK_SIZE*row , w , h);
}
public void reAppear() {
this.col=r.nextInt(Yard.COLS-6)+3;
this.row=r.nextInt(Yard.ROWS-6)+3;
}
}
package demo01;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class Yard extends Frame {
PaintThread paintThread=new PaintThread();
Thread t=new Thread(paintThread);
private boolean gameOver=false;
public final static int ROWS=50;
public final static int COLS=50;
public final static int BLOCK_SIZE=10;
private int score=0;
Egg e=new Egg();
Snake s=new Snake(this);
Image offScreenImage=null;
public static void main(String[] args) {
new Yard().launch();
}
public void launch () {
//创建窗口
setBounds(200,200, COLS*BLOCK_SIZE, ROWS*BLOCK_SIZE);
//设置可见性
setVisible(true);
//添加关闭监听
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//添加键盘监听
addKeyListener(new KeyMonitor());
//刷新线程启动
t.start();
}
@Override
public void paint(Graphics g) {
Color c=g.getColor();
//背景色
g.setColor(Color.GRAY);
//背景大小
g.fillRect(0,0, COLS*BLOCK_SIZE, ROWS*BLOCK_SIZE);
//画线的颜色
g.setColor(Color.DARK_GRAY);
//画线
for(int i=1;i<ROWS;i++) {
g.drawLine(0, BLOCK_SIZE*i,COLS*BLOCK_SIZE , BLOCK_SIZE*i);
// g.drawLine(BLOCK_SIZE*i,0, BLOCK_SIZE*i, COLS*BLOCK_SIZE);
}
for(int i=1;i<COLS;i++) {
g.drawLine(BLOCK_SIZE*i,0, BLOCK_SIZE*i, ROWS*BLOCK_SIZE);
}
g.setColor(Color.yellow);
if(gameOver) {
g.setFont(new Font("宋体",Font.BOLD,30));
g.drawString("game over! you score :"+score,40,60);
paintThread.gameOver();
}else {
g.drawString("score:"+score,10, 50);
}
g.setColor(c);
//画鸡蛋
e.draw(g);
//画蛇
s.draw(g);
//蛇吃蛋
s.eat(e);
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public void update(Graphics g) {
//双缓存结构
if(offScreenImage==null) {
offScreenImage=this.createImage(BLOCK_SIZE*COLS, BLOCK_SIZE*ROWS);
}
Graphics goff=offScreenImage.getGraphics();
print(goff);
g.drawImage(offScreenImage,0,0,null);
}
public void stop() {
gameOver=true;
}
//刷新的线程,每五十毫秒重新画一次蛇
private class PaintThread implements Runnable{
private boolean Running=true;
@Override
public void run() {
while(Running) {
repaint();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void gameOver() {
Running=false;
}
}
//键盘监听
private class KeyMonitor extends KeyAdapter{
@Override
public void keyPressed(KeyEvent e) {
s.keyPress(e);
}
}
}