标签:resizable 时间 keyevent over gety turn 定时器 就是 clear
Java小游戏实战开发——贪吃蛇小游戏 1、Direction类。
Direction:用于存放上下左右四个键。
package com.games; /* *枚举:就是几个固定的常量 */ public enum Direction{ UP,DOWN,LEFT,RIGHT }
2、Snake类
Snake,蛇类:一条蛇有多个节点,使用LinkedList集合出储存Node节点
初始化蛇身体,蛇出生地有6个节点
package com.games; import java.util.LinkedList; /** *Snake类表示蛇 * 一条蛇有多个节点,使用LinkedList集合存储Node节点 * 蛇出生的地方有6个节点 */ public class Snake { //蛇的身体 private LinkedList<Node> body; //蛇的运动方向 private Direction direction = Direction.LEFT; //蛇是否活着 private boolean isLiving = true; //构造方法,在创造Snake对象时执行 public Snake(){ //初始化蛇身体 initSnake(); } //初始化蛇身体 private void initSnake(){ //创建集合 body= new LinkedList<>(); //创建6个节点放在集合中 body.add(new Node(16,20)); body.add(new Node(17,20)); body.add(new Node(18,20)); body.add(new Node(19,20)); body.add(new Node(20,20)); body.add(new Node(21,20)); } //蛇会沿着蛇头的方向移动 //控制蛇移动:在蛇头的运动方向添加一个节点,然后把蛇尾的最后一个节点删除 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() >= 40 || head.getY() >= 40){ 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; } } }
3、Node类
节点类:每一条蛇是由若干个节点组成的,每一个节点有横纵坐标来确定位置
package com.games; 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); } }
4、MainFrame类
实现:
(1)initFrame()方法:初始化窗体参数;设置窗体宽高、窗体默认位置、关闭按钮的作用和窗体大小不可变。
(2)initGamePanel()方法:继承JPanel()类,重写paint()方法,初始化游戏棋盘,在paint()方法中绘制棋盘中的内容,即清空棋盘、绘制横竖线条、绘制蛇和食物,最后把棋盘添加到窗体中。
(3)initSnake()方法:初始化蛇;创建Snake类,在Snake类中初始化蛇的初始位置、构造move()方法和eat()方法。move()方法实现蛇沿着蛇头方向移动、判断蛇是否撞墙和碰到自己身体的功能;eat()方法实现当食物与蛇头重合,会沿蛇头的移动方向添加一个节点。。
(4)initFood()方法:初始化食物;创建Node类,在Node类中用随机数实现食物位置的随机生成。
(5)initTimer()方法:初始化定时器;设置定时任务,根据游戏状态和direction变量设置蛇移动操作,进行食物判定,判断食物与蛇头是否重合,如果重合调用eat()方法并再次随机生成食物。使用定时器,调用repaint()方法实时更新界面。
(6)setKeyListener()方法:设置键盘监听,当键盘按下时,调用keyPressed(KeyEvent e)方法,获取键盘输入,根据键盘输入让蛇随着Direction方向移动。
代码如下:
package com.games; import javax.swing.*; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.Timer; import java.util.LinkedList; import java.util.TimerTask; public class MainFrame extends JFrame { //蛇 private Snake snake; //游戏棋盘 private JPanel jPanel; //定时器,在规定时间内调用蛇移动的方法 private Timer timer; //食物 private Node food; public MainFrame() throws HeadlessException { //初始化窗体参数 initFrame(); //初始化游戏棋盘 initGamePanel(); //初始化蛇 initSnake(); //初始化食物 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(snake.getDirection() != Direction.DOWN){ //修改蛇的运动方向 snake.setDirection(Direction.UP); } break; case KeyEvent.VK_DOWN://下键 if(snake.getDirection() != Direction.UP){ snake.setDirection(Direction.DOWN); } break; case KeyEvent.VK_LEFT://左键 if(snake.getDirection() != Direction.RIGHT){ snake.setDirection(Direction.LEFT); } break; case KeyEvent.VK_RIGHT://右键 if(snake.getDirection() != Direction.LEFT){ snake.setDirection(Direction.RIGHT); } break; } } }); } private void initTimer(){ timer = new Timer(); TimerTask timerTask = new TimerTask() { @Override public void run() { snake.move(); //判断食物与蛇头是否重合 Node head = snake.getBody().getFirst(); if(head.getX() == food.getX() && head.getY() == food.getY()){ snake.eat(food); food.random(); } //重绘游戏棋盘 jPanel.repaint(); } }; //每100毫秒,执行一次定时任务 //蛇的移动速度,如果想改变移动速度,改变最后一个参数即可 timer.scheduleAtFixedRate(timerTask,0,200); } private void initSnake(){ snake = new Snake(); } public void initGamePanel(){ jPanel = new JPanel(){ //绘制棋盘中的内容 public void paint(Graphics g){ //清空棋盘 g.clearRect(0,0,600,600); //Graphics g 可以看做是一个画笔,提供了很多方法可以来绘制一些基本图形(直线、矩形) //绘制40条横线 for(int i = 0;i <= 40; i++){ g.drawLine(0,i*15,600,i*15); } //绘制40条竖线 for(int i = 0; i <= 40; i++){ g.drawLine(i*15,0,i*15,600); } //绘制蛇 LinkedList<Node> body = snake.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(610,640); //设置窗体默认位置 setLocation(408,408); //设置关闭按钮的作用 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置窗体大小不可变 setResizable(false); } public static void main(String[] args) { //创建窗体对象,并显示 new MainFrame().setVisible(true); } }
标签:resizable 时间 keyevent over gety turn 定时器 就是 clear
原文地址:https://www.cnblogs.com/heyu123/p/14899951.html