📄 snake.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 + -