基于自定义类与对象的Processing迷你游戏报错排查求助
核心错误与修正
变量作用域问题:
setup()内定义的waterLevel、lightLevel、growthLevel及按钮相关变量均为局部变量,其他函数/类无法访问,会触发编译错误。需将这些变量移至全局作用域:// 全局变量区添加 int waterLevel; int lightLevel; int growthLevel; int blueX, blueY; int greenX, greenY; int yellowX, yellowY; boolean blueOver = false; boolean greenOver = false; boolean yellowOver = false; int buttonSize = 100;同时删除
setup()内的对应局部变量定义。函数名大小写不匹配:
draw()中调用gameplay(),但实际定义的函数是gamePlay(),需统一函数名,确保调用正确。函数返回类型缺失:
gameOver()未声明返回类型,需改为void gameOver(),符合Processing语法要求。语法错误:
OFlower类的update()方法中,light Level多了空格,修正为lightLevel。循环逻辑失效:
setup()中的noLoop()会让draw()仅执行一次,导致游戏状态无法更新、交互无响应,需移除该语句。
逻辑缺陷优化
音乐重复播放:
draw()内的music.loop()会每帧调用,导致音乐重叠,将其移至setup()中执行一次即可。花卉对象重复创建:
gamePlay()内每次调用都会新建OFlower实例,导致状态丢失。将OFlower o1设为全局变量,在setup()中初始化:OFlower o1; void setup() { // ... 其他初始化代码 o1 = new OFlower(5, 0); }随后在
gamePlay()中直接调用o1.update()。状态衰减逻辑补充:根据需求,添加变量随时间衰减的逻辑,可在
OFlower的update()中加入:void update() { // 每60帧(约1秒)衰减一次 if (frameCount % 60 == 0) { if (waterLevel > 0) waterLevel--; if (lightLevel > 0) lightLevel--; if (growthLevel > 5) growthLevel--; } // ... 原有逻辑 }游戏流程控制:
draw()内的启动逻辑需优化,避免反复进入gamePlay(),添加全局状态变量区分游戏阶段:int gameState = 0; // 0:启动页, 1:游戏中, 2:游戏结束 void draw() { if (gameState == 0) { // 启动页逻辑 image(startScreen, 5, 0); fill(255); text("Click to start", 540, 540); if (mousePressed) { gameState = 1; } } else if (gameState == 1) { gamePlay(); } else if (gameState == 2) { gameOver(); } }同时在
OFlower的update()中,当growthLevel <=0时设置gameState = 2,而非直接调用gameOver()。
修正后的完整代码示例
int gameState = 0; // 0:启动页, 1:游戏中, 2:游戏结束 int waterLevel; int lightLevel; int growthLevel; int blueX, blueY; int greenX, greenY; int yellowX, yellowY; boolean blueOver = false; boolean greenOver = false; boolean yellowOver = false; int buttonSize = 100; OFlower o1; 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; void setup() { size(1090, 720); helvetica = loadFont("Helvetica-20.vlw"); textFont(helvetica); 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"); 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"); music.loop(); waterLevel = 0; lightLevel = 0; growthLevel = 0; o1 = new OFlower(5, 0); } void draw() { if (gameState == 0) { image(startScreen, 5, 0); fill(255); text("Click to start", 540, 540); if (mousePressed) { gameState = 1; } } else if (gameState == 1) { gamePlay(); } else if (gameState == 2) { gameOver(); } } void gamePlay() { image(playScreen, 5, 0); 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); o1.update(); } class OFlower { int flowerX, flowerY; OFlower (int x, int y) { flowerX = x; flowerY = y; } void update() { if (frameCount % 60 == 0) { if (waterLevel > 0) waterLevel--; if (lightLevel > 0) lightLevel--; if (growthLevel > 5) growthLevel--; } if (waterLevel >= 5) { image(wetPot, 5, 0); } else { image(dryPot, 5, 0); } if (growthLevel >=5 && waterLevel >=5 && lightLevel >=5) { if (growthLevel < 10) growthLevel++; } else if (growthLevel >0) { growthLevel--; } if (growthLevel <= 0) { gameState = 2; } 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; return sqrt(sq(disX) + sq(disY)) < diameter/2; } boolean overGreen(int x, int y, int diameter) { float disX = x - mouseX; float disY = y - mouseY; return sqrt(sq(disX) + sq(disY)) < diameter/2; } boolean overYellow(int x, int y, int diameter) { float disX = x - mouseX; float disY = y - mouseY; return sqrt(sq(disX) + sq(disY)) < diameter/2; } 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 (gameState != 1) return; if (blueOver) { water.play(); waterLevel += 10; } if (greenOver) { dirt.play(); growthLevel += 5; } if (yellowOver) { blinds.play(); lightLevel += 3; } } void gameOver() { image(endScreen, 5, 0); fill(255); text("Oh no! Your flower died...", 540, 600); }
内容的提问来源于stack exchange,提问作者Kathrine Lee

