To learn Java, I am making a classic "fly around in space" 2d game. Besides the player object, numerous enemies/obstacles (scavengers, hunters, comets, asteroids) exist, each with their own class that extends a GameObject class. As there can be several scavengers, comets etc these are stored in arraylists. However, as each object can interact with each other, there is a lot of looping and duplicate code to have e.g each alien interact according to the objects in the comet arraylist, the asteroid array list and so on.
In my game update function I have:
public void update() {
ArrayList<Rock> rockList = rock.getRockList();
ArrayList<Scavenger> scavengerList = scavenger.getScavengerList();
ArrayList<Hunter> hunterList = hunter.getHunterList();
....
npc.update(player, scavengerList, hunterList, rockList);
...
}
and in my NPC class (which extends the GameObject class)
public void update(Player player, ArrayList<Scavenger> scavengerList, ArrayList<Hunter> hunterList, ArrayList<Rock> rockList) {
for(int i = 0; i < scavengerList.size(); i++) {
scavengerList.get(i).update(player,scavengerList, ,hunterList rockList);
}
for(int i = 0; i < hunterList.size(); i++) {
hunterList.get(i).update(player,scavengerList, hunterList, rockList);
}
...
}
And finally I have an update function in my scavenger class, my hunter class etc such as
public class Hunter extends NPC{
...
public void update(Player player,ArrayList<Scavenger> scavengerList, ArrayList<Hunter> hunterList, ArrayList<Rock> rockList) {
"update all hunter objects according to the player, scavengers, rocks etc"
}
This approach seems to be rather cumbersome and as more classes are created the number or arraylists that needs to be parsed and looped through are getting out of hand.
Can anyone recommend a better way of doing this?
I guess the obvious way would be to have one list containing all NPC objects and then keeping track of their class type and update accordingly.
Is this a better way of doing it or can anyone point me in the right direction?
Yes there is a much better way.
For each type of object in your game, work out the set of behaviours/characteristics it needs to exhibit. These behaviours should be defined as interfaces. Then the code dealing with the behaviours/characteristics can use the interface without having to know anything at all about the actually class.
For example, if some objects move each turn according to their current velocity and can potential collide with other objects then there might be an interface:
public interface Moving {
void move();
boolean hasCollided(Shape shape);
void handleCollision(Collision collision);
}
Any class that moves would then implement this interface. The World object could then have a List<Moving> movingObjects and then use:
movingObjects.forEach(Moving::move);
in it's update method.
To handle collisions after moving you might have something like:
List<Collision> collisions = getAllCollisions(movingObjects);
for (Collision collision: collisions) {
for (Moving element: collision.getCollidingObjects) {
element.handleCollision(collision);
}
}
If several classes that implement the interface use a similar mechanism to move themselves then you should move that logic into a separate class:
class Inertia implements Moving {
private Velocity velocity;
#Override
public void move(Shape shape) {
velocity.applyTo(shape);
}
#Override
public void applyForceFrom(Position position) {
velocity.accelerateAwayFrom(position);
}
}
Your world objects can then delegate their moving behaviour to this class:
class Asteroid implements Moving {
private final Inertia inertia;
private Shape shape = new Circle(radius);
#Override
public void move() {
inertia.move(shape);
}
#Override
public boolean hasCollided(Shape other) {
return this.shape.intersects(other);
}
#Override
public void handleCollision(Collision collision) {
intertia.applyForceFrom(collision.getCentreOfMass());
}
}
This might seem an unnecessary indirection but experience has shown that it's worthwhile in the long term. See Delegation Pattern for more details.
You could have several delegates if movements differ per object (e.g. some effected by gravity, some controlled by AI etc.), or a class could apply more than one delegate in its move (e.g. gravity and inertia) or a class could implement its own move if its behaviour is unique. All of this can happen without World needing to know anything at all about the class of the object is is calling move on.
As a general rule, try to avoid using extends for the purpose of inheriting behaviour from a superclass. Your structure of Hunter extending NPC extending GameObject will be convenient up until the point at which you realise you also want Hunter to extend Enemy or AIControlled or something else. Hard experiences has shown OO coders that these type of hierarchies look sensible and elegant initially but become unmanageable as you add more complicated functionality.
To go even further and hide all details of which objects implement which behaviour interfaces from World you might like to look at the Visitor Pattern. This would allow the world object to visit all game objects as a mover, then as an AIAgent, then as a user controlled object and so on without ever having to know what they do during the visit (or if they do anything at all). It's very powerful if well applied but it takes a bit of getting used to.
Finally, there's a very common architectural pattern used by game writers called the Entity Component System. If you're just learning Java I'd ignore this for the moment but if you become a serious game developer you'll likely find it's an improvement over the architecture I describe above.
I've obviously left out a lot of detail in the example (such as the definitions of Shape, Circle, Position, Velocity, Collision etc.) but that's the general idea. There's a lot more to this and it's worth looking for a book or tutorial on object oriented design to look deeper.
Related
So, I probably have tought of my program the wrong way, but I can't find how to do what I'm trying to in a pretty way. I also could not find how to search this in Google properly, so sorry if this is already answered. Here is what I have:
I have an abstract class GameWorld which will be extended into several different gameWorlds, like GameAWorld, GameBWorld... I have another abstract class GameRenderer which will be responsible for the rendering of these worlds, and will also be extended into GameARenderer, GameBRenderer...
My issue is, when GameARenderer is created (in another class, not GameAWorld), it receives a general GameWorld (which is actually a GameAWorld). I need to get an object from GameAWorld, which is not in GameWorld. Therefore, what I am doing in the GameARenderer now is:
Obj chair = ((GameAWorld)world).getChair();
because if I simply do world.getA(), without the cast, GameWorld won't have the getA() method.
I believe that this may be sounding confusing, so I will try to clarify it later on, if no one understands...
Feel free to suggest changes on my architecture, if no code will solve it.
As a short but hopefully good enough example I'll try to help you out.
public interface Drawable {
void draw(Graphics g);
}
public class GameWorld {
List<GameObject> gameObjects;
List<GameObject> getGameObjects() {...}
}
public class GameAWorld extends GameWorld {...}
public class GameObject implements Drawable {
// this could be abstract too. Whatever suits your needs.
#Override
public void draw(Graphics g) { ... }
}
//inside a renderer
List<GameObject> gameObjects = gameWorld.getGameObjects();
for (GameObject go : gameObjects)
go.draw(g);
That's the way I'd do it. Be advised I slapped that together quick-like; it might not be 100% correct but you should get the point.
I was reading some article about collision avoidance systems in cars when my programmer mind led me to think of that concept in the object-oriented way, and it made me wonder if those systems respect the object-oriented programming model.
Being mainly a Java developer, I transposed this problem in a Java environment and it raised a particular question: does calling a public method within the same class (in a non-static context) respect and follow the object-oriented way?
I mean, take this brief hypothetical Car class:
public class Car {
// Class attributes.
// Constructors.
public void accelerate(final double amplitude) {
// Accelerate according to the amplitude.
}
public void brake(final double amplitude) {
// Brake according to the amplitude.
}
// Other useful methods.
private void collisionPreventionActions() {
// Some actions.
brake(100.0);
// Some other actions.
}
}
Suppose some Thread is responsible of detecting a collision and take actions when it does detect a collision, and one of those actions would be braking. Obviously the brake(...) method becomes an interesting choice, but doesn't that break the object-oriented way of doing things? It's not just the brakes though. What if the collision avoidance system in this class used the steering wheel instead to avoid the accident? I find it weird that the car would be using its own input from an internal point of view...
On a more general scope, suppose you have a generic object, which I like to see as a black box. The public methods would be the equivalent of levers on that black box that would control its behaviour. Calling a public method within this object would mean that the black box would activate its own levers from its internal mechanism.
I ask because I know it's legal in Java to do so, and that I've seen public methods being called within the same class numerous times in my life, but it being legal doesn't necessarily mean that it's the proper OO way of doing it.
Does using public methods within the same class in a non-static context follow the rules of object-oriented programming and encapsulation? If not, what would be the proper way of doing it or what could be the workaround?
There is nothing wrong with this choice from the OOP perspective: it is perfectly fine for a method to perform things that require combinations of other methods.
In practice, though, a common approach would be to separate the functionality into a public and a private portions, like this:
public void brake(final double amplitude) {
// check preconditions
if (speed == 0) throw new IllegalStateException("cannot brake when standing");
if (amplitude <= 0) throw new IllegalArgumentException("amplitude must be positive");
// ... do other important checks
doBrake(amplitude);
}
private void doBrake(final double amplitude) {
// The real code goes here
}
Now your collisionPreventionActions could call doBrake instead of brake, assuming that you have checked all the necessary preconditions before making the call.
Note: doBrake should check its preconditions as well. However, rather than throwing exceptions when preconditions are not met, it can use assertions. The difference is that exceptions indicate a misuse of your public methods by others, while assertions indicate misuse of your encapsulated methods by you or someone else maintaining your code.
No rules are violated when an object uses its own API. On the contrary, problems are likely to occur if a class has an API that can be overridden, but it fails to use that API internally.
As a trivial example, consider a non-final property accessor. An object could skip the accessor and read (or worse, write) fields directly. Suppose the accessor is overridden in a subclass to compute the property value using the field together with some other information from the subclass. Now the class is broken because it failed to honor its own contract.
Consider the (somewhat contrived) Point and OffsetPoint classes below. The derived class, OffsetPoint is written correctly, but it's inherited toString() method will not work as expected because the parent class, Point, wrongly fails to use its own accessors.
public class Point {
private final int x, y;
public Point(int x, int y) { this.x = x; this.y = y; }
public int getX() { return x; }
public int getY() { return y; }
#Override
public final String toString() {
/* Here's the bug; should be getX() and getY() instead of x and y */
return String.format("(%d,%d)", x, y);
}
}
class OffsetPoint extends Point {
private int dx, dy;
OffsetPoint(Point point, int dx, int dy) {
super(point.getX(), point.getY());
this.dx = dx;
this.dy = dy;
}
#Override
public int getX() { return super.getX() + dx; }
#Override
public int getY() { return super.getY() + dy; }
}
Does using public methods within the same class in a non-static context follow the rules of object-oriented programming and encapsulation?
No, there is no problem with encapsulation becuase the method is public so anyone (even this) can call it.
However, for something like a collision avoidance system, relying on public methods could be bad security wise.
Let's use your example of this intenal Collision detector calling the public method brake(). What if someone subclassed car and overrode the method?
public class BrokenCar extends Car{
#Override
public void brake(final double amplitude) {
//BREAKS CUT!!!
}
}
So there are some security rules of not relying on overridable methods. Making brake and accelerate final methods resolves this problem.
Yes, I think it is proper in an OO context to call your own public method. It's quite common when there are overloads for a method that all but one call the most specific one, either filling in defaults for missing parameters or transforming the type of the argument(s). I also see the pattern where all the overloads call into a private or protected method of the same name with _internal or _impl added to the end. For example, several overloads of ComputeSpeed might all call ComputerSpeed_internal. This pattern would be appropriate if there is parameter validation in the public methods that you don't want to do twice, or would be inappropriate for internal calls.
You can certainly introduce problems by not having a clear separation of concerns. For example, if the caller of collisionPreventionActions also decided it was a good idea to set the brake, you could have a conflict in how much brake is applied.
KC
In general, it is fine to call the public methods. The thing to consider is what the interface of the Car should be. In this case, does preventCollision() belong in the Car class or in some other CollisionPrevention class.
Breaking your code multiple classes each with a single responsibility, and then using them a bigger class like Car, is generally a good idea.
I totally agree with you that it's common that a class itself addresses its private members and methods. But I don't understand why it shouldn't be legal in terms of the Object Oriented Paradigm. Consider the following example:
public class Human {
public Human() {
liveYourLife();
}
private void liveYourLife() {
while(alive){
createYourDay();
}
}
private void createYourDay() {
drink();
eat();
sleep();
awake();
drink();
}
private void eat() {}
private void drink() {}
private void sleep() {}
private void awake() {}
}
Probably someone will criticise the simple rule of life, shown in the example above. But what I want to demonstrate with the few lines above is, that "normally" a human is allowed to decide on his daily routine.
The basic principle of the OO-Paradigm is to describe the actions and properties of real world entities. Hence, as long you are allowed to yourself decide on when you want to eat, drink, sleep, etc. your above described model is absolutely correct. But if you discover some exceptional cases in your problem domain which you want to address in your software (e.g. you got arrested, etc. ) you should update your OO-design.
In case that there is an something, which heavily influences the state of another instance, you should treat that "instance of disturbance" as a different object which has a reference to the actual instance.
public class Prisoner extends Human {
#Override
private void liveYourLife() {
while(jailed){
createYourDay();
}
}
#Override
private void createYourDay() {
// A bit different :)
}
}
public class Prison {
private List<Prisoner> prisoners;
}
I have learned that Java doesn't allow instance fields in an Interface, but I really want this feature.
I am learning to create my first game. My game has different kind of actors such as Hero (to be control by the player), Boss, Canon, etc...
No matter which kind they are, I want that every actors inherit from the base class Model which imparts some fields to its subclasses such as position, width and height so that every subclasses of Model can associate with Controller and Renderer as in MVC pattern.
public class Model {
//position
public float x;
public float y;
public float width;
public float height;
}
Incidentally, I intended that Hero and Boss are entities that can die, so I want that they are instances of Life which is enforced to have, for example, public float hitPoint; as a field, in contrast, a Cannon is not a Life because it will be an immortal entity. Thus I tried:
public interface Life {
public float hitPoint;
}
and expected that an instance of
public class Hero extends Model implements Life {...}
will intrinsically have the hitPoint. But then I learned that instance fields in an Interface are not allow in Java, and it don't support multiple inheritance as well.
Is it possible to achieve the above mentioned design in Java.
only constants can be declared in an interface.
anything you define in an interface is always public static final (except for the methods ofcourse as they are public abstract) if the hitpoints value will never change then this design works for you.
A better solution would be this
public interface Life {
//methods that implementation of this interface should implement
}
public abstract LifeForm extends Model implements Life {
int hitPoints;
//other LifeForm specific methods and instance variables
}
public Hero extends LifeForm {
//Hero specific methods like save the damsel
}
The short answer is 'no'. As you mention, Java doesn't support multiple inheritance -- there are some things you just can't do. However, one can almost always work around this limitation with clever application design. For example, why can't 'Life' extend 'Model'? Or perhaps you could just define accessors (e.g. getHitPoints()) in interfaces? If you really feel the need for an approximation of multiple inheritance, check out Aspect Oriented Programming extensions like AspectJ.
Does it make sense to you to declare Life and Model as field members and change their initial values and state depending on each of the desired Actor implementation?
For example, set the life's value to Infinity for the Cannon objects and to a finite value for other Actors. When you modify the life's value, just be sure to check for Infinity and let it unmodified if it's the case.
public class Hero implements Actor{
//initialize these fields differently in each Actor implementation
private Life life;
private Model model;
public void init() {
// different initialization values here
}
}
public class Cannon implements Actor{
//initialize these fields differently in each Actor implementation
private Life life;
private Model model;
public void init() {
// different initialization values here
}
}
I have an array list as such:
private List<GameObject> gameObjects = new CopyOnWriteArrayList<GameObject>();
GameObject can be one of 3 classes: Spaceship, Beam and Asteroid. They all are similar so I keep them in one array. However spaceships have addition method shoot which is used every 100ms in other thread (which is called ShootRunnable). So I would like to iterate in it only over Spaceship because other doesnt implement shoot method. What is the best way to achieve this?
for (GameObject ob : gameObjects) {
if (ob instanceof Spaceship) {
ob.shoot();
}
}
Can I iterate over it using something like the above? Just with the use of a cast or something? Please help.
The path you're on is technically feasible, though a good rule of thumb is that if you start using reflection, you're probably doing something wrong. In this case, it might be wisest to have a two collections, one for all your game types, and one specifically for spaceships.
In your game, are there any other actions that happen periodically?
If so, you could change the shoot() method into an abstract method (could be named periodicAction()) and place it in the GameObject class. The Spaceship class would implement this method by shooting, the other class with its specific periodic behavior and the Asteroid class by doing nothing.
You should put your shoot() method into the Spaceship class beacause no asteriod or beam will use this method. Done this, you should also keep at least two collections. One of them should only contain your spaceships.
I would rather do this way:
Iterator<Spaceship> getSpaceships(){
// return Iterator over Spaceship objects through use of instanceof
}
...
Iterator<Spaceship> it = getSpaceships()
while(iter.hasNext()) it.next().shoot()
To me it looks more clear.
You could create an interface Action or a method into GameObject:
public interface Action {
void performAction();
}
public abstract class GameObject implements Action {
//...
public void performAction() {
// subclasses should override this method.
// otherwise, it will do nothing.
}
}
and then, implement Spaceship:
public class Spaceship extends GameObject {
#Override
public void performAction() {
this.shoot();
}
}
To Beam and Asteroid, you can leave the method performAction:
Then, you can interate over:
for (GameObject ob : gameObjects) {
ob.performAction();
}
I am in a very early stage of game development. It is some sort of turn based game like Warhammer or Warcraft. Some creatures can regenerate the damage they have suffered and to represent this I have a interface like this
public interface Regenerative {
void regenerates();
}
So a creature that regenerates is
public class SomeMonster() extends BaseCreature implements Regeneative{
//Code
private int hitPoints;
public void regenerates(){
hitPoints = hitPoints + regenerateValue;
}
}
The problem I face is that not all the creatures regenerates the same ammount of hit points so I have to place that amount (regenerateValue) somewhere. Since I cannot put it on the interface (because I don't want the ammount to be the same to all the creatures) I have thought in adding a new property to the creature class
public class SomeMonster() extends BaseCreature implements Regeneative{
//Code
private int regenerateValue;
public void regenerates(){
hitPoints = hitPoints + regenerateValue;
}
}
but I don't like it this way (why a creature that doesn't regenerate should have a regenerateValue of 0?). I think it is giving a class unnecesary properties and thus a bad design. What do you think is the best approach for this case?
The problem I face is that not all the creatures regenerates the same ammount of hit points so I have to place that amount (regenerateValue) somewhere.
Why does it have to be a field anywhere? Some implementations of the interface might use a different value per instance; others might use a constant value.
This is an implementation detail - and thus inappropriate for the interface. You could potentially put it in an abstract superclass which implements the interface, of course.
Code which knows about the interface almost certainly shouldn't know or care the details of how much a creature regenerates - maybe they regenerate in terms of magic rather than just hit points, for example, or maybe the level of regeneration depends on some other function of their state. Callers shouldn't care.
I would add it to the abstract BaseCreature and not worry about it too much. Your BaseCreature may end up with lots of properties which are effectively "turned off" but the alternative is to create a complex inheritance tree. As Java doesn't support multiple inheritance this will frustrate your ability to abstract all the combinations you might like away.
The solution i use may be a bit over-ingeniered, but this allow for a lot of extension (regeneration, poison, protection...)
I use of interface "CreatureProperties" that define a integer value along with an id, and can perform action on a monster at each turn. You subclass those properties to perform a given property
abstract class CreatureProperties {
protected String id = "";
protectd int propertyValue = 0;
public void actOn(BaseMonster);
// plus setter and getter
}
public RegenerationProperty implements CreatureProperties {
final public REGENERATION_ID = "Regeneration";
int regenerationValue = 0;
public RegenerationProperty(int value){
id = REGENERATION_ID;
propertyValue= value;
}
public void actOn(BaseMonster monster){
monster.setHitPoint(monster.getHitPoints()+propertyValue);
}
}
in the BaseMonster class, you manage a set of MonsterProperty, initially empty.
class BaseMonster {
protected List<CreatureProperties> properties =
new ArrayList<CreatureProperties>();
// plus management of propeties : add remove, iterator...
public void update(){
// perform all properties-linked update to monster
foreach (CreatureProperty property : properties){
property.actOn(this);
}
}
}
in the subclass for SomeMonster, you simply add during instanciation the set of properties for this type of monster.
class SomeMonster extends BaseMonster {
public SomeMonster(){
properties.add(new RegenerationProperty(5)); // presto : monster regenerate
}
}
I'm using the Id in some case where the property is not used each tick (ie nothing in the update), but for example damage reduction (id="LightningReduction"), or to modify the list of existing properties (a property that remove all regenerationProperty and add PoisonProperty of same value...).
I think your design is probably ok, as you would only need to include a regenerateValue in the classes that implement the Regenerative interface. So there would be no need to include a regenerateValue.
Otherwise you could look at more complex design patterns that favor composition over inheritance. This way you could cater for the possibility of dynamically adding Regenerative abilities to a monster along with other 'abilities' during the game, rather than having to recompile the game each time you need to make change the behaviour of your monster.
What if all monster regenerate, but some of them with 0 regenerate value (the same as not regenerating)?
So you don't need the inferface:
public class SomeMonster() extends BaseCreature {
//Code
protected int regenerateValue; //protected, so that subclasses can override the value
public void regenerates(){
hitPoints = hitPoints + regenerateValue;
}
}
The regenerateValue starts with 0, so you have to override the value in subclasses that want to actually regenerate
Edited to remove the " implements Regeneative"
You could add a method in your interface, like getRegnerationValue(), making sure all creatures with that interface have this method that holds the value or formula if that is something you would like to work with.
The question you should ask yourself is this: if a creature should regenerate, how do you know that? Will it implement a different (or extending) base class? one that implements Regenerative?
If the answer is that you will extend the base class (to something like BaseRegeneratingCreature) and all regenerating creatures will extend that class, then this is your answer: BaseRegeneratingCreature should implement that interface, and have all properties required for regenerating.
All non-regenerating creatures should directly extend BaseCreature (or another extending class), and will not need the regeneration related properties.
Then, your base class could have some method like:
OnStartOfTurn();
which will, in BaseRegeneratingCreature, call regenerates() (and then probably call super()), and in BaseCreature do something else or call other methods.