Invoking methods of a class that instantiated this one - java

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.

Related

Collisions of while loops when in a row (Java)

I build a game that includes moving between worlds. The main class of the program suppose to start by presenting the first world (world1 which is an instance of the firstWorldClass). It should stay in this world until a variable within the class world1 is changing (checked by world1.getMoveWorldIndicator()). Then, it should move to the next world- remove world1, build world2 and add it to the graphic view. Same from world 2 to 3.
It works fine when I do it between 2 worlds (delete all the code after add(world2)) or if I leave only the transition between the second and the third worlds. When I put both in a row it stops working (when adding the second while loop).
My code:
public class GameManager extends Program implements GameContstants{
public void init() {
world1=new firstWorldClass();
add(world1);
while(!world1.getMoveWorldIndicator()){
pause(200);
if(world1.getMoveWorldIndicator())break;
}
remove(world1);
world1=null;
world2=new secondWorldClass();
add(world2);
pause(200);
while(! world2.getMoveWorldIndicator()){
pause(200);
if(world2.getMoveWorldIndicator()) break;
}
remove(world2);
world2=null;
world3=new thirdWorldClass();
add(world3);
}
private firstWorldClass world1;
private secondWorldClass world2;
private thirdWorldClass world3;
}
I suspect that there's some kind of interaction between the while loops or a memory problem but am open to hear any idea/different way to do it.
Thanks!
I think there are lots of factors coming into play here:
Clean up your code. Keeping a few coding rules is important for bug fixing!
Don't use repetitive code over and over again. Extract to method or Class
Keep to class naming conventions => Upper camel case for classes
Don't set variables to null. Usually compilers will do that for you while optimizing. If you still feel like manually freeing up space or variable names, you should use scope brackets {} around the code instead!
Breaking down your code, we see lots of redundancies, like "getMoveWorldIndicator()" checks twice per loop, without any different effect from using it only once
I have provided a cleaner - but different - version here, to show you.
But for actually helping you with your code, we really DO NEED more of your code to gain some insight to the problem.
public class GameManager /* extends ... */{
static class WorldBase {
public boolean getMoveWorldIndicator() {
return false;
}
}
static class FirstWorld extends WorldBase {}
static class SecondWorld extends WorldBase {}
static class ThirdWorld extends WorldBase {}
public void init() {
playWorld(new FirstWorld());
playWorld(new SecondWorld());
playWorld(new ThirdWorld());
}
private void playWorld(final WorldBase pWorld) {
add(pWorld);
while (!pWorld.getMoveWorldIndicator()) {
pause(200);
}
remove(pWorld);
}
private void remove(final WorldBase pWorld1) {}
private void pause(final int pI) {}
private void add(final WorldBase pWorld1) {}
}

Java: Accessing resources and the Law Of Demeter

Overview
In my (Android) Java game, I have a class called resources. As the name suggests, this class holds the resources for the game. All of my OpenGL objects (Sprites) are created here
It's looks something like the following (obviously, this is a simplified version compared to that which appears in the real project):
public class Resources {
Hero hero;
Enemy enemy;
MenuButtons mainMenuButtons;
Background background;
Scene mainMenu;
public void createObjects(){
hero = new Hero();
enemy = new Enemy();
mainMenuButtons = new MenuButtons();
background = new Background();
mainMenu = new Scene(this);
}
}
So, within my mainMenu scene, I need access my objects, so we may see something like this:
public class mainMenu implements Scene {
Resources resources;
public mainMenu(Resources resources){
this.resources = resources;
}
#Override
public void render(){
resources.background.draw();
resources.hero.draw();
resources.enemy.draw();
mainMenuButtons.draw();
}
#Override
public void updateLogic(){
resources.hero.move();
resources.enemy.move();
resources.mainMenubuttons.animate();
}
}
Now, the above method is just one way to get access to the objects in resources and their methods. But does this actually break the Law of Demeter? If not, why not? If so, what is the best way to get access to these objects in a way that does not violate the LOD?
Accessors?
One option (which I've ruled out TBH - see below) is placing accessor methods into my resources class. So that I could do something like:
resources.drawBackround();
I have a lot of objects and I need an accessor for each method/variable of each object. Not really practical, it seems like I'm writing a ton of extra code and most importantly, it makes the resources class ridiculously long as it becomes filled with these accessors. Therefore, I'm not going down this road.
Passing in objects into the scene's constructor
Of course, I can also do something like this:
hero = new Hero();
enemy = new Enemy();
mainMenuButtons = new MenuButtons();
background = new Background();
mainMenu = new Scene(hero, enemy, mainMenuButtons, background);
So I can simply do this:
background.draw(); //etc....
This is workable for simple scene's (such as menu systems that don't require a lot of objects) but for the main game, it could quickly become a mess as I'd have to pass references to some 30+ objects into the constructor which doesn't really sound quite right......
So I would really appreciate if someone could point out the best way to proceed and why.
So I would really appreciate if someone could point out the best way to proceed and why.
The best way, in my opinion, is to keep the Resources class, make all objects private to not break the law and write accessors (but not for every object like you already ruled out).
I have a lot of objects and I need an accessor for each method/variable of each object. Not really practical, it seems like I'm writing a ton of extra code and most importantly, it makes the resources class ridiculously long as it becomes filled with these accessors. Therefore, I'm not going down this road.
I assume many objects are of the same class. So you do not have to make an accessor for every object what would really blow up the class.
I a game you normally have a hero, one or more enemies and many sprites.
public class Resources {
private Hero hero;
private Enemy enemy;
private MenuButtons mainMenuButtons;
private Background background;
private Scene mainMenu;
public void createObjects(){
hero = new Hero();
enemy = new Enemy();
mainMenuButtons = new MenuButtons();
background = new Background();
mainMenu = new Scene(this);
}
public Hero getBackground() {
return background;
}
public Hero getHero() {
return hero;
}
public List<Enemy> getEnemies() {
ArrayList<Enemy> list = new ArrayList<Enemy>();
list.add(enemy);
list.add(next_enemy);
return list;
}
public List<Sprite> getSprites() {
ArrayList<Sprite> list = new ArrayList<Sprite>();
list.addAll(enemy.getActiveSprites());
return list;
}
}
Instead of getHero() and getEnemy() you could also make a getActor() method if Hero and Enemy are derived from the same class.
The getSprites() method is just an example how it could look like.
If that solution is not going to work for you, I have another suggestion.
Make the Resources class do some work.
public class ResourceManager {
private Hero hero;
private Enemy enemy;
private MenuButtons mainMenuButtons;
private Background background;
private Scene mainMenu;
public void createObjects(){
hero = new Hero();
enemy = new Enemy();
mainMenuButtons = new MenuButtons();
background = new Background();
mainMenu = new Scene(this);
}
public void render(Scene scene) {
this.background.draw();
if (scene != mainMenu) {
this.hero.draw();
this.enemy.draw();
}
this.mainMenuButtons.draw();
}
public void updateLogic(Scene scene){
this.hero.move();
this.enemy.move();
this.mainMenubuttons.animate();
}
}
The mainMenu then calls logic methods directly in the RescourceManager class.
public class mainMenu implements Scene {
ResourceManager resourceManager;
public mainMenu(ResourceManager resourceManager){
this.resourceManager = resourceManager;
}
#Override
public void render(){
resourceManager.render(this);
}
#Override
public void updateLogic(){
resourceManager.updateLogic(this);
}
}
I hope my suggestions helped you a bit figure out how to continue with your project.
You could use dependency injection and eliminate your Resources class. Then you can call functions on your fields and wouldn't be in violation of the Law of Demeter.
Here is an example using constructor injection:
public class MainMenu implements Scene {
Background background;
Hero hero;
Enemy enemy;
MenuButtons buttons
public mainMenu(Background background, Hero hero, Enemy enemy, MenuButtons buttons){
this.background = background;
this.hero = hero;
this.enemy = enemy;
this.buttons = buttons;
}
#Override
public void render(){
this.background.draw();
this.hero.draw();
this.enemy.draw();
this.mainMenuButtons.draw();
}
#Override
public void updateLogic(){
this.hero.move();
this.enemy.move();
this.mainMenubuttons.animate();
}
}
With dependency injection, you pass instances into constructors and functions instead of "newing" them inside your class. You need to manage your instances somewhere though, and there are plenty of libraries that will do that for you. Dagger is a popular one for Android: http://square.github.io/dagger/
The idea of passing a list isn't a bad first step, but it's not sufficient. Game developers have a (somewhat controversial) concept of a structure called a "scene graph" that helps them keep track of their resources (among other things). https://en.wikipedia.org/?title=Scene_graph
It's a pretty complicated concept, but you're going to need to learn about it sooner or later. There's a lot of good advice on gamedev.stackexchange.com, so I'd suggest you take a peek over there.
Here's a nice YouTube video tutorial on the subject. https://www.youtube.com/watch?v=ktz9AlMSEoA
You could create an Drawer class that handles the drawing of all the objects. Your scene objects simply need to feed the Drawer the objects that I assume are Drawable.
public class Drawer {
public void drawObjects(Drawable... objects) {
for(Drawable drawable : objects) {
drawable.draw();
}
}
}
This is then used by Scene to draw those objects.
public class mainMenu implements Scene {
Resources resources;
Drawer drawer;
...
public void render() {
drawer.drawObjects(resources.background,
resources.hero,
resources.enemy,
resources.mainMenuButtons);
}
...
}
A similar strategy, using an Updater, can applied for the other methods. If your updateLogic() method makes as simple of calls as it looks, you can definitely do the same thing, by making all those objects inherit from an Updateable interface.
public interface Updateable {
void update();
}
Hero's and Enemy's update() methods could simply call their move() methods, while MenuButtons's update() could delegate to animate(), etc.
Obviously, if you like, you can use some sort of collection instead of varargs for the parameter of Drawer's drawObjects(). I just like the nice fluency made possible by the varargs, since you don't have to create the collection.
For other tips for keeping code in line with the Law of Demeter, check out this article: Law of Demeter and How to Work With It
I like the concept of a ResourceManager. But a ResourceManager should be responsilbe for loading Resources, caching and freeing them. Rendering is definitly a Method of a Render Object.
So the Scence - render Method could delegate the rendering to it after instantiating a Renderer and feed it with Drawables as the Renderer does not render Resources but renderable objects.
Say:
class MainMenu implements Scene {
Renderer sceneRenderer = new Renderer();
AnimatedRenderer animatedRenderer = new AnimatedRenderer();
ResourceManager resourceManager = ResourceManager.getInstance();
List<Resource> resources;
List<Drawable> renderedObjects;
GameObjectController gameObjectController;
void initializeScene() {
resources = resourceManager.getResources();
renderedObjects = resourcesAsRenderables();
sceneRenderer.setDrawables(renderedObjects);
}
List<Drawable> resourcesAsRenderables() {
// if resources are not directly renderable, do decoration etc
// and return a List of Drawable
}
#Override
public void render(){
sceneRenderer.render();
}
#Override
public void updateLogic(){
moveGameObjects();
doAnimations();
}
protected void moveGameObjects() {
gameObjectController.moveAllObjects(this, resources);
}
protected void doAnimations() {
animatedRenderer.render(resources);
}
class ResourceManager {
private static ResourceManager instance = null;
List<Resource> resources;
public ResourceManager getInstance() {
if(instance == null) {
instance = new ResourceManager();
instance.loadResources();
}
return instance;
}
private void loadResources() {
resources = new LinkedList<Resource>();
resources.add(new Hero());
....
}
public List<Resource> getResources() {
return resources;
}
}
This clearly separates the logic and responsibilities for the tasks carried out during the scene lifecycle. A resource manager which is responsible for retrieving resources and as they may take long loading times does things like caching or freeing in low memory situations hiding the details from the client. A renderer which is responsible for displaying the objects and a controller which is responsible for moving the objects. The controller itself may implement handlers for keyboard events but that is not something which must be transparent to the scene. The renderer may swap backgrounds in or out or scale or set lighting effects but the scene only calls its render method. The animated renderer is responsible for starting , rendering and stopping animations.
Change this:
public void render(){
resources.background.draw();
resources.hero.draw();
resources.enemy.draw();
mainMenuButtons.draw();
}
#Override
public void updateLogic(){
resources.hero.move();
resources.enemy.move();
resources.mainMenubuttons.animate();
}
With this:
public void render(){
resources.render();
}
#Override
public void updateLogic(){
resources.update();
}
ResourceManager don't have to know what's inside Resources. It may be one enemy or ten, it doesn't care to ResourceManager.
And so in 'Resource' you can do:
public void update(){
hero.update();// Cause hero may, or may not move, he makes the choice
enemy.update();//...
mainMenubuttons.update();//.
}
public void render(){
...
}
More than this! you could change the "Resource" implementation with an interface and you will be programming for interfaces and not for implementations, which is cool! This way you can have a 'Resources' for in-game and another one for menus that will be used in same way: Only changing, at runtime, the concrete Resources you will be in a menu or in game!
Anyway, not always is needed to fill Demeter.
As can be seen your Resources dont need to be recreated, instead they do use some resources that cant be reloaded (probably images).
You should share the images object within a Resource class, and create your objects within a Scene class, on the constructor of the entities you can get the shared resource that is pre-loaded.

Java inversion of control on an MVC based application

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.

What OO structure should I use to describe animal's behaviors?

I have a Java assignment in which my professor requires me to use a LeJOS NXT to make a robot that simulates a certain animal's behaviors. I chose to develop a dragon. All the possible behaviors that I've come up so far is:
Turning around if it's too close to an obstacle.
Going to sleep when battery is low.
Pushing an object if touches.
If it's too bright, find a dark spot.
etc.
I'm now quite confused because I don't know whether to develop it sequentially in one class or to split all the dragon's behaviors into different classes. Please have a look at my explanation below.
Instead of writing everything inside one class like this:
Dragon.java
public class Dragon {
LightSensor ls = new LightSensor
public static main(String args[]) {
while (!BUTTON.Escape.IsPressed()) {
if (this.closeToObject()) {
this.turnAround();
}
// more conditions
}
}
private boolean closeToObject() {
//TODO
return false;
}
private void turnAround() {
//TODO
}
//... more methods
}
However, I want to make it appears to be more object-oriented as the course is meant to help us gain more OOP skills. So what my second option is to create action classes that extends Dragon's Behavior abstract class like this (roughly):
Dragon.java
public class Dragon {
Detect detect = new Detect(); // carry all the detection methods: distance, sound, etc.
TurnAround turnAround = new TurnAround();
public static main(String args[]) {
while (!BUTTON.Escape.IsPressed()) {
if (detect.tooCloseToObject()) {
turnAround.prepare(); // beep beep alert
turnAround.setDerection(true); // e.g. turn right
turnAround.turn();
}
}
}
}
DragonBehaviors.java
abstract class DragonBehavior {
abstract void prepare();
public void setDirection(boolean direction) {
//...
}
}
TurnAround.java
public class TurnAround extends DragonBehaviors {
String direction;
public void TurnAround() {}
public void prepare() {
// sound alert
}
public void setDirection(boolean direction) {
if (direction) this.direction = "Right";
else this.direction = "Left";
}
public void turn() {
// TODO
}
}
The code above is roughly a draft, don't focus on it. Eventually, I want to ask if my idea about the OO structure above is reasonable, otherwise it's much easier to develop the whole thing in one class, but it has nothing to do with OOP. I also have several group members to make the code finished, so I think it could be better if we share the classes to develop in an OOP way.
Which way should I go in this circumstance?
I appreciate all the comments (:
Your choice of extracting different actions into classes with common super class is IMHO reasonable. However I would make Dragon class only aware of the DragonBehavior abstract class, not the subclasses. This way you can add and remove behaviours to the dragon without actually changing it.
How? Look at Chain-of-responsibility pattern - each behaviour has its place in the chain. If behaviour decides to activate itself (i.e. perform something) it may or may not allow further behaviours to be triggered. Moreover, you can and remove behaviours (even at runtime!) and rearrange them to change the precedence (is pushing the obstacle more or less important than going to sleep?).

Java3d Behaviors and movement

I would like to move a sphere in a random direction within a simple universe. How could i achieve this with behaviours by changing the location a small amount frame by frame. The reason I am trying to do this is to produce random movement within the universe and eventually build in simple collision detection between the particles.
Any advice/links would be appreciated
Add a new class that extends Behavior, using this skeleton:
public class XXXBehavior extends Behavior
{
private WakeupCondition wc = new WakeupOnElapsedTimer(1000); // 1000 ms
public void initialize()
{
wakeupOn(wc);
}
public void processStimulus(Enumeration criteria)
{
// Move the shape here
// prepare for the next update
wakeupOn(wc);
}
}
You later need to instantiate the class and add it to the scene graph. You also need to defined the bounds, otherwise nothing will happen!
xxxEffect = new XXXBehavior();
xxxEffect.setSchedulingBounds(bounds);
sceneBG.addChild(xxxEffect);

Categories