Jump to content

How to implement Keylistener, Renderer to jpanel and Main class all different classes

- - - - -

  • Please log in to reply
12 replies to this topic

#1
Pow

Pow

    Newbie

  • Members
  • PipPip
  • 11 posts
How to implement Keylistener, Renderer to jpanel, game logic processor class and Main class all as different classes?

I want to make simple arcade game using java but i'm pretty new to it, so i'm not sure how to do it right.

Can you please help me figure out how I can create these 4 classes to be accesible to each other but still remain separate.

Why I dont want all in one class? Because it will become cramped once I really start to implement all the game stuff...

#2
Vladimir

Vladimir

    Learning Programmer

  • Members
  • PipPipPip
  • 79 posts
Can you add some details? Generally you can add setter and pass instance of one class to another like this:

A a = new A();
B b = new B();
b.setA(a);


#3
Pow

Pow

    Newbie

  • Members
  • PipPip
  • 11 posts
something like this

import javax.swing.JFrame;

public class Application {
	//Input input; //input class, like keylistener
	JFrame window;
	//GameLogic game; //game logic class, all game stuff will be handled there
	//Renderer render;  //renderer of game graphics
	
	boolean runapp;
	
	public Application() {
		window = new JFrame("Simple Arcade Game");
		window.setSize(640, 480);
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		window.setVisible(true);
	}
	
	public void mainLoop() {
		while(this.runapp) {
			//main loop here
			/*
			 * here's somthing like
			 * 1. get input
			 * 2. process game
			 * 3. draw to a buffer
			 * 4. draw to a screen
			 * 5. wait a little
			 * */
		}
	}

	public static void main(String[] args) {
		Application app = new Application();
		app.mainLoop();
	}

}


#4
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
I think you will learn A LOT from this tutorial: http://forum.codecal...-detection.html :)

#5
Pow

Pow

    Newbie

  • Members
  • PipPip
  • 11 posts
oxano, thank you but I already read this tutorial :) It helped me alot, but still I dont like the way everything is implemented there because everything (keylistener, renderer, game logic) stuffed inside just one class...

#6
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
Okay then:
Keylistener class

public class MyKeyListener{

    public void keyTyped(KeyEvent e) { }


    public void keyPressed(KeyEvent e) {

        //code  

    }


    public void keyReleased(KeyEvent e){

       //code

    }

}


renderer class

public class MyGui extends JFrame{

     public myGui(){

        super("frametitle");

        addKeyListener(new MyKeyListener() );

    }


   @override

   public void paint(Graphics g){

     //double buffering & everything.

  }

}


game logic class ... Well just a class with a bunch of normal methods methods. No mainloop here.

You'll most likely want another class that controls the loopS.

public class Controller(){

  private GameLogic logic;

  private MyGui gui;


  public Controller(){

    logic = new GameLogic();

    gui = new MyGui(this);

   

    new Thread(new Runnable(){

       public void run(){

          while(true){

             gui.updateData(logic.getGuiData);

             gui.repaint(); //(gui's paint method should have double buffering as in tutorial))

          }

       }

    }).start();


   new Thread(new Runnable(){

       public void run(){

          while(true){             

             logic.update(gui.getUserInput());

             Thread.sleep(50); // i've just put a number there also needs a try catch.

          }

       }

    });

  }

}


So you have
  • Keylistener
  • Gui
  • Logic
  • Controller which creates:
  • 1 quick thread, constantly repainting gui for high FPS
  • 1 slower thread (to reduce cpu stress) for updating the logic
Instead of threads you can use timer and timertasks aswell.

(I have no hands on experience with this 2 thread system ;) )

#7
Pow

Pow

    Newbie

  • Members
  • PipPip
  • 11 posts
oxano, thank you.

but before implementing multithread i tried to make something like this


package total.bs.game.lib;


import javax.swing.JFrame;


public class Application {

	JFrame window;

	Input input; // input class, like KeyListener

	GameLogic gamelogic; // game logic class, all game stuff will be handled there

	Renderer renderer; // renderer of game graphics


	boolean runapp;


	public Application() {

		window = new JFrame(CONST.APPLICATIONTITLE);

		window.setSize(CONST.SCREENWIDTH, CONST.SCREENHEIGHT);

		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// setting subclasses

		input = new Input(this);

		gamelogic = new GameLogic(this);

		renderer = new Renderer(this);

		// ...

		window.setIgnoreRepaint(true);

		window.addKeyListener(input);

		window.setFocusable(true);

		window.setVisible(true);

	}


	public void mainLoop() {

		// application main loop

		while (this.runapp) {

			try {

				// 1. inputs are handled automatically and dont need to be called here

				// ---

				// 2. process game logic

				gamelogic.process();

				// 3. draw to a buffer

				renderer.render();

				// 4. draw to a screen

				renderer.display();

				// 5. wait a little

				try {

					Thread.sleep(10);

				} catch (InterruptedException e) {

					e.printStackTrace();

				}

			} catch (Exception e) {

				e.printStackTrace();

			}

		}

	}


	public static void main(String[] args) {

		Application app = new Application();

		app.mainLoop();

	}


}



package total.bs.game.lib;


public class GameLogic {

	//link to main class

	Application application;

	

	//constructor

	public GameLogic(Application application) {

		//this allows to call main class subclasses inside this class

		this.application = application;

	}

	

	//processes game

	public void process() {

		

	}


}



package total.bs.game.lib;


import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;


public class Input implements KeyListener {

	//link to main class

	Application application;

	// keys being pressed

	boolean l, r, u, d;


	//constructor

	public Input(Application application) {

		//this allows to call main class subclasses inside this class

		this.application = application;

	}


	public void keyTyped(KeyEvent e) {

	}


	public void keyPressed(KeyEvent e) {

		if (e.getKeyCode() == KeyEvent.VK_UP)

			u = true;

		if (e.getKeyCode() == KeyEvent.VK_DOWN)

			d = true;

		if (e.getKeyCode() == KeyEvent.VK_LEFT)

			l = true;

		if (e.getKeyCode() == KeyEvent.VK_RIGHT)

			r = true;

	}


	public void keyReleased(KeyEvent e) {

		if (e.getKeyCode() == KeyEvent.VK_UP)

			u = false;

		if (e.getKeyCode() == KeyEvent.VK_DOWN)

			d = false;

		if (e.getKeyCode() == KeyEvent.VK_LEFT)

			l = false;

		if (e.getKeyCode() == KeyEvent.VK_RIGHT)

			r = false;

	}


}



package total.bs.game.lib;


import java.awt.Color;

import java.awt.Graphics2D;

import java.awt.Toolkit;

import java.awt.image.BufferedImage;


public class Renderer {

	//link to main class

	Application application;

	//graphical buffer to draw image

	BufferedImage buffer;

	

	//constructor

	public Renderer(Application application) {

		//this allows to call main class subclasses inside this class

		this.application = application;

		//buffer var

		buffer = new BufferedImage(CONST.SCREENWIDTH, CONST.SCREENHEIGHT, BufferedImage.TYPE_INT_RGB);

	}

	

	//renders everything in buffer

	public void render() {

		Graphics2D b = buffer.createGraphics();

		b.setColor(Color.black);

		b.fillRect(0, 0, CONST.SCREENWIDTH-1, CONST.SCREENHEIGHT-1);

		

		b.setColor(Color.red);

		b.fillRect(25, 25, 25, 25);

		

		b.setColor(Color.white);

		b.drawString("This is text", 100, 100);

		b.dispose();

	}

	

	//displays buffer on the screen

	public void display() {

		Graphics2D g = (Graphics2D) application.window.getGraphics();

		g.drawImage(buffer, 0, 0, application.window);

		Toolkit.getDefaultToolkit().sync();

		g.dispose();

	}


}



package total.bs.game.lib;


public final class CONST {

	public static final String APPLICATIONTITLE = "Simpla Arcade Game";

	public static final Integer SCREENWIDTH = 640;

	public static final Integer SCREENHEIGHT = 480;


}


But for some reason it doesnt draw anything on the form :(

What do I do wrong?

If I can fix it, I'll then implement multithread that you suggested, but I try to make a single step at a time, so I understand everything I do :)

#8
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
You forgot to initialise
boolean runapp;


#9
Pow

Pow

    Newbie

  • Members
  • PipPip
  • 11 posts

oxano said:

You forgot to initialise
boolean runapp;
ah! you are right, thank you! :)
what a silly mistake :P

it work perfectly okay!
now I'll try to implement game logic and rendering in different threads, and if it will work then I can start on the game ^_^

Also I have one more question...
I get some kind of strange result...
take a look
Posted Image
why it happens? :(
It should be the same because both shifts are 50 pixels...

Edited by Pow, 27 November 2010 - 02:41 PM.


#10
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
Maybe the titlebar is included in the pixel count.
Try to, instead of using the graphics of the JFrame, put a JPanel in the JFrame and use the JPanel's graphics.

#11
Pow

Pow

    Newbie

  • Members
  • PipPip
  • 11 posts

oxano said:

Try to, instead of using the graphics of the JFrame, put a JPanel in the JFrame and use the JPanel's graphics.
You mean to avoid this shift? It may be a good idea.

#12
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
Yes, if my assumption that the titlebar is included in the frame's graphics size is correct, that should be solved with a jpanel inside it

50px from JFrame


+-------------------------------------------------------------+  ^

|titleBar                                                     |  |

+-------------------------------------------------------------+  | 50px  

|                                                             |  v

|         +---------------------------------+                 |

|         |---------------------------------|                 |

|         +---------------------------------+                 |

|                                                             |

+-------------------------------------------------------------+

<-------->

    50px

	

	

50px from JPanel:


+-------------------------------------------------------------+  

|titleBar                                                     |  

+-------------------------------------------------------------+    

|                                                             |  ^

|                                                             |  |

|                                                             |  |

|         +---------------------------------+                 |  v 50px

|         |---------------------------------|                 |  

|         +---------------------------------+                 |

|                                                             |

+-------------------------------------------------------------+

<-------->

    50px






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users