Background
I am building a game library to make game development faster, and so far it is going fairly smoothly.
I have the following:
public static void main(String[] args)
Game
Room
to the JFrame
Room
(Room is a game level) class is created it it starts a thread from the room to draw all the objects added to it.
So above is what the main idea entails.
Here is the entry class (very simple).
package test;
import JGame.Game.Game;
import JGame.Room.Room;
import javax.swing.JFrame;
import test.Rooms.Room1;
public class Main extends JFrame{
public static void main(String[] args){
Game game = new Game("Test Game"); // This sets the window title
game.start(800, 600); // This sets the size of the window
Room room1 = new Room1();
game.setRoom(room1); // adds the JPanel to the main frame
}
}
Room1
extends Room
. Within Room1
all of the game object that are associated with that room are added to it.
public class Room extends JPanel implements Runnable{
ArrayList<GameObject> gameObjects = new ArrayList<>();
@Override
public void run(){
try{
while(true){
this.repaint();
Thread.sleep(5);
}
}
}
public void addGameObjectAt(GameObject gameObject, int x, int y){
// Sets private variables in GameObject
// These are then grabbed in the paintComponent to draw at that location
gameObject.setX(x);
gameObject.setY(y);
gameObjects.add(gameObject);
}
@Override
public void paintComponent(Graphics g){
g.drawImage(bg, 0, 0, this);
for(int i = 0; i < gameObjects.size(); i++){
GameObject go = gameObjects.get(i);
g.drawImage(go.getSprite(), go.getX(), go.getY(), this);
}
}
}
So lets say we create a room:
public class Room1 extends Room{
public Room1(){
this.createShip();
}
public void createShip(){
Ship = new Ship();
// Add an object to a list setting its x,y to 10,10
this.addGameObjectAt(ship, 10, 10);
}
}
Note: These objects are not added to the window with addGameObjectAt
they are simply added to an ArrayList
and then in the thread in Room are painted to the screen.
Now that we added Ship
to the room it can be drawn on the screen using paintComponent()
. This all works fine!
Here is where things start to stop working. Now that we have a Ship
class added, I would like to add some key events, currently I have to add Main
for them to work, but I don't want to add them there, because it gets messy, I would like to add them to Ship
, since that is what the events will effect in the end.
This code doesn't attach the keylistener
// GameObject extends JPanel
public class Ship extends GameObject{
public Ship(){
this.addKeyListener(new AL());
}
public class AL extends KeyAdapter{
@Override
public void keyPressed(KeyEvent evt){
System.out.println("here");
}
@Override
public void keyReleased(KeyEvent evt){
}
}
}
This doesn't work, pressing a key does not print out here , but if I move the AL
class and the addKeyListener()
to the Game
class it works, but I don't want it in the Game
class I want it in the Ship
class.
// This class just sets up the size of the application window
// It also holds an int list of all the game rooms
public class Game extends JFrame{
}
I have been trying to figure this out for at least a week now, and I can't seem figure out how can I get this so that it works in the Ship
class?
JPanel
is not a focusable component so cannot interact with KeyEvents
.
In Swing, the preferred approach is to use Key Bindings . You can map an Action to a KeyStroke even when a component doesn't have focus.
See this example
I think you need to make the JPanel focusable. Try ship.setFocusable(true);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.