java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。
这篇文章主要为大家详细介绍了java贪吃蛇游戏的编写代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
1、采用MVC(model、view、control)框架模式
2、包和类的关系树形图为:
3、源码:
- package com.huai;
- import Java.awt.Color;
- import java.awt.Graphics;
- import java.awt.Point;
- import java.util.HashSet;
- import java.util.LinkedList;
- import java.util.Set;
- import com.huai.listener.SnakeListener;
- import com.huai.util.Constant;
- public class Snake {
- //和蛇的监听器有关
- Set < SnakeListener > snakeListener = new HashSet < SnakeListener > ();
- //用链表保存蛇的身体节点
- LinkedList < Point > body = new LinkedList < Point > ();
- private boolean life = true;
- //默认速度为400ms
- private int speed = 400;
- private Point lastTail = null;
- private boolean pause = false;
- //定义各个方向
- public static final int UP = 1;
- public static final int DOWN = -1;
- public static final int LEFT = 2;
- public static final int RIGHT = -2;
- int newDirection = RIGHT;
- int oldDirection = newDirection;
- public Snake() {
- initial();
- }
- public void initial() {
- //先清空所有的节点
- body.removeAll(body);
- int x = Constant.WIDTH / 2;
- int y = Constant.HEIGHT / 2;
- //蛇的默认长度为7
- for (int i = 0; i < 7; i++) {
- body.add(new Point(x--, y));
- }
- }
- public void setSpeed(int speed) {
- this.speed = speed;
- }
- public void setLife(boolean life) {
- this.life = life;
- }
- public boolean getLife() {
- return this.life;
- }
- public boolean getPause() {
- return this.pause;
- }
- public void setPause(boolean pause) {
- this.pause = pause;
- }
- public void move() {
- //蛇移动的实现所采用的数据结构为:蛇尾删除一个节点,蛇头增加一个节点。
- System.out.println("snake move");
- if (! (oldDirection + newDirection == 0)) {
- oldDirection = newDirection;
- }
- lastTail = body.removeLast();
- int x = body.getFirst().x;
- int y = body.getFirst().y;
- switch (oldDirection) {
- case UP:
- y--;
- break;
- case DOWN:
- y++;
- break;
- case LEFT:
- x--;
- break;
- case RIGHT:
- x++;
- break;
- }
- Point point = new Point(x, y);
- body.addFirst(point);
- }
- //当吃到一个食物的时候,把删掉的蛇尾节点增加回来
- public void eatFood() {
- System.out.println("snake eat food");
- body.addLast(lastTail);
- }
- public boolean isEatItself() {
- for (int i = 2; i < body.size(); i++) {
- if (body.getFirst().equals(body.get(i))) {
- return true;
- }
- }
- return false;
- }
- public void drawMe(Graphics g) {
- System.out.println("draw snake");
- //循环打印蛇的各个身体节点
- for (Point p: body) {
- if (p.equals(body.getFirst())) {
- //当是蛇头的时候,就设置颜色为橘色
- g.setColor(Color.orange);
- } else {
- g.setColor(Color.pink);
- }
- g.fill3DRect(p.x * Constant.CELL_SIZE, p.y * Constant.CELL_SIZE, Constant.CELL_SIZE, Constant.CELL_SIZE, true);
- }
- }
- public void changeDirection(int direction) {
- System.out.println("snake changeDirection");
- this.newDirection = direction;
- }
- //内部类,新增一个游戏线程
- public class DriveSnake implements Runnable {@Override public void run() {
- while (life) {
- if (!pause) {
- //只要让蛇不动就可以暂停游戏
- move();
- }
- //监听蛇每次移动的情况
- for (SnakeListener listener: snakeListener) {
- listener.snakeMove(Snake.this);
- }
- try {
- Thread.sleep(speed);
- } catch(InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- public void startMove() {
- new Thread(new DriveSnake()).start();
- }
- //增加监听器的方法
- public void addSnakeListener(SnakeListener listener) {
- if (listener != null) {
- snakeListener.add(listener);
- }
- }
- //返回蛇的第一个身体节点
- public Point getHead() {
- return body.getFirst();
- }
- //返回蛇的所有身体节点
- public LinkedList < Point > getSnakeBody() {
- return this.body;
- }
- public boolean died() {
- this.life = false;
- return true;
- }
- }
- package com.huai;
- import java.awt.Color;
- import java.awt.Graphics;
- import java.awt.Point;
- import com.huai.util.Constant;
- public class Food {
- private int x = 0;
- private int y = 0;
- //设置食物的默认颜色为红色
- private Color color = Color.red;
- public void newFood(Point point) {
- x = point.x;
- y = point.y;
- }
- //判断是否被吃到
- public boolean isAte(Snake snake) {
- if (snake.getHead().equals(new Point(x, y))) {
- System.out.println("food isAte");
- return true;
- }
- return false;
- }
- public void setFoodColor(Color color) {
- this.color = color;
- }
- public Color getFoodColor() {
- return this.color;
- }
- public void drawMe(Graphics g) {
- System.out.println("draw food");
- g.setColor(this.getFoodColor());
- g.fill3DRect(x * Constant.CELL_SIZE, y * Constant.CELL_SIZE, Constant.CELL_SIZE, Constant.CELL_SIZE, true);
- }
- }
- package com.huai;
- import java.awt.Color;
- import java.awt.Graphics;
- import java.awt.Point;
- import java.util.LinkedList;
- import java.util.Random;
- import com.huai.util.Constant;
- public class Ground {
- //在二维数组中,当为1,表示是砖块
- private int[][] rock = new int[Constant.WIDTH][Constant.HEIGHT];
- private boolean drawLine = true;
- public boolean isDrawLine() {
- return drawLine;
- }
- public void setDrawLine(boolean drawLine) {
- this.drawLine = drawLine;
- }
- public Ground() {
- for (int x = 0; x < Constant.WIDTH; x++) {
- for (int y = 0; y < Constant.HEIGHT; y++) {
- rock[0][y] = 1;
- rock[x][0] = 1;
- rock[Constant.WIDTH - 1][y] = 1;
- rock[y][Constant.HEIGHT - 1] = 1;
- }
- }
- }
- //打印游戏的网格
- public void drawGrid(Graphics g) {
- for (int x = 2; x < Constant.WIDTH; x++) {
- g.drawLine(x * Constant.CELL_SIZE, 0, x * Constant.CELL_SIZE, Constant.CELL_SIZE * Constant.HEIGHT);
- }
- for (int y = 2; y < Constant.HEIGHT; y++) {
- g.drawLine(0, y * Constant.CELL_SIZE, Constant.WIDTH * Constant.CELL_SIZE, y * Constant.CELL_SIZE);
- }
- }
- public void drawMe(Graphics g) {
- System.out.println("draw ground");
- //打印围墙
- g.setColor(Color.pink);
- for (int x = 0; x < Constant.WIDTH; x++) {
- for (int y = 0; y < Constant.HEIGHT; y++) {
- if (rock[x][y] == 1) {
- g.fill3DRect(x * Constant.WIDTH, y * Constant.HEIGHT, Constant.CELL_SIZE, Constant.CELL_SIZE, true);
- }
- }
- }
- if (isDrawLine()) {
- g.setColor(Color.yellow);
- this.drawGrid(g);
- }
- }
- //得到一个随机点
- public Point getRandomPoint(Snake snake, Thorn thorn) {
- Random random = new Random();
- boolean isUnderSnakebody = false;
- boolean isUnderThorn = false;
- int x,
- y = 0;
- LinkedList < Point > snakeBody = snake.getSnakeBody();
- LinkedList < Point > thorns = thorn.getThorns();
- do {
- x = random.nextInt(Constant.WIDTH);
- y = random.nextInt(Constant.HEIGHT);
- for (Point p: snakeBody) {
- if (x == p.x && y == p.y) {
- isUnderSnakebody = true;
- }
- }
- for (Point point: thorns) {
- if (x == point.x && y == point.y) {
- isUnderThorn = true;
- }
- }
- } while ( rock [ x ][y] == 1 && !isUnderSnakebody && !isUnderThorn);
- return new Point(x, y);
- }
- public boolean isSnakeHitRock(Snake snake) {
- System.out.println("snack hit rock");
- for (int i = 0; i < Constant.WIDTH; i++) {
- for (int j = 0; j < Constant.HEIGHT; j++) {
- if (snake.getHead().x == i && snake.getHead().y == j && rock[i][j] == 1) {
- return true;
- }
- }
- }
- return false;
- }
- }
- package com.huai import java.awt.Color;
- import java.awt.Graphics;
- import java.awt.Point;
- import java.util.LinkedList;
- import com.huai.util.Constant;
- public class Thorn {
- int x,
- y;
- private LinkedList < Point > thorns = new LinkedList < Point > ();
- //返回所有荆棘的链表
- public LinkedList < Point > getThorns() {
- return this.thorns;
- }
- public void newThorn(Point point) {
- x = point.x;
- y = point.y;
- thorns.add(new Point(x, y));
- }
- public void drawMe(Graphics g) {
- System.out.println("draw thorns");
- for (Point p: thorns) {
- int[] xb = {
- p.x * Constant.CELL_SIZE,
- (p.x * Constant.CELL_SIZE + Constant.CELL_SIZE / 2),
- (p.x * Constant.CELL_SIZE + Constant.CELL_SIZE),
- (p.x * Constant.CELL_SIZE + Constant.CELL_SIZE / 4 * 3),
- (p.x * Constant.CELL_SIZE + Constant.CELL_SIZE),
- (p.x * Constant.CELL_SIZE + Constant.CELL_SIZE / 2),
- p.x * Constant.CELL_SIZE,
- (p.x * Constant.CELL_SIZE + Constant.CELL_SIZE / 4),
- p.x * Constant.CELL_SIZE
- };
- int[] yb = {
- p.y * Constant.CELL_SIZE,
- (p.y * Constant.CELL_SIZE + Constant.CELL_SIZE / 4),
- p.y * Constant.CELL_SIZE,
- (p.y * Constant.CELL_SIZE + Constant.CELL_SIZE / 2),
- (p.y * Constant.CELL_SIZE + Constant.CELL_SIZE),
- (int)(p.y * Constant.CELL_SIZE + Constant.CELL_SIZE * 0.75),
- (p.y * Constant.CELL_SIZE + Constant.CELL_SIZE),
- (p.y * Constant.CELL_SIZE + Constant.CELL_SIZE / 2),
- p.y * Constant.CELL_SIZE
- };
- g.setColor(Color.darkGray);
- g.fillPolygon(xb, yb, 8);
- }
- }
- public boolean isSnakeHitThorn(Snake snake) {
- for (Point points: thorns) {
- if (snake.getHead().equals(points)) {
- System.out.println("hit thorn");
- return true;
- }
- }
- return false;
- }
- }
- package com.huai.listener;
- import com.huai.Snake;
- public interface SnakeListener {
- public void snakeMove(Snake snake);
- }
- package com.huai.util;
- public class Constant {
- public static int CELL_SIZE = 20;
- public static int WIDTH = 20;
- public static int HEIGHT = 20;
- }
- package com.huai.view;
- import java.awt.Color;
- import java.awt.Graphics;
- import javax.swing.JPanel;
- import com.huai.Food;
- import com.huai.Ground;
- import com.huai.Snake;
- import com.huai.Thorn;
- import com.huai.util.Constant;
- public class GamePanel extends JPanel {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- Snake snake;
- Food food;
- Ground ground;
- Thorn thorn;
- public void display(Snake snake, Food food, Ground ground, Thorn thorn) {
- this.snake = snake;
- this.food = food;
- this.ground = ground;
- this.thorn = thorn;
- System.out.println("display gamePanel");
- this.repaint();
- }
- @Override protected void paintComponent(Graphics g) {
- if (snake != null && food != null && ground != null) {
- g.setColor(Color.lightGray);
- g.fillRect(0, 0, Constant.WIDTH * Constant.CELL_SIZE, Constant.HEIGHT * Constant.CELL_SIZE);
- snake.drawMe(g);
- food.drawMe(g);
- ground.drawMe(g);
- thorn.drawMe(g);
- } else {
- System.out.println("snake = null || food = null || ground = null");
- }
- }
- }
- package com.huai.controller;
- import java.awt.event.KeyAdapter;
- import java.awt.event.KeyEvent;
- import com.huai.Food;
- import com.huai.Ground;
- import com.huai.Snake;
- import com.huai.Thorn;
- import com.huai.listener.SnakeListener;
- import com.huai.view.GamePanel;
- public class Controller extends KeyAdapter implements SnakeListener {
- /**
- * 整个游戏的控制类,属于MVC设计框架中的Controller
- * 其中包括控制游戏的监听事件和游戏逻辑
- */
- Snake snake;
- Food food;
- Ground ground;
- GamePanel gamePanel;
- Thorn thorn;
- public Controller() {}
- //利用构造方法初始化对象
- public Controller(Snake snake, Food food, Ground ground, GamePanel gamePanel, Thorn thorn) {
- super();
- this.snake = snake;
- this.food = food;
- this.ground = ground;
- this.gamePanel = gamePanel;
- this.thorn = thorn;
- }@Override public void keyPressed(KeyEvent e) {
- switch (e.getKeyCode()) {
- case KeyEvent.VK_UP:
- snake.changeDirection(Snake.UP);
- snake.setSpeed(150);
- break;
- case KeyEvent.VK_DOWN:
- snake.changeDirection(Snake.DOWN);
- snake.setSpeed(150);
- break;
- case KeyEvent.VK_LEFT:
- snake.changeDirection(Snake.LEFT);
- snake.setSpeed(150);
- break;
- case KeyEvent.VK_RIGHT:
- snake.changeDirection(Snake.RIGHT);
- snake.setSpeed(150);
- break;
- case KeyEvent.VK_ENTER:
- if (!snake.getPause() && snake.getLife()) {
- //暂停游戏
- snake.setPause(true);;
- } else if (!snake.getLife()) {
- //重新开始游戏
- snake.setLife(true);
- snake.initial();
- snake.changeDirection(Snake.UP);
- thorn.getThorns().removeAll(thorn.getThorns());
- this.startGame();
- } else {
- snake.setPause(false);
- }
- break;
- case KeyEvent.VK_L:
- //当按下L按钮时,是否显示游戏网格
- if (ground.isDrawLine()) {
- ground.setDrawLine(false);
- } else {
- ground.setDrawLine(true);
- }
- break;
- }
- }
- @Override public void keyReleased(KeyEvent e) {
- switch (e.getKeyCode()) {
- case KeyEvent.VK_UP:
- snake.setSpeed(400);
- break;
- case KeyEvent.VK_DOWN:
- snake.setSpeed(400);
- break;
- case KeyEvent.VK_LEFT:
- snake.setSpeed(400);
- break;
- case KeyEvent.VK_RIGHT:
- snake.setSpeed(400);
- break;
- }
- }
- //这是实现SnakeListener监听器所Override的方法
- @Override public void snakeMove(Snake snake) {
- //显示snake ,food,ground,和thorn
- gamePanel.display(snake, food, ground, thorn);
- if (ground.isSnakeHitRock(snake)) {
- snake.died();
- }
- if (snake.isEatItself()) {
- snake.died();
- }
- if (food.isAte(snake)) {
- snake.eatFood();
- food.newFood(ground.getRandomPoint(snake, thorn));
- thorn.newThorn(ground.getRandomPoint(snake, thorn));
- }
- if (thorn.isSnakeHitThorn(snake)) {
- snake.died();
- }
- }
- public void startGame() {
- snake.startMove(); //这个将会启动一个新的线程
- food.newFood(ground.getRandomPoint(snake, thorn));
- thorn.newThorn(ground.getRandomPoint(snake, thorn));
- }
- }
- package com.huai.game;
- import java.awt.BorderLayout;
- import java.awt.Color;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- import com.huai.Food;
- import com.huai.Ground;
- import com.huai.Snake;
- import com.huai.Thorn;
- import com.huai.controller.Controller;
- import com.huai.util.Constant;
- import com.huai.view.GamePanel;
- public class Game {
- public static void main(String args[]) {
- Snake snake = new Snake();
- Food food = new Food();
- GamePanel gamePanel = new GamePanel();
- Ground ground = new Ground();
- Thorn thorn = new Thorn();
- Controller controller = new Controller(snake, food, ground, gamePanel, thorn);
- JFrame frame = new JFrame("怀哥的小小蛇儿游戏");
- frame.add(gamePanel);
- frame.setBackground(Color.magenta);
- frame.setSize(Constant.WIDTH * Constant.CELL_SIZE + 6, Constant.HEIGHT * Constant.CELL_SIZE + 40);
- gamePanel.setSize(Constant.WIDTH * Constant.CELL_SIZE, Constant.HEIGHT * Constant.CELL_SIZE);
- frame.add(gamePanel);
- frame.setResizable(false); //不可改变窗口大小
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.setVisible(true);
- gamePanel.addKeyListener(controller);
- snake.addSnakeListener(controller);
- frame.addKeyListener(controller);
- JLabel label1 = new JLabel();
- label1.setBounds(0, 400, 400, 100);
- label1.setText(" ENTER=>>PAUSE or AGAIN; " + " L=>DRAWGRID");
- label1.setForeground(Color.BLACK);
- frame.add(label1, BorderLayout.SOUTH);
- controller.startGame();
- }
- }
来源: http://www.phperz.com/article/17/0904/338383.html