贪食蛇项目设计

package anqi.xiancheng.shili;


import java.awt.*;
import java.awt.event.*;
import java.util.*;


import javax.swing.*;


//Main Class


public class GreedSnake extends KeyAdapter {


JFrame mainFrame;
Canvas paintCanvas;
JLabel labelScore;// 计分牌
SnakeModel snakeModel = null;// 蛇
public static final int DEFAULT_WIDTH = 500;
public static final int DEFAULT_HEIGHT = 300;
public static final int nodeWidth = 10;
public static final int nodeHeight = 10;


// GreedSnake():初始化游戏界面


public GreedSnake() {


// 设置界面元素
mainFrame = new JFrame("贪吃蛇游戏");
Container cp = mainFrame.getContentPane();
labelScore = new JLabel("所得分数为:", JLabel.CENTER);
cp.add(labelScore, BorderLayout.NORTH);
paintCanvas = new Canvas();
paintCanvas.setSize(DEFAULT_WIDTH + 1, DEFAULT_HEIGHT + 1);
paintCanvas.addKeyListener(this);
cp.add(paintCanvas, BorderLayout.CENTER);
JPanel panelButtom = new JPanel();
panelButtom.setLayout(new BorderLayout());
JLabel labelHelp;// 帮助信息
labelHelp = new JLabel("按 PageUP 或 PageDown 键改变速度", JLabel.CENTER);
panelButtom.add(labelHelp, BorderLayout.NORTH);
labelHelp = new JLabel("按 Enter 或 S 键重新开始游戏", JLabel.CENTER);
panelButtom.add(labelHelp, BorderLayout.CENTER);
labelHelp = new JLabel("按 SPACE 键或 P 键暂停游戏", JLabel.CENTER);
panelButtom.add(labelHelp, BorderLayout.SOUTH);
cp.add(panelButtom, BorderLayout.SOUTH);
mainFrame.addKeyListener(this);
mainFrame.pack();
mainFrame.setResizable(false);// 设置窗口大小不能变化
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setVisible(true);
begin();
}


// keyPressed():按键检测


public void keyPressed(KeyEvent e) {


int keyCode = e.getKeyCode();
if (snakeModel.running)
switch (keyCode) {
case KeyEvent.VK_UP:
snakeModel.changeDirection(SnakeModel.UP);
break;
case KeyEvent.VK_DOWN:
snakeModel.changeDirection(SnakeModel.DOWN);
break;
case KeyEvent.VK_LEFT:
snakeModel.changeDirection(SnakeModel.LEFT);
break;
case KeyEvent.VK_RIGHT:
snakeModel.changeDirection(SnakeModel.RIGHT);
break;
case KeyEvent.VK_ADD:
case KeyEvent.VK_PAGE_UP:
snakeModel.speedUp();// 加速
break;
case KeyEvent.VK_SUBTRACT:
case KeyEvent.VK_PAGE_DOWN:
snakeModel.speedDown();// 减速
break;
case KeyEvent.VK_SPACE:
case KeyEvent.VK_P:
snakeModel.changePauseState();// 暂停或继续
break;
default:
}
// 重新开始
if (keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_ENTER) {
snakeModel.running = false;
begin();
}
}


// repaint():绘制游戏界面(包括蛇和食物)


void repaint() {
Graphics g = paintCanvas.getGraphics();
// draw background
g.setColor(Color.LIGHT_GRAY);
g.fillRect(0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT);
// draw the snake
g.setColor(Color.BLACK);
LinkedList na = snakeModel.nodeArray;
Iterator it = na.iterator();
while (it.hasNext()) {


Node n = (Node) it.next();
drawNode(g, n);
}
// draw the food
g.setColor(Color.RED);
Node n = snakeModel.food;
drawNode(g, n);
updateScore();
}


// drawNode():绘画某一结点(蛇身或食物)


private void drawNode(Graphics g, Node n) {
g.fillRect(n.x * nodeWidth, n.y * nodeHeight, nodeWidth - 1,
nodeHeight - 1);
}


// updateScore():改变计分牌


public void updateScore() {
String s = "所得分数为: " + snakeModel.score;
labelScore.setText(s);
}


// begin():游戏开始,放置贪吃蛇


void begin() {


if (snakeModel == null || !snakeModel.running) {
snakeModel = new SnakeModel(this, DEFAULT_WIDTH / nodeWidth,
DEFAULT_HEIGHT / nodeHeight);
(new Thread(snakeModel)).start();
}
}


// main():主函数


public static void main(String[] args) {


GreedSnake gs = new GreedSnake();
}
}


// Node:结点类


class Node {
int x;
int y;


Node(int x, int y) {
this.x = x;
this.y = y;
}
}


// SnakeModel:贪吃蛇模型


class SnakeModel implements Runnable {


GreedSnake gs;
boolean[][] matrix;// 界面数据保存在数组里
LinkedList nodeArray = new LinkedList();
Node food;
int maxX;// 最大宽度
int maxY;// 最大长度
int direction = 2;// 方向
boolean running = false;
int timeInterval = 200;// 间隔时间(速度)
double speedChangeRate = 0.75;// 速度改变程度
boolean paused = false;// 游戏状态
int score = 0;
int countMove = 0;
// UP和DOWN是偶数,RIGHT和LEFT是奇数
public static final int UP = 2;
public static final int DOWN = 4;
public static final int LEFT = 1;
public static final int RIGHT = 3;


// GreedModel():初始化界面


public SnakeModel(GreedSnake gs, int maxX, int maxY) {


this.gs = gs;
this.maxX = maxX;
this.maxY = maxY;
matrix = new boolean[maxX][];
for (int i = 0; i < maxX; ++i) {
matrix[i] = new boolean[maxY];
Arrays.fill(matrix[i], false);// 没有蛇和食物的地区置false
}
// 初始化贪吃蛇
int initArrayLength = maxX > 20 ? 10 : maxX / 2;
for (int i = 0; i < initArrayLength; ++i) {
int x = maxX / 2 + i;
int y = maxY / 2;
nodeArray.addLast(new Node(x, y));
matrix[x][y] = true;// 蛇身处置true
}
food = createFood();
matrix[food.x][food.y] = true;// 食物处置true
}


// changeDirection():改变运动方向


public void changeDirection(int newDirection) {


if (direction % 2 != newDirection % 2) {// 避免冲突
direction = newDirection;
}
}


// moveOn():贪吃蛇运动函数


public boolean moveOn() {


Node n = (Node) nodeArray.getFirst();
int x = n.x;
int y = n.y;
switch (direction) {
case UP:
y--;
break;
case DOWN:
y++;
break;
case LEFT:
x--;
break;
case RIGHT:
x++;
break;
}
if ((0 <= x && x < maxX) && (0 <= y && y < maxY)) {


if (matrix[x][y]) {// 吃到食物或者撞到身体


if (x == food.x && y == food.y) {// 吃到食物


nodeArray.addFirst(food);// 在头部加上一结点
// 计分规则与移动长度和速度有关
int scoreGet = (10000 - 200 * countMove) / timeInterval;
score += scoreGet > 0 ? scoreGet : 10;
countMove = 0;
food = createFood();
matrix[food.x][food.y] = true;
return true;
} else
return false;// 撞到身体
} else {// 什么都没有碰到
nodeArray.addFirst(new Node(x, y));// 加上头部
matrix[x][y] = true;
n = (Node) nodeArray.removeLast();// 去掉尾部
matrix[n.x][n.y] = false;
countMove++;
return true;
}
}
return false;// 越界(撞到墙壁)
}


/* 发了一份贪吃蛇游戏的代码,谁能帮我解释一下,贪吃蛇程序的运行过程,运行步骤 */
// run():贪吃蛇运动线程


public void run() {
running = true;
while (running) {
try {
Thread.sleep(timeInterval);
} catch (Exception e) {
break;
}
if (!paused) {


if (moveOn()) {// 未结束
gs.repaint();
} else {// 游戏结束
JOptionPane.showMessageDialog(null, "GAME OVER",
"Game Over", JOptionPane.INFORMATION_MESSAGE);
break;
}
}
}
running = false;
}


// createFood():生成食物及放置地点


private Node createFood() {


int x = 0;
int y = 0;
do {
Random r = new Random();
x = r.nextInt(maxX);
y = r.nextInt(maxY);
} while (matrix[x][y]);
return new Node(x, y);
}


// speedUp():加快蛇运动速度


public void speedUp() {
timeInterval *= speedChangeRate;
}


// speedDown():放慢蛇运动速度


public void speedDown() {


timeInterval /= speedChangeRate;
}


// changePauseState(): 改变游戏状态(暂停或继续)


public void changePauseState() {


paused = !paused;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值