蛇游戏。吃烂苹果时如何使蛇掉尾巴?

时间:2019-09-02 19:28:10

标签: java linked-list

我已经在游戏中添加了苹果,并添加了一项功能,该功能可使苹果在经过某些步骤后变烂。但是我希望那条蛇在吃烂苹果时掉一条尾巴。

我已经有了一种方法,每次吃蛇时都会增加一条尾巴。我只需要一些帮助。我已经尝试过使用pollLast()和removeLast(),但无法弄清楚。

*package Game.Entities.Dynamic;
import Main.Handler;
import Resources.Images;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Random;
import javax.swing.JOptionPane;
import Display.DisplayScreen;
import Game.GameStates.State;
/**
 * Created by AlexVR on 7/2/2018.
 */
public class Player {
    public int lenght;
    public boolean justAte;
    private Handler handler;
    public int xCoord;
    public int yCoord;
    public int score;
    public int steps;
    public int moveCounter;
    public String direction;
    private String highscore;
    private Color playerColor;
    private Color appleColor;
    private Color rottenAppleColor;
    private int speedAdjust;
    private Tail tail;
    private String eatSoundEffect;
    private String deathSoundEffect;
    private boolean soundLoop;

    public Player(Handler handler){
        this.handler = handler;
        xCoord = 0;
        yCoord = 0;
        score = 0;
        steps = 0;
        highscore = this.getHighScore();
        moveCounter = 0;
        direction= "Right";
        justAte = false;
        lenght= 1;
        playerColor = Color.green;
        appleColor = Color.red;
        rottenAppleColor = Color.black;
        speedAdjust = 20;
        eatSoundEffect = "res/music/bite.wav";
        deathSoundEffect = "res/music/sound-frogger-dead.wav";
        soundLoop = true;

    }
    public void tick(){
        moveCounter += 2;
        if(moveCounter>=speedAdjust) {
            checkCollisionAndMove();
            checkSteps();
            moveCounter=0;
        }
        if(handler.getKeyManager().keyJustPressed(KeyEvent.VK_UP) || handler.getKeyManager().keyJustPressed(KeyEvent.VK_W)){
            direction="Up";
        }
        if(handler.getKeyManager().keyJustPressed(KeyEvent.VK_DOWN) || handler.getKeyManager().keyJustPressed(KeyEvent.VK_S)){
            direction="Down";
        }
        if(handler.getKeyManager().keyJustPressed(KeyEvent.VK_LEFT) || handler.getKeyManager().keyJustPressed(KeyEvent.VK_A)){
            direction="Left";
        }
        if(handler.getKeyManager().keyJustPressed(KeyEvent.VK_RIGHT) || handler.getKeyManager().keyJustPressed(KeyEvent.VK_D)){
            direction="Right";
        }
        if(handler.getKeyManager().keyJustPressed(KeyEvent.VK_EQUALS)){
            speedAdjust-=2;
        }
        if(handler.getKeyManager().keyJustPressed(KeyEvent.VK_MINUS)){
            speedAdjust+=2;
        }
        if(handler.getKeyManager().keyJustPressed(KeyEvent.VK_N)) {
            this.setJustAte(false);
            EatAndAddTail(); 
        }   
    }
    public void checkCollisionAndMove(){
        handler.getWorld().playerLocation[xCoord][yCoord]=false;
        int x = xCoord;
        int y = yCoord;
        steps++;
        switch (direction){
            case "Left":
                if(xCoord==0){
                    xCoord = handler.getWorld().GridWidthHeightPixelCount-1;
                }else{
                    xCoord--;
                }
                break;
            case "Right":
                if(xCoord==handler.getWorld().GridWidthHeightPixelCount-1){
                    xCoord = 0;
                }else{
                    xCoord++;
                }
                break;
            case "Up":
                if(yCoord==0){
                    yCoord = handler.getWorld().GridWidthHeightPixelCount-1;
                }else{
                    yCoord--;
                }
                break;
            case "Down":
                if(yCoord==handler.getWorld().GridWidthHeightPixelCount-1){
                    yCoord = 0;
                }else{
                    yCoord++;
                }
                break;
        }

        handler.getWorld().playerLocation[xCoord][yCoord]=true;

        if (handler.getWorld().body.size() > 0) {
            for (int i = 0; i < handler.getWorld().body.size(); i++){
                //Kill player when collides with itself
                if(xCoord == handler.getWorld().body.get(i).x && yCoord == handler.getWorld().body.get(i).y) {
                    kill();
                } 
            }
        }

        if(handler.getWorld().appleLocation[xCoord][yCoord]){
            this.setJustAte(true);
            EatAndAddTail();
        }

        //Displays the score on the bottom as soon as the game starts and gets updated whenever the snake eats a dot
        if((xCoord > 0 || yCoord > 0) || justAte==true){
            DisplayScreen.setMessage(String.format("Current Score: %d; %s", score, highscore)); 
        }
        if(!handler.getWorld().body.isEmpty()) {
            handler.getWorld().playerLocation[handler.getWorld().body.getLast().x][handler.getWorld().body.getLast().y] = false;
            handler.getWorld().body.removeLast();
            handler.getWorld().body.addFirst(new Tail(x, y,handler));
        }

        System.out.println(steps);
    }

    //If the snake has made 60 or more steps then the apple becomes rotten.
    public void checkSteps() {
        if (steps >= 80) {
            handler.getWorld().apple.setIsGood(false);
        }
    }
    public void render(Graphics g,Boolean[][] playeLocation){
        //Changes color of the snake
        for (int i = 0; i < handler.getWorld().GridWidthHeightPixelCount; i++) {
            for (int j = 0; j < handler.getWorld().GridWidthHeightPixelCount; j++) {
                g.setColor(playerColor);
                if(playeLocation[i][j]||handler.getWorld().appleLocation[i][j]){
                    g.fillRect((i*handler.getWorld().GridPixelsize),
                            (j*handler.getWorld().GridPixelsize),
                            handler.getWorld().GridPixelsize,
                            handler.getWorld().GridPixelsize);
                }
            }
        }

        //Changes the color of the apple
        for (int i = 0; i < handler.getWorld().GridWidthHeightPixelCount; i++) {
            for (int j = 0; j < handler.getWorld().GridWidthHeightPixelCount; j++) {
                if (handler.getWorld().apple.isGood) {
                g.setColor(appleColor);
                }
                else {
                    g.setColor(rottenAppleColor);
                }
                if(handler.getWorld().appleLocation[i][j]){
                        g.fillRect((i*handler.getWorld().GridPixelsize),
                                (j*handler.getWorld().GridPixelsize),
                                handler.getWorld().GridPixelsize,
                                handler.getWorld().GridPixelsize);

                }
            }
        }
    }
    public void EatAndAddTail(){
        lenght++;
        //Kills the snake if it eats a rotten apple and has no tail.
        if(justAte == true && handler.getWorld().apple.isGood == false && score == 0){
             kill(); 
        }
        else if (justAte == true) {
            this.setSteps(0);
            if (handler.getWorld().apple.isGood) {
                //Score formula when eating a good apple.
                score += Math.sqrt(2*score + 1);
                //Increases the speed of the snake everytime it eats a dot.
                speedAdjust -= 5;
            }
            else if (handler.getWorld().apple.isGood == false) {
                //Score formula when eating a rotten apple.
                score -= Math.sqrt(2*score + 1);
            }
            handler.getGame().playAudio(eatSoundEffect, false);
            handler.getWorld().appleLocation[xCoord][yCoord]=false;
            handler.getWorld().appleOnBoard=false;
            switch (direction){
            case "Left":
                if(handler.getWorld().body.isEmpty()){
                    if(this.xCoord!=handler.getWorld().GridWidthHeightPixelCount-1){
                        tail = new Tail(this.xCoord+1,this.yCoord,handler);
                    }
                    else {
                        if(this.yCoord!=0){
                            tail = new Tail(this.xCoord,this.yCoord-1,handler);
                        }
                        else{
                            tail =new Tail(this.xCoord,this.yCoord+1,handler);
                        }
                    }
                }
                else{
                    if(handler.getWorld().body.getLast().x!=handler.getWorld().GridWidthHeightPixelCount-1){
                        tail=new Tail(handler.getWorld().body.getLast().x+1,this.yCoord,handler);
                    }
                    else {
                        if(handler.getWorld().body.getLast().y!=0){
                            tail=new Tail(handler.getWorld().body.getLast().x,this.yCoord-1,handler);
                        }
                        else {
                            tail=new Tail(handler.getWorld().body.getLast().x,this.yCoord+1,handler);
                        }
                    }
                }
                break;

            case "Right":
                if(handler.getWorld().body.isEmpty()){
                    if(this.xCoord!=0){
                        tail=new Tail(this.xCoord-1,this.yCoord,handler);
                    }
                    else {
                        if(this.yCoord!=0){
                            tail=new Tail(this.xCoord,this.yCoord-1,handler);
                        }
                        else {
                            tail=new Tail(this.xCoord,this.yCoord+1,handler);
                        }
                    }
                }
                else {
                    if(handler.getWorld().body.getLast().x!=0){
                        tail=(new Tail(handler.getWorld().body.getLast().x-1,this.yCoord,handler));
                    }
                    else {
                        if(handler.getWorld().body.getLast().y!=0){
                            tail=(new Tail(handler.getWorld().body.getLast().x,this.yCoord-1,handler));
                        }
                        else
                        {
                            tail=(new Tail(handler.getWorld().body.getLast().x,this.yCoord+1,handler));
                        }
                    }
                }
                break;

            case "Up":
                if(handler.getWorld().body.isEmpty()){
                    if(this.yCoord!=handler.getWorld().GridWidthHeightPixelCount-1){
                        tail=(new Tail(this.xCoord,this.yCoord+1,handler));
                    }
                    else {
                        if(this.xCoord!=0){
                            tail=(new Tail(this.xCoord-1,this.yCoord,handler));
                        }
                        else
                        {
                            tail=(new Tail(this.xCoord+1,this.yCoord,handler));
                        }
                    }
                } 
                else {
                    if (handler.getWorld().body.getLast().y!=handler.getWorld().GridWidthHeightPixelCount-1){
                        tail=(new Tail(handler.getWorld().body.getLast().x,this.yCoord+1,handler));
                    } 
                    else {
                        if(handler.getWorld().body.getLast().x!=0){
                            tail=(new Tail(handler.getWorld().body.getLast().x-1,this.yCoord,handler));
                        }
                        else{
                            tail=(new Tail(handler.getWorld().body.getLast().x+1,this.yCoord,handler));
                        }
                    }
                }
                break;

            case "Down":
                if(handler.getWorld().body.isEmpty()){
                    if(this.yCoord!=0){
                        tail=(new Tail(this.xCoord,this.yCoord-1,handler));
                    }
                    else{
                        if(this.xCoord!=0){
                            tail=(new Tail(this.xCoord-1,this.yCoord,handler));
                        }
                        else{
                            tail=(new Tail(this.xCoord+1,this.yCoord,handler));
                        }
                    }
                }
                else {
                    if(handler.getWorld().body.getLast().y!=0){
                        tail=(new Tail(handler.getWorld().body.getLast().x,this.yCoord-1,handler));
                    }
                    else{
                        if(handler.getWorld().body.getLast().x!=0){
                            tail=(new Tail(handler.getWorld().body.getLast().x-1,this.yCoord,handler));
                        }
                        else{
                            tail=(new Tail(handler.getWorld().body.getLast().x+1,this.yCoord,handler));
                        }
                    }
                }
                break;
            }

            handler.getWorld().body.addLast(tail);
            handler.getWorld().playerLocation[tail.x][tail.y] = true;
        }
        else{
            handler.getWorld().body.addLast(new Tail(xCoord, yCoord, handler));
        }
    }
    public void kill(){
        lenght = 0;
        handler.getGame().stopMainAudio();
        handler.getGame().playAudio(deathSoundEffect, false);

        for (int i = 0; i < handler.getWorld().GridWidthHeightPixelCount; i++) {
            for (int j = 0; j < handler.getWorld().GridWidthHeightPixelCount; j++) {
                handler.getWorld().playerLocation[i][j]=false;
                State.setState(handler.getGame().gameOverState); 
            }
        }
    }
    public boolean isJustAte() {
        return justAte;
    }
    public void setJustAte(boolean justAte) {
        this.justAte = justAte;
    }
}*

1 个答案:

答案 0 :(得分:0)

因此,如果我不误解您的代码,那么好像您每次蛇吃一个苹果时都在创建一条新的尾巴。

EatAndAddTail()方法的顶部,您正在做lenght++,也许您不应该在顶部,因为它实际上是在添加另一个细分,这与您想要的相反去做。也许有一种方法,您可以在吃完苹果后检查长度是否等于段的数量,并相应地调整大小。跟踪大小也可以轻松完成。像这样的东西

if (justAte == true && handler.getWorld().apple.isGood == false){
lenght--;
check(lenght);
size--;
}

else if (justAte == true){
lenght++;
check(lenght);
size++;
}

private void check (int l){
    if (lenght != size){
         if (lenght > size)
         {
             removeTail();
         }
         else
         {  
             addTail();
         }
     }
}

希望这是有道理的。尽管您可能必须添加removeTail()和addTail()方法。