为什么我的代码只检查一次if语句然后停止?

问题描述 投票:0回答:1

我目前正在处理Processing中的游戏,到目前为止,我将其分为三部分。开始屏幕,级别选择屏幕和游戏屏幕。 “开始”屏幕似乎运行良好,但是当用户进入级别选择屏幕时,它仅检查一次if语句,然后停止。这是相关的代码:

int level = 0;
Player myPlayer;
Floor[] level1Floors = new Floor[5];
Selector levelSelector1;
Selector levelSelector2;
Selector levelSelector3;
Selector levelSelector4;
Selector levelSelector5;
Selector levelSelector6;
Selector levelSelector7;
Selector levelSelector8;
Selector levelSelector9;
Selector levelSelector10;


void setup () {
 size(800, 600);
 myPlayer = new Player(width/2, 500, 50, 50, 15, 0, 9, true, false, false, false, false);
 level1Floors[0] = new Floor(0, 525, width);
 level1Floors[1] = new Floor(width, 485, width/2);
 startButton = loadImage("playButton.png");
 startButtonHover = loadImage("playButtonHover.png");
 star = loadImage("Star.png");
 starUnlit = loadImage("StarUnlit.png");
 levelSelector1 = new Selector(1, 110, 210);
 levelSelector2 = new Selector(2, 255, 210);
 levelSelector3 = new Selector(3, 400, 210);
 levelSelector4 = new Selector(4, 545, 210);
 levelSelector5 = new Selector(5, 690, 210);
 levelSelector6 = new Selector(6, 110, 390);
 levelSelector7 = new Selector(7, 255, 390);
 levelSelector8 = new Selector(8, 400, 390);
 levelSelector9 = new Selector(9, 545, 390);
 levelSelector10 = new Selector(10, 690, 390);
}

void draw () {
 if (gamestate == 0) {
   startScreen();
 }
 if (gamestate == 1) {
   println("eh");
   levelSelection();
   levelSelector1.displaySelector();
   levelSelector2.displaySelector();
   levelSelector3.displaySelector();
   levelSelector4.displaySelector();
   levelSelector5.displaySelector();
   levelSelector6.displaySelector();
   levelSelector7.displaySelector();
   levelSelector8.displaySelector();
   levelSelector9.displaySelector();
   levelSelector10.displaySelector();
 }
 if (gamestate == 2) {
   if (level == 1) {
     background(54);
     level1();
   }
 }
}
void collision () {
 int trueY = myPlayer.y + myPlayer.yOffset;
 if (trueY > level1Floors[0].y) {
   myPlayer.y = level1Floors[0].y - myPlayer.yOffset;
   myPlayer.yvel = 0;
   myPlayer.flag = false;
 }else {
   myPlayer.yvel++;
 }
}

void keyPressed () {
 if (key == ' ' && !myPlayer.flag && gamestate == 2) {
   myPlayer.isJump = true;
 }
 if (key == 'a' && myPlayer.left == false && gamestate == 2) {
   myPlayer.left = true;
 }
 if (key == 'd' && myPlayer.right == false && gamestate == 2) {
   myPlayer.right = true;
 }
 if (key == 'g') {
   exit();
 }
}
void keyReleased () {
 if (key == ' ') {
   myPlayer.isJump = false;
 }
 if (key == 'a') {
   myPlayer.left = false;
 }
 if (key == 'd') {
   myPlayer.right = false;
 }
}

class Floor {
 int x1;
 int y;
 int x2;

 Floor (int tempX1, int tempY, int tempX2) {
   x1 = tempX1;
   y = tempY;
   x2 = tempX2;
 }

 void display () {
   strokeWeight(3);
   line(x1, y, x2, y);
 }
}

------------- this code is in a different tab ----------------
PImage star;
PImage starUnlit;
int starSize = 75;

void levelSelection () {
 background(130);
}

class Selector {
 int value;
 int x;
 int y;
 int sizeX;
 int sizeY;
 int radius;
 int fillValue;
 int strokeValue;

 Selector(int tempVal, int tempX, int tempY) {
   value = tempVal;
   x = tempX;
   y = tempY;
   sizeX = 120;
   sizeY = 120;
   radius = 20;
   fillValue = 70;
   strokeValue = 55;
 }

 void displaySelector () {
   fill(fillValue);
   stroke(strokeValue);
   strokeWeight(6);
   rectMode(CENTER);
   rect(x, y, sizeX, sizeY, radius);
   fill(255);
   textSize(40);
   textAlign(CENTER,CENTER);
   text(value, x, (y-20));
   imageMode(CENTER);
   image(starUnlit, (x - 30), (y + 20), starSize, starSize);
   image(starUnlit, x, (y + 30), starSize, starSize);
   image(starUnlit, (x + 30), (y + 20), starSize, starSize);

   if (mouseX > (x - 60) && mouseX < (x + 60) && mouseY > (y - 60) && mouseY < (y + 60)) {
     println("wow ur computer is a potato");
     sizeX = 130;
     sizeY = 130;
     fillValue = 90;
     strokeValue = 75;
   }else {
     println("u succ");
     sizeX = 120;
     sizeY = 120;
     fillValue = 70;
     strokeValue = 55;
   }

   if (mouseX > (x - 60) && mouseX < (x + 60) && mouseY > (y - 60) && mouseY < (y + 60) && mousePressed) {
     gamestate = 2;
     level = value;
   }
 }
}

------------ this is also in a different tab idk if it is relevant though ---------------
PImage startButton;
PImage startButtonHover;
int startButtonx = 400;
int startButtony = 350;

void startScreen () {
 background(130);
 imageMode(CENTER);
 image(startButton, startButtonx, startButtony, 100, 100);
 textAlign(CENTER,CENTER);
 textSize(60);
 text("OBJECTIVE: BREAK OUT", width/2, height/6);

 if (dist(mouseX, mouseY, startButtonx, startButtony) < 43) {
   imageMode(CENTER);
   image(startButtonHover, startButtonx, startButtony, 110, 110);
 }
 if (dist(mouseX, mouseY, startButtonx, startButtony) < 43 && mousePressed) {
   gamestate = 1;
 }
} 

void level1  () {
 background(54);
 myPlayer.display();
 level1Floors[0].display();
 level1Floors[1].display();
 collision();
 myPlayer.jump();
}

class Player {
 int x;
 int y;
 int vSide;
 int hSide;
 int yOffset;
 int speed;
 int yvel;
 int xvel;
 boolean isCollide;
 boolean isJump;
 boolean right;
 boolean left;
 boolean flag;

 Player (int tempX, int tempY, int tempVSide, int tempHSide, int tempSpeed, int tempyvel, int tempxvel, boolean tempIsCollide, boolean tempIsJump, boolean tempRight, boolean tempLeft, boolean tempFlag) {
   x = tempX;
   y = tempY;
   vSide = tempVSide;
   hSide = tempHSide;
   speed = tempSpeed;
   yvel = tempyvel;
   xvel = tempxvel;
   isCollide = tempIsCollide;
   isJump = tempIsJump;
   right = tempRight;
   left = tempLeft;
   flag = tempFlag;
   yOffset = 25;
 }

 void display() {
   fill(0);
   strokeWeight(2);
   stroke(255);
   rectMode(CENTER);
   rect(x, y, hSide, vSide);

   y += yvel;
 }

 void jump () {
   if (isJump) {
     y -= 20;
     flag = true;
   }
   if (left && x >= 25) {
     x -= xvel;
   }
   if (right && x <= (width - 25)) {
     x += xvel;
   }
 }
}

我知道代码非常混乱,我打算稍后解决该问题。如果我是对的,问题就出在Selector类上,因为那是2个if语句不检查条件是否得到满足的地方。任何帮助将不胜感激,谢谢您的时间。

processing
1个回答
0
投票

您的问题比看起来更难诊断。如您所料,级别选择屏幕中存在问题。但是问题也出在startScreen()方法中,您可以看到的症状“冻结”是这些因素与实现的电平选择逻辑有关的结果。

我花了一些时间来查看问题,因为起初它错过了很多功能,甚至后来我仍然没有图像,所以我不得不调整代码以查看内容,这让我半信半疑。和一半的分析。

您可能想知道为什么我要说所有这些话。有一个很好的理由:我希望您能够以一种可以帮助人们回答的方式提出下一个问题。如果您提出了有关特定功能的问题,那将很容易,但这只是调试。调试代码而不运行它比它要困难得多。因此,我告诉您要发布Minimal, Reproducible Example。如果您需要某个错误的帮助,那么对于那些愿意帮助的人来说,能够复制它是一个强大的工具。我可能是唯一一个回答的人,可能与这种缺陷有关。


问题是mousePressed。如果您在Processing文档中单击read a little bit on it,则会看到以下内容:“ mousePressed变量存储当前是否在按下鼠标按钮”。

这也意味着只要按下鼠标按钮,mousePressed就为真。用户可以单击任意位置,按住按钮不放并将鼠标拖向级别选择器,它将在您的代码中注册,就像单击该级别一样。

发生的事情:

  1. startScreen()中,用户单击图像以开始。
  2. 游戏状态进入“关卡选择”的速度比眼睛能看到的快,而且比鼠标的手指释放按钮的速度还快。
  3. 显示在鼠标单击位置的级别选择器。]
  4. 游戏状态更改为“ 2”,但是用户错误选择的级别尚不可用。游戏似乎停滞了,因为它被卡在了那里。
  5. 如您所见,您必须找出一种区分“按下按钮的方式”和用户实际点击的方式。目前,这只是一个小故障,但是当您基于此程序构建程序时,它将成为一个越来越令人沮丧的问题。

    [有很多方法可以解决这个问题。我将为您提供其中之一的代码,我认为它们是简单有效的。但是,如果您有足够的野心,那么创建一个仅存在于管理用户输入的类将是一种更干净,结构更好的方法。

    但是现在让我们走一条简单的路(为了清楚起见,逐步进行::

  1. 添加此全局变量:

    boolean leftMouseButtonClicked = false;
    

    稍后将替换有问题的mousePressed

  2. 将此方法添加到您的项目中:

    void mouseClicked() {
      if (mouseButton == LEFT) {
        leftMouseButtonClicked = true;
      }
    }
    

    这将打开用户单击时在点1中添加的布尔值,然后释放鼠标左键。 mouseClicked是内置的处理功能。您可以read more about it here

  3. 为此更改您的draw()方法:

    void draw () {
      switch (gamestate) {
      case 0:
        startScreen();
        break;
      case 1:
        levelSelection();
        levelSelector1.displaySelector();
        levelSelector2.displaySelector();
        levelSelector3.displaySelector();
        levelSelector4.displaySelector();
        levelSelector5.displaySelector();
        levelSelector6.displaySelector();
        levelSelector7.displaySelector();
        levelSelector8.displaySelector();
        levelSelector9.displaySelector();
        levelSelector10.displaySelector();
        break;
      case 2:
        switch (level) {
        case 1:
          level1();
          break;
        default:
          gamestate = 1;
        }
      }
    
      leftMouseButtonClicked = false;
    }
    

    大约是同一件事,但有一些重要的变化:

  4. 3.1。我自由地使用switch语句,而不是以前的少数if语句。 switch易于阅读,并且大小写必须互斥才能起作用。您可以改用if - else if - else if...形式,但为了可读性我更喜欢switch

    3.2。我在关卡开关中添加了一个default外壳,因此当您误按一个尚不存在的关卡而不是冻结时,它将返回到关卡选择游戏状态。

    3.3。我关闭了leftMouseButtonClicked布尔值,因此它不会一直保持打开状态。

  5. 更改您写mousePressed的每个位置,所以改用leftMouseButtonClicked

  6. 这是纠正这种情况的全部方法。我试图不优化您的代码,以使其保留在您的代码中(我无法抗拒的switch除外)。您的代码很有意义,并且比其他代码结构更好。当然,可以进行很多改进,但这是您在变得更好的同时会学到的东西。而且我相信您会很好。

    我希望我把一切都弄清楚了。编码不错,玩得开心!

© www.soinside.com 2019 - 2024. All rights reserved.