【问题标题】:NullPointerException after pressing reset button. (Processing)按下重置按钮后出现 NullPointerException。 (加工)
【发布时间】:2014-11-19 03:23:36
【问题描述】:

我正在尝试为该程序制作一个重置按钮,但我到处寻找,但找不到有效的方法。我试着让它在游戏结束时,当你输了,你按“重新开始”,游戏将从草图的开头开始。该程序运行良好,但是一旦您按下重新启动按钮,我在控制台区域收到 NullPointerException 错误并且游戏不会重新启动。我在“if (!drop[i].finished) {”行中收到 NullPointerException 错误。我读过它与构造函数没有初始化数组有关,但它已经初始化了它。这是否与重置按钮和构造函数没有重新初始化数组有关,还是其他原因?我不知道为什么,但它很少起作用,但所有文本都向左移动并离开屏幕。谢谢你的帮助。

boolean button = false;
Catcher catcher;    
Timer timer;        
Drop[] drops;      
int totalDrops = 0; 
int x = 200;
int y = 100;
int w = 150;
int h = 60;

// Is the game over?
boolean gameOver = false;

// Variables for score level lives and level counter
int score = 0;     
int level = 1;      
int lives = 10;     //10 lives per level, resets at next level
int levelCounter = 0;

PFont f;
void reset() {
  score = 0;
  level = 1;
  levelCounter = 0;
  lives = 10;
  timer.setTime(constrain(300-level*25,0,300));
  totalDrops = 0; 
  gameOver = false;
  button = false;
}


void setup() {
  size(400,400);
  smooth();
  catcher = new Catcher(32);
  drops = new Drop[50];    
  timer = new Timer(300);   
  timer.start();  
  gameOver = false;  
  finished = false;
  level = 1;
  score = 0;


  f = createFont("Arial",12,true); 
}

void draw() {
  background(255);

  // If the game is over
  rectMode (CENTER);
  if (gameOver) {
    textFont(f,48);
    textAlign(CENTER);
    fill(0);
    text("GAME OVER",width/2,height/2);
    textFont(f,24);
    text("Your score was "+ score,200,225);
    textFont(f,16);
    text("You reached level "+ level,200,245);
    fill(255);
    stroke(0);
    rect(200,100,150,60);
    stroke(255);
    fill(0);
    textFont(f,20);
    text("Restart",200,107);


  } 
  else {

    // Set catcher location
    catcher.setLocation(mouseX,mouseY); 

    catcher.display(); 

    // Check the timer
    if (timer.isFinished()) {
      if (totalDrops < drops.length) {
        drops[totalDrops] = new Drop();

        totalDrops++;
      }
      timer.start();
    }

    // Move and display all drops
    for (int i = 0; i < totalDrops; i++ ) {


      if (!drops[i].finished) {

        drops[i].move();
        drops[i].display();
        if (drops[i].reachedBottom()) {
          levelCounter++;
          drops[i].finished(); 
          // If the drop reaches the bottom a live is lost and you lose 5 points
          lives--;
          score=score-5;
          // If lives reach 0 the game is over
          if (lives <= 0) {
            gameOver = true; 
          }
        } 

        // Everytime you catch a drop, the score goes up
        if (catcher.intersect(drops[i])) {
          drops[i].finished();
          levelCounter++;
          score=score+10;
        }
      }
    }


    // If all the drops are done, that level is over!
    if (levelCounter >= drops.length) {
      // Go up a level
      level++;
      // Reset all game elements
      levelCounter = 0;
      lives = 10;
      timer.setTime(constrain(300-level*25,0,300));
      totalDrops = 0; 
    }





    // Display number of lives left
    rectMode(CORNER);
    textFont(f,14);
    fill(0);
    text("Lives left: " + lives,10,20);
    rect(10,24,lives*10,10);

    text("Level: " + level,300,20);
    text("Score: " + score,300,40);
  }

if (mousePressed) {
  if (mouseX >= x && mouseX <= x + w && mouseY >= y && mouseY <= y + h && gameOver == true){
    setup();
  }
}
println();
}
//----------------------Drop Class-----------------------------
class Drop {
  float x,y;  
  float speed; 
  color c;
  float r;     

  //Is the drop used?
  boolean finished = false;

  Drop() {
    r = 8;               
    x = random(width);     
    y = -r*4;              
    speed = random(2,5);   
    c = color(random(255),random(255),random(255)); 
  }


  void move() {

    y += speed; 
  }

  // Check if it hits the bottom
  boolean reachedBottom() {
    // If it passes the bottom
    if (y > height + r*4) { 
      return true;
    } 
    else {
      return false;
    }
  }


  void display() {
    fill(c);
    noStroke();
    for (int i = 2; i < r; i++ ) {
      ellipse(x,y + i*4,i*2,i*2);
    }
  }

  // If the drop is caught
  void finished() {
    finished = true;
  }
}

这是堆栈跟踪:

Exception in thread "Animation Thread" java.lang.NullPointerException
    at Raindrop_Catcher.draw(Raindrop_Catcher.java:113)
    at processing.core.PApplet.handleDraw(Unknown Source)
    at processing.core.PApplet.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:662)

【问题讨论】:

  • 你已经初始化了数组drops = new Drop[50];,但没有填充任何东西,因此所有元素都是null
  • 这听起来你可能有一个多线程竞争条件,即在你重置状态的同时,游戏试图更新视图,导致神秘的崩溃,如这个,时不时...
  • 对不起,我是这方面的业余爱好者,所以你能告诉我如何填充数组以使其不为空吗?顺便说一句,非常感谢您的帮助

标签: java arrays if-statement nullpointerexception processing


【解决方案1】:

看起来您只是在 if 语句中用对象填充数组 drops

// Check the timer
if (timer.isFinished()) {
  if (totalDrops < drops.length) {
    drops[totalDrops] = new Drop(); 

    totalDrops++;
  }
  timer.start();
}

因此,如果 if 语句的计算结果为 false,则数组仍会填充空值,从而导致 NullPointerException。在尝试使用它们之前,请确保数组包含对象。

在你的设置方法中,添加这个以确保你的数组填充了非空值:

for (int i = 0; i < drops.length; i++)
{
     drops[i] = new Drop();
}

【讨论】:

  • 非常感谢!现在我只需要让它在我重新启动时不会掉下 50 滴,但我可以弄清楚,这只是一个逻辑错误!再次感谢,这困扰了我很长一段时间!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多