Huge update. See detailed notes.
Keine Lust auf englischen Text gerade, hier die Übersicht: Es gibt jetzt eine eigene Datenstruktur, die im Grunde nichts weiter ist, als eine recht stumpfe, verkettete Liste. Besonderheit: Sie macht sich weniger Gedanken über Modifikationen während des Iterierens und wächst momentan etwas stetig. Es gibt eine neue Methode die() im LivingEntity, die per default Explosion auslöst und das Entity danach wegräumt. Wenn Items gedroppt werden sollen oder sonstwas passieren soll, bitte Overriden. Die Kollisionserkennung wurde in den CollisionHelper ausgelagert, zunächst aber noch mit Rectangles weitergeführt. Wer mutig genug ist, darf sich gerne austoben und eine Kollisionserkennung mit vielen If und ints bauen. :-) LivingEntity implementiert zunächst Hittable. Der Player kümmert sich selbst um Kollisionen mit Items aka aufsammeln. Das Collidable-Interface enthält alles notwendige für Kollisionserkennung auf int-Basis. Der Screen gibt nur noch Iteratoren für die Entity-Liste aus. Ich glaube, das wars.
This commit is contained in:
parent
dda0fb8313
commit
1086effdad
@ -0,0 +1,76 @@
|
||||
package de.teamteamteam.spacescooter.datastructure;
|
||||
|
||||
/**
|
||||
* The Iterator belonging to the link ConcurrentLinkedList.
|
||||
*/
|
||||
public class ConcurrentIterator<T> {
|
||||
|
||||
/**
|
||||
* List the iterator belongs to.
|
||||
*/
|
||||
private ConcurrentLinkedList<T> list;
|
||||
|
||||
/**
|
||||
* Current node the iterator is on.
|
||||
* Is null when the end of the list has been reached.
|
||||
*/
|
||||
private ConcurrentLinkedListNode<T> currentNode;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor initializing the iterator.
|
||||
*/
|
||||
public ConcurrentIterator(ConcurrentLinkedList<T> list) {
|
||||
this.list = list;
|
||||
this.reset();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset the Iterator to repeat the iteration.
|
||||
*/
|
||||
public void reset() {
|
||||
this.currentNode = this.list.head;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether there is one more element to iterate over.
|
||||
* Always use this for iteration purposes before calling next()!
|
||||
*/
|
||||
public boolean hasNext() {
|
||||
if(this.currentNode == null) {
|
||||
return false;
|
||||
}
|
||||
this.currentNode = this.currentNode.next();
|
||||
while(this.currentNode != null && this.currentNode.getValue() == null) {
|
||||
this.currentNode = this.currentNode.next();
|
||||
}
|
||||
return (this.currentNode != null && this.currentNode.getValue() != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next value.
|
||||
*/
|
||||
public T next() {
|
||||
if(this.currentNode == null) {
|
||||
throw new RuntimeException("End of concurrent list has no next element!");
|
||||
}
|
||||
T value = this.currentNode.getValue();
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add this element to the list.
|
||||
*/
|
||||
public void add(T element) {
|
||||
this.list.add(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the current element from the list.
|
||||
*/
|
||||
public void remove() {
|
||||
this.currentNode.setValue(null);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package de.teamteamteam.spacescooter.datastructure;
|
||||
|
||||
/**
|
||||
* A very simple and non-List conform type of List whose aim is to deal with
|
||||
* most concurrent modifications.
|
||||
*/
|
||||
public class ConcurrentLinkedList<T> {
|
||||
|
||||
/**
|
||||
* Head of the list.
|
||||
*/
|
||||
protected ConcurrentLinkedListNode<T> head;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor to initialize the empty list.
|
||||
*/
|
||||
public ConcurrentLinkedList() {
|
||||
this.head = new ConcurrentLinkedListNode<T>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add an element to the list.
|
||||
*/
|
||||
public void add(T element) {
|
||||
ConcurrentLinkedListNode<T> newNode = new ConcurrentLinkedListNode<T>(element);
|
||||
ConcurrentLinkedListNode<T> currentNode = this.head;
|
||||
while(currentNode.hasNext()) currentNode = currentNode.next();
|
||||
currentNode.setNext(newNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an element from the list.
|
||||
*/
|
||||
public void remove(T element) {
|
||||
ConcurrentIterator<T> iter = this.iterator();
|
||||
while (iter.hasNext()) {
|
||||
T e = iter.next();
|
||||
if (e.equals(element)) {
|
||||
iter.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Lists iterator.
|
||||
*/
|
||||
public ConcurrentIterator<T> iterator() {
|
||||
return new ConcurrentIterator<T>(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple way to print the whole list content for debugging purposes.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
ConcurrentLinkedListNode<T> currentNode = this.head;
|
||||
s.append(this.head + ": " + this.head.getValue() + "\n");
|
||||
while((currentNode = currentNode.next()) != null) {
|
||||
s.append(currentNode + ": " + currentNode.getValue() + "\n");
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package de.teamteamteam.spacescooter.datastructure;
|
||||
|
||||
/**
|
||||
* The node for the link ConcurrentLinkedList.
|
||||
*/
|
||||
public class ConcurrentLinkedListNode<T> {
|
||||
|
||||
/**
|
||||
* The next node after this one.
|
||||
*/
|
||||
private ConcurrentLinkedListNode<T> next;
|
||||
|
||||
/**
|
||||
* This nodes value.
|
||||
*/
|
||||
private T content;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor to create a null node.
|
||||
*/
|
||||
protected ConcurrentLinkedListNode() {
|
||||
this.content = null;
|
||||
this.next = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to create a node with content.
|
||||
*/
|
||||
protected ConcurrentLinkedListNode(T content) {
|
||||
this.content = content;
|
||||
this.next = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value for this list node.
|
||||
*/
|
||||
public void setValue(T content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nodes value.
|
||||
*/
|
||||
public T getValue() {
|
||||
return this.content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the next node.
|
||||
*/
|
||||
public void setNext(ConcurrentLinkedListNode<T> next) {
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the next node.
|
||||
*/
|
||||
public ConcurrentLinkedListNode<T> next() {
|
||||
return this.next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether the current node has a next node.
|
||||
*/
|
||||
public boolean hasNext() {
|
||||
return (this.next != null);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package de.teamteamteam.spacescooter.datastructure;
|
||||
|
||||
public class EntityContainer {
|
||||
|
||||
// private ConcurrentLinkedList<Background> backgrounds;
|
||||
// private ConcurrentLinkedList<Enemy> backgrounds;
|
||||
// private ConcurrentLinkedList<Player> backgrounds;
|
||||
// private ConcurrentLinkedList<Shot> backgrounds;
|
||||
// private ConcurrentLinkedList<Gui> backgrounds;
|
||||
//
|
||||
}
|
@ -1,14 +1,12 @@
|
||||
package de.teamteamteam.spacescooter.entity;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.List;
|
||||
|
||||
import de.teamteamteam.spacescooter.entity.enemy.Enemy;
|
||||
import de.teamteamteam.spacescooter.entity.explosion.Explosion;
|
||||
import de.teamteamteam.spacescooter.entity.item.Items;
|
||||
import de.teamteamteam.spacescooter.entity.shot.Shot;
|
||||
import de.teamteamteam.spacescooter.entity.spi.Collidable;
|
||||
import de.teamteamteam.spacescooter.screen.Screen;
|
||||
import de.teamteamteam.spacescooter.entity.spi.Hittable;
|
||||
import de.teamteamteam.spacescooter.utility.GameConfig;
|
||||
|
||||
/**
|
||||
@ -18,7 +16,7 @@ import de.teamteamteam.spacescooter.utility.GameConfig;
|
||||
* Also, it contains the generic logic about health points and shield points and
|
||||
* takes care of damage calculations.
|
||||
*/
|
||||
public abstract class LivingEntity extends Entity implements Collidable {
|
||||
public abstract class LivingEntity extends Entity implements Collidable, Hittable {
|
||||
|
||||
/**
|
||||
* Damage other LivingEntities take when colliding with this.
|
||||
@ -53,50 +51,24 @@ public abstract class LivingEntity extends Entity implements Collidable {
|
||||
this.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update logic containing basic collision detection and collision handling.
|
||||
*/
|
||||
public void update() {
|
||||
if(!(this instanceof ShootingEntity)) return; //Only check collisions for ShootingEntity.
|
||||
List<Entity> entities = Screen.currentScreen.getEntities();
|
||||
for (Entity e : entities) {
|
||||
if (e.equals(this)) //Do not collide with myself!
|
||||
continue;
|
||||
if(!(e instanceof Collidable)) //Do not collide with non-collidable!
|
||||
continue;
|
||||
Collidable ce = (Collidable) e;
|
||||
if (ce.getCollisionBox().intersects(this.getCollisionBox())) {
|
||||
this.collideWith(ce);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle collisions based on what the LivingEntity collided with.
|
||||
* Triggers damage calculations for both LivingEntities involved.
|
||||
* Triggers damage calculations for itself only.
|
||||
* Override to add specific behaviour, e.g. a Player picking up Items.
|
||||
*/
|
||||
public void collideWith(Collidable entity) {
|
||||
//this instanceof ShootingEntity
|
||||
if(entity instanceof Shot) {
|
||||
Shot s = (Shot) entity;
|
||||
this.takeDamage(s.getDamageValue());
|
||||
s.takeDamage(this.getCollisionDamage());
|
||||
}
|
||||
if(entity instanceof Player && (!(this instanceof Player))) {
|
||||
Player player = (Player) entity;
|
||||
player.takeDamage(this.getCollisionDamage());
|
||||
this.takeDamage(player.getCollisionDamage());
|
||||
}
|
||||
if(entity instanceof Enemy && (!(this instanceof Enemy))) {
|
||||
Enemy enemy = (Enemy) entity;
|
||||
enemy.takeDamage(this.getCollisionDamage());
|
||||
this.takeDamage(enemy.getCollisionDamage());
|
||||
}
|
||||
if(this instanceof Player && entity instanceof Items){
|
||||
Items item = (Items) entity;
|
||||
item.setHealthPoints(0);
|
||||
item.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,6 +98,8 @@ public abstract class LivingEntity extends Entity implements Collidable {
|
||||
* Also check for the need of triggering an explosion if dead.
|
||||
*/
|
||||
public void takeDamage(int damage) {
|
||||
//Skip everything if already dead.
|
||||
if(this.isAlive() == false) return;
|
||||
if(this instanceof Shot) {
|
||||
if(GameConfig.DEBUG) System.out.println("Shot took damage: " + damage + "left: "+this.getHealthPoints()+" (" + this + ")");
|
||||
}
|
||||
@ -133,8 +107,7 @@ public abstract class LivingEntity extends Entity implements Collidable {
|
||||
this.healthPoints -= damage;
|
||||
if (this.isAlive() == false) {
|
||||
if(GameConfig.DEBUG) System.out.println(this + " ist gestorben. RIP");
|
||||
this.explode();
|
||||
this.remove();
|
||||
this.die();
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,6 +118,15 @@ public abstract class LivingEntity extends Entity implements Collidable {
|
||||
public void explode() {
|
||||
new Explosion(this.getX(), this.getY());
|
||||
}
|
||||
|
||||
/**
|
||||
* The default way the LivingEntity dies.
|
||||
* Override this method for a different death behaviour.
|
||||
*/
|
||||
public void die() {
|
||||
this.explode();
|
||||
this.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current health points.
|
||||
|
@ -4,7 +4,9 @@ import java.awt.event.KeyEvent;
|
||||
|
||||
import de.teamteamteam.spacescooter.control.Keyboard;
|
||||
import de.teamteamteam.spacescooter.control.KeyboardListener;
|
||||
import de.teamteamteam.spacescooter.entity.item.Items;
|
||||
import de.teamteamteam.spacescooter.entity.shot.Shot;
|
||||
import de.teamteamteam.spacescooter.entity.spi.Collidable;
|
||||
import de.teamteamteam.spacescooter.sound.SoundSystem;
|
||||
import de.teamteamteam.spacescooter.utility.GameConfig;
|
||||
|
||||
@ -53,6 +55,16 @@ public class Player extends ShootingEntity implements KeyboardListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collideWith(Collidable entity) {
|
||||
super.collideWith(entity);
|
||||
if(this instanceof Player && entity instanceof Items){
|
||||
Items item = (Items) entity;
|
||||
item.setHealthPoints(0);
|
||||
item.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void explode() {
|
||||
super.explode();
|
||||
@ -86,6 +98,5 @@ public class Player extends ShootingEntity implements KeyboardListener {
|
||||
}
|
||||
|
||||
public void keyTyped(KeyEvent e) {}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -73,7 +73,6 @@ public abstract class ShootingEntity extends LivingEntity {
|
||||
* Update logic making sure that the currentShootDelay is updated.
|
||||
*/
|
||||
public void update() {
|
||||
super.update();
|
||||
if(this.currentShootDelay > 0) this.currentShootDelay--;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
package de.teamteamteam.spacescooter.entity.enemy;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import de.teamteamteam.spacescooter.datastructure.ConcurrentIterator;
|
||||
import de.teamteamteam.spacescooter.entity.Entity;
|
||||
import de.teamteamteam.spacescooter.entity.Player;
|
||||
import de.teamteamteam.spacescooter.entity.item.Items;
|
||||
@ -30,6 +29,16 @@ public class EnemyThree extends Enemy{
|
||||
this.newY = this.getY();
|
||||
}
|
||||
|
||||
/**
|
||||
* This enemy spawns an Item on its death and causes another enemy to appear.
|
||||
*/
|
||||
@Override
|
||||
public void die() {
|
||||
if(random.nextInt(10) < 5) Items.create(getX(), getY());
|
||||
new EnemyThree(0, 0);
|
||||
super.die();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
@ -38,12 +47,7 @@ public class EnemyThree extends Enemy{
|
||||
this.remove();
|
||||
new EnemyThree(0, 0);
|
||||
}
|
||||
if(!this.isAlive()){
|
||||
if(random.nextInt(10) < 5) Items.create(getX(), getY());
|
||||
new EnemyThree(0, 0);
|
||||
}
|
||||
List<Entity> list = Screen.currentScreen.getEntities();
|
||||
Iterator<Entity> i = list.iterator();
|
||||
ConcurrentIterator<Entity> i = Screen.currentScreen.getEntityIterator();
|
||||
while (i.hasNext()) {
|
||||
Entity entity = i.next();
|
||||
if(entity instanceof Player){
|
||||
|
@ -1,7 +1,6 @@
|
||||
package de.teamteamteam.spacescooter.entity.item;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.teamteamteam.spacescooter.datastructure.ConcurrentIterator;
|
||||
import de.teamteamteam.spacescooter.entity.Entity;
|
||||
import de.teamteamteam.spacescooter.entity.LivingEntity;
|
||||
import de.teamteamteam.spacescooter.entity.Player;
|
||||
@ -20,8 +19,9 @@ public abstract class Items extends LivingEntity{
|
||||
this.remove();
|
||||
};
|
||||
if(!this.isAlive()){
|
||||
List<Entity> entities = Screen.currentScreen.getEntities();
|
||||
for (Entity e : entities) {
|
||||
ConcurrentIterator<Entity> i = Screen.currentScreen.getEntityIterator();
|
||||
while(i.hasNext()) {
|
||||
Entity e = i.next();
|
||||
if(e instanceof Player){
|
||||
itemCollected((Player) e);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package de.teamteamteam.spacescooter.entity.shot;
|
||||
|
||||
import de.teamteamteam.spacescooter.entity.LivingEntity;
|
||||
import de.teamteamteam.spacescooter.entity.spi.Collidable;
|
||||
import de.teamteamteam.spacescooter.utility.GameConfig;
|
||||
|
||||
/**
|
||||
@ -77,4 +78,16 @@ public class Shot extends LivingEntity {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When a shot collides with something, leave behind a small explosion
|
||||
* and vanish.
|
||||
* TODO: Stronger shots may later survive a specific amount of collisions.
|
||||
*/
|
||||
@Override
|
||||
public void collideWith(Collidable entity) {
|
||||
super.collideWith(entity);
|
||||
this.explode();
|
||||
this.remove();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,16 +1,29 @@
|
||||
package de.teamteamteam.spacescooter.entity.spi;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
/**
|
||||
* Interface providing everything needed for collision handling.
|
||||
*/
|
||||
public interface Collidable {
|
||||
|
||||
/**
|
||||
* Provide information about the position and dimensions of the Entity.
|
||||
* Get X-Position of the Collidable.
|
||||
*/
|
||||
public Rectangle getCollisionBox();
|
||||
public int getX();
|
||||
|
||||
/**
|
||||
* Get Y-Position of the Collidable.
|
||||
*/
|
||||
public int getY();
|
||||
|
||||
/**
|
||||
* Get the width of the Collidable.
|
||||
*/
|
||||
public int getWidth();
|
||||
|
||||
/**
|
||||
* Get the height of the Collidable.
|
||||
*/
|
||||
public int getHeight();
|
||||
|
||||
/**
|
||||
* Notify the Collidable that a collision happened.
|
||||
|
@ -23,7 +23,7 @@ public interface Hittable {
|
||||
/**
|
||||
* Set the Hittables current health points.
|
||||
*/
|
||||
public int setHealthPoints();
|
||||
public void setHealthPoints(int healthPoints);
|
||||
|
||||
/**
|
||||
* Get the Hittables current shield points.
|
||||
@ -33,7 +33,7 @@ public interface Hittable {
|
||||
/**
|
||||
* Set the Hittables current shield points.
|
||||
*/
|
||||
public int setShieldPoints();
|
||||
public void setShieldPoints(int shieldPoints);
|
||||
|
||||
|
||||
|
||||
|
@ -2,8 +2,8 @@ package de.teamteamteam.spacescooter.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.List;
|
||||
|
||||
import de.teamteamteam.spacescooter.datastructure.ConcurrentIterator;
|
||||
import de.teamteamteam.spacescooter.entity.Entity;
|
||||
import de.teamteamteam.spacescooter.entity.Player;
|
||||
import de.teamteamteam.spacescooter.screen.Screen;
|
||||
@ -20,8 +20,9 @@ public class HealthBar extends Entity {
|
||||
}
|
||||
|
||||
public void paint(Graphics2D g) {
|
||||
List<Entity> entities = Screen.currentScreen.getEntities();
|
||||
for (Entity e : entities) {
|
||||
ConcurrentIterator<Entity> entities = Screen.currentScreen.getEntityIterator();
|
||||
while(entities.hasNext()) {
|
||||
Entity e = entities.next();
|
||||
if(e instanceof Player){
|
||||
this.width = ((Player) e).getHealthPoints();
|
||||
}
|
||||
|
@ -5,10 +5,9 @@ import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import de.teamteamteam.spacescooter.control.Keyboard;
|
||||
import de.teamteamteam.spacescooter.datastructure.ConcurrentIterator;
|
||||
import de.teamteamteam.spacescooter.entity.Entity;
|
||||
import de.teamteamteam.spacescooter.entity.Player;
|
||||
import de.teamteamteam.spacescooter.gui.Button;
|
||||
@ -43,8 +42,7 @@ public class GameOverScreen extends Screen {
|
||||
@Override
|
||||
protected void paint(Graphics2D g) {
|
||||
g.drawImage(this.img, 0, 0, null);
|
||||
List<Entity> list = this.getEntities();
|
||||
Iterator<Entity> i = list.iterator();
|
||||
ConcurrentIterator<Entity> i = this.getEntityIterator();
|
||||
while (i.hasNext()) {
|
||||
i.next().paint(g);
|
||||
}
|
||||
@ -59,8 +57,7 @@ public class GameOverScreen extends Screen {
|
||||
|
||||
@Override
|
||||
protected void update() {
|
||||
List<Entity> list = this.getEntities();
|
||||
Iterator<Entity> i = list.iterator();
|
||||
ConcurrentIterator<Entity> i = this.getEntityIterator();
|
||||
while (i.hasNext()) {
|
||||
i.next().update();
|
||||
}
|
||||
|
@ -5,10 +5,9 @@ import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import de.teamteamteam.spacescooter.control.Keyboard;
|
||||
import de.teamteamteam.spacescooter.datastructure.ConcurrentIterator;
|
||||
import de.teamteamteam.spacescooter.entity.Entity;
|
||||
import de.teamteamteam.spacescooter.entity.Player;
|
||||
import de.teamteamteam.spacescooter.gui.Button;
|
||||
@ -43,8 +42,7 @@ public class GamePausedScreen extends Screen {
|
||||
@Override
|
||||
protected void paint(Graphics2D g) {
|
||||
g.drawImage(this.img, 0, 0, null);
|
||||
List<Entity> list = this.getEntities();
|
||||
Iterator<Entity> i = list.iterator();
|
||||
ConcurrentIterator<Entity> i = this.getEntityIterator();
|
||||
while (i.hasNext()) {
|
||||
i.next().paint(g);
|
||||
}
|
||||
@ -59,8 +57,7 @@ public class GamePausedScreen extends Screen {
|
||||
|
||||
@Override
|
||||
protected void update() {
|
||||
List<Entity> list = this.getEntities();
|
||||
Iterator<Entity> i = list.iterator();
|
||||
ConcurrentIterator<Entity> i = this.getEntityIterator();
|
||||
while (i.hasNext()) {
|
||||
i.next().update();
|
||||
}
|
||||
|
@ -4,17 +4,17 @@ import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import de.teamteamteam.spacescooter.background.StarBackground;
|
||||
import de.teamteamteam.spacescooter.control.Keyboard;
|
||||
import de.teamteamteam.spacescooter.datastructure.ConcurrentIterator;
|
||||
import de.teamteamteam.spacescooter.entity.Entity;
|
||||
import de.teamteamteam.spacescooter.entity.Player;
|
||||
import de.teamteamteam.spacescooter.entity.enemy.EnemyFour;
|
||||
import de.teamteamteam.spacescooter.entity.enemy.EnemyThree;
|
||||
import de.teamteamteam.spacescooter.entity.item.ItemChance;
|
||||
import de.teamteamteam.spacescooter.gui.HealthBar;
|
||||
import de.teamteamteam.spacescooter.utility.CollisionHandler;
|
||||
|
||||
/**
|
||||
* In this GameScreen, the actual gameplay takes place.
|
||||
@ -42,8 +42,7 @@ public class GameScreen extends Screen {
|
||||
|
||||
@Override
|
||||
protected void paint(Graphics2D g) {
|
||||
List<Entity> list = this.getEntities();
|
||||
Iterator<Entity> i = list.iterator();
|
||||
ConcurrentIterator<Entity> i = this.getEntityIterator();
|
||||
while (i.hasNext()) {
|
||||
i.next().paint(g);
|
||||
}
|
||||
@ -51,20 +50,26 @@ public class GameScreen extends Screen {
|
||||
|
||||
@Override
|
||||
protected void update() {
|
||||
List<Entity> list = this.getEntities();
|
||||
Iterator<Entity> i = list.iterator();
|
||||
ConcurrentIterator<Entity> i = this.getEntityIterator();
|
||||
while (i.hasNext()) {
|
||||
i.next().update();
|
||||
}
|
||||
// Pass the collision handler a copy of the entity list
|
||||
CollisionHandler.handleCollisions();
|
||||
if (Keyboard.isKeyDown(KeyEvent.VK_ESCAPE)) {
|
||||
this.setOverlay(new GamePausedScreen(this));
|
||||
}
|
||||
if (list.get(1) instanceof Player) {
|
||||
Player player = (Player) list.get(1);
|
||||
if (!player.isAlive()) {
|
||||
this.parent.setOverlay(new GameOverScreen(this.parent));
|
||||
i.reset();
|
||||
while (i.hasNext()) {
|
||||
Entity e = i.next();
|
||||
if (e instanceof Player) {
|
||||
Player player = (Player) e;
|
||||
if (!player.isAlive()) {
|
||||
this.parent.setOverlay(new GameOverScreen(this.parent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,13 +3,11 @@ package de.teamteamteam.spacescooter.screen;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import de.teamteamteam.spacescooter.background.StarBackground;
|
||||
import de.teamteamteam.spacescooter.control.Keyboard;
|
||||
import de.teamteamteam.spacescooter.datastructure.ConcurrentIterator;
|
||||
import de.teamteamteam.spacescooter.entity.Entity;
|
||||
import de.teamteamteam.spacescooter.entity.Player;
|
||||
import de.teamteamteam.spacescooter.gui.Button;
|
||||
@ -43,8 +41,7 @@ public class MainMenuScreen extends Screen {
|
||||
|
||||
@Override
|
||||
public void paint(Graphics2D g) {
|
||||
List<Entity> list = this.getEntities();
|
||||
Iterator<Entity> i = list.iterator();
|
||||
ConcurrentIterator<Entity> i = this.getEntityIterator();
|
||||
while (i.hasNext()) {
|
||||
i.next().paint(g);
|
||||
}
|
||||
@ -62,8 +59,7 @@ public class MainMenuScreen extends Screen {
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
List<Entity> list = this.getEntities();
|
||||
Iterator<Entity> i = list.iterator();
|
||||
ConcurrentIterator<Entity> i = this.getEntityIterator();
|
||||
while (i.hasNext()) {
|
||||
i.next().update();
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package de.teamteamteam.spacescooter.screen;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import de.teamteamteam.spacescooter.datastructure.ConcurrentIterator;
|
||||
import de.teamteamteam.spacescooter.datastructure.ConcurrentLinkedList;
|
||||
import de.teamteamteam.spacescooter.entity.Entity;
|
||||
|
||||
/**
|
||||
@ -33,17 +33,19 @@ public abstract class Screen {
|
||||
/**
|
||||
* List of entities this screen is taking care of
|
||||
*/
|
||||
protected List<Entity> entities;
|
||||
|
||||
private ConcurrentLinkedList<Entity> entities;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize parent, overlay and the Entity list
|
||||
*/
|
||||
public Screen(Screen parent) {
|
||||
this.setOverlay(null);
|
||||
this.parent = parent;
|
||||
this.entities = new LinkedList<Entity>();
|
||||
this.entities = new ConcurrentLinkedList<Entity>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Method for each Screen to implement. Does the actual painting.
|
||||
*/
|
||||
@ -69,12 +71,13 @@ public abstract class Screen {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a copy of the List of the Entities this Screen takes care of.
|
||||
* Get an Iterator over the Entity List.
|
||||
* Use this within update method context!
|
||||
*/
|
||||
public List<Entity> getEntities() {
|
||||
return new LinkedList<Entity>(this.entities);
|
||||
public ConcurrentIterator<Entity> getEntityIterator() {
|
||||
return this.entities.iterator();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This gets called by the PaintThread. It takes care of the painting order,
|
||||
* so an overlay Screen is actually in front of its parent Screen.
|
||||
@ -99,19 +102,6 @@ public abstract class Screen {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When a Screens life ends, because it is removed, this method will take
|
||||
* care of existing overlays and remove all references to existing entities.
|
||||
*/
|
||||
public void cleanup() {
|
||||
if(this.overlay != null) this.overlay.cleanup();
|
||||
//tell all entities to cleanup themselves.
|
||||
for(Entity e : this.getEntities()) {
|
||||
e.remove();
|
||||
}
|
||||
this.entities.removeAll(this.entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the overlay Screen for the current Screen. In case an overlay is
|
||||
* being replaced, the old overlays cleanup-method is called. Also, this
|
||||
@ -127,4 +117,18 @@ public abstract class Screen {
|
||||
}
|
||||
this.overlay = screen;
|
||||
}
|
||||
|
||||
/**
|
||||
* When a Screens life ends, because it is removed, this method will take
|
||||
* care of existing overlays and remove all references to existing entities.
|
||||
*/
|
||||
private void cleanup() {
|
||||
if(this.overlay != null) this.overlay.cleanup();
|
||||
//tell all entities to cleanup themselves.
|
||||
ConcurrentIterator<Entity> i = this.getEntityIterator();
|
||||
while(i.hasNext()) {
|
||||
Entity e = i.next();
|
||||
e.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,74 @@
|
||||
package de.teamteamteam.spacescooter.utility;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import de.teamteamteam.spacescooter.datastructure.ConcurrentIterator;
|
||||
import de.teamteamteam.spacescooter.entity.Entity;
|
||||
import de.teamteamteam.spacescooter.entity.Player;
|
||||
import de.teamteamteam.spacescooter.entity.enemy.Enemy;
|
||||
import de.teamteamteam.spacescooter.entity.spi.Collidable;
|
||||
import de.teamteamteam.spacescooter.screen.Screen;
|
||||
|
||||
/**
|
||||
* This class contains helper methods to handle collisions efficiently.
|
||||
*/
|
||||
public class CollisionHandler {
|
||||
|
||||
/**
|
||||
* Private constructor, this class will not be instantiated.
|
||||
*/
|
||||
private CollisionHandler() {}
|
||||
|
||||
|
||||
/**
|
||||
* Use a list of entities to filter out the ones that can collide with each other,
|
||||
* then intelligently check them against each other to reduce the amount of checks.
|
||||
*/
|
||||
public static void handleCollisions() {
|
||||
ConcurrentIterator<Entity> iteratorOne = Screen.currentScreen.getEntityIterator();
|
||||
ConcurrentIterator<Entity> iteratorTwo = Screen.currentScreen.getEntityIterator();
|
||||
while(iteratorOne.hasNext()) {
|
||||
Entity entityOne = iteratorOne.next();
|
||||
//Only check Player and Enemy for the active side of a collision.
|
||||
if(!((entityOne instanceof Player) || (entityOne instanceof Enemy))) continue;
|
||||
Collidable collidableOne = (Collidable) entityOne;
|
||||
//Loop to check collisions against entityOne.
|
||||
iteratorTwo.reset();
|
||||
while(iteratorTwo.hasNext()) {
|
||||
Entity entityTwo = iteratorTwo.next();
|
||||
//We want all Collidables on the passive side of the collision.
|
||||
if(!(entityTwo instanceof Collidable)) continue;
|
||||
Collidable collidableTwo = (Collidable) entityTwo;
|
||||
//skip checks against itself
|
||||
if(entityTwo.equals(entityOne)) continue;
|
||||
//Weed out Player and Enemy from the passive side
|
||||
if(entityTwo instanceof Player || entityTwo instanceof Enemy) continue;
|
||||
//check for the actual collision
|
||||
if(CollisionHandler.doCollide(collidableOne, collidableTwo)) {
|
||||
CollisionHandler.handleCollision(collidableOne, collidableTwo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the collision between the two given Collidables by telling each
|
||||
* of them, who it collided with.
|
||||
*/
|
||||
private static void handleCollision(Collidable collidableOne,
|
||||
Collidable collidableTwo) {
|
||||
collidableOne.collideWith(collidableTwo);
|
||||
collidableTwo.collideWith(collidableOne);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if two Collidables actually collided.
|
||||
* TODO: Do not use Rectangles, since there are so many created that it gets messy.
|
||||
*/
|
||||
private static boolean doCollide(Collidable cOne, Collidable cTwo) {
|
||||
Rectangle one = new Rectangle(cOne.getX() , cOne.getY(), cOne.getWidth(), cOne.getHeight());
|
||||
Rectangle two = new Rectangle(cTwo.getX() , cTwo.getY(), cTwo.getWidth(), cTwo.getHeight());
|
||||
return one.intersects(two);
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user