Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (522)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (590)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  [SOLVED]Mouse Controller code  (Read 1257 times)
0 Members and 1 Guest are viewing this topic.
Offline UDKO2

Junior Newbie





« Posted 2013-11-14 16:16:16 »

I am doing a game for the university and I would like to ask for help as I can't create a good mouse controller.

I would like to ask for that code as mine is working properly. Here's my code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
   private void setMouseListeners() {
      addMouseListener(new MouseAdapter() {
         boolean mousePressed = false;
         Thread t = null;
          public void mousePressed(MouseEvent me) {
             if ( t == null ){
                t = new Thread(new Runnable() {
                      @Override
                      public void run() {
                     
                         mousePressed = true;
                         
                          while (mousePressed) {
                             
                              try {
                                 Thread.sleep(TIME_PER_SHOT);
                                 if (mousePressed) {shootDefender();}
                              } catch (InterruptedException e) {}
                           
                          }
                      }
                  });
                  t.start();
             }
          }
          public void mouseClicked (MouseEvent me){
            if ( !mousePressed )
               shootDefender();
         }
          public void mouseReleased(MouseEvent me){
             mousePressed = false;
             t = null;
          }  
      });
     
      addMouseMotionListener(new MouseMotionAdapter(){
         public void mouseDragged(MouseEvent me) {
            mousePosition = me.getPoint();
         }
         
         public void mouseMoved(MouseEvent me) {
            mousePosition = me.getPoint();
         }
      });
   }


My intention is this to work like in this Geometry Wars Remake from this Basic Game tutorial. Unfortunately, there is no mouse related code.

If someone could fix it I would really appreciate it. Actually, it works, but if you click quickly twice and keep pressing it shootDefender() runs twice and isn't waiting the TIME_PER_SHOOT value.
Online KevinWorkman

JGO Kernel


Medals: 99
Projects: 11
Exp: 12 years


klaatu barada nikto


« Reply #1 - Posted 2013-11-14 16:46:10 »

I gather that you're trying to put a time delay in between shots fired. Why are you firing off extra threads just for that? Can't you just check the last time a shot was fired and only fire another shot if enough time has elapsed?

Static Void Games - Play indie games, learn game programming, upload your own games!
Offline lcass
« Reply #2 - Posted 2013-11-14 17:25:44 »

I would suggest holding a fired boolean then when the mouse is clicked it sets it to true. you then start a timer with the cooldown length on it (with in a tick function) when this timer reaches a certain value it resets and turns off along with setting fired to false.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline CodeHead

JGO Knight


Medals: 41


From rags to riches...to rags.


« Reply #3 - Posted 2013-11-14 18:20:26 »

If someone could fix it I would really appreciate it. Actually, it works, but if you click quickly twice and keep pressing it shootDefender() runs twice and isn't waiting the TIME_PER_SHOOT value.

It does that because that's the way you've written it. Since you only want the firing to occur once for a click event, grab the click count from the event object and only fire if click count is less than 2 and the shot cool down time has passed. There are better ways to approach the situation that would make the code easier, but that's the reason the existing code is exhibiting the behavior that you describe.

As stated by lcass and Kevin, the thread is unneeded (and most likely detrimental because it's causing a lot of extra dead threads for the GC to tidy up). Consider that a mouse clicked event still issues a mouse button press and release event so essentially you get two shots for each click (one for the initial press followed by one for the click). The only reason you're seeing 2 shots occur on a double click and not 4 is because your timing thread sleeps before issuing the shootDefender() call and checks to see if the mouse is still pressed when it wakes up. In this case, I'd say the cool down time is greater than the time it takes for the average user to press and release a mouse button. Move your Thread.sleep() call after your shootDefender() call, and the problem should become more obvious.

The best advice would be to avoid using threads unless they're absolutely needed. When used incorrectly, they inject a lot of complications into scenarios that can otherwise be solved in a more straightforward way. Smiley

Arthur: Are all men from the future loud-mouthed braggarts?
Ash: Nope. Just me baby...Just me.
Offline UDKO2

Junior Newbie





« Reply #4 - Posted 2013-11-15 13:31:06 »

Thank you very much, I didn't even think that solution. I've updated my code and it works nearly perfect, the code is below.

I just have one problem. When I keep pressing the mouse and I move it, it works well, but if it stays there, it doesn't shoot. I thought that mousePressed method would fix it but it doesn't. Any clue ?

Thank you in advance.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
private class MouseController{
     
      private MouseMotion mouseMotion;
      private Mouse mouse;
     
      public MouseController(){
         mouseMotion = new MouseMotion();
         mouse = new Mouse();
      }
     
      private class MouseMotion extends MouseMotionAdapter{
         public void mouseDragged(MouseEvent me) {
            mousePosition = me.getPoint();
            manageDefenderShoot();
         }
         public void mouseMoved(MouseEvent me) {
            mousePosition = me.getPoint();
         }
      }
     
      private class Mouse extends MouseAdapter{
         public void mousePressed (MouseEvent me){
            manageDefenderShoot();
         }
          public void mouseClicked (MouseEvent me){
            manageDefenderShoot();
         }
      }
     
      public MouseMotionAdapter getMouseMotionAdapter(){
         return mouseMotion;
      }
     
      public MouseAdapter getMouseAdapter(){
         return mouse;
      }
   }
   private void setMouseRelatedListeners() {
      MouseController mc = new MouseController();
     
      addMouseListener(mc.getMouseAdapter());
      addMouseMotionListener(mc.getMouseMotionAdapter());
     
   }

Offline CodeHead

JGO Knight


Medals: 41


From rags to riches...to rags.


« Reply #5 - Posted 2013-11-15 16:55:08 »

I just have one problem. When I keep pressing the mouse and I move it, it works well, but if it stays there, it doesn't shoot. I thought that mousePressed method would fix it but it doesn't. Any clue ?

If you look at your code, you'll notice that you call "manageDefenderShoot()" exactly once for each event notification. In the case of mouse dragged events, the application sends a notification each time the mouse position is updated, therefore whenever you drag the mouse, you're generating another call to your fire shot function. In the case of a mouse pressed event, the application only sends the notification once, so logically your fire shot function is only called a single time.

In order to achieve the desired behavior, you'll need to do a little refactoring. First, move the "manageDefenderShoot()" calls out of your event listeners and put it into your main game loop so it gets called once per screen update. You'll quickly notice that this results in a constant stream of shots being fired which isn't the desired result, so we'll have to do a couple more changes.

Add two variables that are visible to your listener and your main game loop. Make the first one a boolean, give it a name like "DefenderShooting" (or whatever makes sense to you), and initialize it to false. This variable will be used to determine if we actually need to consider generating a shot on the current frame or not. Now add a long variable, call it something like "LastShotTime" and initialize it to 0. This will hold the time of the last shot (in nanoseconds) and will be used to determine if enough time has passed for us to generate a new one. Now to tie it all together.

Each time your game loop cycles through, you'll need to check the "DefenderShooting" variable and see if it's set to true. If it is, subtract the value of "LastShotTime" from System.nanoTime() and use the result to determine how much time has passed since the previous shot. If it's greater than the shot "cool down" time, update the LastShotTime to System.nanoTime(), and call your manageDefenderShoot() function. If the DefenderShooting variable is false or the "cool down" time hasn't elapsed yet, just skip calling the manageDefenderShoot() function.

Now all that's left is to tweak the listeners. Your mouse pressed listener should set the "DefenderShooting" variable to true as well as setting the "LastShotTime" variable back to 0, and the mouse released listener should set "DefenderShooting" to false. This will cause all "held shots" to be subjected to the cool down period while still allowing for quick firing via rapid mouse clicking. You can clear out all shooting related calls from the mouse dragged and mouse clicked listeners.

Pseudocode:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
public class MyGame {
    // Keep track of whether the player is shooting or not.
    private boolean DefenderShooting = false;
    // When was the last shot fired?
    private long LastShotTime = 0L;
    // Convenience variable to define cool down time as .25 seconds between shots
    private long CoolDownTime = 250000L;

    /*
    * Snip
    */


    // Called once every iteration through the game loop.
    private void updateGameState() {
        /*
        * Snip
        */

       
        // Make sure all the criteria have been met before allowing the player to take the shot.
        if(DefenderShooting && (System.nanoTime() - LastShotTime) >= CoolDownTime) {
            // Update the last shot fired time.
            LastShotTime = System.nanoTime();
            // Give them baddies a taste of your vengeance!!!
            manageDefenderShoot();
        }
       
        /*
         * Snip
         */

    }

    private class MouseController{    
        /*
        * Snip
        */


        private class Mouse extends MouseAdapter{
            public void mousePressed (MouseEvent me){
                // Tell the game we're shooting.
                DefenderShooting = true;
                // Clear out the cooldown time so that the first shot
                // happens immediately.
                LastShotTime = 0L;
            }
            public void mouseReleased (MouseEvent me){
                // Tell the game we're not shooting anymore.
                DefenderShooting = false;
            }
        }

        /*
        * Snip
        */

    }
}


Hope this helps. Smiley

Arthur: Are all men from the future loud-mouthed braggarts?
Ash: Nope. Just me baby...Just me.
Offline UDKO2

Junior Newbie





« Reply #6 - Posted 2013-11-16 13:28:03 »

Oh yeah ! It works perfectly now, thank you !

However, I don't find my game very addictive so I post it here so that you can comment on it.

Actually I cannot make the Applet run... I don't know why, any ideas ? Game link here : click me
Offline CodeHead

JGO Knight


Medals: 41


From rags to riches...to rags.


« Reply #7 - Posted 2013-11-16 18:44:27 »

No problem. Noticed I had the "mouseReleased" function named "mouseClicked" by mistake in my last post (edited now), but it sounds like you got around that. Wink What problems are you having getting it to run? The jar file ran with no problems for me.

As for how to improve the game play, I'll offer a few suggestions:

  • Make the size of the bullets smaller making the enemies harder to hit.
  • Limit the firing rate to 1 active bullet on the screen at a time which makes accuracy more important.
  • Vary the size of the enemies.
  • Vary the speed of the enemies.
  • Have some enemies take more hits to kill than others.
  • Add some sounds.
  • Add some explosion animations.
  • Have some power-ups mixed in with the enemies; you only collect them if they make it all the way down the field to you without being hit by a shot.

Honestly, there's only so much you can do with a game of this sort to make it compelling; no offense intended. The key to make it, or any game, as good as possible is going to be lots of polish. It's all part of the learning experience. Cool

Arthur: Are all men from the future loud-mouthed braggarts?
Ash: Nope. Just me baby...Just me.
Offline UDKO2

Junior Newbie





« Reply #8 - Posted 2013-11-16 23:49:28 »

When I said it couldn't make it run, I was talking about the Applet. I tried to change the code : implement JApplet, change main() to init() and so on.
But I haven't been able to post it here, so I wrote the URL to the uploaded file  Grin

I have written down all your suggestions and I am starting to apply them right now. Let's see what I am capable of  Cheesy

However, I have just realised that if I make those changes I would be so close to a Geometry War Remake, wouldn't I ?

Thanks and see you !
Offline CodeHead

JGO Knight


Medals: 41


From rags to riches...to rags.


« Reply #9 - Posted 2013-11-17 01:04:51 »

Hmmm, Oddly enough, I don't think I've ever really played Geometry Wars. Most of the suggestions I posted were based on things that seemed to work for the early arcade and home PC games. In the end, it's your creation, so go with what feels the best to you. Smiley

Looking forward to see your future developments. Cool

Arthur: Are all men from the future loud-mouthed braggarts?
Ash: Nope. Just me baby...Just me.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

trollwarrior1 (29 views)
2014-11-22 12:13:56

xFryIx (71 views)
2014-11-13 12:34:49

digdugdiggy (50 views)
2014-11-12 21:11:50

digdugdiggy (44 views)
2014-11-12 21:10:15

digdugdiggy (38 views)
2014-11-12 21:09:33

kovacsa (62 views)
2014-11-07 19:57:14

TehJavaDev (67 views)
2014-11-03 22:04:50

BurntPizza (64 views)
2014-11-03 18:54:52

moogie (80 views)
2014-11-03 06:22:04

CopyableCougar4 (80 views)
2014-11-01 23:36:41
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!