Vars类
public class Vars {
// 定义贪吃蛇运动的边界范围{y的起点,y的终点,x的起点,x的终点}
public static final int XSTAR=40;
public static final int XEND=1200;
public static final int YSTAR=20;
public static final int YEND=700;
// 定义贪吃蛇运动初始化第一个节点的位置
public static final int XSNAKE=100;
public static final int YSNAKE=100;
}
Food类
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.Random;
//定义食物类,蛇头碰到食物后蛇身加1,食物在屏幕中随意出现
public class Food {
private int x;
private int y;
public Food() {
super();
Random rand=new Random();
x=Vars.XSNAKE+rand.nextInt((Vars.XEND-Vars.XSTAR-Vars.XSNAKE)/20)*20;
y=Vars.YSNAKE+rand.nextInt((Vars.YEND-Vars.YSTAR-Vars.YSNAKE)/20)*20;
// TODO Auto-generated constructor stub
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Food other = (Food) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
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;
}
}
Jf类
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
import snake.MyJPanel;
public class Jf extends JFrame{
private Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
private JpanelPaint jpanel = new JpanelPaint();
void init(){
this.setSize(d);
this.add(jpanel);
this.addKeyListener(jpanel);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
JpanelPaint类
package snakexiu;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
/*
* 定义一个画蛇的画板
* 主要进行蛇的运动
*
*/
public class JpanelPaint extends JPanel implements KeyListener {
// 新建一个蛇,通过构造函数在(100,100)的位置连续生成5个节点
Snake s = new Snake();
// 新建一个食物
Food f = new Food();
// 蛇启动的延迟时间,单位毫秒
long delayTime = 500;
// 蛇每次往前走一步的间隔时间,单位毫秒
long speed = 100;
int score = 0;
// 通过构造函数调用自动前行的方法
public JpanelPaint() {
this.setOpaque(false);
autoStep();
// TODO Auto-generated constructor stub
}
// 蛇身自动前行
public void autoStep() {
Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
if (s.getSnakeMessage().equals("方向冲突")) {
t.cancel();
JOptionPane.showMessageDialog(null, "方向冲突,游戏结束");
} else if (s.getSnakeMessage().equals("超出边界")) {
t.cancel();
JOptionPane.showMessageDialog(null, "超出边界,游戏结束!");
}
repaint();
SnakeNode tFood = new SnakeNode(f.getX(), f.getY());
if (s.getSnake().getFirst().getX() == tFood.getX() && s.getSnake().getFirst().getY() == tFood.getY()) {
s.step(s.getDir(), true);
score += 2;
f = new Food();
} else {
s.step(s.getDir(), false);
}
}
}, delayTime, speed);
}
public void paint(Graphics p) {
super.paint(p);
// 画出蛇身
p.setColor(Color.GREEN);
for (int i = 0; i < s.getSnake().size(); i++) {
p.fillRect(s.getSnake().get(i).getX(), s.getSnake().get(i).getY(), SnakeNode.WIDTH, SnakeNode.HEIGHT);
}
// 画出食物
p.setColor(Color.PINK);
p.fillRect(f.getX(), f.getY(), SnakeNode.WIDTH, SnakeNode.HEIGHT);
// 画出边界
p.setColor(Color.BLACK);
p.setFont(new Font("Microsoft YaHei", Font.BOLD, 80));
//上下边框
for (int i = 0; i <=(Vars.YEND-Vars.YSTAR)/20; i++) {
p.drawLine(Vars.XSTAR, Vars.YSTAR+i*20, Vars.XEND, Vars.YSTAR+i*20);
}
//左右横线
for (int i = 0; i <=(Vars.XEND-Vars.XSTAR)/20; i++) {
p.drawLine(Vars.XSTAR+i*20, Vars.YSTAR, Vars.XSTAR+i*20, Vars.YEND);
}
//告警信息
p.setColor(Color.BLACK);
p.setFont(new Font("Microsoft YaHei", Font.BOLD, 20));
p.drawString(s.getSnakeMessage(), Vars.XSTAR, Vars.YEND + 50);
//分数
p.setColor(Color.BLACK);
p.setFont(new Font("Microsoft YaHei", Font.BOLD, 20));
p.drawString("分数:"+String.valueOf(score), Vars.XSTAR + 800, Vars.YEND + 50);
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
//通过事件获取键盘的上下左右
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
s.setDir(Snake.up);
break;
case KeyEvent.VK_DOWN:
s.setDir(Snake.down);
break;
case KeyEvent.VK_RIGHT:
s.setDir(Snake.right);
break;
case KeyEvent.VK_LEFT:
s.setDir(Snake.left);
break;
case KeyEvent.VK_SPACE:
s.setDir(Snake.pause);
break;
default:
break;
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Snake类
package snakexiu;
import java.util.LinkedList;
import snake.SnakeNode;
import snaketedu.Node;
/*
* 定义蛇身类
* 属性:集合类-蛇身
* 方向
* 初始节点数
* 告警信息
* 方法:构造函数Snake初始化一个蛇
* 定义蛇的运动
*
*/
public class Snake {
private LinkedList<SnakeNode> snake = new LinkedList<SnakeNode>();
public static final int up = -10;
public static final int down = 10;
public static final int left = -1;
public static final int right = 1;
public static final int pause = 0;
private int dir;
private int nodeNum=5;
private String snakeMessage="游戏开始";
//初始化一个蛇 从(100,100)每间隔节点宽添加一个坐标到蛇身
public Snake() {
int x = Vars.XSNAKE;
int y = Vars.YSNAKE;
for (int i = 0; i < nodeNum; i++) {
SnakeNode st = new SnakeNode();
st.setX(x);
st.setY(y);
snake.add(st);
x += st.getWidth();
}
dir = right;
}
//定义蛇的运动
// @dir 键盘输入方向
// @eat 是否吃到食物 吃到食物为真,没吃到食物为假
public void step(int dir,boolean eat){
// 新增一个蛇头
SnakeNode n = snake.getFirst();
int i = n.getX() + (dir % 10)*20;
int j = n.getY() + (dir / 10)*20;
// 判断是否超过边界 ,没有则将蛇头添加到列表
if(i>=Vars.XEND||j>=Vars.YEND||i<=Vars.XSTAR||j<=Vars.YSTAR)
{
snakeMessage="超出边界";
}else{
n = new SnakeNode(i, j);
snake.addFirst(n);}
// 判断是否吃到食物,没有吃到去掉蛇尾,吃到不去掉蛇尾
if(!eat){
snake.removeLast();
}
}
public int getDir() {
return dir;
}
public void setDir(int dir) {
// 判断方向是否前后冲突
if((dir+this.dir)==0)
{ snakeMessage="方向冲突";
}else{
this.dir = dir;}
}
public LinkedList<SnakeNode> getSnake() {
return snake;
}
public void setSnake(LinkedList<SnakeNode> snake) {
this.snake = snake;
}
public String getSnakeMessage() {
return snakeMessage;
}
public void setSnakeMessage(String snakeMessage) {
this.snakeMessage = snakeMessage;
}
}
SnakeNode类
package snakexiu;
/*
* 蛇身节点
* 一个正方形 (x,y,width,height)
*/
public class SnakeNode {
private int x;
private int y;
public final static int HEIGHT=20;
public final static int WIDTH=20;
public SnakeNode(int x, int y) {
super();
this.x = x;
this.y = y;
}
public SnakeNode() {
super();
// TODO Auto-generated constructor stub
}
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;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SnakeNode other = (SnakeNode) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
Test类
package snakexiu;
public class Test {
public static void main(String[] args) {
Jf j=new Jf();
j.init();
}
}