这个版本的贪吃蛇我是跟着“黑马程序员”写的。小伙伴们可以跟着视频试着做一下,同时视频也会更详细。
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;/*SNK类表示蛇,一条蛇有多个节点使用LinkedList集合存储Node节点,蛇出生时有4个节点*/
public class SNK
{private LinkedList<Node>body;//设置蛇的运动方向,默认向左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;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){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()//当键盘按下会自动调用此方法{@Overridepublic 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(){@Overridepublic 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(){//绘制@Overridepublic 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<Node> 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);}
}