这个版本的贪吃蛇我是跟着“黑马程序员”写的。小伙伴们可以跟着视频试着做一下,同时视频也会更详细。
B站学习链接:【黑马】两个小时带你用Java语言写一个贪吃蛇游戏【配套源码+笔记】_哔哩哔哩_bilibili
相对于新手而言,贪吃蛇应该算是一个简单一点的实战小游戏,(这里我写的是简易版)
这里我写了四个类
Node类,用来随机食物位置
SNK类,用确定蛇的位置以及一些指令
命名一个枚举类:Direction来写一些固定常量(指令名称)
最后是主类MainFrame,游戏运行的主面板(该类是继承JFrame类的)
最终效果
随机位置确定
package Snake;
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 r=new Random();
//随机生成横坐标
this.x=r.nextInt(35);
//随机生成纵坐标
this.y=r.nextInt(36);
}
}
绘制蛇以及判断
package Snake;
import java.util.LinkedList;
public class SNK
{
private LinkedListbody;
//设置蛇的运动方向,默认向左
private Direction direction=Direction.LEFT;
//蛇是否活着
private boolean isLiving=true;
public SNK() {
initSNK();
}
public void initSNK()
{
//创建蛇的躯体
body=new LinkedList<>();
body.add(new Node(20,20));
body.add(new Node(20,21));
body.add(new Node(20,22));
body.add(new Node(21,22));
}
//控制蛇移动:在蛇头的运动方向添加一个节点,然后把蛇尾的节点删除
public void move()
{
if(isLiving) {
Node head = body.getFirst();
switch (direction) {
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()>34||head.gety()>35)
{
isLiving=false;
}
//判断蛇是否碰到自己的身体
for(int i=1;igetBody()
{
return body;
}
public void setBody(LinkedListbody)
{
this.body=body;
}
public Direction getDirection()
{
return direction;
}
public void setDirection(Direction direction)
{
this.direction=direction;
}
public void eat(Node food)
{
Node head=body.getFirst();
switch (direction) {
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;
}
}
}
列一个枚举类,里面写几个常量(记得选E)
package Snake;
public enum Direction
{
UP,DOWN,LEFT,RIGHT
}
游戏主面板,最后在这里运行
package Snake;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
public class MainFrame extends JFrame
{
private SNK SNK; //蛇
private JPanel jpanel;//游戏棋盘
private Timer timer;//定时器,在指定的时间调用蛇移动的方法
private Node food; //食物
public MainFrame()throws HeadlessException
{ //初始化窗口参数
initFrame();
//初始化游戏棋盘
initGamePanel();
//初始化蛇
initSNK();
//初始化食物
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(SNK.getDirection()!=Direction.DOWN) {
SNK.setDirection(Direction.UP);
}
break;
case KeyEvent.VK_DOWN:
if(SNK.getDirection()!=Direction.UP) {
SNK.setDirection(Direction.DOWN);
}
break;
case KeyEvent.VK_LEFT:
if(SNK.getDirection()!=Direction.RIGHT) {
SNK.setDirection(Direction.LEFT);
}
break;
case KeyEvent.VK_RIGHT:
if(SNK.getDirection()!=Direction.LEFT) {
SNK.setDirection(Direction.RIGHT);
}
break;
}
}
});
}
//初始化定时器
private void initTimer()
{
//创建定时器对象
timer=new Timer();
//初始化定时任务
TimerTask timerTask=new TimerTask()
{
@Override
public void run()
{
SNK.move();
//判断蛇头是否与食物重合
Node head=SNK.getBody().getFirst();
if(head.getx()==food.getx()&&head.gety()==food.gety())
{
SNK.eat(food);
food.random();
}
//重绘游戏棋盘
jpanel.repaint();
}
};
//每100毫秒,执行一次定时任务
timer.scheduleAtFixedRate(timerTask,0,100);
}
private void initSNK()
{
SNK=new SNK();
}
//初始化游戏棋盘
public void initGamePanel()
{
jpanel=new JPanel()
{
//绘制
@Override
public void paint(Graphics g) //Graphics g可以理解为一个画笔
{
//清空棋盘
g.clearRect(0,0,600,600);
//super.paint(g);
//绘制横线
for(int i=0;i<=35;i++)
{
g.drawLine(0,i*15,600,i*15);
}
//绘制竖线
for(int i=0;i<=36;i++)
{
g.drawLine(i*15,0,i*15,600);
}
//绘制蛇
LinkedList body=SNK.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);
}
//初始化窗口参数
public void initFrame()
{ //设置窗体长宽高
setSize(540,575);
//设置窗口位置
setLocation(240,50);
//设置关闭按钮
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//规定窗口大小不可变
setResizable(false);
}
public static void main(String[]args)
{
new MainFrame().setVisible(true);
}
}



