Reputation: 63
So I'm making a game in java, and I have objects all with the 2 methods; update()
and render()
.
In my main class, where the game loop resides, I have to call both the update()
and render()
methods for every object that is updatable and renderable.
Is there any way to set up some form of interface where I can call the methods once and it will call it in all implemented objects?
Upvotes: 1
Views: 5607
Reputation: 34460
The other answers are correct, however it would be much better to use the composite pattern:
public interface GameComponent {
void render();
void update();
}
public abstract class ChildComponent implements GameComponent {
protected ContainerComponent parent; // (see below)
// getter and setter for parent
}
public class ContainerComponent implements GameComponent {
protected List<GameComponent> children = new ArrayList<>();
public void add(GameComponent child) {
this.children.add(child);
child.setParent(this);
}
@Override
public void update() {
for (GameComponent c : this.children) {
c.update();
}
}
@Override
public void render() {
for (GameComponent c : this.children) {
c.render();
}
}
}
Then you implement your specific GameComponent
s so that they extend either ChildComponent
or ContainerCompoenent
:
public class Player extends ChildComponent {
@Override
public void update() {
// update player
}
@Override
public void render() {
// render player
}
}
public class World extends ContainerComponent {
@Override
public void update() {
super.update(); // update world's children (the player)
// update the world (this can be done either after or before updating children,
// you choose how to update your world)
}
@Override
public void render() {
super.render(); // render world's children (the player)
// render the world (this can be done either after or before rendering children,
// you choose how to render your world)
}
}
Then, in your main loop:
// Create player and world
Player p = new Player();
World w = new World();
// Add player to world
w.add(p);
// Update everything
w.update();
// Render everything
w.render();
This way, you create a composite of GameComponent
s, and then you update()
and render()
just the topmost-level ContainerComponent
.
Upvotes: 3
Reputation: 7730
One of the main use of Interface is to achieve polymorphism, or the ability to perform the same operation on a number of different objects. If different objects all implement the same interface and have the same method, you can store all of those objects in a Vector/List, for example, and iterate through the Vector calling that method on each one.
As per your requirements :
interface I {
void render();
void update();
}
class first implements I {
public void update(){
// doWhaterver you want to do
}
public void render() {
// doWhaterver you want to do
}
}
class second implements I {
public void update(){
// doWhaterver you want to do
}
public void render() {
// doWhaterver you want to do
}
}
Now add them to List
List<I> list = new ArrayList();
list.add(new first());
list.add(new second());
for(I i:list) {
i.update();
i.render();
}
it will call the implemented function ,thats called Polymorphism
Upvotes: 0
Reputation: 1445
This is one of the pillars of object oriented programming, polymorphism.
Basically, you need to define an interface with the methods you need. Note that in java, interface methods are public by default.
public interface Renderable {
void render();
void update();
}
And then you define the implementation. To implement an interface you need to use the "implements" key word. In the example below, you'll see "implements Renderable"
public class MyRenderable implements Renderable {
public void render() {
... // method impl
}
public void update() {
... // method impl
}
}
And finally, you create an instance and call the methods through the interface.
Renderable r = new MyRenderable();
r.render();
r.update();
From here you can populate a list with the type being that of your interface. You can iterate over that list, calling the methods from the interface, invoking the implementations.
Upvotes: 0
Reputation: 24630
That is interface are for:
interface I {
void render();
}
class A implements I {
public void render() {
// render an A object ...
}
}
class B implements I {
public void render() {
// render an B object ...
}
}
and anywhere you may have
List<I> list = new ArrayList();
list.add(new A());
list.add(new B());
for(I i:list) {
i.render();
}
Objects of class A and B are diferent, but they implements the same contract (interface).
Upvotes: 0