Correctly Initializing the Physics State Outside of SimpleApplication - java

So I've been learning how to use the jme3 engine and SDK. I started toying around with working outside of the main application file that extends SimpleApplication to further objet-orient my application.
My question is this.. How do I correctly initialize the physics object? As in.. You create a Player class that has a BulletAppState object named phyiscs, but is not assigned a value AT FIRST! It is assigned within the constructor.
class Player {
BulletAppState physics;
public Player(BulletAppState physicsState) {
this.physics = physicsState; // State should now be initialized when
// this constructor is is called
}
}
Then, in the main class file
class Main extends SimpleApplcation {
Player player;
BulletAppState physics;
public static void main(String[] args) {
Main app = new Main();
app.start();
}
#Override
public void simpleInitApp() {
physics = new BulletAppState();
physics.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
stateManager.attach(physics);
player = new Player();
}
}
I do not get the desired result that I expect.
The output results are:
Main class physics state enabled? True
Player class physics state enabled? False

Just pass the physics in your Player() constructor to initialize BulletAppState like this.
player = new Player(physics);

Big hint: stateManager.attach() adds the thing to a Queue!
The only appStates that are initialized during the call to simpleInitApp are those passed into the constructor at new Main(appStates...)
I've got this working well in my object-oriented game project:
Main app = new Main( new StatsAppState(), new FlyCamAppState(), new DebugKeysAppState(), physics );
And it passes nicely to all objects in the simpleInitApp() call.

Related

Java - How do you avoid a StackOverflow after creating multiple objects?

I am currently working on my exam-project for uni. The task is to create the boardgame ludo. After writing some code and doing some testing, I ran into a StackOverflowError.
So here is the structure (5 classes are essential):
Main.class GUI.class Game.class Player.class Piece.class
Main creates a new object of type GUI called mainGUI. This creates the visuals for the game, including a small settings area with a start button.
On the press of the Start button, a new object of the type Game is created which then creates 4 new Objects of the type Player (4 players obviously).
When creating an object of type Player, this type gets the argument 'nmbr' which just states the Number of the Player (Player1, Player2 and so on).
Each Player has 4 pieces to move around on the board, so each of those 4 Players create another 4 objects of type Piece.
Now when pressing the Start button, what should happen is, that the pieces are displayed on the board. But that doesn't happen. Instead I get an errormessage stating, that there is a StackOverflowError on the call of the first Player object.
So I tried to read into the behaviour of Object creation in java and StackOverflow and stuff like that. But the only conclusion I can get right here, is that I've created too many objects inside one another.
public class Main {
public static void main(String[] args){
Main start = new Main();
start.activate();
}
static GUI mainGui;
public Main() {
mainGui = new GUI();
}
Inside the GUI there is the JButton 'submit'
This button is supposed to start the game by creating the an object of the type Game.
submit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Object btn = e.getSource();
boolean ACTIVE = ((JButton) btn).isEnabled();
if (ACTIVE) {
submit.setVisible(false);
cancel.setVisible(true);
Game spiel = new Game();
spiel.begin();
}
}
});
public class Game {
public Game() {
}
Player player1 = new Player(1); //this is where the Error occurs
Player player2 = new Player(2);
Player player3 = new Player(3);
Player player4 = new Player(4);
}
etc.
public class Player extends Game {
private String name;
private Color color;
private boolean artiPlayer;
private int playerNmbr, start, end;
private int[] startArea, endArea;
Piece piece1, piece2, piece3, piece4;
public Player(int nmbr){
if (nmbr == 1) {
System.out.println("1.1");
piece1 = new Piece(500,175, Color.BLUE, Main.mainGui);
piece2 = new Piece(550, 175, Color.BLUE, Main.mainGui);
piece3 = new Piece(500,125, Color.BLUE, Main.mainGui);
piece4 = new Piece(550, 125, Color.BLUE, Main.mainGui);
start = 0;
end = 64;
}
}
Type Piece => Piece(xPos, yPos, Color, GUI)
//and so on
Here is the exact error message:
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at spielPackage.Player.<init>(Player.java:18)
at spielPackage.Game.<init>(Game.java:9)
Sorry if the code is a bit unclean. I am fairly new to java and this is still a work in progress.
At this point I am lost as to why Java throws a StackOverflowError
Your Player should not extend Game since a Player is not a Game.
Right now you create a game which creates four players with every one of them being a different "Game" and creating four more players which are games and create four new players each......

How do I use serialization to save a gamestate using multiple classes?

For a project I am involved in, I have the task of writing some code to be able to save and load the current gamestate. Now, being that I am using java, I already know Serialization is probably the best way to go about this. Now, the gamestate that I have to save involves one main class witha singleton pattern shown here:
public class Game implements java.io.Serializable
{
private static ArrayList<Room> world;
private static Game game = nul
private Game(){}
public static Game getGame()
{
if (game != null)
{
game = new Game();
}
return game;
}
A little bit further down in the code are a bunch of objects that are used to help the game run.
Position heroPos = new Position(HERO_ROOM_INDEX,
HERO_POS_X, HERO_POS_Y);
Rectangle heroHitbox = new Rectangle(
new Position(HERO_ROOM_INDEX,
HERO_HITBOX_X_OFFSET, HERO_HITBOX_Y_OFFSET),
HERO_HITBOX_WIDTH,
HERO_HITBOX_HEIGHT);
Entity hero = new Player(heroPos, heroHitbox, HERO_SYMBOL);
Position leverPos = new Position(getPlayerRoomIndex(), LEVER_POS_X,
LEVER_POS_Y);
(The actual code is pretty long and would be hard to read, but it follows mostly the same format)
Where Entity, Rectangle, Position are all separate classes in different packages than Game. So, if I were to try and serialize this Game object, how would I go about it? Would I have to use ObjectOutputStream to write every single object that Game creates into a file? Or do I just have to make sure that all of these classes that Game uses implement the Serializable interface, and then just serialize the Game object?

Invoking methods of a class that instantiated this one

I'm developing a game in Java which uses the Lightweight Java Game Library (LWJGL) with OpenGL.
I encountered the following problem.
I want to create an ArrayList of all textures in an object in the main loop, and access these from objects instantiated in this main object. A simplified example:
game.class:
public class Game {
ArrayList Textures; // to hold the Texture object I created
Player player; // create Player object
public Game() {
new ResourceLoader(); // Here is the instance of the ResourceLoader class
player = new Player(StartingPosition) // And an instance of the playey, there are many more arguments I give it, but none of this matter (or so I hope)
while(true) { // main loop
// input handlers
player.draw() // here I call the player charcter to be drawn
}
}
// this method SHOULD allow the resource loader to add new textures
public void addTextures (Texture tx) {
Textures.add(tx);
}
}
ResourceLoader.class
public class ResourceLoader {
public ResourceLoader() {
Interface.this.addTexture(new Texture("image.png")); // this is the line I need help with
}
}
Player.class
public class Player {
public player() {
// some stuff, including assignment of appropriate textureID
}
public void draw() {
Interface.this.Textures.get(this.textureID).bind(); // this also doesn't work
// OpenGL method to draw the character
}
}
In my real code the ResourceLoader class has about 20 textures to load.
There is a total of over 400 entities in the game that have a draw method just like Player.class and most of them share the same texture; e.g. there are about 150-180 wall object all showing the same image of bricks.
The Game object is not the main class and it does not have the static void main() method, but it is one of the only few things instantiated in the main() method of the game.
Also, in the past, I worked around the problem by letting each entity load its own texture file. But as I increased the complexity and map size, it becomes very inefficient to load the same image hundreds of times.
I arrived at the state of the code above from this answer.
I believe I would have to put ResourceLoader.class and Player.class inside the game.class, which would not be a good solution considering that there are about 20 files that need this treatment and most of them are 200+ lines long.
I think my Texture object as well as initialization of OpenGL and other stuff are pretty generic and should not impact the issue in question. I can provide these if necessary.
Make the "outer" class instance a parameter to the constructors:
public class Player {
final Interface obj;
public player(Interface obj) {
this.obj = obj;
// some stuff, including assignment of appropriate textureID
}
public void draw() {
obj.Textures.get(this.textureID).bind();
}
}
public class ResourceLoader {
public ResourceLoader(Interface obj) {
obj.addTexture(new Texture("image.png"));
}
}
And instantiate those in Game like:
new Player(this);
Note: The example lines used Interface but Game does not implement it. I assume that's an artifact of code cleaned for the posting. Just use the type that is appropriate for your situation.

Java using an object from a central class

I am making a game in Java and I have a central(Engine) class which will render the scenery/player/etc.
In the Engine class I create my player object like so
public class Engine() {
public static Player player;
public Engine() {
RenderPlayer();
}
protected static void RenderPlayer() {
player = new Player();
}
}
I also have a Canvas class which handles the drawing of the player.
I want to be able to call the Players functions without having to create a new instance( since I created the player in the Engine class ). Whenever I try to use a function from the player, I get a null pointer expection.
This is how I call it.
Engine.player.tick();
I have spent a couple hours trying to figure it out, May someone tell me what I am doing wrong, and help me in the right direction? Thank you.
You need to call Engine.RenderPlayer() prior calling Engine.player.tick(); as this method assigns a new Player instance to the static player attribute. Before you call this method player is null and it is causing your NullPointerException.
You can fix this issue by simply changing:
public static Player player;
to:
public static Player player = new Player();
player is null if you never create an instance of Engine because RenderPlayer() is in the constructor of Engine.
You could just do
public static Player player = new Player();
or make sure to call RenderPlayer() explicitly before accessing player.

Adding Objects to JFrame from another class?

I'm trying to create a blackjack program for my final project in Java. I'm still very new to Java and OOD so I apologize if my problem seems very trivial to you :(
How my program works: I have three classes so far.
main.java
This class builds my frame and runs all the other methods.
cards.java
This class creates an array that holds the card values and location to picture. I have a for loop in there that auto-populates it.
hits.java
This class is meant to "randomly" generate a number that will represent the chosen card. The way this works is by taking the randomly created int and pointing it to a matching index location on the array.
I assign the value to string objects that I then try to add to a jlabel and then add that jlabel to my main frame. The code is as follows:
hits.java
// Import necessary classes.
import java.util.Random;
public class hits {
// Create random object.
Random rand = new Random();
// Declare variables.
int card;
String cardVal, cardPic;
// Instantiate the needed classes.
main s = new main();
cards t = new cards();
// Constructor for the class.
public hits() {
// Randomly generate a number (0 - 9).
card = rand.nextInt(10);
// Populate the array.
t.runCards();
// Assign the cards according to the num. generated.
cardVal = t.deck[card][0];
cardPic = t.deck[card][1];
}
// Run Method
public void runHits() {
// Add the card chosen to the GUI.
s.a.setText("hello");
s.dealerCards.add(s.a);
}
}
I have "hello" as the text for the label because I wanted to see if perhaps my array was not populating, but even that doesn't work. If it helps here is my main.java as well (constructor and main method):
// Constructor for the main class.
public main() {
// Setup the MAIN container.
f1.getContentPane().setLayout(new GridLayout(0, 1));
f1.setSize(200, 200);
f1.add(dealerName);
f1.add(dealerCards);
f1.add(userCards);
f1.add(userName);
// Setup the inner panels.
dealerCards.setLayout(new GridLayout(1, 2));
dealerCards.add(b);
userCards.setLayout(new GridLayout(1, 6));
userCards.add(c);
userCards.add(d);
}
// Build the frame.
public void GUILaunch() {
// Display Frame
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.setVisible(true);
}
// Main method.
public static void main(String args[]) {
// Distribute the dealer's/player's starting hands.
hits deal = new hits();
deal.runHits();
// Launch the GUI
main gui = new main();
gui.GUILaunch();
}
Hopefully I have provided enough information to help you understand what's going on here. So to sum it all up: how can i add my jlabel(from another class) holding the randomly selected card to my main frame
Thanks in advance.
The deal.runHits() adds a label to the Main object that deal owns rather than the gui object.
I would suggest the following :
Make your main class have an instance of hits and hits have an instance of the cards object...
so you get something like this
public class main {
private hits hits_instance
//constructor
main(){ hits_instance = new hits(); }
//this method will add your cards
public void addCards(){
// frame = whatever frame you are using
frame.add(hits_instance.getCards());
}
}
public class hits {
private cards cards_instance;
hits(){ cards_instance= new cards();}
public JLabel getCards() {return cards_instance.getCard(randomNumber);}
}

Categories