package snakegame;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainFrame extends JFrame {
//蛇
private sanke sanke;
private Timer timer;//定时器,在规定时间内调用蛇;
private JPanel jPanel;//游戏棋盘;
private Node food;//食物;
public MainFrame(){
//初始化窗体的参数
initFrame();
//初始化游戏棋盘;
inintGamePanel();
//初始化蛇;
initsanke();
//初始化食物;
initfood();
//初始化定时器
initTimer();
//设置键盘监听;
setKeyListener();
}
private void initfood() {
food = new Node();
food.random();
}
private void setKeyListener() {
addKeyListener(new KeyAdapter(){
//当键盘按下时自动调用此方法
@Override
public void keyPressed(KeyEvent e){
//键盘中每一个见都有一个编号
switch(e.getKeyCode()){
case KeyEvent.VK_UP://上
//改变蛇的运动方向;
if(sanke.getDirecton()!=Directon.DOWN){
sanke.setDirecton(Directon.UP);
}
break;
case KeyEvent.VK_DOWN://XIA
if(sanke.getDirecton()!=Directon.UP){
sanke.setDirecton(Directon.DOWN);
}
break;
case KeyEvent.VK_LEFT://左
if(sanke.getDirecton()!=Directon.RIGHT){
sanke.setDirecton(Directon.LEFT);
}
break;
case KeyEvent.VK_RIGHT://右
if(sanke.getDirecton()!=Directon.LEFT){
sanke.setDirecton(Directon.RIGHT);
}
break;
}
}
});
}
//初始化定时器
private void initTimer() {
//创建定时器对象;
timer = new Timer();
//初始化定时任务;
TimerTask timertask = new TimerTask() {
@Override
public void run() {
sanke.move();
//判断是否迟到食物
Node node = sanke.getBody().getFirst();
if(node.getX()==food.getX()&&node.getY()==food.getY()){
sanke.eat(food);
food.random();
}
//重新绘制棋盘;
jPanel.repaint();
}
};
//100毫秒执行一次;
timer.scheduleAtFixedRate(timertask,0,100);
}
private void initsanke() {
sanke = new sanke();
}
//初始化游戏棋盘;
private void inintGamePanel() {
jPanel = new JPanel(){
//绘制游戏棋盘中的内容
@Override
public void paint(Graphics g) {
//清空棋盘;
g.clearRect(0, 0, 600, 600);
//Graphics g看作是一个画笔提供了很多方法可以绘制一些基本的图形
//绘制四十条横线;
for(int i=0; i<=40; i++){
g.drawLine(0, i*15, 600, i*15);
}
//绘制四十条竖线;
for(int i=0; i<=40; i++){
g.drawLine(i*15, 0,i*15, 600);
}
//绘制蛇;
LinkedList<Node> body = sanke.getBody();
for(Node node : body){
g.fillRect(node.getX()*15, node.getY()*15, 15, 15);
}
//绘制食物;
g.fillRect(food.getX()*15, food.getY()*15, 15, 15);
}
};
//棋盘添加到窗体中;
add(jPanel);
}
private void initFrame() {
//创建窗体宽和高
setSize(610,640);
//设置窗体的位置;
setLocation(700,200);
//设置关闭按钮的作用;
setDefaultCloseOperation(EXIT_ON_CLOSE);
//固定窗体大小
setResizable(false);
}
public static void main(String[] args){
//创建窗体对象并显示
new MainFrame().setVisible(true);
}
}
这里我们创建一个节点类因为蛇都是由若干个节点组成的
package snakegame;
import java.util.Random;
//节点类每一条蛇有由若干个节点组成的
public class Node {
private int x;
private int y;
public Node(){
}
public Node(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;
}
//随机生成位置(食物);
public void random(){
//创建random对象;
Random r = new Random();
//随机生成横坐标;
this.x = r.nextInt(40);
//随机生成纵坐标
this.y = r.nextInt(40);
}
}
下面我们创建一个蛇类封装蛇身(小编英语不太好类名打错了不过不要在意这些细节)
package snakegame;
import java.util.LinkedList;
public class sanke {
//蛇的身体
private LinkedList<Node> body;
//蛇的运动方向;
//默认向左
private Directon directon = Directon.LEFT;
//蛇是否活着;
private boolean isLiving = true;
//构造方法在sanke对象是时执行;
public sanke(){
//初始化射身体;
initSanke();
}
private void initSanke() {
//创建集合
body = new LinkedList<>();
//创建六个节点放到集合中
body.add(new Node(16,10));
body.add(new Node(17,10));
body.add(new Node(18,10));
body.add(new Node(19,10));
body.add(new Node(20,10));
body.add(new Node(21,10));
}
//蛇随着蛇头的方向移动
//控制蛇移动
public void move(){
if(isLiving){
//获取蛇头;
Node head = body.getFirst();
switch(directon){
case UP:
//在蛇头上方添加一个节点;
body.addFirst(new Node(head.getX(),head.getY()-1));
break;
case DOWN:
body.addFirst(new Node(head.getX(),head.getY()+1));
break;
case LEFT:
body.addFirst(new Node(head.getX()-1,head.getY()));
break;
case RIGHT:
body.addFirst(new Node(head.getX()+1,head.getY()));
break;
}
//删除最后的节点;
body.removeLast();
//判断蛇是否活着;
head = body.getFirst();
if(head.getX()<0||head.getY()<0||head.getX()>=40||head.getY()>=40){
isLiving = false;
}
//判断蛇是否碰到自己;
for(int i=0;i<body.size();i++){
Node node = body.get(i);
/*if(head.getX()==node.getX()&&head.getY()==node.getY()){
isLiving = false;
}*/
}
//判断是否迟到食物
}
}
public LinkedList<Node> getBody(){
return body;
}
public void setBody(LinkedList<Node> body){
}
public Directon getDirecton(){
return directon;
}
public void setDirecton(Directon directon){
this.directon = directon;
}
public void eat(Node food) {
// 吃食物;
Node head = body.getFirst();
switch(directon){
case UP:
//在蛇头上方添加一个节点;
body.addFirst(new Node(head.getX(),head.getY()-1));
break;
case DOWN:
body.addFirst(new Node(head.getX(),head.getY()+1));
break;
case LEFT:
body.addFirst(new Node(head.getX()-1,head.getY()));
break;
case RIGHT:
body.addFirst(new Node(head.getX()+1,head.getY()));
break;
}
}
}
下面代码是一个枚举类里创建上下左右来控制蛇的移动
package snakegame;
//枚举类
public enum Directon {
UP,DOWN,LEFT,RIGHT;
}