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.
Related
I will try to explain as well as I can the problem I'm dealing with.
SO I have a substract class "WeaponCarrier" in which I have a weapon.
That "Weapon" is a class that has a "void setHolder(WeaponCarrier holder){this.holder = holder}.
That "Weapon" class also has a "WeaponCarrier getHolder(){return holder;}" method.
What I'm trying to do is change the weapon setHolder/getHolder through a subclass in WeaponCarrier.
Something like:
private class sword extends WeaponCarrier
{
void methodName(){ weapon.setHolder(weapon.holder);} //This code doesn't work but I have tried a lot of things and nothing seemed to work either
}
The result I want is: When I "System.out.println(getHolder)" I want to get the new value from setHolder that I gave through the subclass.
I will take this question down if it doesn't make any sense to you.
Thank you so much for your valuable time.
You could use an abstract class weapon and use an instance of that.
Then use code like this
public abstract class Weapon{
Weaponcarrier holder;
String name;
//this creates the name var for the weapon
public Weapon(String name){
this.name = name;
//this sets the name that gets coded for the weapon to the instance of the weapon.
}
public void setHolder(weaponCarrier){
this.holder = weaponCarrier;
}
public Weaponcarrier getHolder(){
return this.holder
}
}
Then to make a sword(for example)
public class Sword extends Weapon{
public Sword(){
super("Sword"/*the name*/);
}
now make a list where you add all Weapons to called weaponlist and add all weapons to that.
Then make a function which returns the weapon's class when called.
Then you can use that class to call the functions for that one instance. This is scalable to include all weapons that you want to use. if you don't understand the second part you can just ask and I will tell you the code for that.
Then you can enter the one you want to set it to between the brackets and it sets it to that. Also make sure you put the right new in because now it is setting itself to what it currently is
This code does not work ...
If we look closely at this line ...
void methodName(){ weapon.setHolder(weapon.holder);}
... then we will see that it makes no sense, because the weapon object is setting a value on its field equal to its current value. It does not change anything ever.
If you change this line to something more useful, then you can do an override of a getter or a setter in the same way you would override any other method.
Ideally, you should cover your code by unit tests to ensure that it works exactly how you invisioned it.
I'm creating a program where I have an Animal class, and extending that, a 'Sheep' and 'Cow' class.
In my program, I also have a 'Farm' class that will create a new animal when 'generate()' is called. When I initialize the program, each farm is given a specific animal to generate.
I can think of several ways of doing this, but none of them seem particularly nice. One way I've come up with is to have my classes set out like this:
public class Farm {
public Animal typeOfAnimalToSpawn;
public Farm(Animal a) {
typeOfAnimalToSpawn = a;
}
public void generate() {
typeOfAnimalToSpawn.spawnMe();
}
}
public abstract class Animal {
public abstract void spawnMe();
}
public class Sheep {
public void spawnMe() {
new Sheep().create();
}
public void create() {
// Spawn this sheep onto the field (By making it visible or something)
// Do whatever needs done when a sheep arrives
}
}
This seems crazily complicated and convoluted for something that I can only assume has a simple and elegant solution. In this scenario, I'm actually using the Sheep both as a type (For the farm) and an object (For when it's created). On top of this, it bugs me that calling 'new Sheep()' doesn't actually create a sheep, and it's only after something calls create() that anything happens. It also doesn't feel right to store an entire instance of an animal simply to serve as a type for the farm to spawn future animals.
It would be easy enough to simply have a farm for every type of animal:
public abstract class Farm {
public abstract generate();
}
public class SheepFarm extends Farm {
public void generate() {
new Sheep();
}
}
public class Sheep {
public Sheep() {
// Do whatever needs done when a sheep arrives
}
}
That's nice and neat on the surface but involves an extra, completely useless class for every new animal added to the program. Not exactly ideal either.
There is another way, with reflection, but I'm reluctant to use it as I'm sure there's some more sensible way of doing things.
So, my question is, what's the best way to approach a situation such as this one, and is there a simpler way of doing things than the solutions I've posted above?
I'm completely self-taught so I don't know of the proper way to do things and have had to work things out for myself with Google but it's completely failed me here; I've got no idea where to even start finding information about common programming paradigms, except, of course, for Wikipedia, which doesn't exactly come with a 'learn to write neat code' tutorial.
If my question comes off vague or even down-right nonsensical, please just ask me to clarify.
A way that I would go about it is to use generic types for Farm (however, you'd have to remove the abstract identifier on the Animal class):
public class Farm<E extends Animal> {
private E e;
public Farm() {
this.e = (E) new Animal();
}
public void generate() {
e.spawnMe();
}
}
If you're not familiar with generic types, I'd definitely research them!
Your first solution seems pretty efficient. I think it'd be the best way to go about it since you can just enter Farm sheepfarm = new Farm(new Animal...). Good luck :)
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.
Edit: Have edited to provide more spefic code
As you can see my sprite drawing is breaking this rule.
I would be really grateful if someone could explain by way of pseudo code based on my code below (This is because I've read many explanations of this rule but I still don't really understand why it's a problem or how to do what I need to do without breaking this rule :-( )
1) Why would this cause a problem in my code?
&
2) Please explain an alternative way of doing what I'm attempting to do (while keeping a separate resource class that is specifically for loading my resources and creating my sprite objects).
Is there anything wrong with accessing objects through 2 or more class objects. I will explain through some code:
Here I have 3 classes, is there anything wrong with accessing the method from class2 through another object as in the third class below..........:
Code
My Resource Class
//Resource class
public Class Resource(){
Bitmap myTexture;
Quad mySprite;
public void LoadResources(){
//Load graphics
myTexture = BitmapFactory.decodeResource(view.getResources(), R.drawable.myBitmap);
//Create my objects
mySprite = new Quad(); //Create new Quad object
mySprite.setTexture(myTexture); //Set texture to this quad
mySprite.setSize(100,100); //Set size of this quad
}
}
My Quad Class
public class Quad(){
//This custom class has the bulk of the code to create all of the Quads / Sprites
public void setTexture(Bitmap textre){
//etc.....
}
//etc....
}
public void draw(int x, int y){
//Draw code here
}
And finally, my main GLRenderer class:
public class MyGLRenderer implements GLSurfaceView.Renderer{
Resource res;
public MyGLRenderer(){
res = new Resources(); //Create object to my resources
}
public voide onDrawFrame(){
//Here is my main loop and I need to draw my sprites here, so........
res.mySprite.draw(x, y); //Draw my sprite
}
Why it's bad to have several chained method calls
The law this violates
This violates a coding practice known as the law of demeter. This law states that you should only talk to those classes "next to you".
Why this is a bad thing
The reason for this is because, by calling methods in several other classes, your class needs to know about those methods, and depends on those methods changing. This is called close coupling. If the methods change, you need to change lots of code in other classes. This is called "Shotgun Surgery" and isn't a desirable feature in a program!
A possible solution
Look into the proxy design pattern. It's primarily designed to provide an interface to another class, and it might help you here. Perhaps by having a reference to both objects, this class can provide a common interface for all methods to talk via and reduce the coupling between the classes.
Edit to help with your example
Your example isn't actually that bad. You get an object, and you make a method call on it. The dependency comes in one form: If you remove the mySprite field from your class, your code won't work, and if you remove the draw method from your sprit it won't work. To me, the easiest solution is to add a Proxy method to your Resources class, called draw() that accepts a sprite as an argument.
Secondly, perhaps instead of accessing mySprite directly, you can put it through a method. Let's say you had a member that looked like this:
private ArrayList<Quad> sprites = new ArrayList<Quad>();
This means that in order to gain access to these sprites from the outside, you would need to have some sort of method. Now, by forcing other classes to talk via these methods, you're reducing coupling. This is because the original class only needs to know the one method in another class, and the other class will do the work. Then you wrote a drawSprite method that looked something like:
public void drawSprite(int index) // Index really is up to you {
sprites.get(x).draw();
}
Now I know it might have more parameters than that, but it only means one method call from your MyGLRenderer class, hence conforming to the law of demeter, and reducing coupling in your classes.
Sorry, but it wouldn't work...
As Mike pointed out, Classes instantiated in any of SomeClass's methods are "alive"/valid only when you're inside the method. This means that the instantiated object is specific to the method, and can't be accessed outside the method.
A possible solution:
The solution to this is to add a SomeClass2 member to SomeClass. If you instantiate this member in SomeClass's constructor, it'll stay alive till SomeClass is in scope, making it available for you to use. The code would look something like this:
SomeClass:
class SomeClass
{
// Define the class attributes. This class can be then accessed publicly
SomeClass2 class2
// Constructor - Instantiate all your members here
public SomeClass()
{
// Instantiate class2 in the constructor
this.class2 = new SomeClass2();
}
// Your method which does what you need
public void classMethod()
{
class2Object.class2Method();
}
}
SomeClass2 will stay the same
And SomeClass3 will be:
class SomeClass3
{
public void class3Method()
{
SomeClass classObject = new SomeClass();
// Call the instantiated member and then call it's method
classObject.class2.class2Method();
}
}
This should compile/run. I would comment on the design, but I'll wait to find out what you're planning to use this for before I do! :)
It will work (except you your SomeClass2 object is declared within the method, and it should be within the class as a member variable, but I assume that's a typo).
But I would consider using getters and setters instead (it's considered better practice):
class SomeClass{
private SomeClass2 class2Object = new someClass2();
public SomeClass2 getClass2Object() { return class2Object; }
}
class SomeClass2{
public void class2Method(){
//Some code here
}
}
SomeClass3{
public void class3Method(){
SomeClass classObject = new SomeClass();
classObject.getClass2Object().class2Method();
}
}
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();
}