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.
Related
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?
I'm building an MVC based java application/game and trying to use IoC to separate object creation from application logic.
Let's assume I have just 2 entity : Board and Player where
each one has a Model class, a View class and a Controller class.
The BoardModel needs a PlayerModel (to handle some app logic) and the BoardView needs a PlayerView (to render it inside its space ).
To create a new Player I use a PlayerFactory class that creates the PlayerModel, the PlayerView and the PlayerController and wires them together.
The problem is that after creating the Player I need the PlayerModel and PlayerView instances to create the Board.
My solution is to "wrap" the PlayerModel, PlayerView and PlayerController in a Player class that only has these 3 fields and 3 getters; pass the Player to the BoardFactory and inside the factory use the 3 getter to get the View and the Model needed by the Board.
I'm doing something like this :
PlayerFactory pFactory = new PlayerFactory();
Player player = pFactory.build("HUMAN");
BoardFactory bFactory = new BoardFactory();
Board board = bFactory.build(player);
My worries are about the "wrapper" Player class.
Does it make sense to have a class just to hold 3 objects ?
Is there a better way to pass the dependencies to the Board without using a IoC container?
Your overall approach looks good. Although, there are a couple of changes I would make :
PlayerController and Player seem to have the same responsibility. I would get rid of Player completely and just use a PlayerController instead
The pseudo-code would look like this :
public class PlayerController {
private PlayerView playerView;
private PlayerModel playerModel;
//constructor that intializes playerView and playerModel
public void render() { playerView.render() }
public void moveForward(int steps) {
if(playerModel.canMoveForward()) {
playerView.moveForward(steps);
}
}
}
Similarly, you can get rid of Board and just have a BoardController instead. BoardController can then depend on PlayerController instead of depending on Player. The pseudo-code for this would look something like :
public class BoardController {
private PlayerController playerController;
private BoardView boardView;
private BoardModel boardModel;
//constructor that intializes the dependencies
public void render() {
playerController.render();
boardView.render();
}
public void movePlayerForward(int steps) {
if(!boardModel.isGameOver()) {
playerController.moveForward(steps);
}
}
}
This way, you get rid of Player and Board classes that were really not doing much. Alternately, you can rename the above classes to Player and Board. Another advantage of the above pseudo-code is that you also end up making your code more readable by implementing the Tell Dont Ask principle.
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.
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.
I am making a game, I have got several different classes as I dont like to put everything in one. I have a GameView class and a players class. The problem is that I am calling a method in players class from GameView. But its giving me an null pointer error. Below is my code:
GameVie class:
Panel p2 = new Panel();
p2.setLayout(new BorderLayout());
JLabel player1Lbl = new JLabel("Player 1");
p2.add(player1Lbl, BorderLayout.WEST);
player.enterNameP1(); //Having an error here.
player1Lbl.setText(player.enterNameP1());
Players Class:
public class Players
{
//storing the player 1 name
private String p1name;
//storing the player 2 name
private String p2name;
/**
* Constructor for objects of class Players
*/
public Players()
{
this.p1name = p1name;
this.p2name = p2name;
}
/**
*Enter the player 1 name in a dialog box
*/
public String enterNameP1() //It was public void before but it wasnt accepting a void method in the gameView so I changed it to String
{
this.p1name = JOptionPane.showInputDialog("Please enter player 1 name","Specify name");
return p1name;
}
you should initialized player first..... ?
Players player = new Players();
Your player isn't initialised at the moment you call:
player.enterNameP1(); //Having an error here.
To solve this, you have to make sure that the reference player actually points to a real instance of Player. This should be done by adding at a logic place in your code this:
player = new Players();
That is the reason why you got a NullPointerException. When you call a method from a specific object, the object must be initialised (which means that the pointer player points to an actual instance of the class Players).
You did not instantiated player
So it is null causing a NPE