我是一名文凭学生,是基于处理程序制作游戏的,这是一种塔防游戏,女主人公将朝着向城堡冲刺的僵尸射击箭。我对此有多个问题。


充电器僵尸被枪杀后不会重生。
当我仅拍摄一个充电器僵尸时,所有充电器僵尸都会死在一起。


假设我希望丧尸在击落一组敌人后反复产生波浪,然后我希望充电器丧尸单独死亡,具体取决于我单击的那个。

这是我的源代码:

import processing.opengl.*; // transparency
import gifAnimation.*; // after add gifAnimation library
import ddf.minim.*; // importing music

PImage backgroundImg;
PImage animation;

int counter;

//settings
int score = 50, totalScore = 0;
int titleX = 200, titleY = 200;
boolean shotsFired = false;
PFont scorePoints, castleHealthPoints, font; //font for startingScreen
int chargerKilled;

//Charger class
int maxChargerOnScreen;
Charger[] chargerArr;   //chargerArray undefined
int chargerIndex;
final int numCharger = 300;
ArrayList<Charger> onScreen = new ArrayList<Charger>();

boolean chargerReachedTarget = false, chargerShot = false, chargerDive = true;
Gif chargerCharge, chargerAttack, chargerDied, shootingStance;
int chargerMoveX = 800, chargerMoveY = 450;


// CastleWallHealth
int castleHealth = 1000;

// audio
Minim minim;
AudioPlayer song;
AudioSnippet arrowShoot;

//-------------------------------Codes start here --------------------------------------------------//
void setup() {
    //ipad mini size
    //  frameRate(10);
    frameRate(60);
    size(800, 600);
    smooth();

    minim = new Minim(this);
    // song = minim.loadFile("InGameSoundtrack.mp3");
    // song.play();
    arrowShoot = minim.loadSnippet("arrowSound1.wav");

    backgroundImg = loadImage("GameBackground.jpg");
    backgroundImg.resize(800, 600);
    chargerCharge = new Gif(this, "ChargerCharge.gif");
    chargerAttack = new Gif(this, "ChargerAttack.gif");
    chargerDied   = new Gif(this, "ChargerDie.gif");
    gargoyleFly   = new Gif(this, "GargoyleFly.gif");
    gargoyleAttack = new Gif(this, "GargoyleAttack.gif");
    shootingStance = new Gif(this, "ShootingGif.gif");

    scorePoints =  createFont("Arial", 16, true);
    castleHealthPoints = createFont("Arial", 16, true);
    // loopingGif.play() plays the animation without loop
    // must make charger
    chargerCharge.play();
    chargerAttack.play();
    chargerDied.play();

    resetGames();  // starts with respawning 5 charges
}

void draw() {
    // backgroud
    background(backgroundImg);
    image(shootingStance, 120,200);

    // scores and health
    textFont(scorePoints, 15);
    fill(0);
    text("Score: " + totalScore, 100, 100);
    displayCastleHealth();

  //*********************************************charger settings code********************************************************************
    // If there's no more zombies. prompt reset (screen no zombies) , index from 0 add till 300 then game won
    if (onScreen.size() == 0 && chargerIndex == numCharger) {
        println("Game won! :)");
        // gameWon = true;
    }

    // while onScreen charger less than 5 only and chargerIndex havent reach 300 it will only respawn
    while (onScreen.size () < maxChargerOnScreen && chargerIndex <= numCharger - 1) {

        if (chargerIndex < chargerArr.length) { // <--- this is the problem chargerArrayLength
            Charger chargerMobs = chargerArr[chargerIndex];
            // starts from chargerArray[0] to chargerArray[300]
            onScreen.add(chargerMobs);
            chargerIndex++;
            // chargerIndex keeps looping why?
            // println("ADDED ZOMBIE TO ONSCREEN Zombs on screen: " + onScreen.size());
        }
    }

    // Adjusts maxZombOnScreen based off the current index   Difficulties?
    if (chargerIndex == 10)
        maxChargerOnScreen++;
    else if (chargerIndex == 50)
        maxChargerOnScreen++;
    else if (chargerIndex == 100)
        maxChargerOnScreen += 2;
    else if (chargerIndex == 150)
        maxChargerOnScreen += 2;
    else if (chargerIndex == 190)
        maxChargerOnScreen += 3;
    else if (chargerIndex == 250)
        maxChargerOnScreen += 3;
    else if (chargerIndex == 260)
        maxChargerOnScreen += 3;
    else if (chargerIndex == 270)
        maxChargerOnScreen += 5;

    // removes dead zombies, living zombies act normally
    for(int i = 0; i < onScreen.size(); i++) {
        Charger c = onScreen.get(i);

        // add money when a zombie is dead
        // if (c.getHealth() <= 0)
        if (chargerShot==true) {
            c.chargerDying();
            onScreen.remove(i);
            chargerKilled++;
            i--;
        } else {
            c.act(); ///it should just act
        //  c.displayHealth(); // if gt time only do
    //  }
        }
    }

    // creating list of predetermined zombies and their characteristics
    println("chargerIndex: " + chargerIndex); // debug
    println("onScreenSize: " + onScreen.size());
//  println("ChargerArray: " + chargerArray.length); chargerArray point null?

    // cursor
    if (mouseY > height - 500) {
        noFill();
        stroke(255, 0, 0);
        ellipse(mouseX, mouseY, 35, 35);
        line(mouseX - 25, mouseY, mouseX + 25, mouseY);
        line(mouseX, mouseY - 25, mouseX, mouseY + 25);
    }

}

void resetGames() {
    // resetting variables
    chargerIndex = 0;
    maxChargerOnScreen = 5;
    chargerKilled = 0;
    createNewCharger();
}

void createNewCharger() {

    Charger[] temp = new Charger[numCharger];
    for (int i = 0; i < numCharger; i++)
        temp[i] = new Charger((int) random(800, 1200), chargerMoveY);

    chargerArr = temp;
}

//____________________________________________________________________________________________________________-
class Charger {

    private int chargerMoveX, chargerMoveY;
    Gif chargerGif; // by default
    // chargerGif will change based on input (either it reaches the castle or its shot)

    // no constructor
    Charger() {
        chargerMoveX = 0;
        chargerMoveY = 450;
    }

    // overloaded constructor
    Charger(int cMoveX,int cMoveY) {
        chargerMoveX = cMoveX;
        chargerMoveY = cMoveY;
    }

    void act() { // use

        // if reached castle it wont move
        if (chargerMoveX <= 180) {
            // remove gif images
            chargerDive = false;
            chargerReachedTarget = true;
        }

        // if not shot or reached castle it will move
        if (chargerDive == true) {
            chargerGif = chargerCharge;
            image(chargerGif, chargerMoveX, chargerMoveY);
            chargerMoveX -= 2;
        }

        // if reached castle perform attack animation
        if (chargerReachedTarget == true) {
            chargerGif = chargerAttack;
            image(chargerGif, chargerMoveX - 80, chargerMoveY - 120);
        }

        if (mousePressed &&
            mouseX < chargerMoveX + 180
            && mouseX > chargerMoveX
            && mouseY < chargerMoveY + 120
            && mouseY > chargerMoveY) {

            // score board
            totalScore = totalScore + score ;
            float r = random(50);
            println(r);
            chargerShot = true;
            chargerDive = false;
        }

    }

    void chargerDying() {
        chargerReachedTarget = false;
        chargerGif = chargerDied;
        image(chargerGif, chargerMoveX, chargerMoveY);
    }
}

void displayCastleHealth() {
    if (castleHealth <= 0) {
      fill(250, 70, 0);
      textFont(castleHealthPoints, 20);
      text("HP: 0", 100, 50);
    } else {
      fill(250, 70, 0);
      textFont(castleHealthPoints, 20);
      text("HP: " + castleHealth, 100, 50);
    }
}

void mousePressed() {
    strokeWeight(2);
    arrowShoot.rewind();
    arrowShoot.play();

    for (int i = 0 ; i < 3; i++)
        shootingStance.play();

    shotsFired = true;
}

void mouseReleased() {
    strokeWeight(1);

    if (shotsFired == true)
        shootingStance.pause();
}

public void stop() {
    arrowShoot.close();
}


充电器的大部分问题都来自这里:

if (onScreen.size() == 0 && chargerIndex == numCharger) {
    println("Game won! :)");
    // gameWon = true;
}

// while onScreen charger less than 5 only and chargerIndex havent reach 300 it will only respawn
while (onScreen.size () < maxChargerOnScreen && chargerIndex <= numCharger - 1) {

    if (chargerIndex < chargerArr.length) { // <--- this is the problem chargerArrayLength
        Charger chargerMobs = chargerArr[chargerIndex];
        // starts from chargerArray[0] to chargerArray[300]
        onScreen.add(chargerMobs);
        chargerIndex++;
        // chargerIndex keeps looping why?
        // println("ADDED ZOMBIE TO ONSCREEN Zombs on screen: " + onScreen.size());
    }
}

// Adjusts maxZombOnScreen based off the current index   Difficulties?
if (chargerIndex == 10)
    maxChargerOnScreen++;
else if (chargerIndex == 50)
    maxChargerOnScreen++;
else if (chargerIndex == 100)
    maxChargerOnScreen += 2;
else if (chargerIndex == 150)
    maxChargerOnScreen += 2;
else if (chargerIndex == 190)
    maxChargerOnScreen += 3;
else if (chargerIndex == 250)
    maxChargerOnScreen += 3;
else if (chargerIndex == 260)
    maxChargerOnScreen += 3;
else if (chargerIndex == 270)
    maxChargerOnScreen += 5;

// removes dead zombies, living zombies act normally
for(int i = 0; i < onScreen.size(); i++) {
    Charger c = onScreen.get(i);

    // add money when a zombie is dead
    // if (c.getHealth() <= 0)
    if (chargerShot==true) {
        c.chargerDying();
        onScreen.remove(i);
        chargerKilled++;
        i--;
    } else {
        c.act(); ///it should just act
    //  c.displayHealth(); // if gt time only do
//  }
    }
}


评价和批评表示赞赏。

最佳答案

该代码有几个问题,但现在,我将忽略有些“不干净”或“不优雅”的部分,而将重点放在引起该问题的主要问题上:

所有Charger实例的状态都相同。田野

boolean chargerReachedTarget = false, chargerShot = false, chargerDive = true;


已全局定义。只需将这一行(即这3个字段)移到Charger类中,然后更改该行

if (chargerShot==true) {




if (c.chargerShot==true) {


游戏似乎已经很接近您想找的东西了。修改后,可以射击单个对手,而在旧对手消失之后,新对手不断出现。

再说一遍:该代码的结构并不是很好,并且有许多可能的细微改进。例如,类似if (c.chargerShot==true) { ... }的东西最好是if (charger.isShot()) { ... }。但是我对处理及其最佳实践不是很熟悉,因此我不确定在全球范围内“最佳”解决方案的外观如何……

10-05 22:43