我正在制作一个简单的游戏,其中一个红球和一个蓝球以随机速度沿 x 轴(以及沿 y 轴恒定速度)在屏幕上移动。玩家通过点击球来得分,这会重置他们的位置并根据球沿 x 轴移动的速度为玩家的得分添加分数。我已经实现了一个 MouseListener 来跟踪玩家的动作。当球的运动被注释掉时,MouseListener 完美地记录了一切。当球被允许移动时,MouseListener 只会以看似随机的间隔注册。我不再相信这是一个命中检测问题,因为无论您击中还是未命中,程序都会播放声音,并且当 MouseListener 无法注册时没有声音播放。
代码:
主班
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Main extends Applet implements Runnable, MouseListener{
    private static final long serialVersionUID = 7526472295622776147L; 
    private int speed;
    boolean isStopped=true;
    private Player player;
    private Ball redball;
    private Ball blueball;
    Thread t;
    AudioClip shotnoise;
    AudioClip hitnoise;
    AudioClip outnoise;
    Font f = new Font ("Serif", Font.BOLD, 20);
    Cursor c;
    private Image dbImage;
    private Graphics dbg;
    public void init(){
        this.addMouseListener(this);
        setSize(400,400);
        c=new Cursor(Cursor.CROSSHAIR_CURSOR);
        this.setCursor(c);
        setBackground (Color.black);
        setFont (f);
        if (getParameter ("speed") != null)
        {
            speed = Integer.parseInt(getParameter("speed"));
        }
        else speed = 15;
        hitnoise = getAudioClip (getCodeBase() , "gun.au");
        hitnoise.play();
        hitnoise.stop();
        shotnoise = getAudioClip (getCodeBase() , "miss.au");
        shotnoise.play();
        shotnoise.stop();
        outnoise = getAudioClip (getCodeBase() , "error.au");
        outnoise.play();
        outnoise.stop();
        player = new Player ();
        redball = new Ball (10, 190, 250, 1, -1, 4, Color.red, outnoise, player);
        blueball = new Ball (10, 190, 150, 1, 1, 3, Color.blue, outnoise, player);
    }
    public void start ()
    {
        t = new Thread (this);
        t.start ();
    }
    public void stop ()
    {
    }
    public void run(){
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
        while(true){
            if(player.getLives()>=0 && !isStopped){
                redball.move();
                blueball.move();
            }
            repaint();
            try{
                Thread.sleep(speed);
            }
            catch(InterruptedException e){
            }
            Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
        }
    }
    public void paint(Graphics g){
        if(player.getLives()>=0){
            g.setColor(Color.yellow);
            g.drawString("Score: " + player.getScore(),10,40);
            g.drawString("Lives: "+ player.getLives(), 300, 40);
            redball.DrawBall(g);
            blueball.DrawBall(g);
            if(isStopped){
                g.setColor(Color.yellow);
                g.drawString("Double Click to Start",40, 200);
            }
        }
        else if(player.getLives()<0){
            g.setColor(Color.yellow);
            g.drawString("Game Over!",130,100);
            g.drawString("You Scored: "+player.getScore()+"Points!",90, 140);
            if (player.getScore() < 300) g.drawString ("Well, it could be better!", 100, 190);
            else if (player.getScore() < 600 && player.getScore() >= 300) g.drawString ("That was not so bad", 100, 190);
            else if (player.getScore() < 900 && player.getScore() >= 600) g.drawString ("That was really good", 100, 190);
            else if (player.getScore() < 1200 && player.getScore() >= 900) g.drawString ("You seem to be very good!", 90, 190);
            else if (player.getScore() < 1500 && player.getScore() >= 1200) g.drawString ("That was nearly perfect!", 90, 190);
            else if (player.getScore() >= 1500) g.drawString ("You are the Champingon!",100, 190);
            g.drawString("Double Click on the Applet to Play Again!",20,220);
            isStopped=true;
        }
    }
    public void update(Graphics g){
        if(dbImage==null){
            dbImage=createImage(this.getSize().width,this.getSize().height);
            dbg=dbImage.getGraphics();
        }
        dbg.setColor(getBackground());
        dbg.fillRect(0,0,this.getSize().width,this.getSize().height);
        dbg.setColor(getForeground());
        paint(dbg);
        g.drawImage(dbImage,0,0,this);
    }
    public void mouseClicked(MouseEvent e){
        if(!isStopped){
            if(redball.userHit(e.getX(),e.getY())){
                hitnoise.play();
                redball.wasHit();
            }
            else if (blueball.userHit (e.getX(),e.getY())){
                hitnoise.play();
                blueball.wasHit();
            }
            else{
                shotnoise.play();
            }
        }
        else if(isStopped&&e.getClickCount()==2){
            isStopped=false;
            init();
        }
    }
    public void mouseEntered(MouseEvent e){
    }
    public void mouseExited(MouseEvent e){
    }
    public void mousePressed(MouseEvent e){
    }
    public void mouseReleased(MouseEvent e){
    }
}
球类
import java.applet.*;
import java.awt.*;
import java.util.*;
public class Ball{
    private int x_pos;
    private int y_pos;
    private int x_speed;
    private int y_speed;
    private int radius;
    private int first_x;
    private int first_y;
    private int max_speed;
    private final int x_leftout = 10;
    private final int x_rightout = 370;
    private final int y_upout = 45;
    private final int y_downout = 370;
    Color color;
    AudioClip out;
    Player player;
    Random rnd=new Random();
    public Ball(int radius, int x, int y, int vx, int vy, int ms, Color color, AudioClip out, Player player){
        this.radius=radius;
        x_pos=x;
        y_pos=y;
        first_x=x;
        first_y=y;
        x_speed=vx;
        y_speed=vy;
        max_speed = ms;
        this.color = color;
        this.out = out;
        this.player = player;
    }
    public void move(){
        x_pos+= x_speed;
        y_pos+=y_speed;
        isOut();
    }
    public void wasHit(){
        x_pos = first_x;
        y_pos = first_y;
        x_speed = (rnd.nextInt ()) % max_speed;
    }
    private boolean isOut(){
        if(x_pos>x_rightout){
            x_pos=first_x;
            y_pos=first_y;
            out.play();
            x_speed=(rnd.nextInt())%max_speed;
            player.looseLife();
            return true;
        }
        else if(x_pos<x_leftout){
            x_pos=first_x;
            y_pos=first_y;
            out.play();
            x_speed=(rnd.nextInt())%max_speed;
            player.looseLife();
            return true;
        }
        else if(y_pos>y_downout){
            x_pos=first_x;
            y_pos=first_y;
            out.play();
            x_speed=(rnd.nextInt())%max_speed;
            player.looseLife();
            return true;
        }
        else if(y_pos<y_upout){
            x_pos=first_x;
            y_pos=first_y;
            out.play();
            x_speed=(rnd.nextInt())%max_speed;
            player.looseLife();
            return true;
        }
        else return false;
    }
    public boolean userHit(int mouse_x, int mouse_y){
        int dx=Math.abs(x_pos-mouse_x);
        int dy=Math.abs(y_pos-mouse_y);
        if(dx>radius){
            return false;
        }
        else if(dy>radius){
            return false;
        }
        else{ 
            player.AddScore(10*Math.abs(x_speed)+10);
            return true;
        }
    }
    public void DrawBall (Graphics g)
    {
        g.setColor (color);
        g.fillOval (x_pos - radius, y_pos - radius, 2*radius, 2*radius);
    }
}
玩家等级
public class Player{
    private int lives;
    private int score;
    public Player(){
        lives=10;
        score=0;
    }
    public int getScore(){
        return score;
    }
    public int getLives(){
        return lives;
    }
    public void looseLife(){
        lives--;
    }
    public void AddScore(int points){
        score+=points;
    }
}