How to iterate only over specific kind of elements? - java

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();
}

Related

Game design: organizing object arraylists

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.

Java: Best way to get object from extended sub-class

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.

Comparing custom object within a method

In my app (which is an Android game - so, Java), I have a custom class called Quad which I use for my games objects. The class creates a textured openGL quad.
I have another class called Enemy which extends Quad.
I have a method which is called from my game class and I can pass in various objects. Now, I want to do different things depending on which object was passed in, I'll try to demonstrate with some code.
bird = new Enemy(); //Create a bird sprite
snail = new Enemy(); //Create snail sprite
public void doSomething(Quad sprite){
//Do work here regardless of which object was passed in
move(object);
if (sprite == bird){
//Do bird specific stuff here
}
else if {sprite == snail}{
//Do snail stuff here
}
}
So, as you can see, I want to execute some common code regardless of the object passed into the method, (whether a bird, snail or some other object), then after the common code, there should be some object specific code run.
Now, I remember reading on one of my other questions that although this worked, it wasn't the correct thing to do.
Since the ratio of code is heavily skewed in the favour of the common code, (ie, the majority of the code in the method should run regardless of what the object is), it doesn't seem a great idea to create different methods for birds and snails. Too much code duplication.
I could do this:
public void doSomething(Quad sprite){
move(object);
}
public void doBirdStuff(){
doSomething(bird);
//Bird specific code here
}
public void doSnailStuff(){
doSomething(snail);
//Snail specific code here
}
And then just call the specific object, so:
doSnailStuff(snail);
doBirdStuff(bird);
However, this just seems overly complicated and inefficient
So my question is, if comparing custom objects in this way isn't the 'Java' thing to do, how can I achieve my goal in a more acceptable way and why exactly is the first method deemed unacceptable?
You can create two classes (Bird and Snail) that extends Quad and use instanceof :
public void doSomething(Quad sprite){
//Do work here regardless of which object was passed in
move(object);
if(sprite instanceof Bird) {
//Do bird specific stuff here
}
else if {sprite instanceof Snail}{
//Do snail stuff here
}
}
An example of how to use it :
public void main(){
Bird bird = new Bird();
Snail snail = new Snail();
// Do something with a bird
doSomething(bird);
// Do something with a snail
doSomething(snail);
}
Update
Because most code isn't specific to bird/snail the best way is to use an enum that define enemy type :
public enum EnemyType{
Bird,
Snail
}
And use it in your Enemy class :
public class Enemy extends Quad{
private EnemyType mType;
//All other class members...
// Constructor with type
public Enemy(EnemyType type){
this.mType = type;
}
public void doEnemyStuff(){
if(isBird()){
// Bird Stuff
}
else if(isSnail()){
// Snail Stuff
}
}
//Check if current enemy is a Bird
public boolean isBird(){
return mType == EnemyType.Bird;
}
//Check if current enemy is a Snail
public boolean isSnail(){
return mType == EnemyType.Snail;
}
}
And finally wherever you want you can use a method like :
public void doSomething(Quad sprite){
//Do work here regardless of which object was passed in
move(object);
if(sprite instanceof Enemy) {
//Do enemy specific stuff here
((Enemy) sprite).doEnemyStuff();
}
}
With your first idea you were creating objects and keeping references to them only to make a check. Moreover it shouldn't work because the default behavior of "==" is to check equality of references (There is a little explanation about == operator).
Either create a Bird and a Snail class and let the classes extend from Quad. Then you can check with
if (sprite instanceof Bird) {
// ...
}
Or you could create a enumeration and add an attribute to Quad.
This looks like an example of using an object oriented language (Java), but not applying object oriented concepts.
The natural object oriented way is to have the code that does "bird stuff" in a Bird class, and the snail specific code in a Snail class. Sketching this out in your example, the code shared for all enemy types would go into the Enemy class:
public class Enemy extends Quad {
...
public void doSomething() {
// common stuff
}
...
}
Then you derive the specific enemies from this class, and implement methods with the specific behavior. These methods invoke the common behavior from their base class:
public class Bird extends Enemy {
...
#Override
public void doSomething() {
// invoke base method that does common stuff
super.doSomething();
// bird stuff
}
...
}
public class Snail extends Enemy {
...
#Override
public void doSomething() {
// invoke base method that does common stuff
super.doSomething();
// snail stuff
}
...
}
Then you need no ugly type checks to invoke specific behavior. You simply call the method, and the specific implementation for each type of enemy is invoked. If badEnemy is a variable of type Enemy:
badEnemy.doSomething();
This encapsulates all behavior of a specific enemy type in a class, while the rest of the code does not need to know anything about specific enemy types. When you want to introduce a new kind of enemy, you simply implement a new Enemy subclass with the same interface, and it will work within the system without additional changes.

How to make a class (which is not a descendant of collection) "compatible" with for-each loop?

NOTE: In real life situation I would use an appropriate Java collection but in this task I would like to do everything form scratch.
I've done my Googling here on SO and on the rest of the web, but didn't find exactly what I was looking for.
It's my understanding that for-each loop can operate on any class that implements iterable interface and at the same time this class does not have to implement iterator. Am I right here?
Let say, I have the following two classes that are not explicitly derived from any other class.
public class Pile {
private Thing aThing = new Thing();
// other varibles
// constructor
// other methods (including getters and setters)
}
and
public class Thing {
private object value; // Payload
private Thing link1; // variables that enable awareness
private Thing link2; // of other Thing objects
// For example, link1 could be reference to the previous object
// and link2 - to the next
// other varibles
// constructor
// other methods (including getters and setters)
}
In this example, Pile would be a double-linked List. But it does not have to.
My goal would be to create IterablePile class through inheritance.
public class IterablePile extends Pile {
}
The only requirement of Iterable interface is to implement Iterator method.
And here I'm stumped. It seems that all examples (or at least those that I found so far) immediately assume that my class is derived from one of the Java collections (for example ArrayList).
What if this not the case? What exactly needs to be done in such case? What steps need to be taken?
Can you point me in the right direction (preferably not writing the code itself)?
And one more question. Will the situation change if Thing is a private inner class of Pile?
It seems to me that I'm missing something basic but can't put my finger on it.
If only your IterablePile needs to be iterated, then you just have to implement the Iterable interface that will provide an Iterator. Here's a basic example:
public class IterablePile extends Pile implements Iterable<Thing> {
//current class implementation...
private class MyIterablePileIterator implements Iterator<Thing> {
private Thing thing;
private MyIterablePileIterator(Thing thing) {
this.thing = thing;
}
#Override
public boolean hasNext() {
//add the implementation...
return (thing.getLink1() != null || thing.getLink2() != null);
}
#Override
public Thing next() {
//add the implementation...
//since it is a tree structure, you could use a Queue<Thing>
//to implement prefix, infix or postfix navigation
}
#Override
public void remove() {
//add the implementation...
//in case you don't want to implement it, you can leave it blank
//or throw new UnsupportedOperationException("never remove!")
}
}
#Override
public Iterator<Thing> iterator() {
return new MyIterablePileIterator(getAThing());
}
}
Still, I would find very odd that only your IterablePile would be iterable, while the Pile won't. Note that your code should be oriented to interfaces (or abstract/super classes) instead of specific implementations. Anyway, this should do.
More info:
What does it mean to "program to an interface"?

Where to put a interface related variable that it is not static and final

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.

Categories