Java 贪吃蛇

刚考完试,趁着现在还有空,弄了一下贪吃蛇的游戏。本来想弄个HTML版的,奈何不会JS,就弄了个Java的。整个程序由三个类(MainInterface、Snake、SNode)构成。

数据参数建议自己定义变量名,这样使用起来比较方便,也便于修改。如画板的宽度和高度,蛇与食物的大小。

完成效果长这样

MainInterface.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
	import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;


public class MainInterface extends JFrame implements KeyListener {
Snake snake;
static int rx;
static int ry;
static int score = 0;
boolean start = false;
public MainInterface() {
super("贪吃蛇");
snake=new Snake();
//食物出现的位置
rx = ((int)(Math.random() * (500 - 20) + 60))/10*10;
ry = ((int)(Math.random() * (500 - 40) + 60))/10*10;
this.setSize(600, 600);
this.setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(this);//添加监听
new Thread(new snackThread()).start();
}

public void paint(Graphics g)
{
super.paint(g); //没有会将面板刷掉
g.setColor(Color.black);
g.fillRect(50, 50, 500, 500); //刷新界面
g.setColor(Color.white);
g.drawRect(50, 50, 500, 500); //绘制边界
g.setColor(Color.red);
g.drawString("按方向键开始游戏",200,570);
g.setColor(Color.red);
g.drawString("Scores: " + score,440,570); //食物数量
g.setColor(Color.red);
g.fillRect(rx, ry, 10, 10); //食物
g.setColor(Color.green); //蛇头
g.fillRect(snake.snacknode.get(0).getX(), snake.snacknode.get(0).getY(), 10, 10);
g.setColor(Color.white); //蛇身
for(int i = 1; i < snake.snacknode.size(); i++) {
g.fillRect(snake.snacknode.get(i).getX(), snake.snacknode.get(i).getY(), 10, 10);
}
}

@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if(e.getKeyCode()==KeyEvent.VK_UP || e.getKeyCode()==KeyEvent.VK_DOWN || e.getKeyCode()==KeyEvent.VK_LEFT || e.getKeyCode()==KeyEvent.VK_RIGHT){
start = true;
}
if(start){
switch(e.getKeyCode()) {
case KeyEvent.VK_UP:
snake.changeDirection("Up");
break;
case KeyEvent.VK_DOWN:
snake.changeDirection("Down");
break;
case KeyEvent.VK_LEFT:
snake.changeDirection("Left");
break;
case KeyEvent.VK_RIGHT:
snake.changeDirection("Right");
break;
}
}

}

@Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub

}

@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub

}
@Override
public void update(Graphics arg0) {
// TODO Auto-generated method stub
super.update(arg0);
}

class snackThread implements Runnable
{
public void run() {
while(true) {
try {
Thread.sleep(500);
repaint();
if(start) {
snake.Move();
}
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new MainInterface();
}
}

Snake.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	import java.util.ArrayList;

import javax.swing.JOptionPane;

public class Snake {
ArrayList<SNode> snacknode = new ArrayList<>(); // 蛇的集合
private String direction; //蛇头移动方向
private int length = 0; //蛇的长度
private int headx; //蛇头X轴坐标
private int heady; ////蛇头Y轴坐标

/*
* 初始化蛇
* */
public Snake() {
direction = "Left";
snacknode.add(new SNode(300,350));
snacknode.add(new SNode(310,350));
snacknode.add(new SNode(320,350));
length = snacknode.size();
}

public String getDirection() {
return direction;
}

public void setDirection(String direction) {
this.direction = direction;
}

public int getLenght() {
return length;
}

public void setLength(int length) {
this.length = length;
}

boolean Dead(){
for(int i = 1; i < snacknode.size(); i++) {
//撞到自己
if(snacknode.get(0).getX() == snacknode.get(i).getX() && snacknode.get(0).getY() == snacknode.get(i).getY())
return true;
}
//撞到墙
if(snacknode.get(0).getX() < 60 || snacknode.get(0).getX() > 530 || snacknode.get(0).getY() < 60 || snacknode.get(0).getY() > 520) {
return true;
}
return false;
}
//蛇移动
public void Move() {
headx = snacknode.get(0).getX();
heady = snacknode.get(0).getY();
switch (direction) {
case "Up":
heady = heady - 10;
break;
case "Down":
heady = heady + 10;
break;
case "Left":
headx = headx - 10;
break;
case "Right":
headx = headx + 10;
break;
default:
break;
}
SNode newNode = new SNode();
boolean eat = false;
//吃掉食物
if(Math.abs(headx - MainInterface.rx) < 10 && Math.abs(heady - MainInterface.ry) < 10) {
eat = true;
newNode = new SNode(snacknode.get(snacknode.size() - 1).getX(),snacknode.get(snacknode.size() - 1).getY());
MainInterface.rx = ((int)(Math.random() * (500 - 20) + 60))/10*10;
MainInterface.ry = ((int)(Math.random() * (500 - 40) + 60))/10*10;
}
for(int i = snacknode.size() - 1; i > 0; i--){
snacknode.set(i, snacknode.get(i - 1));
}
snacknode.set(0,new SNode(headx,heady)); //将食物添加到蛇身
if(Dead()) {
JOptionPane.showMessageDialog(null, "Snake Dead!", "Message", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
if(eat) {
snacknode.add(newNode);
MainInterface.score++;
}
}
public void changeDirection(String dir) {
direction = dir;
}
}

SNode.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
	/*
* 定义蛇身结点
*
* */

public class SNode {
private int x;
private int y;
public SNode() {}
public SNode(int x ,int y){
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;
}
}