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...
How to implement Keylistener, Renderer to jpanel and Main class all different classes
Started by Pow, Nov 27 2010 05:50 AM
12 replies to this topic
#1
Posted 27 November 2010 - 05:50 AM
|
|
|
#2
Posted 27 November 2010 - 08:26 AM
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
Posted 27 November 2010 - 08:54 AM
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
Posted 27 November 2010 - 09:02 AM
I think you will learn A LOT from this tutorial: http://forum.codecal...-detection.html :)
#5
Posted 27 November 2010 - 09:09 AM
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
Posted 27 November 2010 - 09:24 AM
Okay then:
Keylistener class
renderer class
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.
So you have
(I have no hands on experience with this 2 thread system ;) )
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
(I have no hands on experience with this 2 thread system ;) )
#7
Posted 27 November 2010 - 10:57 AM
oxano, thank you.
but before implementing multithread i tried to make something like this
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 :)
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
Posted 27 November 2010 - 11:06 AM
You forgot to initialise
boolean runapp;
#9
Posted 27 November 2010 - 01:32 PM
oxano said:
You forgot to initialise
boolean runapp;
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

why it happens? :(
It should be the same because both shifts are 50 pixels...
Edited by Pow, 27 November 2010 - 02:41 PM.
#10
Posted 28 November 2010 - 02:16 AM
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.
Try to, instead of using the graphics of the JFrame, put a JPanel in the JFrame and use the JPanel's graphics.
#11
Posted 28 November 2010 - 03:40 AM
oxano said:
Try to, instead of using the graphics of the JFrame, put a JPanel in the JFrame and use the JPanel's graphics.
#12
Posted 28 November 2010 - 03:46 AM
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


Sign In
Create Account


Back to top









