⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snake.java

📁 希望大家多多交流
💻 JAVA
字号:
package snake;

import java.util.*;

import system.*;
import food.*;

//贪吃蛇类
public class Snake
    extends ArrayList
    implements Runnable {
  private MainFrame mainFrame;
  private int direction = Direction.NONE; //蛇下一步的移动方向
  private int preDirection = Direction.NONE; //蛇上次实际移动的方向
  private int speed = Speed.SPEED_ONE; //贪吃蛇的移动速度
  private MoveThread moveThread; //控制贪吃蛇移动的线程
  private boolean isAllowToMove = false; //用来控制贪吃蛇的移动与暂停
  private int x;
  private int y; //贪吃蛇的初始位置

  public static final int STEP = 20; //蛇移动一步的长度
  public static final int LENGTH = 3; //蛇身的初始长度

  public Snake(MainFrame frame, int direction) {
    //初始化蛇身为3格的长度
    for (int i = 0; i < LENGTH; i++) {
      this.add(new Block());
    }

    this.mainFrame = frame;
    this.direction = direction;
  }

  //设置蛇身的位置
  public void setLocation(int x, int y){
    this.x = x;
    this.y = y;
    //贪吃蛇的初始化位置为垂直方向,头在上
    for (int i = 0; i < this.size(); i++) {
      Block b = (Block)this.get(i);
      b.setLocation(x, y);
      y += Block.WIDTH;
    }
    //初始化蛇头图片
    Block head = this.getHead();
    head.changeImage(Direction.UP);
    //更新蛇的位置
    this.mainFrame.getMainPanel().repaint();
  }

  //蛇身的长度增长L个单位
  public void grow(int l) {
    //添加到蛇身
    for (int i = 0; i < l; i++) {
      this.add(new Block());
    }
  }

  //蛇身的长度增长1个单位
  public void growOne() {
    this.grow(1);
  }

  //蛇身缩短L个单位
  public void shorten(int l) {
    if (this.size() == 1) {
      System.out.println("Snake.java--蛇已只剩下蛇头,不能再缩短!");
      return;
    }
    //缩短蛇身
    for (int i = 0; i < l; i++) {
      if (this.size() == 1) {
        break; //当只剩下蛇头时,跳出循环
      }
      int j = this.size() - 1; //从蛇尾开始减
      this.remove(j);
    }
  }

  //把贪吃蛇缩短到size的大小
  public void shortenTo(int size){
    if(this.size() <= size){
      return;
    }

    do{
      this.remove(this.size() - 1);//从尾部开始减
    }
    while(this.size() > size);
  }

  //重新初始化贪吃蛇的长度
  public void resize(){
    this.shortenTo(Snake.LENGTH);
  }

  //改变蛇的运动方向
  public void changeDirection(int i) {
    //当i和贪吃蛇的上一步移动方向不是一对相反的方向时
    if (this.preDirection + i != Direction.OPPOSITE) {
      this.direction = i;
    }
    else {
      System.out.println("Snake.java------贪吃蛇不能一次转180度的弯!");
    }
  }

  //设置蛇的前一移动方向,用于游戏的开始时防止蛇向后方移动的错误
  public void setPreDirection(int i){
    this.preDirection = i;
  }

  //返回贪吃蛇的移动速度
  public int getSpeed(){
    return this.speed;
  }

  //设置速度
  public void setSpeed(int speed){
    this.speed = speed;
  }

  //提升速度一个等级
  public void speedUp(){
    if(this.speed < Speed.MAX_SPEED){//小于最高速度
      int level = this.mainFrame.getLevel();
      //根据难度等级设置移动速度
      if(level == Speed.LEVER_ONE){
        this.speed = Speed.SPEED_ONE;
      }
      else if(level == Speed.LEVER_TWO){
        this.speed = Speed.SPEED_TWO;
      }
      else if(level == Speed.LEVER_THREE){
        this.speed = Speed.SPEED_THREE;
      }
      else if(level == Speed.LEVER_FOUR){
        this.speed = Speed.SPEED_FOUR;
      }
      else if(level == Speed.LEVER_FIVE){
        this.speed = Speed.SPEED_FIVE;
      }
    }
  }

  //蛇移动一步
  public void moveOneStep() {
    if (this.direction == Direction.NONE) { //不移动
      return;
    }

    for (int i = this.size() - 1; i > 0; i--) {
      Block b = (Block)this.get(i);
      Block preb = (Block)this.get(i - 1); //前一个块
      //将前一个块的位置赋给当前块
      b.setLocation(preb.getX(), preb.getY());
    }

    Block head = this.getHead(); //取得蛇头
    if (this.direction == Direction.UP) { //蛇头向上移动一步
      head.setLocation(head.getX(), head.getY() - Snake.STEP);
      head.changeImage(Direction.UP);//改变蛇头的显示图片
    }
    else if (this.direction == Direction.DOWN) { //蛇头向下移动一步
      head.setLocation(head.getX(), head.getY() + Snake.STEP);
      head.changeImage(Direction.DOWN);//改变蛇头的显示图片
    }
    else if (this.direction == Direction.LEFT) { //蛇头向左移动一步
      head.setLocation(head.getX() - Snake.STEP, head.getY());
      head.changeImage(Direction.LEFT);//改变蛇头的显示图片
    }
    else if (this.direction == Direction.RIGHT) { //蛇头向右移动一步
      head.setLocation(head.getX() + Snake.STEP, head.getY());
      head.changeImage(Direction.RIGHT);//改变蛇头的显示图片
    }
    this.preDirection = this.direction; //保存移动方向
    //重绘贪吃蛇
    this.mainFrame.getMainPanel().repaint();
  }

  //开始移动
  public void startToMove() {
    if (this.moveThread != null && this.moveThread.isAlive()) {
      //安全停止线程的运行
      this.moveThread.setDead(true);
      this.moveThread = null;
    }
    this.moveThread = new MoveThread(this);
    this.isAllowToMove = true; //设置贪吃蛇为允许移动
    this.moveThread.start();
  }

  //继续移动贪吃蛇
  public void moveOn() {
    if (this.moveThread != null && this.moveThread.isAlive()
        && (!this.isAllowToMove)) {
      this.isAllowToMove = true;
    }
  }

  //停止移动
  public void stop() {
    if (this.moveThread != null && this.moveThread.isAlive()
        && this.isAllowToMove) {
      this.isAllowToMove = false; //设置贪吃蛇为不允许移动
    }
  }

  //获得蛇头
  public Block getHead() {
    return (Block)this.get(0);
  }

  //判断贪吃蛇是否能够吃到食物
  public boolean canEatFood(){
    Block head = this.getHead();
    Food food = this.mainFrame.getFood();

    if(head.getX() == food.getX() && head.getY() == food.getY()){
      return true;
    }

    return false;
  }

  //贪吃蛇吃掉一个食物
  public void eatFood(){
    this.mainFrame.getFood().changeLocation();//更新食物的位置
    this.growOne();//蛇身增长一
  }

  //判断贪吃蛇是否撞死
  public boolean isDead() {
    Block head = this.getHead();

    //撞到边缘
    int width = this.mainFrame.getMainPanel().getWidth();
    int height = this.mainFrame.getMainPanel().getHeight();
    if (head.getX() < 0 || head.getX() > width - Block.WIDTH
        || head.getY() < 0 || head.getY() > height - Block.HEIGHT) {
      return true;
    }

    //撞到自身
    for (int i = 1; i < this.size(); i++) {
      Block b = (Block)this.get(i);
      if (head.isAtSamePlace(b)) {
        return true;
      }
    }

    return false;
  }

  //===================实现Runnable接口=====================================
  public void run() {
    while (true) {
      Thread t = Thread.currentThread();
      if (t instanceof MoveThread) {
        MoveThread m = (MoveThread) t;
        if (m.isDead()) {
          return; //如果当前线程已经被设置为死亡,则跳出循环,停止线程的运行
        }
      }
      else {
        return;
      }

      try {
        Thread.sleep(this.speed); //贪吃蛇暂停一段时间
      }
      catch (InterruptedException e) {
        e.printStackTrace();
      }

      t = Thread.currentThread();
      if (t instanceof MoveThread) {
        MoveThread m = (MoveThread) t;
        if (m.isDead()) {
          return; //如果当前线程已经被设置为死亡,则跳出循环,停止线程的运行
        }
      }
      else {
        return;
      }

      if (this.isAllowToMove == false) {
        continue; //如果贪吃蛇处于不允许移动状态,不执行任何动作,但继续保持循环
      }

      this.moveOneStep(); //移动一步

      if (this.isDead()) {
        this.mainFrame.setGameOver(true); //贪吃蛇死亡
        this.mainFrame.addToHeroInfos();//冲击排行榜
        this.isAllowToMove = false;
      }

      if(this.canEatFood()){
        this.eatFood();//贪吃蛇吃掉一个食物
        int score = this.mainFrame.getLevel() * 5;//计算得分
        this.mainFrame.addScore(score);//增加得分

        if(this.mainFrame.shouldLevelUp()){//是否应该升级?
          this.mainFrame.levelUp();//提升一级
        }
      }

      System.out.println("Snake.java---snake is moving....................");
    }
  }
} //:~zj

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -