I'm making a tankgame. In my PlayPanel
class I wrote this code, as you can see it is mostly the same but it's used for 3 different ArrayList
s.
I would really like to know how to write this method once only in order to reuse it for all the ArrayList
s because it seems so untidy.
//obstacles
for (int i = 0 ; i<obstacles.size() ; i++) {
if (obstacles.get(i).dood)
obstacles.remove(i);
}
//bullets
for (int i = 0; i< bullets.size(); i++) {
bullets.get(i).redraw();
//de positie van elke kogel wordt geupdate.
if(bullets.get(i).OutOfScreen()) {
bullets.remove(i);//uit scherm -> verwijdert en verplaatst
}
}
for (int i = 0; i< enemyBullets.size(); i++) {
enemyBullets.get(i).redraw();
if(enemyBullets.get(i).OutOfScreen()) {
enemyBullets.remove(i);
}
}
I thought about writing this, but it doesn't seem right:
public void remove(ArrayList object) {
for (int i = 0; i< object.size(); i++) {
object.get(i).redraw();
if(object.get(i).OutOfScreen()) {
object.remove(i);
}
}
}
Also, I don't really know how to call this method to use it for one of the ArrayList
s.
If you use Java 8, you can filter the list with by passing a Predicate
.
public class Helper {
//removePredicate can be any function that returns a boolean that will help
//to filter the data
static <T> void remove(List<T> list, Predicate<? super T> removePredicate) {
List<T> filteredList = list.stream()
.filter(removePredicate)
.collect(Collectors.toList());
list.clear();
list.addAll(filteredList);
}
}
Here's an example of how to use method above for List<Bullet>
:
//sample implementation for Bullet class
class Bullet {
int value;
public Bullet(int value) { this.value = value; }
public boolean outOfScreen() {
return value > 10;
}
@Override public String toString() {
return String.format("Bullet: {%d}", value);
}
}
//somewhere you need to execute this code...
//initialize your List
List<Bullet> bulletList = new ArrayList<>(Arrays.asList(
new Bullet(15), new Bullet(1), new Bullet(20), new Bullet(6)));
//show the contents of the list
System.out.println(bulletList);
//remove the elements by using whatever you want/need
//see how you can pass any way to filter the elements of the list
Helper.remove(bulletList, b -> !b.outOfScreen());
//show the contents of the list again to show how it was filtered
System.out.println(bulletList);
The benefit of using this approach is that you don't need class inheritance or something like that.
The second and third loop can be combined in a single piece of code as shown as follows.
- You have a parent class (Abstract or Interface) called ParentBullets.
- Bullets and EnemyBullets are child classes of ParentBullets class.
Now via Polymorphism you can do the following
public void loop(List<? extends ParentBullets> bullets){
for (int i = 0; i< bullets.size(); i++) {
bullets.get(i).redraw();
//de positie van elke kogel wordt geupdate.
if(bullets.get(i).OutOfScreen()) {
bullets.remove(i);//uit scherm -> verwijdert en verplaatst
}
}
}
Now you can have bullets and enemybullets as a collection is an ArrayList and you can call the above method like:
loop(bullets);
or
loop(enemyBullets);
Your method remove
won't work, since you are giving as an argument an ArrayList
of Object
s. They don't have methods redraw
and OutOfScreen
. What you could do is define an interface, say GameObject
, containing these methods, and make Bullet
implement it.
Change signature of remove
to
public void remove(ArrayList<? extends GameObject> object) {
//rest as before
}
Then you can call for example remove(bullets)
or remove(enemyBullets)
.