I'm building a basic game from a brief, and have been given some code to look at. All characters in the game are game objects, some are moveable ones, and some aren't. The moveable ones have a position and direction.
I have been given a MoveableObject class (below). Moveable GameObjects instantiate this class in their own constructor. I have not been guaranteed this code is right, so I'm trying to grasp the theory behind it.
public class MoveableObject {
int speed;
String direction;
public MoveableObject(){
speed = 0;
direction = "unknown";
}
public MoveableObject(int iSpeed, String sDirection){
speed = iSpeed;
direction = sDirection;
}
and all the moveable characters create an instance of this class in a constructor. For example, from a vampire class.
public class Vampire
public Vampire(){
MoveableObject thisObject = new MoveableObject(30, "South-East");
}
}
To my knowledge, this is known as aggregation. I thought this was to be used in a HAS-A relationship, and not an IS-A. Since a character IS-A moveable object, should I not use inheritance or an interface? I also don't understand why you need to create an instance of a MoveableObject, if each character either is or isn't moveable, surely, you should give them the ability to be moveable or not (through inheritance or interface) and then instantiate the character?
Thanks in advance.
That depends if the MoveableObject class also takes care of the actual movement of the object (i.e. update its position according to the speed and direction members) or just holds the speed and direction members so that the engine module of the game will use it to calculate the object's position.
In the latter case I would change the name of the MoveableObject class to something more appropriate and stick with the aggregation. Otherwise an inheritance will be more appropriate for movable objects. That way the moving logic will be implemented once and the sub classes can take care only for their own specific need.
To explain further if the MoveableObject is just a data container you can create an interface :
public Interface Moveable {
public MoveableObject getMovementData();
}
and each moveable class will look like :
public class Vampire implements Moveable {
.
.
private MoveableObject movementData; //
.
.
public MoveableObject getMovementData() {
return movementData;
}
}
and in your game engine hold an array of all moving objects (Type moveable) and in the update method get the movement data and process it:
public Class GameEngine {
.
.
private ArrayList<Moveable> movableObjects = .....
.
.
public void gameUpdate() {
for (Moveable moveableObj : movableObjects) {
MoveableObject movementData = moveableObj.getMovementData();
// Process and update as required using the given data
}
}
Related
As you can see, I've created (instantiated?) a static array of Corner objects in the object Corner. Is this good form? I want all the Corner object to have access to all the other Corner objects.
package Main;
public class Corner {
private String biome;
private static Corner[][] corners;
private float elevation, moisture, heat;
private boolean isRiver, isLake;
private int x, y;
public void createArray(int width, int height) {
corners = new Corner[width][height];
}
public String getBiome() { return biome; }
public void setBiome(String biome) {
this.biome = biome;
}
public float getElevation() { return elevation; }
public void setElevation(float elevation) {
this.elevation = elevation;
}
public float getMoisture() {
return moisture;
}
public void setMoisture(float moisture) {
this.moisture = moisture;
}
public float getHeat() { return heat; }
public void setHeat(float heat) { this.heat = heat; }
public boolean isRiver() {
return false;
}
public boolean isLake() {
return false;
}
public static Corner[][] getCorners() {
return corners;
}
}
There are no more details to add.
If the amount of Corners changes you need to create a new bigger array and copy all the Corners from the old array to the new bigger one. This should indicate to you that you might want to ave a different data structure than an array. One that can grow like a List or a Set.
In general, a Corner should not need to know of other Corners. A different type should manage all the Corners and handle dependencies between them.
You did not wrote why 'I want all the Corner object to have access to all the other Corner objects' so I cannot recommend how this managing type could look like.
First of all, taking in not what Kevin has said, you should change
public void createArray(int, int);
to
public static void createArray(int, int);
I do not understand the need to have a two-dimensional array for accessing other Corner objects.
Also array is not a good structure type for dynamic allocation. List is better alternative and in this case List. So you should implement it as -
You should create a list as -
private static List<Corner>;
In general, static is an abnormality in good OO design. You only use it if there are very good reasons to do so.
Your example doesn't look like such a case. You see, you are mixing up things that don't belong together. A "corner" is simply that a "corner". It doesn't know about other "corners".
In the model that you are actually creating, you have some "enclosing" thing that deals with corners in plural. That enclosing thing could have some List<Corner> field that is used to track all Corner objects belonging to the enclosing entity.
static often looks like an easy, convenient way to solve such problems. But in reality, you are just creating a lot of problems by implementing something like this. It works initially, but it breaks as soon you try to enhance your program.
Is this good form?
No.
There are two reasons:-
Reason 1 :- Single responsibility principle. Every object should be responsible about its concern . So its not the concern of corner object to maintain the list of other corner object. Maintaining corner object can go under some util class method or singleton object maintaining the corner cache(which will be easy to test also)
Reason 2 :-
unit testing. Say you want to write unit test for static method you won't be able to do it easily until and unless you provide any third party lib that provides static mocking like jmockit,
Let's say I have a Projectile class which acts as a base class for all projectiles in my game. This contains default values for maximum speed, gravity coefficient, bounce coefficient, etc.
public abstract class Projectile {
protected float maxSpeed = 100.0f;
protected float gravityCoefficient = 1.0f;
protected float bounceCoefficient = 1.0f;
...
}
I then have a bunch of subclasses, each of which may choose to override some of these default values.
Which is the better approach here?
1. Set field values in child constructor
public class Arrow {
public Arrow(){
super();
maxSpeed = 200.0f;
}
}
2. Make child override getter
public class Arrow {
public float getMaxSpeed(){
return 200.0f;
}
}
I am inclined to say that the first approach is better, since it means the field can be accessed directly without the need for any extra function calls. However, it does mean that the value is set twice during object creation, once by the parent and once by the child.
Am I missing anything here? Is there, perhaps, another approach?
Intuitively, the maximum speed of any particular projectile is unlikely to vary over its lifetime (even in the case where different instances of the same type can have different maximum speeds), therefore I would favour a final field for it. I would also favour making it final - I very rarely use non-private fields, other than for genuine constants.
As you have some state (the field) for Projectile, I would avoid allowing the confusion of having the maximum speed has revealed by getMaxSpeed differing from the field.
I would probably design it like this:
public abstract class Projectile {
private final float maxSpeed;
protected Projectile(float maxSpeed) {
this.maxSpeed = maxSpeed;
}
// Only if you really need this...
protected Projectile() {
this(200f);
}
public final getMaxSpeed() {
return maxSpeed;
}
}
public class Arrow extends Projectile {
public Arrow() {
super(100f);
}
}
The gravity coefficient and bounce coefficient may be treated in a similar way - or if all of these really act as "the same values for every instance of a particular type" you could introduce a new class to represent these constants, which separates the varying state of instances of a type from the constant restrictions/coefficients - and each instance could just have a final reference to an instance of that new class. Unfortunately Java (and at least some similar languages) don't really model this kind of hierarchy well. It's always an annoyance :(
you should have a setter and use it, that is what setters are for. It will allow you to keep the field private. The other benefit is that using Java Bean convention will allow you to use libraries such as Apache Commons BeanUtils to populate and manipulate your Objects. You will also be able to persist your data in DB or file.
public abstract class Projectile {
private float maxSpeed = 100.0f; // default
protected void setMaxSpeed(float newSpeed) {
maxSpeed = newSpeed;
}
}
public class Arrow extends Projectile {
public Arrow() {
super();
setMaxSpeed(200.0f); // arrow specific values
}
}
First approach. Declare a method named modifyDefaults() in your abstract base class. Implement it in each class and call in the constructor so that whenever someone sees abstract class, it can be concluded that you will be modifying defaults in children.
Or just hand over responsibility of Projectile creation to a projectileFactory if there are only a few deciding parameters.
Your inclination towards the first answer should be. It does clearly state the following:
The child class has it's responsibility of creating it's own instance variables (properties)
Overriding of getter, though sounds good at certain views, doesn't usually give a good maintainability. Constructor clearly states the extra set of property defaults whatsoever very cleanly.
I'm not sure about your design, but if you have your super class which doesn't have state of it's own, try making it abstract and the design changes completely than we discussed in that case (option 2 might be considered that time).
For java, compiler optimization and JIT optimization are of great importance for the improvement of performance.
The second piece of code will be much more easier to be optimized with no worry of extra operations.
Got a design patterns question (some terminology related to Java as that's my current project).
Current layout of code:
class Game - holds game state and manages logic,
Super abstract class Player
Player has subclasses for different types of players (AI, human, etc).
Each player can make up to three moves (A, B, C) but they must be in that order. Hence a player may on their turn choose any of the following move sequences:
(A,B),
(B,C),
(A, B, C)
(A, C),
(a),
etc
Players should receive feedback between each move so that they may decide whether to execute another or end their turn.
Assuming set of type abstract Player here are two designs I have:
Solution 1:
for all players in set call player.takeTurn(game). So every player knows when it is their turn and they have a reference to the current Game object. Their turn ends when takeTurn() returns. Player.takeTurn is overridden by all subclasses of player. Within the method, any player who wishes to carry out moves can reference the passed in Game object. example:
game.makeMoveA(),
game.makeMoveB(),
etc
Game.makeMove() can return ok/error values to tell the player whether the move was legal or not. Also, the updated game state is available by the Game object that is still in scope within the takeTurn() method.
Problem is that you are relying on all subclasses to remember to call makeMove() What if they don't or what if they call them in the wrong order? I guess that calling methods in the wrong order could be handled by exceptions/error messages but we still have the problem that nothing enforces the instantiated class to actually respond and make a move.
Solution 2:
Abstract class Player contains three abstract methods getMoveA getMoveB and getMoveC.
Hence all inheritors must implement these methods.
The abstract super class Player contains a method takeTurn().
takeTurn(Game game) {
game.makeMove(this.getMoveA())
game.makeMove(this.getMoveB());
etc
}
This is nice as behaviour is enforced but now we have a messy problem of how to give feedback to the player who made the move. What if it was an illegal move, etc. You could enforce another method handleMoveResponse() but then every player has to keep track of what move the success/error message refers to.
Any ideas? Would love to hear your opinion on this.
Many thanks
It looks to me like you are trying to get your requirements to fit a pattern rather than breaking down the requirements until you see the pattern.
A brief attempt at implementing your requirements produced this. There's a Strategy pattern and a Template pattern in there that doesn't seem to have the issues you mention.
enum Move {
A, B, C;
}
class Strategy {
final List<Move> moves;
public Strategy(List<Move> moves) {
// TODO: Make sure it is valid.
this.moves = moves;
}
}
class Game {
}
abstract class Player {
// Call before each move.
abstract Strategy getStrategy(Game game);
void move(Game game, Move move) {
// By default do nothing.
}
}
/**
* The rules control the game.
*/
class Rules {
public void play(Game game, Player player) {
while (!gameOver(game)) {
Strategy strategy = player.getStrategy(game);
for (Move move : strategy.moves) {
player.move(game, move);
// Do your feedback here.
}
}
}
private boolean gameOver(Game game) {
return false;
}
}
So apologies if this question has been answered already, although I did have an extensive look but couldnt quite find the answer. To sum up the situation I am trying to create a simulator program that deals with different predator and prey creatures and currently have the issue of getting each creature to check what type of creature it is next to, which I would prefer to do checking if the instance belongs to the same object.
So say for example I did this:
private class Creature {
...
Creature [] fish = new Creature();
Creature [] shark = new Creature();
Creature [] penguin = new Creature();
}
and then created several instances (creatures) of each type in a loop like so:
for (int f=1;f<rnd;f++) {
fish[f] = new Creature();
//set attributes of creature
and then so the program can tell where they are located in relation to each other I created a grid system like so:
Creature [][] gridloc = new Creature[x][y]; //relates to number of spaces tiles that determines movement.
Creature [] crloc = new Creature[tc]; //stores a reference to all creatures created.
...
crloc[tc] = fish[f]; gridloc[x][y]=crloc[tc] //or fish[f]
}
Anyway to sum even tho I summarised the code there quite a lot, that all works but when getting each creature to check next to it in gridloc for what is there e.g. a predator I am unsure of a way to check if it finds another creature to determine if that is an instance of the same object type or a different one. So something like:
if (!gridloc[x][y].getObject().equals(gridloc[x+1][y].getObject()) //if the current creature is not the same as the one next to it.
I am aware of things like instanceof but that only works with checking if an object is an instance of a class, not if a instance belongs to the same type of object. I also can't simply use fish[1].equals(fish[2]) because they have different attributes and that would check if they are exactly the same.
Any ideas/suggestions would be welcome. Thanks!
You need to look into Polymorphism (http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html). You declare a Creature as a base class (or interface) and extend/implement from Creature class for each type of a creature you have. Each subclass will implement it's own methods to override Creature and allow you to correctly use the methods and also to detect the type using the class metadata that each instance will have.
It's an issue with your design. You have to create a Super class called Creature and sub classes for fish , penguin and all others. Then create the arrays with those sub class types. Then you can do the instanceof checks with your adjacent objects of the grid.
This design is based on Polymorphism.
In the long run this is the best approach since code is more clean and structured. If you do this way, even after few years when you take a look at the code; still it will make sense.
One option (and perhaps the best in the long run, see answers by #AlexC and #Don) would be to make subclasses of Creature, called Fish, Shark, Penguin etc. Then you can use instanceof.
To combine that with polymorphism, you'd add a method public boolean eats(Creature other) As an aside, when I helped babysit a 4 year old his favorite game with little plastic animal figures was "what eats what" with loud screams of delight.
In Creature, the code would be return false; (though arguably fish eat fish?)
In Penguin, the code would be return other instanceof Fish;
In Shark, the code would be return true;
Another option would be to have a field of Creature that describes it. Maybe an enum, or a String for the latin classification names. Then, you could use something like genus.equals("Carcharodon") for Shark or latinName.contains("Spheniscidae") for Penguin.
Maybe creature should be an enum...
public enum Creature {
FISH(false), SHARK(true), PENGUIN(true);
private boolean isPredator;
private Point gridLocation;
Creature(boolean isPredator) {
this.isPredator = isPredator;
}
// ...getters/setters
}
with a separate world class for grid locations...
public class World {
List<Creature> creatures = new LinkedList<>();
public boolean isNearPredator(Creature c) {
for (Creature i : creatures) {
if (i.getGridLocation().distance(c.getGridLocation()) < 2
&& i.isPredator()) {
System.out.println("About to get eaten!");
}
}
}
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I am trying to turn a board game into a multiplayer game using java, but I have a few questions as to how I can achieve what I want.
In the game, there is a bag that holds Creatures, Buildings and Magic. Each player draws from this bag to get their game pieces. They then proceed to either put the pieces on tiles in the game board that they own right away, or they hold onto the pieces and play them at a later date. The tiles can hold creatures, magic, buildings, forts.
Right now I have an ArrayList that is holding all of the creatures, and each tile has an ArrayList that can hold creatures.
It looks like an ArrayList is not what I want to be using, as I would have to have the ArrayList be of type Object (which is bad). Any ideas on how I can design my program so I don't have to cast to Object? I'm not sure if I need a wrapper class, or just multiple array lists, but The confusing things is when a player is drawing from the bag that contains a bunch of different things. I should be able to differentiate what is moving around the board easily enough.
Any suggestions?
Can Creatures, Buildings, and Magic all implement the same interface or extend the same class? Then you could have an ArrayList that contains that interface or class. Alternatively, just have a data structure that contains three ArrayLists and write code that picks fairly between them.
I would suggest an interface that each object implements:
interface Bagable {
public String getType();
}
Then each object can be done in this fashion:
class Creature implements Bagable {
public String getType() {
return "Creature";
}
// Normal Creature Class methods...
}
class Building implements Bagable {
public String getType() {
return "Buidling";
}
// Normal Building Class methods...
}
class Magic implements Bagable {
public String getType() {
return "Magic";
}
// Normal Magic Class methods...
}
public static void main(String args[]) {
ArrayList<Bagable> bag = new ArrayList<Bagable>();
bag.add(new Creature());
bag.add(new Building());
bag.add(new Magic());
for (int i = 0; i < bag.size(); i++ ) {
System.out.println(bag.get(i).getType());
}
}
Or you could have the types as built in values
int ITEM_TYPE_MAGIC = 0;
int ITEM_TYPE_CREATURE = 1;
int ITEM_TYPE_BUILDING = 2;
and check them against these built in values
One solution would be to create an interface, for example BagItem (which could define any common behaviours that the items in the bag would be expected to do), and have each of Creature, Building, Magic, etc, implement this interface. This would mean you could have an ArrayList<BagItem> (or other collection).
In my opinion, the real benefit to this is that common behaviour can be defined at the interface level, rather than just being able to stuff random stuff into the bag. If there isn't any common functionality between the items being put into a given bag/collection, then maybe consider having more than one bag (or maybe 'pockets' in the bag?) if that's an option.