diff --git a/pom.xml b/pom.xml
index 8692d4b..e5c8d17 100644
--- a/pom.xml
+++ b/pom.xml
@@ -49,6 +49,17 @@
4.13.2
test
+
+ net.java.jinput
+ jinput
+ 2.0.10
+
+
+ net.java.jinput
+ jinput
+ 2.0.10
+ natives-all
+
21
@@ -80,6 +91,7 @@
UTF-8
+
org.apache.maven.plugins
maven-dependency-plugin
@@ -150,6 +162,19 @@
maven-project-info-reports-plugin
3.5.0
+
+ com.googlecode.mavennatives
+ maven-nativedependencies-plugin
+ 0.0.7
+
+
+ unpacknatives
+
+ copy
+
+
+
+
diff --git a/src/com/redomar/game/Game.java b/src/com/redomar/game/Game.java
index f5b5709..3716d45 100644
--- a/src/com/redomar/game/Game.java
+++ b/src/com/redomar/game/Game.java
@@ -423,7 +423,13 @@ public void run() {
*/
public void tick() {
setTickCount(getTickCount() + 1);
+
+ // Polling the controller on every tick
+ input.pollController();
+
+ // Example of existing input handling logic
Either musicKeyAction = input.toggleActionWithCheckedRunnable(input.getM_KEY(), musicPlaying, () -> Game.getBackgroundMusic().play(), () -> Game.getBackgroundMusic().stop());
+
musicKeyAction.either(exception -> {
printer.cast().print("Failed to play music", PrintTypes.MUSIC);
printer.exception(exception.toString());
@@ -434,9 +440,12 @@ public void tick() {
input.overWriteKey(input.getM_KEY(), false);
}
});
+
+ // Update game logic (e.g., entities, levels)
level.tick();
}
+
/**
* This method displays the current state of the game.
*/
@@ -466,7 +475,7 @@ public void render() {
for (int y = 0; y < screen2.getHeight(); y++) {
for (int x = 0; x < screen2.getWidth(); x++) {
int colourCode = screen2.getPixels()[x + y * screen2.getWidth()];
- if (colourCode < 1){
+ if (colourCode < 1) {
pixels3[x + y * WIDTH] = 0xff0000;
} else if (colourCode < 255) {
pixels3[x + y * WIDTH] = colours[colourCode];
@@ -537,7 +546,7 @@ public void render() {
*/
private void overlayRender(Graphics2D g) {
g.setColor(new Color(0f, 0f, 0f, 0f)); // Transparent color
- g.fillRect(0, 0, getWidth(), getHeight()-30);
+ g.fillRect(0, 0, getWidth(), getHeight() - 30);
}
/*
diff --git a/src/com/redomar/game/entities/Mob.java b/src/com/redomar/game/entities/Mob.java
index 1c71e05..63ddf3d 100644
--- a/src/com/redomar/game/entities/Mob.java
+++ b/src/com/redomar/game/entities/Mob.java
@@ -225,9 +225,10 @@ protected void moveMob(double xa, double ya, Mob mob) {
}
}
- protected void shoot(double x, double y, double dir, double buttonId) {
+ protected void shoot(double x, double y, double dir, double buttonId, double[] playerVelocity) {
if (buttonId == 1) {
- Projectile p = new Small(level, (int) x, (int) y, dir);
+ // model the projectile speed and direction as a 2d vector
+ Projectile p = new Small(level, (int) x, (int) y, dir, playerVelocity);
projectiles.add(p);
level.addProjectileEntities(p);
}
diff --git a/src/com/redomar/game/entities/Player.java b/src/com/redomar/game/entities/Player.java
index 59caf87..44499f4 100644
--- a/src/com/redomar/game/entities/Player.java
+++ b/src/com/redomar/game/entities/Player.java
@@ -80,7 +80,8 @@ public void tick() {
double dir = Math.atan2(dy, dx);
// Continue with shooting logic
- shoot(x, y, dir, Game.getMouse().getButton());
+ double[] playerVelocity = {xa, ya};
+ shoot(x, y, dir, Game.getMouse().getButton(), playerVelocity);
entityPrinter.highlight().print("Direction: " + dir + "ยบ\t" + dx + "x\t" + dy + "y");
}
diff --git a/src/com/redomar/game/entities/projectiles/Medium.java b/src/com/redomar/game/entities/projectiles/Medium.java
index 72262aa..1c38e9f 100644
--- a/src/com/redomar/game/entities/projectiles/Medium.java
+++ b/src/com/redomar/game/entities/projectiles/Medium.java
@@ -8,8 +8,8 @@ public class Medium extends Projectile{
public static final int FIRE_RATE = 20;
- public Medium(LevelHandler level, int x, int y, double dir) {
- super(level, x, y, dir);
+ public Medium(LevelHandler level, int x, int y, double dir, double[] playerVelocity) {
+ super(level, x, y, dir, playerVelocity);
range = 60 - life.nextInt(10);
damage = 80;
speed = 1;
diff --git a/src/com/redomar/game/entities/projectiles/Projectile.java b/src/com/redomar/game/entities/projectiles/Projectile.java
index 0633fe9..d9e5d07 100644
--- a/src/com/redomar/game/entities/projectiles/Projectile.java
+++ b/src/com/redomar/game/entities/projectiles/Projectile.java
@@ -17,7 +17,7 @@ public abstract class Projectile extends Entity {
private boolean removed = false;
- public Projectile(LevelHandler level, int x, int y, double dir) {
+ public Projectile(LevelHandler level, int x, int y, double dir, double[] playerVelocity) {
super(level);
xOrigin = x;
yOrigin = y;
diff --git a/src/com/redomar/game/entities/projectiles/Small.java b/src/com/redomar/game/entities/projectiles/Small.java
index e1c8054..6626db4 100644
--- a/src/com/redomar/game/entities/projectiles/Small.java
+++ b/src/com/redomar/game/entities/projectiles/Small.java
@@ -12,14 +12,14 @@ public class Small extends Projectile {
public static final int FIRE_RATE = 10;
private static final File smallShot = new File("/music/small.wav");
- public Small(LevelHandler level, int x, int y, double dir) {
- super(level, x, y, dir);
+ public Small(LevelHandler level, int x, int y, double dir, double[] playerVelocity) {
+ super(level, x, y, dir, playerVelocity);
range = 125 - life.nextInt(30);
damage = 20;
speed = 2;
- nx = speed * Math.cos(angle);
- ny = speed * Math.sin(angle);
+ nx = speed * Math.cos(angle) + playerVelocity[0];
+ ny = speed * Math.sin(angle) + playerVelocity[1];
try {
AudioHandler smallSound = new AudioHandler(smallShot);
diff --git a/src/com/redomar/game/event/InputHandler.java b/src/com/redomar/game/event/InputHandler.java
index 93b7c65..a4705d3 100644
--- a/src/com/redomar/game/event/InputHandler.java
+++ b/src/com/redomar/game/event/InputHandler.java
@@ -5,6 +5,10 @@
import com.redomar.game.lib.SleepThread;
import com.redomar.game.log.PrintTypes;
import com.redomar.game.log.Printer;
+import net.java.games.input.Controller;
+import net.java.games.input.ControllerEnvironment;
+import net.java.games.input.Event;
+import net.java.games.input.EventQueue;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
@@ -26,10 +30,142 @@ public class InputHandler implements KeyListener {
private final KeyHandler M_KEY = new KeyHandler();
+ private Controller controller;
+
public InputHandler(Game game) {
InputContext context = InputContext.getInstance();
frenchKeyboardLayout = context.getLocale().getCountry().equals("BE") || context.getLocale().getCountry().equals("FR");
game.addKeyListener(this);
+
+ // Detect the controller
+ Controller[] controllers = ControllerEnvironment.getDefaultEnvironment().getControllers();
+ for (Controller c : controllers) {
+ if (c.getType() == Controller.Type.GAMEPAD) {
+ controller = c;
+ break;
+ }
+ }
+
+ if (controller == null) {
+ System.out.println("No gamepad found.");
+ } else {
+ System.out.println("Gamepad detected: " + controller.getName());
+ }
+ }
+
+ public void pollController() {
+ if (controller == null) {
+ return;
+ }
+
+ controller.poll();
+ EventQueue queue = controller.getEventQueue();
+ Event event = new Event();
+
+ while (queue.getNextEvent(event)) {
+ String componentName = event.getComponent().getName();
+ float value = event.getValue();
+
+ // Process the event
+ processControllerInput(componentName, value);
+ }
+ }
+
+ private void processControllerInput(String componentName, float value) {
+
+
+ // Threshold to detect significant movement
+ float threshold = 0.5f; // Adjusted for more responsive input
+
+ // if the value is lower than -0.5 or higer that 0.5 print whcih key is pressed
+ if (value <= -0.5 || value >= 0.5) {
+ System.out.println(componentName + " " + value);
+ }
+ switch (componentName) {
+
+
+ case "x": // Horizontal movement (left/right)
+ if (value < -threshold) {
+ LEFT_KEY.setPressed(true);
+ } else if (value > threshold) {
+ RIGHT_KEY.setPressed(true);
+ } else {
+ LEFT_KEY.setPressed(false);
+ RIGHT_KEY.setPressed(false);
+ }
+ break;
+
+ case "y": // Vertical movement (up/down)
+ if (value < -threshold) {
+ UP_KEY.setPressed(true);
+ } else if (value > threshold) {
+ DOWN_KEY.setPressed(true);
+ } else {
+ UP_KEY.setPressed(false);
+ DOWN_KEY.setPressed(false);
+ }
+ break;
+
+ // Handle other components (e.g., buttons or additional axes) as needed
+ case "ry":
+ if (value > -threshold) {
+ SHIFTED.setPressed(true);
+ } else {
+ SHIFTED.setPressed(false);
+ }
+ break;
+
+ case "0":
+ if (value == 1) {
+ Game.setChangeLevel(true);
+ }
+ break;
+
+ case "4":
+ if (value == 1) {
+ if (!Game.isNpc()) {
+ Game.setNpc(true);
+ Game.npcSpawn();
+ inputPrinter.print("Dummy has been spawned", PrintTypes.GAME);
+ }
+ }
+ break;
+
+
+ case "5": // toggle K key
+ if (value == 1) {
+ if (Game.isNpc()) {
+ Game.setNpc(false);
+ Game.npcKill();
+ inputPrinter.print("Dummy has been removed", PrintTypes.GAME);
+ }
+ }
+ break;
+
+
+
+ case "9": // toggle M key
+ if (value == 1) {
+ M_KEY.setPressedToggle(M_KEY.isPressed());
+ }
+ break;
+
+
+ case "13":
+ if (value == 1) {
+ if (!Game.isClosing()) {
+ Game.setDevMode(!Game.isDevMode());
+ new Thread(new SleepThread());
+ inputPrinter.print(String.format("Debug Mode %s", Game.isDevMode() ? "Enabled" : "Disabled"));
+ }
+ }
+ break;
+ case "8":
+ if (value == 1) {
+ this.quitGame();
+ }
+
+ }
}
public void keyPressed(KeyEvent e) {
@@ -102,6 +238,7 @@ private void toggleKey(int keyCode, boolean isPressed) {
keyCodeActions.put(KeyEvent.VK_SHIFT, () -> SHIFTED.setPressed(isPressed));
keyCodeActions.put(KeyEvent.VK_M, () -> M_KEY.setPressedToggle(isPressed));
+
if (frenchKeyboardLayout) {
keyCodeActions.put(KeyEvent.VK_Q, () -> LEFT_KEY.setPressed(isPressed));
keyCodeActions.put(KeyEvent.VK_Z, () -> UP_KEY.setPressed(isPressed));