aspose file tools*
The moose likes Game Development and the fly likes Beginner question - Key events Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » Game Development
Bookmark "Beginner question - Key events" Watch "Beginner question - Key events" New topic
Author

Beginner question - Key events

Hans vogn
Ranch Hand

Joined: Feb 04, 2009
Posts: 46
Hi

I've just started to try programming games in Java, and at this moment I'm actually just trying to figure out how it all works.

So as a start i have chosen to try to make a very simple "game" where you just move a ball around with AWSD.

looks like this so far:



So, i would like to know, how i can make the ball react when i press buttons on my keyboard.

(I'm sorry if the question is too dumb or simple, or if it's posted the wrong place)

Thanks in advance.
Florin Florentin
Ranch Hand

Joined: May 12, 2009
Posts: 43
you have to extend the KeyListener inteface in the class game, implement the specifics methods and add to the ball object the keyListener.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Having your Ball class extend JPanel may work in this case, but I think you will run into problems as soon as you want to have more than one ball, or if you want other types of moving objects.

Consider having a separate ball class that extends nothing, and has instance variables such as x, y, and diameter (width & height).

See the thread about Multiplayer Pong for some more details about what yu are doing.

good luck, and have fun with it
Hans vogn
Ranch Hand

Joined: Feb 04, 2009
Posts: 46
Thanks guys, i'll try to experiment a little with it.

Edit:

I'm sorry if i'm all wrong, but souldn't it work if I change the game class to this?:

pete stein
Bartender

Joined: Feb 23, 2007
Posts: 1561
A few recommendations:

1) I agree, don't have ball subclass JPanel as it logically is not going to function as a panel. You can still give it a paint method and then have it call this paint method in the containing JPanel's paintComponent method override.
2) Don't add key listeners to Ball objects. Instead you'll want to use key bindings attached to the JPanel that holds the ball(s).
3) Don't give up good OOP technique here by making your ball fields public and letting other classes directly manipulate them. Instead give ball public methods that other objects can call.
4) Look at the Swing Timer class as it may help you with animations that you know you'll want to be doing.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
I agree more or less with what Pete says is the best way, but I also think there is value in trying to get your way as shown here to work also.

KeyBindings may be best, but KeyListeners should also work, and you will learn about KeyListeners. Eventually you will have different versions of the game that use each method.

Get something working, anything, then you can start thinking about what is best. IMO there is nothing wrong with trying to make your method work. Then looking for ways to improve your design. If you look for perfection from the get go, there is too much to learn at once.

So what happens with your design as shown? I'm thinking there is more code than you have shown here? Does it compile and run? Does it respond to key presses the way you want?
Hans vogn
Ranch Hand

Joined: Feb 04, 2009
Posts: 46
Thanks for the help, I really appreciate it

And I finally got something that worked, and it respond to the keyboard just as it should.

It looks like this now: http://pastebin.com/m17520f07
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Good stuff Hans, looks like you are well on the way. I guess the next step is to expand your program to include more than one ball, or maybe you will want your keys to move a paddle while your ball moves itself, as in a pong game. You will probably also want to incorporate some collision detection, to deal with situations where the ball hits the edge of the application, or collides with another ball, or the paddle. I have a feeling you might have to make some fundamental design changes to what you have now, in order to make all this new stuff work, but you'll find that out soon enough. Anyways, this is a good start.

p.s. there is usually more than one way to accomplish the same end result. I have found one of the best ways to learn is to explore different ways of achieving the same end result, then deciding for yourself which method makes it easier to expand the functionality of your program. good luck with it.
Hans vogn
Ranch Hand

Joined: Feb 04, 2009
Posts: 46
Actually, it's funny that you mention more balls and coalision detection, because, i've just finished a VERY simple water simulation (I guesse it it is )

It looks like this:



600 small blue balls are spawned, and as they hit the box or the edge of the frame, they reflect. When they reach the bottom if the frame, they are reset.

The coalision detection is very bad though, if the balls comes with too much speed they will go through the box, and they often have to go about 5 pixels into the box before they reflect.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
cool. Collision detection can be tricky, the problems you've described is similar to problems I've had to deal with. One problem I've had to resolve is multiple collisions, where a second collision is detected before the first collision has a chance to resolve. So the colliding objects end up doing some weird wobbly dance.

I have no idea how you designed this water simulation, but the one thing that comes to mind is that if you have a well designed ball class, then you can probably use it interchangeably in both examples.
Hans vogn
Ranch Hand

Joined: Feb 04, 2009
Posts: 46
I think my design could be better. What i do is making the ball class with a getter method for y and x locations, and then a panel with all the components that check for coalition.

Is there a more effektive way?
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Hans vogn wrote:I think my design could be better. What i do is making the ball class with a getter method for y and x locations, and then a panel with all the components that check for coalition.

Is there a more effektive way?


As far as I can see, in the first example your Ball class extends JPanel, but no use is made of this fact. I also don't see where you make use of the paintBall routine.

Now that I think about it, it's not clear that your Ball class is being used at all, it looks like you instantiate a ball object but never use it. Are you sure your program as shown on pastebin doesn't just move a square of size 50 around?
Hans vogn
Ranch Hand

Joined: Feb 04, 2009
Posts: 46
It does, I changed it to a square.

And I see, that program des not contain the coalition detection i use. An example could be the water simulation:

http://pastebin.com/m6cbcd05d
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Hans vogn wrote:It does, I changed it to a square.

And I see, that program des not contain the coalition detection i use. An example could be the water simulation:

http://pastebin.com/m6cbcd05d


By changing from g.fillOval(x, y, 50, 50); to g.fillRect(x, y, 50, 50); in your paintComponent method? If that's the case, my point still stands that even though you were using fillOval before, no use is being made of your ball class. See what I mean?
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
OK start by doing this.

1. remove extends JPanel and paintBall from your Ball class so that is an empty class. recompile and run and you will see it makes no difference.

2. add instance variables int x & y to your Ball class, recompile and run. Still no difference. These variables are not yet being used.

3. in you Panel constructor, change Ball b = new Ball(); to b = new Ball(); recompile and run. can you see why this works still? note that your Ball class at the moment is empty, so nothing really is being used there.

4. remove int x = 50; int y = 50; from the beginning of your Panel class. If you try to recompile now, you will have problems.

5. in your Panel constructor, after b = new Ball(), add the lines b.x = 50; and b.y = 50;

6. in your key listeners, and your paintComponent method, change every occurrence of x and y to b.x and b.y. now you are using your Ball class.

if you recompile now, you should have exactly the same thing. Now is the time to stop and think about why this is the same result, but a much better design. It's not quite perfect, but it's better than what you had. Note that even though program is using x & y from the b object of the Ball class, it is not a ball, it is a rectangle still. If you change your fill methed to fillOval in the paintComponent method of your Panel class, then you have a ball.

Once you are clear about what has been done so far, then we can talk about using a Ball constructor, and maybe a move() method in your ball class so that your key listeners do not access the ball instance variables x & y directly.
Hans vogn
Ranch Hand

Joined: Feb 04, 2009
Posts: 46
I do see the point, but isn't the most of that done with my water thing?
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Hans vogn wrote:I do see the point, but isn't the most of that done with my water thing?


OK, I was responding to the question about the Ball example code, not the Water simulation code. Yeah, I didn't scrutinize the water simulation code closely, but at first glance it looks a lot more sophisticated. I wan't offer an opinion on that one though.

But I think a redesigned Ball example, based on what I suggested, would be a good starting point to more sophisticated programs such as pong.

Also, a properly design Ball or Pong application should probably use animation threads. Which you will probably want to look into sooner or later.

Hans vogn
Ranch Hand

Joined: Feb 04, 2009
Posts: 46
I don't know how close it is to what you was thinking, but I've tryed to make a pong game.



It uses Thread (like Thread.sleep(1)) and the ball moves by itself and reflects, the computer paddle trys to follow the balls y location when the ball is on the left side of the screen. The userpaddle is moved with the arrowkeys. The Panel class implements KeyListener, and send the keyevent to the userpaddles move method as an argument.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Hans vogn wrote:I don't know how close it is to what you was thinking, but I've tryed to make a pong game.



It uses Thread (like Thread.sleep(1)) and the ball moves by itself and reflects, the computer paddle trys to follow the balls y location when the ball is on the left side of the screen. The userpaddle is moved with the arrowkeys. The Panel class implements KeyListener, and send the keyevent to the userpaddles move method as an argument.


If it works, then I'd say you've progressed quite a ways from your original Ball example.

Question. Based on your current design, are you able to use keys to control more than one object? for example, are you able to have two players each controlling their own paddle? It seems to me that being able to control more than one object with keystrokes would indicate you have overcome some significant obstacles.

Hans vogn
Ranch Hand

Joined: Feb 04, 2009
Posts: 46
No, those obstacles are unfortuanly still in my way.

I can only use a single buttom at a time, and when i hold it down, the paddle needs to "accelerate" before reaching the wanted speed.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
The thread in this Games forum about multiplayer pong deals with the issue of players controlling one or more paddle.
Hans vogn
Ranch Hand

Joined: Feb 04, 2009
Posts: 46
Thanks foe all your help
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Beginner question - Key events