共计 5318 个字符,预计需要花费 14 分钟才能阅读完成。
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);
}
}