Java Listeners

Started by
5 comments, last by Glass_Knife 9 years, 1 month ago

I have been looking at a lot of peoples code lately. Seeing how they handle their player input and things of the sort. One thing that I keep coming across and dislike is when people use one or two classes to handle all the input for the game. Doesn't it seem better if the input for the player is handled in the Player class? And if you have several different interfaces, I wouldn't want to handle all of the mouse input in one single class for every other interface. It just makes more sense, to me anyway, if the input is handled in it's own separate "interface" class or something of the sort. However, something that starts to become an issue with this approach, is that for every interface that is displayed and for every player on the screen there has to be another KeyListener or MouseMotionListener added to the game. Does this become inefficient? Is this the reason people use one or two classes to handle all the keyboard and mouse input? I am just curious as to what would be the "best" way of doing it. I know that prettier isn't always better, but it is just something that has been bothering me for quite a while. Thanks for anyone who could shed some light on the subject.

Advertisement

I don't really understand your questions, to be honest.


for every player on the screen there has to be another KeyListener

Are you talking about a multiplayer game ? About a server side implementation ?


MouseMotionListener added to the game

You have always two ways of handling events, either pushing (send event to listener) or pulling (ask if a new event occurs or a certain state changed). The listener concept (or a BUS system) are pushing systems. If you have very large amount of potentially listeners, which don't need to listen to all events all the time, it could be more effeciently to use a pulling system (only the component which needs the data gets it).

A possible setup would be


// pushing system
interface InputListener {
  void newEvent(...);
}
class InputManager
{
  void addListener( InputListener);
  void removeListener(InputListener);
}

// pulling system
class InputManager
{
   MouseCoord getCurrentMousePosition();
}

For input handling both systems seems valid and using a listener system in java isn't unheart of. Therefor I can't see a reason to not using a listener based input handler, which would only use one class and one interface, thougth multiple listener instances. But you should not have a lot input listener at all, even in a multiplayer game (where you would have network listeners or similar interfaces).

It s actually not necessary to send input asynchronously at all (at least in the described situation). It is absolutely fine to collect input inside the input sub-system to have some kind of short input history, and to let higher level sub-systems (like player control) investigate the input queue to look for input situations that match their needs. This is because during the execution of the game loop the various sub-systems are updated anyway, and they usually can not do something meaningful with input until their are updated.

EDIT: Ah, Ashaman73 already mentioned this with "input pulling".

I don't really understand your questions, to be honest.


for every player on the screen there has to be another KeyListener

Are you talking about a multiplayer game ? About a server side implementation ?


MouseMotionListener added to the game

You have always two ways of handling events, either pushing (send event to listener) or pulling (ask if a new event occurs or a certain state changed). The listener concept (or a BUS system) are pushing systems. If you have very large amount of potentially listeners, which don't need to listen to all events all the time, it could be more effeciently to use a pulling system (only the component which needs the data gets it).

A possible setup would be


// pushing system
interface InputListener {
  void newEvent(...);
}
class InputManager
{
  void addListener( InputListener);
  void removeListener(InputListener);
}

// pulling system
class InputManager
{
   MouseCoord getCurrentMousePosition();
}

For input handling both systems seems valid and using a listener system in java isn't unheart of. Therefor I can't see a reason to not using a listener based input handler, which would only use one class and one interface, thougth multiple listener instances. But you should not have a lot input listener at all, even in a multiplayer game (where you would have network listeners or similar interfaces).

I guess what I am asking is... If I were ever going to display more than one interface on the players screen at one time. I would have to add a new MouseListener to handle every interface being displayed.That is if I wanted to have the code for each interface in its own class. Or I could handle every button of every interface in one class and only add one MouseListener. So what would be the best way to keep the code for each interface separated and not have to deal with multiple MouseListeners. I hope that makes sense, it's sort of hard for me to explain.


I guess what I am asking is... If I were ever going to display more than one interface on the players screen at one time. I would have to add a new MouseListener to handle every interface being displayed.That is if I wanted to have the code for each interface in its own class. Or I could handle every button of every interface in one class and only add one MouseListener. So what would be the best way to keep the code for each interface separated and not have to deal with multiple MouseListeners. I hope that makes sense, it's sort of hard for me to explain.

The reason this seems like the right solution is because that's how Java handles mouse/keyboard input for a Swing or JavaFX GUI code. If you are using a JPanel for each player then this is an option. If you were coding in DirectX or OpenGL, there would only ever be one mouse. You don't have the concept of a mouse listener.

Whenever I see someone ask "What's the best way to [insert thing here]" alarm bells go off. How is your game structured? Are you using GUI components and callbacks, or are you doing a game loop with active rendering?

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532


I guess what I am asking is... If I were ever going to display more than one interface on the players screen at one time. I would have to add a new MouseListener to handle every interface being displayed.That is if I wanted to have the code for each interface in its own class. Or I could handle every button of every interface in one class and only add one MouseListener. So what would be the best way to keep the code for each interface separated and not have to deal with multiple MouseListeners. I hope that makes sense, it's sort of hard for me to explain.

The reason this seems like the right solution is because that's how Java handles mouse/keyboard input for a Swing or JavaFX GUI code. If you are using a JPanel for each player then this is an option. If you were coding in DirectX or OpenGL, there would only ever be one mouse. You don't have the concept of a mouse listener.

Whenever I see someone ask "What's the best way to [insert thing here]" alarm bells go off. How is your game structured? Are you using GUI components and callbacks, or are you doing a game loop with active rendering?

You are correct I guess I don't have a proper concept on what a mouse listener really easy. But I have come up with something that I want to try an do and I would love your opinion on it. I am currently not using GUI components and I am using a game loop and active rendering.

Basically I am going to have one class called ComponentHandler and it's job is to handle the input of all GUI Components.


package com.sage.rpg.gui;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;

import com.sage.rpg.Game;

public class ComponentHandler extends MouseAdapter {
	
	public static List<Component> components;
	
	public ComponentHandler(final Game game) {
		
		game.addMouseListener(this);
		game.addMouseMotionListener(this);
	}
	
	public void mouseMoved(MouseEvent e) {
		
		int x = e.getX();
		int y = e.getY();
		int componentId = -1;
		
		for (Component c : components) {
			
			if (c.contains(x, y))
				componentId = c.getId();
		}
		
		if (componentId != -1) { 
			
			switch(componentId) {
			
			case 0:
				// handle input
				break;
			}
		}
	}
	
	public void mousePressed(MouseEvent e) {
		
		int x = e.getX();
		int y = e.getY();
		int componentId = -1;
		
		for (Component c : components) {
			
			if (c.contains(x, y))
				componentId = c.getId();
		}
		
		if (componentId != -1) { 
			
			switch(componentId) {
			
			case 0:
				// handle input
				break;
			}
		}
	}
}

I have some rather strong opinions about Java game programming, just to warn you.

I would start with these two tutorials:

http://www.gamedev.net/page/resources/_/technical/general-programming/java-games-active-rendering-r2418

http://www.gamedev.net/page/resources/_/technical/general-programming/java-games-keyboard-and-mouse-r2439

You can also check out the first two chapters of source code from my book. That may give you some ideas:

https://github.com/TimothyWrightSoftware/Fundamental-2D-Game-Programming-With-Java

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

This topic is closed to new replies.

Advertisement