Results 1 to 9 of 9
  1. #1
    A Common Hero is offline Member
    Join Date
    Aug 2012
    Posts
    5
    Rep Power
    0

    Default Java: MouseListener does not register when objects move on screen

    I am in dire need of assistance on this issue. In the name of fairness, I should inform you that in hopes of finding an answer more quickly, I also posted this question at: http://stackoverflow.com/questions/1...move-on-screen

    Alright, I'm very new to Java and programming in general, and I'm in a bit of a bind here. My short term goal is to learn enough about Java to create some simple, 2d games. I was following a pretty lousy, and out of date tutorial earlier, leading me to this problem:

    I am making a simple game where a red ball and a blue ball move across the screen at a random speed along the x-axis (and a constant speed across the y axis). The player scores points by clicking on the balls, which resets their position and adds points to the player's score based on the speed the ball was moving along the x-axis. I have implemented a MouseListener to track the player's actions. When the ball movement is commented out, the MouseListener registers everything perfectly. When the balls are allowed to move, the MouseListener will only register at seemingly random intervals. I don't believe it is a hit detection problem anymore, because the program plays a sound whether you hit or you miss, and when the MouseListener is failing to register no sound plays.

    This applet uses three classes: Main, Ball, and Player.

    Main:
    Java Code:
    import java.applet.*;
    import java.awt.*;
    import java.awt.event.*;
    
    public class Main extends Applet implements Runnable, MouseListener{
        private static final long serialVersionUID = 7526472295622776147L; 
    
        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);
    
            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(15);
                }
    
                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){
        }
    }
    Ball:
    Java Code:
    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);
        }
    }
    Player:
    Java Code:
    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;
        }
    }
    Last edited by A Common Hero; 08-16-2012 at 05:57 AM.

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default Re: Java: MouseListener does not register when objects move on screen

    Double posted: stackoverflow.com:java-mouselistener-does-not-register-when-objects-move-on-screen. It's not fair to the volunteers of this or any other forum for you to multi-post the question without notifying all forums that you're doing this. Please do the considerate thing and post those notifications. This action will be greatly appreciated by all, and inaction will also be noted and may effect the desire of folks to help you.

  3. #3
    A Common Hero is offline Member
    Join Date
    Aug 2012
    Posts
    5
    Rep Power
    0

    Default Re: Java: MouseListener does not register when objects move on screen

    Oh, I apologize. I hadn't considered that. You are correct, this question is also posted in that place, I will inform them there as well.

  4. #4
    kammce's Avatar
    kammce is offline Senior Member
    Join Date
    Dec 2010
    Location
    California
    Posts
    194
    Rep Power
    4

    Default Re: Java: MouseListener does not register when objects move on screen

    Alright, aside from you double posting. This is a lot of information!

    userHit(int mouse_x, int mouse_y) I believe is incorrect. The math you implement in the method is incorrect. I will explain why it does not work but I will give you an example of what will work.

    Java Code:
    if( (mouse_x <= (x_pos + radius*2) && mouse_x >= xpos) && (mouse_y <= (y_pos + radius*2) && mouse_y >= ypos) ) { return true; } else { return false }
    try that out. Sorry it is so long. I like my hitTests all in one line.
    The x and y coords are always the top left corner of the box that is painted into... for the most part unless you altered it.

    You want the area in between. So you just make sure that the mouse is in between both of those values. Same with the mouse_y.

    if i have the x coord of 110. The x_pos is equal to 100. Lets say that the radius is 25 (to make a circle with the diameter 50. So the distance from the x_pos and the edge are 50). your equation will give me this:

    Java Code:
    int dx=Math.abs(x_pos-mouse_x); // dx will equal 10
    if(dx>radius) 
    {
         return false;
    }
    //this will be passed by because the radius is 25 and the dx equals 10. This works as planned.
    if i have the x coord of 145. x_pos and radius are the same as before. your equation will give you this:

    Java Code:
    int dx=Math.abs(x_pos-mouse_x); // dx will equal 45
    if(dx>radius) 
    {
         return false;
    }
    //this will actually execute and return false. Because dx IS greater than the radius 25, but is still within the area of the circle/ball.
    A QUICK FIX would be to multiply the radius number by 2 and you should get the right forumla.
    My API:
    Java Code:
    cat > a.out || cat > main.class

  5. #5
    A Common Hero is offline Member
    Join Date
    Aug 2012
    Posts
    5
    Rep Power
    0

    Default Re: Java: MouseListener does not register when objects move on screen

    I apologize for the information overload; I dumped absolutely all my code here because I am unsure where exactly the problem is. I didn't believe it was the hit detection, though I was unsure. After further testing, I believe my hit detection works. The lack of response when the objects are in motion is a different problem.

    Thank you for the suggestion, however your methodology didn't work consistently. You did, however, make a good suggestion. I had been only testing my hit detection when the balls were motionless, or when they were in motion. What I failed to do was test my hit detection when the balls were motionless, but in several different places other than what my program originally specified as the default. However, upon further testing, I have found my methodology to work. Yours, unfortunately, sometimes detect when the ball is being clicked, and sometimes registers as a miss, even when the cursor is well within the area of the ball. I did modify my checks to multiply the radius by two, but this created an effect where I could click some ways out of the circle and still register a hit, where my previous code was precise. So I do not believe the hit detection is, in fact, an issue.

    I also took this time to test that the speed of my clicking was not an issue, as I might have been clicking faster when the balls were moving in order to try to catch them. However, when tested with the balls motionless, there was no difference in performance whether I clicked faster or not. To put it another way, my score incremented to match the speed of my clicking, I never clicked too fast for the game to register a hit.

    Thank you for the help, however. The simple ideas you gave me for further testing gave me greater insight into the problem, even if no solution was reached.

  6. #6
    kammce's Avatar
    kammce is offline Senior Member
    Join Date
    Dec 2010
    Location
    California
    Posts
    194
    Rep Power
    4

    Default Re: Java: MouseListener does not register when objects move on screen

    What have you specified to be Integer.parseInt(getParameter("speed"));? How fast is this thing going. Does your program have the time to register that the ball has been clicked? Here is another suggestion. Make a method within the class ball and name it update(). Besides calling move() in the Thread you have, call move within that update() method. Have that method make all of the actions that you have the main class doing for the ball. This will make that object more self contained. Also, make the mouseEvent, only set a flag (a boolean) in that object and change some of it's values (maybe an internal mouse_x/y). Then when update() get called again, it will check to see if it was hit, before calling move(). Then you can add any order of things into update() method. Also, make sure to put things in proper order. placing move() before you put in a method to figure out if a mouseClick was right on target, would be cheating the User out of getting a hit. Order matters.

    By making mouseEvent refrain from calling a method in ball and allowing one method that is called in ball.update(), you can keep mouseEvent from interfering with the Thread and causing miss fires in your code.

    This is just a possibility.
    My API:
    Java Code:
    cat > a.out || cat > main.class

  7. #7
    A Common Hero is offline Member
    Join Date
    Aug 2012
    Posts
    5
    Rep Power
    0

    Default Re: Java: MouseListener does not register when objects move on screen

    Quote Originally Posted by kammce View Post
    What have you specified to be Integer.parseInt(getParameter("speed"));?
    I just checked the html file that came with the tutorial, and the value of "speed" there is 15. I really have no idea why this check was used at all if the end result was just that variable speed=15 either way. I'm going to remove that part. So the thread sleeps for fifteen milliseconds. In fact, this is the only place speed is used, and since I don't think I'll be using this code again, and adjusting the speed directly on the line of code it is used seems easier to me, I'm going to remove that variable altogether and just tell the thread to sleep for fifteen milliseconds. For future readers, I am updating the code in the first post to reflect this.

    As for the update suggestion, should I just move the method "update" out of main and into ball, copy and paste the method so there is one in each, or does the update method in ball have nothing to do with the one in main? I figure the one in main is only used for double buffering and won't have any impact on the new method in ball, but I just want to know what you think.

  8. #8
    kammce's Avatar
    kammce is offline Senior Member
    Join Date
    Dec 2010
    Location
    California
    Posts
    194
    Rep Power
    4

    Default Re: Java: MouseListener does not register when objects move on screen

    No, no. keep the update method in your main program. That has nothing to do with the methods within the ball class. Having methods with the same name, but in different classes will not have any effect on the program.
    My API:
    Java Code:
    cat > a.out || cat > main.class

  9. #9
    A Common Hero is offline Member
    Join Date
    Aug 2012
    Posts
    5
    Rep Power
    0

    Default Re: Java: MouseListener does not register when objects move on screen

    Since the original purpose of this project was to learn how java coding works, and I only half feel I have learned anything at all, I am moving on to a different java tutorial at this point and will no longer be checking for answers here.

Similar Threads

  1. Simple First Java program: Basic Contact register
    By ZinoXxX in forum New To Java
    Replies: 8
    Last Post: 03-17-2012, 03:13 PM
  2. Replies: 3
    Last Post: 07-04-2011, 12:50 PM
  3. Replies: 0
    Last Post: 01-05-2011, 09:57 AM
  4. Move from one screen fto other screen
    By jprgmr75 in forum CLDC and MIDP
    Replies: 0
    Last Post: 01-02-2011, 06:32 PM
  5. Move objects with Timer
    By ProGenius in forum New To Java
    Replies: 6
    Last Post: 12-27-2009, 02:52 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •