Improve implementation continuous/spontaneous fire.

Das Keyboard bietet nun allen, die den KeyboardListener implementieren,
den Service, sich an ihm zu registrieren.
Ist dies erfolgt, so reicht es die Events an die registrierten Listener
weiter.
Auf diese Weise wurde das Dauerfeuer und Spontanfeuer implementiert.
This commit is contained in:
Jan Philipp Timme 2014-11-04 19:07:44 +01:00
parent cf8ff46dfb
commit 16bcddb273
5 changed files with 134 additions and 30 deletions

View File

@ -4,34 +4,104 @@ import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
/**
* This is our main control input source.
* It accumulates pressed keys, so we can use them to do player movement and more.
* It also provides methods to pass on the KeyListener events in case somebody wants
* to implement something special (such as continuous fire versus spontaneous fire)
*/
public class Keyboard implements KeyListener {
/**
* Instance of the Keyboard class to pass to others.
*/
private static Keyboard instance = new Keyboard();
/**
* ArrayList containing registered KeyboardListeners.
*/
private static ArrayList<KeyboardListener> listener = new ArrayList<KeyboardListener>();
/**
* ArrayList containing the currently pressed keys.
*/
private static ArrayList<Integer> activeKeys = new ArrayList<Integer>();
/**
* Private constructor, this class will only be instantiated once.
*/
private Keyboard() {}
/**
* Static method to get the Keyboard instance.
*/
public static Keyboard getInstance() {
return Keyboard.instance;
}
/**
* Returns true if the given keyCodes key is down.
*/
public static boolean isKeyDown(int keyCode) {
return Keyboard.activeKeys.contains((Integer) keyCode);
}
/**
* Returns true if the given keyCodes key is up.
*/
public static boolean isKeyUp(int keyCode) {
return !Keyboard.activeKeys.contains((Integer) keyCode);
}
public void keyPressed(KeyEvent e) {
if(Keyboard.activeKeys.contains((Integer) e.getKeyCode())) return;
Keyboard.activeKeys.add((Integer) e.getKeyCode());
/**
* Register given listener to the event notifications.
*/
public void addListener(KeyboardListener listener) {
Keyboard.listener.add(listener);
}
/**
* Remove the given listener from the event notifications.
*/
public void removeListener(KeyboardListener listener) {
Keyboard.listener.remove(Keyboard.listener);
}
/**
* KeyListener method.
* Registers the pressed key and passes the event on to registered listeners.
*/
public void keyPressed(KeyEvent e) {
if(Keyboard.activeKeys.contains((Integer) e.getKeyCode())){
return;
}
Keyboard.activeKeys.add((Integer) e.getKeyCode());
for(KeyboardListener kl : Keyboard.listener) kl.keyPressed(e);
}
/**
* KeyListener method.
* Registers the released key and passes the event on to registered listeners.
*/
public void keyReleased(KeyEvent e) {
if(Keyboard.activeKeys.contains((Integer) e.getKeyCode())) {
Keyboard.activeKeys.remove((Integer) e.getKeyCode());
}
for(KeyboardListener kl : Keyboard.listener) kl.keyReleased(e);
}
/**
* KeyListener method.
* Registers the typed key and passes the event on to registered listeners.
*/
public void keyTyped(KeyEvent e) {
for(KeyboardListener kl : Keyboard.listener) kl.keyTyped(e);
//Nice for cheatcodes and eastereggs later...
//System.out.println("keyTyped: " + e);
}
}

View File

@ -0,0 +1,10 @@
package de.teamteamteam.spacescooter.control;
import java.awt.event.KeyListener;
/**
* Marker Interface for the Keyboard to check for compliant listeners on registration.
*/
public interface KeyboardListener extends KeyListener {
}

View File

@ -1,24 +1,31 @@
package de.teamteamteam.spacescooter.entity;
import java.awt.event.KeyEvent;
import de.teamteamteam.spacescooter.control.Keyboard;
import de.teamteamteam.spacescooter.control.KeyboardListener;
import de.teamteamteam.spacescooter.utility.GameConfig;
public class Player extends ShootingEntity {
public class Player extends ShootingEntity implements KeyboardListener {
private boolean shoot = false;
private boolean canMove = true;
private Keyboard keyboard = null;
public Player(int x, int y) {
super(x, y);
this.setImage("images/ship.png");
this.setShootDelay(5);
this.setShootDelay(20);
this.setShootSpawn(50, 16);
this.setShootDirection(Shot.RIGHT);
this.setShootSpeed(10);
this.setHealthPoints(100);
inputThread.start();
this.registerOnKeyboard(Keyboard.getInstance());
}
private void registerOnKeyboard(Keyboard keyboard) {
this.keyboard = keyboard;
this.keyboard.addListener(this);
}
public void update() {
@ -37,32 +44,45 @@ public class Player extends ShootingEntity {
if(Keyboard.isKeyDown(KeyEvent.VK_RIGHT) && this.x < (GameConfig.windowWidth - this.getImage().getWidth())) {
this.x += off;
}
if(shoot == true) {
//continuous fire takes place here
if(Keyboard.isKeyDown(KeyEvent.VK_SPACE)) {
this.shoot();
setShootDelay(20);
}
}
}
public void setCanMove(boolean canMove){
this.canMove = canMove;
}
public void setShoot(boolean shoot){
this.shoot = shoot;
/**
* On cleanup, unregister from the keyboard.
*/
@Override
public void remove() {
super.remove();
this.keyboard.removeListener(this);
this.keyboard = null;
}
Thread inputThread = new Thread(new Runnable() {
public void run() {
while (true) {
setShootDelay(5);
setShoot(false);
while(Keyboard.isKeyDown(KeyEvent.VK_SPACE)) {
setShoot(true);
}
}
}
});
@Override
public void keyPressed(KeyEvent e) {
//spontaneous fire happens here
if(e.getKeyCode() == KeyEvent.VK_SPACE) {
this.shoot();
}
}
@Override
public void keyReleased(KeyEvent e) {
//space up -> reset shot cooldown
if(e.getKeyCode() == KeyEvent.VK_SPACE) {
this.resetShootDelay();
}
}
@Override
public void keyTyped(KeyEvent e) {}
}

View File

@ -41,6 +41,10 @@ public abstract class ShootingEntity extends LivingEntity {
this.shootDelay = shootDelay;
}
public void resetShootDelay() {
this.currentShootDelay = 0;
}
public void setShootSpawn(int x, int y) {
this.shootSpawnX = x;
this.shootSpawnY = y;

View File

@ -39,7 +39,7 @@ public class GameFrame extends JFrame {
// Make sure we get the keyboard events. Use Keyboard.isKeyDown() to ask
// about keys status.
this.addKeyListener(new Keyboard());
this.addKeyListener(Keyboard.getInstance());
this.setVisible(true);