Hello in my game when I walk and jump, it stops everything after the jump finishes:
Can you see after a jump, it continues walking for a bit & then stops?
It should stop immediately but my walking queue continues executing because I didn't reset it, it should only reset upon keypress or release. But keypressing will stop working after i release my jump key. I think if I use 2 keys at a time and release on, the OS won't remember the old key I am still pressing. Even in your browser URL input, press and any key and hold, and then hold another key for bit & release it, it won't write the old key anymore.
Is there a fix for this? I am using keylistener, because i couldn't figure out how to find out when a key was released in KeyBinds.
This is how I do it:
public class Keyboard implements KeyListener {
private Player player;
public Keyboard(Player p) {
this.player = p;
}
#Override
public void keyPressed(KeyEvent e) {
System.out.println("yes");
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
this.player.getMovement().moveLeft();
break;
case KeyEvent.VK_RIGHT:
this.player.getMovement().moveRight();
break;
case KeyEvent.VK_SPACE:
this.player.getMovement().jump();
break;
}
}
#Override
public void keyReleased(KeyEvent e) {
int left = KeyEvent.VK_LEFT;
int right = KeyEvent.VK_RIGHT;
if (e.getKeyCode() == left || e.getKeyCode() == right) {
this.player.getMovement().stopMovement();
}
}
#Override
public void keyTyped(KeyEvent e) {
}
}
How can I fix this issue? If you need more parts of the code like the jump or walking queue, let me know.
Keylog:
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Space is a nice button
Remember process all the keypresses in a separate Thread.
http://wiki.processing.org/w/Multiple_key_presses
Method #1
/**
multiplekeys taken from http://wiki.processing.org/index.php?title=Keep_track_of_multiple_key_presses
#author Yonas Sandbæk http://seltar.wliia.org
*/
// usage:
// if(checkKey("ctrl") && checkKey("s")) println("CTRL+S");
boolean[] keys = new boolean[526];
void draw(){}
boolean checkKey(String k)
{
for(int i = 0; i < keys.length; i++)
if(KeyEvent.getKeyText(i).toLowerCase().equals(k.toLowerCase())) return keys[i];
return false;
}
void keyPressed()
{
keys[keyCode] = true;
println(KeyEvent.getKeyText(keyCode));
}
void keyReleased()
{
keys[keyCode] = false;
}
Methord #2 (And a simpler way of doing this just checking a few keys (without an array))
boolean keyup = false;
boolean keyright = false;
boolean keyleft = false;
boolean keydown = false;
float x,y;
void setup() {
size(640,360);
x = width/2;
y = height/2;
}
void draw() {
background(51);
fill(255);
ellipse(x,y,16,16);
if (keyup) y--;
if (keydown) y++;
if (keyleft) x--;
if (keyright) x++;
}
void keyPressed() {
if (key == CODED) {
if (keyCode == UP) keyup = true;
if (keyCode == DOWN) keydown = true;
if (keyCode == LEFT) keyleft = true;
if (keyCode == RIGHT) keyright = true;
}
}
void keyReleased() {
if (key == CODED) {
if (keyCode == UP) keyup = false;
if (keyCode == DOWN) keydown = false;
if (keyCode == LEFT) keyleft = false;
if (keyCode == RIGHT) keyright = false;
}
}
Method #3
/**
Modified version of Option 1 multiplekeys (should provide improved performance and accuracy)
#author Yonas Sandbæk http://seltar.wliia.org (modified by jeffg)
*/
// usage:
// if(checkKey(KeyEvent.VK_CONTROL) && checkKey(KeyEvent.VK_S)) println("CTRL+S");
boolean[] keys = new boolean[526];
void draw(){}
boolean checkKey(int k)
{
if (keys.length >= k) {
return keys[k];
}
return false;
}
void keyPressed()
{
keys[keyCode] = true;
println(KeyEvent.getKeyText(keyCode));
if(checkKey(CONTROL) && checkKey(KeyEvent.VK_S)) println("CTRL+S");
}
void keyReleased()
{
keys[keyCode] = false;
}
Method #5
/**
* Snappier multiple key detection using Primitive Collections Classes for Java http://pcj.sourceforge.net/
* (standard Java Collection Objects can be used instead)
* #author analogAI http://recursivepath.com/analogAI/
*/
// usage:
// if(this.checkKeysHeld(KeyEvent.VK_CONTROL) && this.checkKeysHeld(KeyEvent.VK_S)) println("CTRL+S");
import bak.pcj.set.IntSet;
import bak.pcj.set.IntOpenHashSet;
public class HelloWorld extends PApplet {
public IntSet keysheld = new IntOpenHashSet();
/**
* #param keycode key integer code, the value are constants defined in KeyEvent Class
* http://java.sun.com/j2se/1.4.2/docs/api/java/awt/event/KeyEvent.html
* e.g. KeyEvent.VK_A for letter A
* KeyEvent.VK_0 for number 0
* KeyEvent.VK_SHIFT for shift button
* #return true if the key is currently held down, false otherwise
*/
public boolean checkKeysHeld(int keycode){
return this.keysheld.contains(keycode);
}
public void keyPressed(){
// add key to the list of keys held down
// with processing, the KeyEvent object is always available as "keyEvent",
// the getKeyChar() is already in the variable 'key', and getKeyCode() is in the variable 'keyCode'.
this.keysheld.add(this.keyEvent.getKeyCode());
println("key pressed: "+KeyEvent.getKeyText(this.keyEvent.getKeyCode()));
println("keys in current held list: "+this.keysheld.toString());
}
public void keyReleased(){
// remove key from the list of keys held down
this.keysheld.remove(this.keyEvent.getKeyCode());
}
}
Related
I am trying to create a simple mp3 player in green foot and use buttons to control the volume. I have some code that I think should be working but it isnt. Im not sure what the problem is. I am trying to increase the volume bu one when the up button is pushed and decrease the volume by 1 when the down button is pushed I am fairly new to programming so any help would be great. Thanks!
public class Play extends Actor
{
public GreenfootSound sound = new GreenfootSound("AdventureOfaLifetime.mp3");
private boolean off = true;
int currentVolume = sound.getVolume();
Up volumeUp;
Down volumeDown;
/**
* Act - do whatever the Play wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act()
{
if (Greenfoot.mouseClicked(this) && off)
{
setImage("Pause.png");
sound.play();
off = false;
}
else if(Greenfoot.mouseClicked(this) && !off)
{
setImage("Play.png");
sound.pause();
off = true;
}
if(volumeUp.clicked)
{
if(currentVolume < 100)
{
currentVolume = currentVolume + 1;
sound.setVolume(currentVolume);
}
}
if(volumeDown.clicked)
{
if(currentVolume > 0)
{
currentVolume = currentVolume - 1;
sound.setVolume(currentVolume);
}
}
}
public class Down extends Play
{
static boolean clicked = false;
/**
* Act - do whatever the Down wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act()
{
if (Greenfoot.mouseClicked(this))
{
clicked = true;
}
else
{
clicked = false;
}
}
public class Up extends Play
{
static boolean clicked = false;
/**
* Act - do whatever the Up wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act()
{
if (Greenfoot.mouseClicked(this))
{
clicked = true;
}
else
{
clicked = false;
}
}
I got something to work. I just set currentVolume equal to 50 then changed my if statement to currentVolume += 1;and currentVolume -= 1;. Probably isn't the best solution but at least its working.
I'm creating a custom textfield class in which i have a custom behaviour depending on if the user types digit keys on it.
!event.getCode().isDigitKey() always returns true, even when i type digits. I tried to check if KeyCode is a letter also and still it returns false. What seems to be the issue here?
I always get false when checking the event's KeyCode against any other KeyCode, even when they should be equal.
public class ScoreField extends TextField implements Customizable {
public ScoreField() {
super();
customize();
}
#Override
public void customize() {
this.setOnKeyTyped(new EventHandler<KeyEvent>() {
int curChar = 0;
#Override
public void handle(KeyEvent event) {
event.consume();
KeyCode keyTyped = event.getCode();
char charTyped = event.getCharacter().charAt(0);
System.out.println(charTyped);
// Do nothing if not a digit
if (!event.getCode().isDigitKey()) {
System.out.println("NOT A DIGIT KEY");
if (keyTyped == KeyCode.BACK_SPACE) {
System.out.println("RESETTING");
resetText();
return;
}
return;
}
if (getText().length() >= 5) {
if (curChar == 2) {
curChar = 3;
}
if (curChar == 5) {
curChar = 0;
}
StringBuilder builder = new StringBuilder(getText());
builder.setCharAt(curChar, charTyped);
setText(builder.toString());
curChar++;
return;
}
if (getText().length() == 2) {
setText(getText() + ":");
}
setText(getText() + charTyped);
}
});
}
private void resetText() {
setText("");
}
}
As James_D stated:
For key typed events, the code is always KeyCode.UNDEFINED
So i did as he suggested and instead of checking the KeyCode if it's a digit, i checked event.getCharacter()[0] using Character.isDigit(char) in the 1ST if statement, and it worked perfectly for my case.
P.S: I tried to use a TextFormatter with a StringConverter, but i couldn't get it to work.
I want to write a little game where I can move a ball on a JavaFX Panel using the W, A, S, D keys.
I have a getPosX() and setPosX() but I don't know how to write a KeyListener which will e.g. calculate setPosX(getPosX()+1) if I press D.
What do I have to do?
From a JavaRanch Forum post.
Key press and release handlers are added on the scene and update movement state variables recorded in the application. An animation timer hooks into the JavaFX pulse mechanism (which by default will be capped to fire an event 60 times a second) - so that is a kind of game "loop". In the timer the movement state variables are checked and their delta actions applied to the character position - which in effect moves the character around the screen in response to key presses.
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.image.*;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/**
* Hold down an arrow key to have your hero move around the screen.
* Hold down the shift key to have the hero run.
*/
public class Runner extends Application {
private static final double W = 600, H = 400;
private static final String HERO_IMAGE_LOC =
"http://icons.iconarchive.com/icons/raindropmemory/legendora/64/Hero-icon.png";
private Image heroImage;
private Node hero;
boolean running, goNorth, goSouth, goEast, goWest;
#Override
public void start(Stage stage) throws Exception {
heroImage = new Image(HERO_IMAGE_LOC);
hero = new ImageView(heroImage);
Group dungeon = new Group(hero);
moveHeroTo(W / 2, H / 2);
Scene scene = new Scene(dungeon, W, H, Color.FORESTGREEN);
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
switch (event.getCode()) {
case UP: goNorth = true; break;
case DOWN: goSouth = true; break;
case LEFT: goWest = true; break;
case RIGHT: goEast = true; break;
case SHIFT: running = true; break;
}
}
});
scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
switch (event.getCode()) {
case UP: goNorth = false; break;
case DOWN: goSouth = false; break;
case LEFT: goWest = false; break;
case RIGHT: goEast = false; break;
case SHIFT: running = false; break;
}
}
});
stage.setScene(scene);
stage.show();
AnimationTimer timer = new AnimationTimer() {
#Override
public void handle(long now) {
int dx = 0, dy = 0;
if (goNorth) dy -= 1;
if (goSouth) dy += 1;
if (goEast) dx += 1;
if (goWest) dx -= 1;
if (running) { dx *= 3; dy *= 3; }
moveHeroBy(dx, dy);
}
};
timer.start();
}
private void moveHeroBy(int dx, int dy) {
if (dx == 0 && dy == 0) return;
final double cx = hero.getBoundsInLocal().getWidth() / 2;
final double cy = hero.getBoundsInLocal().getHeight() / 2;
double x = cx + hero.getLayoutX() + dx;
double y = cy + hero.getLayoutY() + dy;
moveHeroTo(x, y);
}
private void moveHeroTo(double x, double y) {
final double cx = hero.getBoundsInLocal().getWidth() / 2;
final double cy = hero.getBoundsInLocal().getHeight() / 2;
if (x - cx >= 0 &&
x + cx <= W &&
y - cy >= 0 &&
y + cy <= H) {
hero.relocate(x - cx, y - cy);
}
}
public static void main(String[] args) { launch(args); }
}
On filters, handlers and focus
To receive key events, the object that the event handlers are set on must be focus traversable. This example sets handlers on the scene directly, but if you were to set handlers on the pane instead of the scene, it would need to be focus traversable and have focus.
If you want a global intercept point to override or intercept events that are to be routed through the in-built event handlers which will consume events you want (e.g. buttons and text fields), you can have an event filter on the scene rather than a handler.
To better understand the difference between a handler and a filter, make sure that you study and understand the event capturing and bubbling phases as explained in the JavaFX event tutorial.
Generic input handler
Please ignore the rest of this answer if the information already provided is sufficient for your purposes.
While the above solution is sufficient to answer this question, if interested, a more sophisticated input handler (with a more general and separated, input and update handling logic), can be found in this demo breakout game:
Breakout input handler.
Example generic input handler from the sample breakout game:
class InputHandler implements EventHandler<KeyEvent> {
final private Set<KeyCode> activeKeys = new HashSet<>();
#Override
public void handle(KeyEvent event) {
if (KeyEvent.KEY_PRESSED.equals(event.getEventType())) {
activeKeys.add(event.getCode());
} else if (KeyEvent.KEY_RELEASED.equals(event.getEventType())) {
activeKeys.remove(event.getCode());
}
}
public Set<KeyCode> getActiveKeys() {
return Collections.unmodifiableSet(activeKeys);
}
}
While an ObservableSet with an appropriate set change listener could be used for the set of active keys, I have used an accessor which returns an unmodifiable set of keys which were active at a snapshot in time, because that is what I was interested in here rather than observing changes to the set of active keys in real-time.
If you want to keep track of the order in which keys are pressed, a Queue, List, or TreeSet can be used rather than a Set (for example, with a TreeSet ordering events on the time of keypress, the most recent key pressed would be the last element in the set).
Example generic input handler usage:
Scene gameScene = createGameScene();
// register the input handler to the game scene.
InputHandler inputHandler = new InputHandler();
gameScene.setOnKeyPressed(inputHandler);
gameScene.setOnKeyReleased(inputHandler);
gameLoop = createGameLoop();
// . . .
private AnimationTimer createGameLoop() {
return new AnimationTimer() {
public void handle(long now) {
update(now, inputHandler.getActiveKeys());
if (gameState.isGameOver()) {
this.stop();
}
}
};
}
public void update(long now, Set<KeyCode> activeKeys) {
applyInputToPaddle(activeKeys);
// . . . rest of logic to update game state and view.
}
// The paddle is sprite implementation with
// an in-built velocity setting that is used to
// update its position for each frame.
//
// on user input, The paddle velocity changes
// to point in the correct predefined direction.
private void applyInputToPaddle(Set<KeyCode> activeKeys) {
Point2D paddleVelocity = Point2D.ZERO;
if (activeKeys.contains(KeyCode.LEFT)) {
paddleVelocity = paddleVelocity.add(paddleLeftVelocity);
}
if (activeKeys.contains(KeyCode.RIGHT)) {
paddleVelocity = paddleVelocity.add(paddleRightVelocity);
}
gameState.getPaddle().setVelocity(paddleVelocity);
}
Scene myScene = new Scene();
KeyCombination cntrlZ = new KeyCodeCombination(KeyCode.Z, KeyCodeCombination.CONTROL_DOWN);
myScene.setOnKeyPressed(new EventHandler<KeyEvent>(){
#Override
public void handle(KeyEvent event) {
if(contrlZ.match(event)){
//Do something
}
}
});
using JNativeHook:
https://github.com/kwhat/jnativehook
<!-- https://mvnrepository.com/artifact/com.1stleg/jnativehook -->
<dependency>
<groupId>com.1stleg</groupId>
<artifactId>jnativehook</artifactId>
<version>2.1.0</version>
</dependency>
private void initKeyListener(Stage primaryStage){
/* Note: JNativeHook does *NOT* operate on the event dispatching thread.
* Because Swing components must be accessed on the event dispatching
* thread, you *MUST* wrap access to Swing components using the
* SwingUtilities.invokeLater() or EventQueue.invokeLater() methods.
*/
try {
GlobalScreen.registerNativeHook();
} catch (NativeHookException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
GlobalScreen.addNativeKeyListener(new NativeKeyListener() {
public void nativeKeyPressed(NativeKeyEvent e) {
if ( (e.getModifiers() & NativeKeyEvent.CTRL_MASK) != 0
&& (e.getModifiers() & NativeKeyEvent.ALT_MASK) != 0
&& (e.getKeyCode() == NativeKeyEvent.VC_B)){
logger.debug("key :Hide");
primaryStage.hide();
}
if ( (e.getModifiers() & NativeKeyEvent.CTRL_MASK) != 0
&& (e.getModifiers() & NativeKeyEvent.SHIFT_MASK) != 0
&& (e.getModifiers() & NativeKeyEvent.ALT_MASK) != 0
&& (e.getKeyCode() == NativeKeyEvent.VC_B)){
logger.debug("key :Show");
primaryStage.show();
}
//System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public void nativeKeyReleased(NativeKeyEvent e) {
//System.out.println("Key Released: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public void nativeKeyTyped(NativeKeyEvent e) {
//System.out.println("Key Typed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
}
});
/*
GlobalScreen.addNativeMouseListener(new NativeMouseListener() {
#Override
public void nativeMouseReleased(NativeMouseEvent arg0) {
// TODO Auto-generated method stub
System.out.println("MouseReleased()");
}
#Override
public void nativeMousePressed(NativeMouseEvent arg0) {
// TODO Auto-generated method stub
System.out.println("MousePressed()");
}
#Override
public void nativeMouseClicked(NativeMouseEvent arg0) {
// TODO Auto-generated method stub
System.out.println("MouseClicked()");
}
});
*/
}
Today's question rattling my mind is such. I'm creating a program that allow the user to jump and move left or right, to problem is that whenever I try to jump the program freezes... The idea behind my code is simple, whenever the users presses space(jump) the rectangle "jumps" up and if the y of the rectangle is within a certain height above the obstacle(in this case a rectangle with dimmensions brickx,bricky,brickw, and brickh is the obstacle) then the animation is supposed to stop and the rectangle is supposed to wait for the next command while in place on top of the obstacle. To do this a method stayOnBrick is called during each iteration of the while loop and checks; during the jump, if y is within the needed range, and if y is it then sets the boolean jump = true which should break the loop on the next iteration as well as setting y to the needed value. But when space is pressed, nothing happens, or should I say the program freezes. Thoughts?
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class KeyTest extends Core implements KeyListener{
Window w;
public int x,y;
boolean jump = true;
public int brickx, bricky, brickw, brickh;
public static void main(String args[]){
new KeyTest().run();
}
private String mess = "";
//init also called init from superclass
public void init(){
super.init();
Window w = s.getFullScreenWindow();
w.setFocusTraversalKeysEnabled(false);
w.addKeyListener(this);
y = s.getHeight()-15;
mess = "Press esc to exit";
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
e.consume();
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_ESCAPE){
stop();
}else if(keyCode == KeyEvent.VK_SPACE){
mess = "Pressed: " + KeyEvent.getKeyText(keyCode);
while(y>s.getHeight()-200){
stayOnBrick();
if(jump==false){break;}
else{ try{
y-=20;
w.repaint();
Thread.sleep(40);
}catch(Exception jumpError){
System.out.println("Error in Jumping");
}
}
while(y<s.getHeight()-15){
stayOnBrick();
if(jump==false){
w.repaint();
break;}
else{
try{
y+=20;
Thread.sleep(40);
w.repaint();
}catch(Exception jumpError){
System.out.println("Error in Jumping");
}
}
}
}
}
else if(keyCode == e.VK_RIGHT){
if(x>=s.getWidth()-30){x=s.getWidth()-30;}
x+=20;
w.repaint();
}
else if(keyCode == e.VK_LEFT){
if(x<=0){x=0;}
x-=20;
w.repaint();
}
e.consume();
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
int keyCode = e.getKeyCode();
mess = "Released: " + KeyEvent.getKeyText(keyCode);
jump = true;
e.consume();
}
#Override
public synchronized void draw(Graphics2D g){
brickx=0; bricky=s.getHeight()-100; brickw=300; brickh=20;
Window w = s.getFullScreenWindow();
g.setColor(w.getBackground());
g.fillRect(0, 0, s.getWidth(), s.getHeight());
g.setColor(w.getForeground());
g.fillRect(x, y, 30, 15);
g.drawString(mess, 30, 30);
g.setColor(Color.BLUE);
g.fillRect(brickx, bricky, brickw, brickh);
}
public void stayOnBrick(){
if(y<bricky && y>bricky-30){
y=bricky-15;
jump = false;
}
else{jump = true;}
}
}
whenever I try to jump the program freezes
I'd start by having a look at Concurrency in Swing for the reason for the problem.
I'd suggest having a look at How to use Swing Timers for a possible solution.
I'd also recommend having a look at How to Use Key Bindings to solve the focus related issues with KeyListener
And you might find How to make sprite jump in java? and JApplet creates a ball that bounces and gets progressively less high in Java helpful
I am currently working on a Pac-Man remake in Java, and I am having a problem with player movement. I use a KeyListener to detect when the W A S or D keys are pressed, and sets a variable as true or false. The variables are up, down, left, right. This works fine, but the "tick" method does not recognize the value change, almost as if there are two variables. For example, I will press the W key and up is set to true. In the tick method, however, up is not true. This also happens when getting the position of the player. It will only get the first position of the player, but after I edit the position in the KeyListener method, the tick method will not recognize that the position has been changed.
I have also found that when I move the position directly from the KeyListener method and print it to the console, it works correctly. But when I print the position from the tick method, it always prints the original position. If I print both, it seems as if there are two variables, because the KeyListener method will always print the correct value, and the tick method will always print the original, but does not reset the KeyListener value.
Sorry if this sounds confusing, please ask if you need me to describe it in a different way.
Anyway, the tick method is being called 60 times every second.
Can someone please help me fix this problem? Help is appreciated.
Here is the class for the Player, containing the tick and KeyListener methods.
package com.graysullivan.entities;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import com.graysullivan.main.Location;
public class Player implements KeyListener {
Location pos;
private int width = 80;
private int height = 80;
private boolean up, down, left, right;
public Player() {
pos = new Location(360, 701);
}
public void init() {
}
public void tick(double deltaTime) {
//System.out.println(pos.y);
if(up) {
System.out.println("up");
pos.y--;
}
if(down) {
pos.y++;
}
if(left) {
pos.x--;
}
if(right) {
pos.x++;
}
}
public void render(Graphics2D g) {
g.fillRect((int)pos.x,(int)pos.y, 40, 40);
}
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_W) {
up = true;
System.out.println(up);
}
if(key == KeyEvent.VK_S) {
down = true;
}
if(key == KeyEvent.VK_A) {
left = true;
}
if(key == KeyEvent.VK_D) {
right = true;
}
if(key == KeyEvent.VK_DELETE) {
System.exit(0);
}
}
#Override
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_W) {
up = false;
}
if(key == KeyEvent.VK_S) {
down = false;
}
if(key == KeyEvent.VK_A) {
left = false;
}
if(key == KeyEvent.VK_D) {
right = false;
}
}
#Override
public void keyTyped(KeyEvent e) {
}
Looking at your code, there is a part that look suspicious.
In Game.java you created an instance of Player
frame.addKeyListener(new Player());
Another instance of Player is also created in LevelLoader.java
Player player = new Player();
...which is the one that getting the tick method triggered.
They are two different objects which has nothing to do with each other (other than the fact that they are from the same class). Changing a state of one object doesn't change the state of another. What happen in your case is that the first Player instance listen to key press but the second instance is getting the tick method triggered.
What you need to do is to create a player instance in Game.java and pass the object to LevelLoader.java (via StateManager.java?) instead of creating another instance in LevelLoader.java itself.
I think what you need is to declare synchronized on the method which manipulate up, down, right, and left to avoid memory consistency error and thread interference.
Something like this:
public synchronized void tick(double deltaTime) {
...
}
Edit: you might want to declare the members with volatile to ensure that the changes in keyPressed method happens before the tick.