snake.java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import simpleFrame.FrameUtil;
import simpleFrame.MyFrame;
public class SnakeView extends JPanel {
// 地图的宽和高
public static final int WIDTH = 40;
public static final int HEIGHT = 30;
// 格子的宽和高
public static final int CELLWIDTH = 20;
public static final int CELLHEIGHT = 20;
// 使用四个常量表示四个方向
public static final int UP_DIRECTION = 1; // 上
public static final int DOWN_DIRECTION = -1; // 下
public static final int LEFT_DIRECTION = 2; // 左
public static final int RIGHT_DIRECTION = -2; // 右
// 蛇当前的方向
int currentDrection = -2; // 蛇默认向右行走
// 记录游戏是否结束
static boolean isGameOver = false; // 默认游戏没有结束
// 包含蛇所有节点的信息
LinkedList<Point> snake = new LinkedList<Point>();
// 食物
Point food;
// 地图
public char[][] background = new char[HEIGHT][WIDTH];
// 改变当前方向
public void changeDirection(int newDirection) {
// 判断新方向与当前方向是否是相反方向
if (newDirection + currentDrection != 0) {
this.currentDrection = newDirection;
}
}
// 蛇移动的方法
public void move() {
Point head = snake.getFirst();
// 蛇是根据当前方向移动的
switch (currentDrection) {
case UP_DIRECTION:
snake.addFirst(new Point(head.x, head.y - 1));
break;
case DOWN_DIRECTION:
snake.addFirst(new Point(head.x, head.y + 1));
break;
case LEFT_DIRECTION:
if (head.x == 0) {
snake.addFirst(new Point(WIDTH - 1, head.y));
} else {
snake.addFirst(new Point(head.x - 1, head.y));
}
break;
case RIGHT_DIRECTION:
if (head.x == WIDTH - 1) {
snake.addFirst(new Point(0, head.y));
} else {
snake.addFirst(new Point(head.x + 1, head.y));
}
break;
default:
break;
}
if (eatFood()) {
// 吃到了食物
createFood();
} else {
// 删除蛇尾
snake.removeLast();
}
}
// 初始化地图
public void initBackground() {
for (int rows = 0; rows < background.length; rows++) {
for (int cols = 0; cols < background[rows].length; cols++) {
if (rows == 0 || rows == HEIGHT - 1 || cols == 0
|| cols == WIDTH - 1) {
background[rows][cols] = '*'; // 打印墙体
} else {
background[rows][cols] = ' '; // 打印空白
}
}
}
}
// 初始化蛇
public void initSnake() { // 初始化蛇在地图的中间位置
int x = WIDTH / 2;
int y = HEIGHT / 2;
snake.addFirst(new Point(x - 1, y));
snake.addFirst(new Point(x, y));
snake.addFirst(new Point(x + 1, y));
}
// 生成食物
public void createFood() {
// 创建一个随机数对象
Random random = new Random();
while (true) {
int x = random.nextInt(WIDTH); // 0~width-3
int y = random.nextInt(HEIGHT);
if (background[y][x] != '*') {
food = new Point(x, y);
break;
}
}
}
// 吃食物
public boolean eatFood() {
// 获取蛇头
Point head = snake.getFirst();
if (head.equals(food)) {
return true;
}
return false;
}
@Override
public void paint(Graphics g) {
// 画地图
for (int rows = 0; rows < background.length; rows++) {
for (int cols = 0; cols < background[rows].length; cols++) {
if (background[rows][cols] == '*') {
// 石头
g.setColor(Color.GRAY);
} else {
// 地图
g.setColor(Color.white);
}
g.fill3DRect(cols * CELLWIDTH, rows * CELLHEIGHT, CELLWIDTH,
CELLHEIGHT, true);
}
}
// 画蛇
// 画出蛇头
Point head = snake.getFirst();
g.setColor(Color.red);
g.fill3DRect(head.x * CELLWIDTH, head.y * CELLHEIGHT, CELLWIDTH,
CELLHEIGHT, true);
// 蛇身
for (int i = 1; i < snake.size(); i++) {
Point body = snake.get(i);
g.setColor(Color.green);
g.fill3DRect(body.x * CELLWIDTH, body.y * CELLHEIGHT, CELLWIDTH,
CELLHEIGHT, true);
}
// 显示食物
background[food.y][food.x] = '@';
if (background[food.y][food.x] == '@') {
g.setColor(Color.BLUE);
g.fill3DRect(food.x * CELLWIDTH, food.y * CELLHEIGHT, CELLWIDTH,
CELLHEIGHT, true);
}
}
// 游戏结束的方法
public void isGameOver() {
// 撞墙结束
Point head = snake.getFirst();
if (background[head.y][head.x] == '*') {
isGameOver = true;
}
// 咬到自己
for (int i = 1; i < snake.size(); i++) {
Point body = snake.get(i);
if (head.equals(body)) {
isGameOver = true;
}
}
}
//游戏运行
public void Start() {
JFrame frame = new JFrame("贪吃蛇 @羊羊羊");
JFrame frame2 = new JFrame("游戏结束");
SnakeView snakeView = new SnakeView();
frame.setResizable(false);
snakeView.initBackground();
snakeView.initSnake();
snakeView.createFood();
frame.add(snakeView);
FrameUtil.initFrame(frame, WIDTH * CELLWIDTH + 10, HEIGHT * CELLHEIGHT
+ 35);
// 给窗口添加事件监听器
frame.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
switch (code) {
case KeyEvent.VK_UP:
snakeView.changeDirection(UP_DIRECTION);
break;
case KeyEvent.VK_DOWN:
snakeView.changeDirection(DOWN_DIRECTION);
snakeView.repaint();
break;
case KeyEvent.VK_LEFT:
snakeView.changeDirection(LEFT_DIRECTION);
snakeView.repaint();
break;
case KeyEvent.VK_RIGHT:
snakeView.changeDirection(RIGHT_DIRECTION);
snakeView.repaint();
break;
default:
break;
}
snakeView.move();
snakeView.isGameOver(); // 判断游戏是否结束
// 刷新游戏
snakeView.repaint(); // 实际上就是调用paint的方法
if (isGameOver) {
/*
* System.out.println("游戏结束"); System.exit(0);
*/
MyFrame.init(frame2, 300, 200);
}
snakeView.repaint();
}
});
}
//游戏退出
public void Exit(){
System.exit(0);
}
public static void main(String[] args) {
SnakeView snakeView = new SnakeView();
snakeView.Start();
}
}
FrameUtil.java
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
//初始化窗口的工具类
public class FrameUtil {
public static void initFrame(JFrame frame,int width,int height){
Toolkit toolkit=Toolkit.getDefaultToolkit(); //获取一个与系统相关的工具类对象
//返回屏幕的尺寸
Dimension d=toolkit.getScreenSize();
int x=(int)d.getWidth();
int y=(int)d.getHeight();
frame.setBounds((x-width)/2, (y-height)/2, width, height);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
snake_贪吃蛇.java
最新推荐文章于 2019-04-28 17:02:56 发布