玩家的得分增加9而不是1

  • 本文关键字:增加 玩家 java
  • 更新时间 :
  • 英文 :


所以在这个游戏中,我要测试,每当球击中桨,我希望分数增加1。而是增加了9。我该如何解决这个问题?下面是代码。第二个方法是update()方法,它包含了分数的增加。

public class PlayState extends State {
    private Catcher catcher;
    private Ball ball;
    boolean visible  ;
    private int playerScore = 0;
    private Font scoreFont;
    @Override
    public void init() {
        catcher = new Catcher(400,425,80,25);
        ball= new Ball(200,0,40,40);
    }
    @Override
    public void update() {
        visible=true;
        catcher.update();
        ball.update();
        if(ballCollides(catcher)){
            playerScore++;
            visible = false;
        }
    }
    @Override
    public void render(Graphics g) {
        //Draw Background
        g.setColor(Color.blue);
        g.fillRect(0, 0, GameMain.GAME_WIDTH, GameMain.GAME_HEIGHT);
        //Draw Ball(s)
        if(visible == true){
            g.setColor(Color.green);
            g.fillOval(ball.getX(),ball.getY(),ball.getWidth(),ball.getHeight());
        }
        // Draw catcher
        g.setColor(Color.white);
        g.fillRect(catcher.getX(), catcher.getY(), catcher.getWidth(),
                   catcher.getHeight());
        // Draw Score
        g.setFont(scoreFont); // Sets scoreFont as current font
        g.setColor(Color.white);
        g.drawString("" + playerScore, 350, 40); // Draws String using current font
    }
    @Override
    public void onClick(MouseEvent e) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onKeyPress(KeyEvent e) {
        // TODO Auto-generated method stub
        if (e.getKeyCode() == KeyEvent.VK_RIGHT){
            catcher.moveRight();
        }
        if (e.getKeyCode()==KeyEvent.VK_LEFT){
            catcher.moveLeft();
        }
    }
    private boolean ballCollides(Catcher c) {
        return ball.getRect().intersects(c.getRect());
    }
    @Override
    public void onKeyRelease(KeyEvent e) {
        // TODO Auto-generated method stub
        if (e.getKeyCode() == KeyEvent.VK_LEFT
            || e.getKeyCode() == KeyEvent.VK_RIGHT) {
            catcher.stop();
        }
    }
}

调用更新方法的第2块代码

package com.jamescho.game.main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JPanel;
import com.jamescho.framework.util.InputHandler;
import com.jamescho.game.state.LoadState;
import com.jamescho.game.state.State;
@SuppressWarnings("serial")
public class Game extends JPanel implements Runnable {
    private int gameWidth;
    private int gameHeight;
    private Image gameImage;
private Thread gameThread;
private volatile boolean running;
private volatile State currentState;
private InputHandler inputHandler;
public Game(int gameWidth, int gameHeight) {
    this.gameWidth = gameWidth;
    this.gameHeight = gameHeight;
    setPreferredSize(new Dimension(gameWidth, gameHeight));
    setBackground(Color.BLACK);
    setFocusable(true);
    requestFocus();
}
public void setCurrentState(State newState) {
    System.gc();
    newState.init();
    currentState = newState;
    inputHandler.setCurrentState(currentState);
}
@Override
public void addNotify() {
    super.addNotify();
    initInput();
    setCurrentState(new LoadState());
    initGame();
}
private void initGame() {
    running = true;
    gameThread = new Thread(this, "Game Thread");
    gameThread.start();
}
@Override
public void run() {
    // These variables should sum up to 17 on every iteration
    long updateDurationMillis = 0; // Measures both update AND render
    long sleepDurationMillis = 0; // Measures sleep
    while (running) {
        long beforeUpdateRender = System.nanoTime();
        long deltaMillis = updateDurationMillis + sleepDurationMillis;
        updateAndRender(deltaMillis);
        updateDurationMillis = (System.nanoTime() - beforeUpdateRender) / 1000000L;
        sleepDurationMillis = Math.max(2, 17 - updateDurationMillis);
        try {
            Thread.sleep(sleepDurationMillis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    // End game immediately when running becomes false.
    System.exit(0);
}
private void updateAndRender(long deltaMillis) {
    currentState.update(deltaMillis / 1000f);
    prepareGameImage();
    currentState.render(gameImage.getGraphics());
    renderGameImage(getGraphics());
}
private void prepareGameImage() {
    if (gameImage == null) {
        gameImage = createImage(gameWidth, gameHeight);
    }
    Graphics g = gameImage.getGraphics();
    g.clearRect(0, 0, gameWidth, gameHeight);
}
public void exit() {
    running = false;
}
private void renderGameImage(Graphics g) {
    if (gameImage != null) {
        g.drawImage(gameImage, 0, 0, null);
    }
    g.dispose();
}
private void initInput() {
    inputHandler = new InputHandler();
    addKeyListener(inputHandler);
    addMouseListener(inputHandler);
}

}

看起来好像ballCollides可以在单个碰撞的多个更新中返回true。如果没有查看整个程序的代码,我不能确定这一点,但根据已经发布的内容,这似乎是最有可能的情况。

一种修复方法是跟踪每个接球者和球组合的先前碰撞状态(如果可以有多个球和接球者),并且仅在当前状态发生碰撞而先前状态未发生碰撞时更新分数。

// Example using a single previousCollides state variable...
// Not suitable for a multi catcher / multi-ball game.
// The modifications break the contract this methods name seems to
// imply so the previousCollides logic should probably exist elsewhere
// and this code is only to illustrate the idea. 
private boolean ballCollides(Catcher c) {
    boolean collides = ball.getRect().intersects(c.getRect());
    boolean result = collides && !previousCollides;
    previousCollides = collides;
    return result;
}

上面只是一个例子,在哪里实际跟踪以前的碰撞数据取决于你。也许它应该保存在捕获器对象本身中,因为这样看起来最有意义。

最新更新