使用自定义类和对象的迷你游戏错误

Mini Game using Custom Classes and Objects Errors

提问人:Kathrine Lee 提问时间:8/21/2023 最后编辑:super turkeyKathrine Lee 更新时间:8/30/2023 访问量:54

问:

我有一个项目,我们应该使用类和对象来创建各种迷你游戏。我已经输入了游戏的主要结构,但我不知道它是否会起作用。我在尝试让它运行时遇到了几个错误,但我的大脑太累了,无法分辨问题出在哪里。如果您能看一下我的代码并给我一些反馈,我将不胜感激。

void setup() {
  size(1090, 720); //canvas size
  //defining image variables
  helvetica = loadFont("Helvetica-20.vlw");
  startScreen = loadImage("Title Screen.png");
  playScreen = loadImage("Play Screen.png");
  endScreen = loadImage("End Screen.png");
  blindsOpen = loadImage("Open Blinds.png");
  blindsHalf = loadImage("Half Blinds.png");
  blindsClosed = loadImage("Closed Blinds.png");
  dryPot = loadImage("Pot Dry.png");
  wetPot = loadImage("Pot Wet.png");
  sprout = loadImage("Sprout.png");
  stem = loadImage("Stem.png");
  bud = loadImage("Bud.png");
  bloomRose = loadImage("Bloom Rose.png");
  bloomClemantis = loadImage("Bloom Clemantis.png");
  bloomAster = loadImage("Bloom Aster.png");
  //defininng sound variables
  blinds = new SoundFile(this, "Blinds.wav");
  dirt = new SoundFile(this, "Dirt_Sound.wav");
  water = new SoundFile(this, "Pouring_Water.wav");
  music = new SoundFile(this, "Gentle_Music.wav");
  //no loop to keep the sound from overlapping itself
  noLoop();
  //variables for the flower object
  int waterLevel;
  int lightLevel;
  int growthLevel;
  //initial values
  waterLevel = 0;
  lightLevel = 0;
  growthLevel = 0;
  //variables for the buttons
  int blueX, blueY;
  int greenX, greenY;
  int yellowX, yellowY;
  boolean blueOver = false;
  boolean greenOver = false;
  boolean yellowOver = false;
  int buttonSize = 100;
}

void draw() {
  //start screen image
  image(startScreen, 5, 0);
  music.loop(); //play gentle music for the entirety of the game
  fill(255);
  text("Click to start", 540, 540); //tell the user to click the screen
  //when mouse is clicked, switch to the main gameplay screen
  if (mousePressed) {
    gameplay();
  }
}

//gameplay function
void gamePlay() {
  //play screen image
  image(playScreen, 5, 0);
  //buttons for gameplay
  blueX = 100;
  blueY = 690;
  greenX = 540;
  greenY = 680;
  yellowX = 1000;
  yellowY = 680;
  fill(0, 0, 255);
  noStroke();
  smooth();
  circle(blueX, blueY, buttonSize);
  fill(0, 200, 0);
  circle(greenX, greenY, buttonSize);
  fill(220, 220, 0);
  circle(yellowX, yellowY, buttonSize);
  fill(255);
  text("Water", 77, 687);
  text("Seed", 520, 687);
  text("Light", 980, 687);
  update(mouseX, mouseY);
  OFlower o1 = new OFlower(5, 0);
  o1.update();
}

//flower class defined
class OFlower {
  int flowerX, flowerY;
  OFlower (int x, int y) {
    flowerX = x;
    flowerY = y;
  }
  void update() {
    if (waterLevel >= 5) {
      image(wetPot, 5, 0);
    } else {
      image(dryPot, 5, 0);
    }
    if (growthLevel == 5 && waterLevel >= 5 && lightLevel >= 5) {
      growthLevel = growthLevel+1;
    } else {
      growthLevel = growthLevel-1;
    }
    if (growthLevel <= 0) {
      gameOver();
    }
    if (growthLevel == 5) {
      image(sprout, 5, 0);
    } else if (growthLevel == 6) {
      image(stem, 5, 0);
    } else if (growthLevel == 7) {
      image(bud, 5, 0);
    } else if (growthLevel >= 8 && lightLevel <=7) {
      image(bloomClemantis, 5, 0);
    } else if (growthLevel >= 8 && lightLevel == 8) {
      image(bloomRose, 5, 0);
    } else if (growthLevel >= 8 && light Level >= 9) {
      image(bloomAster, 5, 0);
    }
  }
}

boolean overBlue(int x, int y, int diameter) {
  float disX = x - mouseX;
  float disY = y - mouseY;
  if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
    return true;
  } else {
    return false;
  }
}

boolean overGreen(int x, int y, int diameter) {
  float disX = x - mouseX;
  float disY = y - mouseY;
  if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
    return true;
  } else {
    return false;
  }
}

boolean overYellow(int x, int y, int diameter) {
  float disX = x - mouseX;
  float disY = y - mouseY;
  if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
    return true;
  } else {
    return false;
  }
}

void update(int x, int y) {
  if ( overBlue(blueX, blueY, buttonSize) ) {
    blueOver = true;
    greenOver = false;
    yellowOver = false;
  } else if (overGreen(greenX, greenY, buttonSize) ) {
    blueOver = false;
    greenOver = true;
    yellowOver = false;
  } else if (overYellow(yellowX, yellowY, buttonSize) ) {
    blueOver = false;
    greenOver = false;
    yellowOver = true;
  } else {
    blueOver = greenOver = yellowOver = false;
  }
}

void mousePressed() {
  if (blueOver) {
    water.play();
    waterLevel = waterLevel+10;
  }
  if (greenOver) {
    dirt.play();
    growthLevel = growthLevel+5;
  }
  if (yellowOver) {
    blinds.play();
    lightLevel = lightLevel+3;
    if (lightLevel <= 3) {
      image(blindsClosed, 5, 0);
    } else if (lightLevel <= 7) {
      image(blindsHalf, 5, 0);
    } else if (lightLevel >=10) {
      image(blindsOpen, 5, 0);
    }
  }
}

gameOver() {
  image(endScreen, 5, 0);
  fill(255);
  text("Oh no! Your flower died...", 540, 600);
}

PImage startScreen;
PImage playScreen;
PImage endScreen;
PImage blindsOpen;
PImage blindsHalf;
PImage blindsClosed;
PImage dryPot;
PImage wetPot;
PImage sprout;
PImage stem;
PImage bud;
PImage bloomRose;
PImage bloomClemantis;
PImage bloomAster;
PFont helvetica;

import processing.sound.*;

SoundFile blinds;
SoundFile dirt;
SoundFile water;
SoundFile music;

游戏的运作方式有点像一只 tamagatchi 宠物,它设置了随着时间的推移而退化的变量。正如我上面提到的,我遇到了很多错误,但无法看到它们。

JavaScript 对象 变量 处理

评论

1赞 Dave Newton 8/29/2023
请参阅“如何提问”页面 - 我们也无法看到您的错误;)
1赞 trincot 8/29/2023
这需要调试信息。

答:

2赞 George Profenza 8/30/2023 #1

理想情况下,您应该发布一个版本来隔离问题(并排除我们无法访问的资产,以便运行您的代码/复制问题)。

我确实明白一开始可能很难。看起来你已经为此付出了很多努力,但也陷入了我在开始时发现的陷阱:在没有测试的情况下添加越来越多的内容。理想情况下,你会编写少量的功能并立即测试它(例如,加载图像、放置图像、加载声音等)。这样,您就可以在错误发生时一次捕获一个错误,而不是同时捕获多个错误,这更难跟踪和修复。

不过,这不应该让你气馁。以下是到目前为止我发现的一些陷阱:

  • gameplay() / gamePlay()错字。处理是密钥敏感的:名称应匹配。(例如,在您的调用中,不存在/可能应该是draw()gameplay()gamePlay())
  • 中定义的一些变量(例如等)是局部的,但后来被引用为全局变量。也许您打算将定义移到设置上方,以便它们是全局的?blueX, blueYsetup()draw()
  • gameOver()定义时没有返回类型(例如void gameOver(){ ... })
  • noLoop()意味着将渲染单个帧,因此无法与按钮交互。也许这是调试时错误地留在那里?(在类似的音符上,如果意图是开始循环播放音乐一次而不是每秒多次,也许应该在 ,而不是在)setup()music.loop();setup()draw()
  • 可能有更多的逻辑错误,但这里有一些突出的错误:
  • growthLevel是一个全局变量,但它在类中是局部的。如果有多个实例都更改了同一个变量,则行为可能不是您想要的OFlower
  • growthLevel从 0 开始,结果立即结束比赛
  • 按下 3 个按钮(水、种子、光)中的任何一个都会降低该值(添加可以更轻松地调试此问题)。逻辑需要修正,否则无法赢得比赛。growthLevelprintln(growthLevel);

下面是一个经过调整的代码版本,解决了上述一些问题(但也注释了声音以简化测试):

//variables for the flower object
int waterLevel = 0;
int lightLevel = 0;
int growthLevel = 100;
//variables for the buttons
int blueX, blueY;
int greenX, greenY;
int yellowX, yellowY;
boolean blueOver = false;
boolean greenOver = false;
boolean yellowOver = false;
int buttonSize = 100;

void setup() {
  size(1090, 720); //canvas size
  //defining image variables
  helvetica = loadFont("Helvetica-20.vlw");
  startScreen = loadImage("Title Screen.png");
  playScreen = loadImage("Play Screen.png");
  endScreen = loadImage("End Screen.png");
  blindsOpen = loadImage("Open Blinds.png");
  blindsHalf = loadImage("Half Blinds.png");
  blindsClosed = loadImage("Closed Blinds.png");
  dryPot = loadImage("Pot Dry.png");
  wetPot = loadImage("Pot Wet.png");
  sprout = loadImage("Sprout.png");
  stem = loadImage("Stem.png");
  bud = loadImage("Bud.png");
  bloomRose = loadImage("Bloom Rose.png");
  bloomClemantis = loadImage("Bloom Clemantis.png");
  bloomAster = loadImage("Bloom Aster.png");
  //defininng sound variables
  //blinds = new SoundFile(this, "Blinds.wav");
  //dirt = new SoundFile(this, "Dirt_Sound.wav");
  //water = new SoundFile(this, "Pouring_Water.wav");
  //music = new SoundFile(this, "Gentle_Music.wav");
  //no loop to keep the sound from overlapping itself
  //noLoop();
}

void draw() {
  //start screen image
  image(startScreen, 5, 0);
  //music.loop(); //play gentle music for the entirety of the game
  fill(255);
  text("Click to start", 540, 540); //tell the user to click the screen
  //when mouse is clicked, switch to the main gameplay screen
  if (mousePressed) {
    gamePlay();
  }
}

//gameplay function
void gamePlay() {
  //play screen image
  image(playScreen, 5, 0);
  //buttons for gameplay
  blueX = 100;
  blueY = 690;
  greenX = 540;
  greenY = 680;
  yellowX = 1000;
  yellowY = 680;
  fill(0, 0, 255);
  noStroke();
  smooth();
  circle(blueX, blueY, buttonSize);
  fill(0, 200, 0);
  circle(greenX, greenY, buttonSize);
  fill(220, 220, 0);
  circle(yellowX, yellowY, buttonSize);
  fill(255);
  text("Water", 77, 687);
  text("Seed", 520, 687);
  text("Light", 980, 687);
  update(mouseX, mouseY);
  OFlower o1 = new OFlower(5, 0);
  o1.update();
  println(growthLevel);
}

//flower class defined
class OFlower {
  int flowerX, flowerY;
  OFlower (int x, int y) {
    flowerX = x;
    flowerY = y;
  }
  void update() {
    if (waterLevel >= 5) {
      image(wetPot, 5, 0);
    } else {
      image(dryPot, 5, 0);
    }
    if (growthLevel == 5 && waterLevel >= 5 && lightLevel >= 5) {
      growthLevel = growthLevel+1;
    } else {
      growthLevel = growthLevel-1;
    }
    if (growthLevel <= 0) {
      gameOver();
    }
    if (growthLevel == 5) {
      image(sprout, 5, 0);
    } else if (growthLevel == 6) {
      image(stem, 5, 0);
    } else if (growthLevel == 7) {
      image(bud, 5, 0);
    } else if (growthLevel >= 8 && lightLevel <=7) {
      image(bloomClemantis, 5, 0);
    } else if (growthLevel >= 8 && lightLevel == 8) {
      image(bloomRose, 5, 0);
    } else if (growthLevel >= 8 && lightLevel >= 9) {
      image(bloomAster, 5, 0);
    }
  }
}

boolean overBlue(int x, int y, int diameter) {
  float disX = x - mouseX;
  float disY = y - mouseY;
  if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
    return true;
  } else {
    return false;
  }
}

boolean overGreen(int x, int y, int diameter) {
  float disX = x - mouseX;
  float disY = y - mouseY;
  if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
    return true;
  } else {
    return false;
  }
}

boolean overYellow(int x, int y, int diameter) {
  float disX = x - mouseX;
  float disY = y - mouseY;
  if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
    return true;
  } else {
    return false;
  }
}

void update(int x, int y) {
  if ( overBlue(blueX, blueY, buttonSize) ) {
    blueOver = true;
    greenOver = false;
    yellowOver = false;
  } else if (overGreen(greenX, greenY, buttonSize) ) {
    blueOver = false;
    greenOver = true;
    yellowOver = false;
  } else if (overYellow(yellowX, yellowY, buttonSize) ) {
    blueOver = false;
    greenOver = false;
    yellowOver = true;
  } else {
    blueOver = greenOver = yellowOver = false;
  }
}

void mousePressed() {
  if (blueOver) {
    //water.play();
    waterLevel = waterLevel+10;
  }
  if (greenOver) {
    //dirt.play();
    growthLevel = growthLevel+5;
  }
  if (yellowOver) {
    //blinds.play();
    lightLevel = lightLevel+3;
    if (lightLevel <= 3) {
      image(blindsClosed, 5, 0);
    } else if (lightLevel <= 7) {
      image(blindsHalf, 5, 0);
    } else if (lightLevel >=10) {
      image(blindsOpen, 5, 0);
    }
  }
}

void gameOver() {
  image(endScreen, 5, 0);
  fill(255);
  text("Oh no! Your flower died...", 540, 600);
}

PImage startScreen;
PImage playScreen;
PImage endScreen;
PImage blindsOpen;
PImage blindsHalf;
PImage blindsClosed;
PImage dryPot;
PImage wetPot;
PImage sprout;
PImage stem;
PImage bud;
PImage bloomRose;
PImage bloomClemantis;
PImage bloomAster;
PFont helvetica;

//import processing.sound.*;

//SoundFile blinds;
//SoundFile dirt;
//SoundFile water;
//SoundFile music;

希望这有助于将大问题分解为小问题,以便一次解决一个问题。