So I am trying to make a basic game engine, based around the idea of tags, where every object has a bunch of tags that I can use to group things like wall segments and perform actions on them all at once. Since I don't want to have to surround every function with a loop to call it on each object, I am trying to make a method that can call the passed method on each object.
here is some example suto-code:
//have a list of objs. some door, some not.
//an example of stuff I could want to do
// - check returns on any functions called
// - call a function on a bunch of objects, possibly with parameters
if (runOnTag("door", isClosed())[aPositionInReturnList] == true){
runOnTag("door", open());
}
//the method
public couldBeAnyType[] runOnTag(String tag, function(anyPerams)){ //dont want the function to compile here
for (String currentObj : listOfObjsWith[tag]){
returns[index++] = currentObj.function(anyPerams); //so that it can be executed on this object
}
return returns; //want to be able to colect returns
}
I have already looked through a bunch of other answers to this type of question, but I don't understand what is going on in them. If anyone could explain it more simply, I would greatly appreciate it.
Assumption: you do not have objects that change tags dynamically.
Why not implement your tags as interfaces? This is faster than string matching, type-safe and in general more efficient.
interface Door {boolean isClosed(); void open();}
class State {
private Collection<Object> gameObjects;
public <T,R> Stream<R> onTagged(Class<T> type, Function<T,R> apply) {
return gameObjects
.stream()
.filter(type::isInstance)
.map(type::cast)
.map(apply);
}
}
Ignore the name ( onTagged
), make your own. This can be used like this fe to find if there is any door open:
State state = ...;
if(state.onTagged(Door.class, door -> !door.isClosed()).anyMatch(Boolean.TRUE::equals)) {
// ... do stuff ...
}
You will however find that it's usually better like this, because then you can compose operations (map/filter/any*) very easily:
public <T> Stream<T> withTag(Class<T> type) {
return gameObjects
.stream()
.filter(type::isInstance)
.map(type::cast);
}
if(state.withTag(Door.class).anyMatch(door -> !door.isClosed())) {
// ... do stuff ...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.