首款用Java语言实现的小游戏,一些模块做得不是很好,界面的设计及整体的布局比较简单,一些应该实现的的功能没有实现,一些该有的组件没有定义出来,所以仅供参考。如果您可以提出宝贵意见,我将感激不尽!
游戏窗口的界面设置及主函数入口:
public class SnakeDemo {
public SnakeDemo() {
JFrame frame = new JFrame("贪吃蛇demo1.0");
frame.setBounds(0, 0, 550, 450);// 设置窗体的大小
SnakeGame sn = new SnakeGame();
frame.setLocationRelativeTo(null);
sn.setFocusable(true);// 表示Component 是否可以获得焦点
frame.add(sn);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
sn.requestFocus();
}
public static void main(String[] args) {
new SnakeDemo();
}
}
程序主体,包括蛇体的绘制、蛇体的链表存储、蛇体的移动控制、食物的随机出现等方法模块:
public class SnakeGame extends JPanel {
private final int length = 20;// 定义活动范围
private final int width = 20;// 定义活动范围
private final int BLOCK_SIZE = 20;// 定义单位长度
private int SnakeLength;// 定义蛇身的长度
private int Scores;// 定义游戏得分
private ArrayList<SnakeBody> snake = new ArrayList<>();// 定义蛇身的集合
private int oldDirection;// 定义蛇头的方向
private SnakeBody newFood = new SnakeBody(1, 1, Color.GREEN);// 定义随机点
Timer time = new Timer(400, new ThingsListener());
public SnakeGame() {// 初始化各项数据与方法
snake.add(new SnakeBody(width / 2, length / 2, Color.red));
snake.add(new SnakeBody(width / 2, length / 2 + 1, Color.BLUE));
snake.add(new SnakeBody(width / 2, length / 2 + 2, Color.blue));
oldDirection = 1;// 定义初始方向为向上
SnakeLength = 3;// 蛇身长度为3
createNewFood();// 产生随机点
time.start();
this.addKeyListener(new KeyAdapter() {// 捕捉键盘的按键事件
public void keyPressed(KeyEvent e) {
int newdirection = 0;// 定义一个按下按钮后要去的新方向
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:// 按下向上,返回1
newdirection = 1;
break;
case KeyEvent.VK_DOWN:// 按下向下,返回-1
newdirection = -1;
break;
case KeyEvent.VK_LEFT:// 按下相左,返回2
newdirection = 2;
break;
case KeyEvent.VK_RIGHT:// 按下向右,返回-2
newdirection = -2;
break;
}
if (newdirection + oldDirection != 0) {// 不能反向运动
oldDirection = newdirection;
Move(newdirection);// 按此方向移动
repaint();// 重画
}
}
});
}
/**
* 移动模块 定义蛇身移动的方法 同时判断蛇是否吃到食物或自己,是否撞墙
*
* @param newdirection
*/
public void Move(int newdirection) {// 定义蛇身移动的方向
int FirstX = snake.get(0).getX();// 获取蛇第一个点的X坐标
int FirstY = snake.get(0).getY();// 获取蛇第一个点的Y坐标
switch (newdirection) {
case 1:
FirstY--;
break;
case -1:
FirstY++;
break;
case 2:
FirstX--;
break;
case -2:
FirstX++;
break;
default:
break;
}
if (FirstX == newFood.getX() && FirstY == newFood.getY()) {// 当碰到随机点时
eatFood();
Scores += 5;
return;
}
for (int x = 0; x < SnakeLength; x++) {// 当碰到蛇身自己时
if ((FirstX == snake.get(x).getX()) && (FirstY == snake.get(x).getY())) {
Dead("你吃到自己啦(\"▔□▔)");
}
}
if (FirstX < 0 || FirstX > width - 1 || FirstY < 0 || FirstY > length - 1) {
Dead("你撞墙了");
}
for (int x = SnakeLength - 1; x > 0; x--) {
snake.get(x).setX(snake.get(x - 1).getX());
snake.get(x).setY(snake.get(x - 1).getY());
}
snake.get(0).setX(FirstX);
snake.get(0).setY(FirstY);
repaint();
}
/**
* 吃食物模块
*/
public void eatFood() {
snake.add(new SnakeBody());
SnakeLength++;
for (int x = SnakeLength - 1; x > 0; x--) {
snake.get(x).setX(snake.get(x - 1).getX());
snake.get(x).setY(snake.get(x - 1).getY());
snake.get(x).setColor(snake.get(x - 1).getColor().BLUE);
}
snake.get(0).setX(newFood.getX());
snake.get(0).setY(newFood.getY());
createNewFood();
repaint();
}
/**
* 游戏结束模块
*/
public void Dead(String s) {
Date date = new Date();
SimpleDateFormat sd = new SimpleDateFormat();
String str2 = sd.format(date);
String str = s + "\n" + "所以说游戏必须结束啦";
System.out.println(Scores);
JOptionPane.showMessageDialog(this, str2 + "\n" + str);
System.exit(0);
}
/**
* 创造新的随机食物的方法
*/
public void createNewFood() {// 创造新的随机食物的方法
int newX = 0;
int newY = 0;
Boolean flag = true;
while (flag) {
newX = new Random().nextInt(width);
newY = new Random().nextInt(length);
for (int i = 0; i < SnakeLength; i++) {
if (snake.get(i).getX() == newX && snake.get(i).getY() == newY) {
flag = true;
break;
}
flag = false;
}
}
newFood.setX(newX);
newFood.setY(newY);
this.setBackground(Color.WHITE);
}
/**
* 创建一个内部类,设置一个监听器事件
*
*/
class ThingsListener implements ActionListener {// 设置一个监听器事件
public void actionPerformed(ActionEvent e) {
Move(oldDirection);
repaint();
}
}
/**
* 设置窗口属性
*/
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.gray);// 画出网格线,颜色为灰色
for (int i = 1; i < width; i++) {
g.drawLine(0, BLOCK_SIZE * i, length * BLOCK_SIZE, BLOCK_SIZE * i);
}
for (int i = 1; i < length; i++) {
g.drawLine(BLOCK_SIZE * i, 0, BLOCK_SIZE * i, BLOCK_SIZE * width);
}
g.setColor(newFood.getColor().GREEN);
g.fillOval(newFood.getX() * BLOCK_SIZE, newFood.getY() * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
g.setColor(newFood.getColor().black);
g.drawRect(0, 0, width * BLOCK_SIZE, length * BLOCK_SIZE);
g.drawString("当前分数:" + Scores, 410, 20);
g.drawString("当前蛇身长度:" + SnakeLength, 410, 40);
for (int x = 0; x < SnakeLength; x++) { // 画出蛇体
g.setColor(snake.get(x).getColor());
g.fillOval(snake.get(x).getX() * BLOCK_SIZE, snake.get(x).getY() * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
}
}
}
蛇身集合中的各个元素点的定义:
package SnakeGame3;
import java.awt.Color;
public class SnakeBody {// 定义蛇身集合中的各个元素点
private int x;
private int y;
private Color color;
public SnakeBody() {
super();
}
public SnakeBody(int x, int y, Color color) {
super();
this.x = x;
this.y = y;
this.color = color;
}
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 Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
此游戏有待改进……
继续努力、继续学习、继续敲代码……
这是一条不归路……