Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (539)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (603)
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  
  Event handling with custom UI  (Read 1501 times)
0 Members and 1 Guest are viewing this topic.
Offline donmc

Junior Devvie


Projects: 1



« Posted 2008-07-13 20:22:30 »

hello,
I'm working on a 2d game.  I'm new to java.  I have a frame object in the class that contains my entry point.  I have keyboard and mouse listeners attached to that object.  I'm running in fullscreen mode, utilizing a typical double-buffer strategy.  I'm using vanilla java 2d from AWT.  My event handling works fine, but as I begin to flesh out my program i have an issue.

My game has a startup screen, an options screen, and the main game screen.  In addition i'm rolling my own UI.  I won't know ahead of time if a player is clicking on the terrain, or an object on the terrain, or perhaps the titlebar to a window, a button, and so on.

I *could* use the event handlers attached to my frame object and check numerous variables to see what screen the user is currently viewing and decide which events I wish to handle.  This gets a bit harder with the main game screen and mouse clicks as I would have situations where I might have a window atop the terrain and I would want the action associated with the window and not the terrain beneath it.  I know I could do all this in the frame's event handlers, but the code would quickly become a mess with lots of variable tracking, UI tracking, and if statements! 

I'm looking for an elegant solution.  I have googled around, and poured over the threads here and at gamedev.net but I haven't found what i'm hoping exists.  I built a web2.0 app some time ago and as part of it I rolled my own UI system including windows with titlebars, minimzie/close buttons, resizing handlers, etc.  Javascript had a nice clean way of allowing me to attaching any event handler I wanted to a given object and JS was nice enough to check for focus and let my components know when they had an event that needed to be handled.  I'm hoping Java has similar functionality.

I'm looking for advice or ideas for how to proceed.  Again i'm using just AWT at this point and no 3rd party libs. 

thanks,
don
Offline cylab

JGO Ninja


Medals: 55



« Reply #1 - Posted 2008-07-13 22:22:25 »

You can add mouse and keyboard listeners to any Component derived object and only the one that has focus will get the event.

Mathias - I Know What [you] Did Last Summer!
Offline zoto

Senior Devvie


Medals: 4



« Reply #2 - Posted 2008-07-14 18:37:24 »

http://java.sun.com/docs/books/tutorial/uiswing/events/index.html
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline noblemaster

« JGO Spiffy Duke »


Medals: 20
Projects: 10


Age of Conquest makes your day!


« Reply #3 - Posted 2008-07-14 19:31:02 »

How about you create a separate "State" for each screen. You will have a StartupState, OptionState, GameState... Only one state at a time will receive all the mouse/keyboard events.

E.g. the game starts in the StartupState. Once initialized, you move to the MenuState. From the menu state you have several buttons to either proceed to the OptionState or GameState. You will have to separate the logic into the corresponding states. Also look at the MVC pattern. You can keep your code base very clean if you do it right.

That's what I do. I am not sure if that's what you are looking for.  Huh

Offline donmc

Junior Devvie


Projects: 1



« Reply #4 - Posted 2008-07-14 21:21:15 »

You can add mouse and keyboard listeners to any Component derived object and only the one that has focus will get the event.

i'm not entirely sure if i understand, but let me take a stab at it.

Can I create a class that extends the Component class, enable events for my new class, and process the events within the class?  If so do I still need the event handlers attached to my frame which is the anchor for my application?

Here's a code snippet:

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  
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;

public class Button extends Component
{
   public Button()
   {
      enableEvents(AWTEvent.MOUSE_EVENT_MASK);
   }
   
   public void Render(Graphics2D g)
   {
      g.setColor(Color.WHITE);
      g.fillRect(400, 0, 100, 50);
   }
   
   public void processMouseEvent(MouseEvent e)
   {
      System.out.println("button pressed!");
      switch(e.getID())
      {
      case MouseEvent.MOUSE_PRESSED:
         System.out.println("button pressed!");
         break;
     
      }
      super.processMouseEvent(e);
   }  
}


I can create a button object from my main class and call render from there and it shows up fine.  I deleted the handlers from my base class, but the event never triggers if I click on my ghetto button.  Am I moving the right direction or am I missing something fundamental here?

@zoto

those examples appear to be for applications that are using swing components to register listeners on those components.  I'm not using swing GUI elements, i'm rolling my own.  I'm not entirely sure what you were pointing at on that page.

@kingaschi

thx for the advice.  that's what i'm basically doing now and it does work ok for each of the various screens.  My big concern is in my main game screen where I can have multiple elements stacked ontop of one another (a close box on a window over a monster ontop of the terrain).  I want only the top most element (the one with focus) to handle the event.  I could get the mouse coords when a click happens and then run through everything on screen to see what was on the top, but that doesn't seem very clean to me.

thx
Offline decafmatan

Junior Newbie





« Reply #5 - Posted 2008-07-14 22:37:54 »

@donmc:

I've recently been working on a "layout engine" for my latest game that works similarly to the JavaScript/DOM event implementation.
One way you could do it is follow an interface along the lines of:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
interface Event
{
   /* your requirements here */
}

interface Node
{
   void appendNode(Node n);
   Iterable<Node> nodes();
   boolean handlesEvent(Event e);
   void removeNode(Node n);
}


In this instance, you create a few "top-level" nodes (assume DefaultNode is a working implementation of Node, and that RootNode is an already instanced object)

1  
2  
3  
4  
5  
6  
7  
Node optionsLayer = new DefaultNode();
Node startupScreen = new DefaultNode();
Node gameScreen = new DefaultNode();

rootNode.appendNode(optionsLayer);
rootNode.appendNode(startupScreen);
rootNode.appendNode(gameScreen);


Then, for event handling, you start at the root node, and then iterate through all nodes and their children in a "tree-like" format

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
public static boolean fireEvent(Event e)
{
   return fireEvent(rootNode, e);
}

private static boolean fireEvent(Node currentNode, Event e)
{
   for (Node child : currentNode.nodes())
      if (fireEvent(child, e))
         return true;

   return currentNode.handlesEvent(e);
}


The end result would be as such:

1  
2  
3  
4  
5  
6  
7  
Fire Event: Root Node
   Node 0 (Options Layer)
      If Node in Options Layer available to Handle Event, Return True
   Node 1 (Startup Screen)
      ...
   Node 2 (Game Screen)
      ...


I've used a derivative of this technique for a simple Real-Time simulation with thousands of objects, and it worked fine. Depending on your implementation of the Node interface performance will vary - I'd just use a simple ArrayList as the backing until you have a working model that is to slow to work with.
Offline cylab

JGO Ninja


Medals: 55



« Reply #6 - Posted 2008-07-15 08:17:23 »

i'm not entirely sure if i understand, but let me take a stab at it.

Can I create a class that extends the Component class, enable events for my new class, and process the events within the class?  If so do I still need the event handlers attached to my frame which is the anchor for my application?

I can create a button object from my main class and call render from there and it shows up fine.  I deleted the handlers from my base class, but the event never triggers if I click on my ghetto button.  Am I moving the right direction or am I missing something fundamental here?


You would have to add the component to a swing container. If you want to layout your components for yourself, you have to use a null or absolute layout manager and update the components Bounds property. Also instead of your Render method you have to override paintComponent. This should make your game components swing compatible and you can utilize swings event processing mechanism.

But I don't know, how nicely swing component hierarchies play with active rendering, maybe someone with more 2D game knowlege here can elababorate this?

Mathias - I Know What [you] Did Last Summer!
Offline donmc

Junior Devvie


Projects: 1



« Reply #7 - Posted 2008-07-19 15:53:52 »

Thanks for all the replies.  After spending a couple days googling around I still wasn't able to find what I was looking for.  Thus I went the same route as decaf and just wrote my own event handler.  I was worried at first that there would be performance issues, but I was pleasantly surprised by the snappy response to my input events.

cheers,
don
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.

rwatson462 (30 views)
2014-12-15 09:26:44

Mr.CodeIt (23 views)
2014-12-14 19:50:38

BurntPizza (50 views)
2014-12-09 22:41:13

BurntPizza (84 views)
2014-12-08 04:46:31

JscottyBieshaar (45 views)
2014-12-05 12:39:02

SHC (59 views)
2014-12-03 16:27:13

CopyableCougar4 (57 views)
2014-11-29 21:32:03

toopeicgaming1999 (123 views)
2014-11-26 15:22:04

toopeicgaming1999 (114 views)
2014-11-26 15:20:36

toopeicgaming1999 (32 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

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
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!