Jump to content

Hi all!

 

I'm working on a simple Java game (I learned some Java in school and wanted to continue this summer) and I have run into a problem that I can't seem to fix.

 

I tried to use KeyListener to track the keyboard input to move the character. (In the code, the character is "zeus"). Basically, when the character hits  w, a, s, or d a method is supposed to be called that moves the image of the character a bit. For some reason, this won't work. I can launch the program without getting any error messages and there are no error warnings in the code editor (Eclipse).

 

Keep in mind that the images are rendered onto the screen, they just won't move when the WASD keys are pressed.

 

If you would take the time to look through my code and try to figure out what is wrong, your help would be greatly appreciated.

 

 

Thanks,

xw

 

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.Timer;

public class GameScreen extends JPanel implements Runnable, ActionListener, KeyListener{
	private static final long serialVersionUID = 1L;
	//Checks if game is running
	
	//variables
	private BufferStrategy strat; 
	
	private Graphics2D g;
	
	private boolean running = false;
	
	private Thread screen;
	
	private Dimension screen_size;
	
	Image background;
	
	Image enemy;
	
	Image zeus;
	
	Timer t = new Timer(5, this);
	
	int x = 250, y = 250, velX = 0, velY = 0;
	
	//sets screen dimensions as 1920x1080
	public GameScreen(){
		screen_size = new Dimension(1920,1080);
		background = GameScreen.loadImage("/GameBackground.png");
		zeus = GameScreen.loadImage("/GameZeus.png");
		enemy = GameScreen.loadImage("/GameEnemy.png");
		t.start();
		addKeyListener(this);
		setFocusable(true);
		setFocusTraversalKeysEnabled(false);
	
	}
		
	//tells screen to display 1920x1080 space
	public Dimension getScreenSize(){
		return screen_size;
	}
	
	//if game is running, repeatedly run the rendering and updating methods
	//as well as draw the graphics to the screen
	public void run(){
		
		while(running){
			
			g = (Graphics2D) strat.getDrawGraphics();
			
			renderGameScreen();
			
			g.dispose();
			
			strat.show();
			
			updateGame(0);
			
		}
		
	}
	
	public static Image loadImage(String file){
		Image image = null;
	
		try{	
		image = ImageIO.read(GameScreen.class.getResource(file));
		}catch (IOException e){
			System.out.println("Image failed to load"+file);
			e.printStackTrace();
		}
		
		return image;
		
	}
	
	public void setBuffer(BufferStrategy strat){
		this.strat = strat;
		
	}
	//renders everything within the brackets onto the screen
	public void renderGameScreen(){
		
		g.drawImage(background,0,0,null);
		g.drawImage(enemy,1700,765,null);
		g.drawImage(zeus, x, y, null);
				
	}
	
	public void actionPerformed(ActionEvent e){
		
		repaint();
		
		if(x < 0 || x > 1793){
			velX = 0;
		}
		if(y < 0 || y > 773){
			velY = 0;
		}
		
		x += velX;
		y += velY;
		
	}
	
	public void w(){
		velY = -2;
		velX = 0;	
	}

	public void s(){
		velY = 2;
		velX = 0;
	}
	
	public void a(){
		velX = -2;
		velY = 0;
	}
	
	public void d(){
		velX = 2;
		velY = 0;
	}
	
	public void keyPressed(KeyEvent e){
		int code = e.getKeyCode();
		
		if(code == KeyEvent.VK_W){
			w();
		}
		if(code == KeyEvent.VK_S){
			s();
		}	
		if(code == KeyEvent.VK_A){
			a();
		}
		if(code == KeyEvent.VK_D){
			d();
		}	
	}
	
	public void keyTyped(KeyEvent e){}
	
	public void keyReleased(KeyEvent e){
		int code2 = e.getKeyCode();
			if(code2==KeyEvent.VK_A||code2==KeyEvent.VK_D){
				velX = 0;
			
			if(code2==KeyEvent.VK_W||code2==KeyEvent.VK_S){
				velY = 0;
			}
			
						
			}
	}
	//updates the game screen very frequently
	public void updateGame(long t){
		
		
	}

	//Once the game is run, checks to see if game is running and stops it from re-launching
	public void start(){
		if(running)
			return;
		running = true;
		screen = new Thread(this);
		screen.start();
		
	}
	//allows the game to be stopped
	public void stop(){
		if(running)
			return;
		running = false;
		try{
			screen.join();
		}catch(InterruptedException e){
			e.printStackTrace();
			System.exit(0);
			
		}
		
	}
}

 

 

 

 

 

 

 

 

Link to comment
https://linustechtips.com/topic/609842-need-help-with-simple-java-game/
Share on other sites

Link to post
Share on other sites

3 minutes ago, manikyath said:

i'm guessing you're using LWJGL?

 

they have some great examples on their website you could look into, its most likely just a simple thing you missed.

Thanks for this, I will take a look at the examples and see if I missed something.

Link to post
Share on other sites

Please just post the code here inside code tags.

i5 4670k @ 4.2GHz (Coolermaster Hyper 212 Evo); ASrock Z87 EXTREME4; 8GB Kingston HyperX Beast DDR3 RAM @ 2133MHz; Asus DirectCU GTX 560; Super Flower Golden King 550 Platinum PSU;1TB Seagate Barracuda;Corsair 200r case. 

Link to post
Share on other sites

I'm pretty sure you aren't calling the keyPressed() function anywhere.

i5 4670k @ 4.2GHz (Coolermaster Hyper 212 Evo); ASrock Z87 EXTREME4; 8GB Kingston HyperX Beast DDR3 RAM @ 2133MHz; Asus DirectCU GTX 560; Super Flower Golden King 550 Platinum PSU;1TB Seagate Barracuda;Corsair 200r case. 

Link to post
Share on other sites

	public void keyPressed(KeyEvent e){
		int code = e.getKeyCode();
		
		if(code == KeyEvent.VK_W){
			w();
		}
		if(code == KeyEvent.VK_S){
			s();
		}	
		if(code == KeyEvent.VK_A){
			a();
		}
		if(code == KeyEvent.VK_D){
			d();
		}	
	}

This bit of code is intended to call the methods above it, which move the character. Am I doing something wrong here? @Nineshadow

 

public void w(){
		velY = -2;
		velX = 0;	
	}

	public void s(){
		velY = 2;
		velX = 0;
	}
	
	public void a(){
		velX = -2;
		velY = 0;
	}
	
	public void d(){
		velX = 2;
		velY = 0;
	}

 

Link to post
Share on other sites

5 minutes ago, xwboy said:

	public void keyPressed(KeyEvent e){
		int code = e.getKeyCode();
		
		if(code == KeyEvent.VK_W){
			w();
		}
		if(code == KeyEvent.VK_S){
			s();
		}	
		if(code == KeyEvent.VK_A){
			a();
		}
		if(code == KeyEvent.VK_D){
			d();
		}	
	}

This bit of code is intended to call the methods above it, which move the character. Am I doing something wrong here? @Nineshadow

 


public void w(){
		velY = -2;
		velX = 0;	
	}

	public void s(){
		velY = 2;
		velX = 0;
	}
	
	public void a(){
		velX = -2;
		velY = 0;
	}
	
	public void d(){
		velX = 2;
		velY = 0;
	}

 

Yes, but are you calling keyPressed() itself anywhere?

i5 4670k @ 4.2GHz (Coolermaster Hyper 212 Evo); ASrock Z87 EXTREME4; 8GB Kingston HyperX Beast DDR3 RAM @ 2133MHz; Asus DirectCU GTX 560; Super Flower Golden King 550 Platinum PSU;1TB Seagate Barracuda;Corsair 200r case. 

Link to post
Share on other sites

9 hours ago, Nineshadow said:

Yes, but are you calling keyPressed() itself anywhere?

keyPressed() is a method that comes from the keyListener interface, there's no need to call it, it's called by itself when a key is pressed

 

 

 

I would try, instead of repainting the window through the actionPerformed, doing it on the keyPressed() after you determine which key has been pressed

The best way to measure the quality of a piece of code is "Oh F*** "s per line

Link to post
Share on other sites

5 hours ago, espurritado said:

keyPressed() is a method that comes from the keyListener interface, there's no need to call it, it's called by itself when a key is pressed

 

 

 

I would try, instead of repainting the window through the actionPerformed, doing it on the keyPressed() after you determine which key has been pressed

Thanks for the suggestion. I tried this but it didn't work. If it helps at all, I have another class that creates the JFrame, called GameWindow. I tried creating/initializing the JFrame under the main method, but the problem still persisted.

 

Here's the code for GameWindow:

 

import java.awt.Canvas;

import javax.swing.JFrame;

public class GameWindow extends JFrame{
	private static final long serialVersionUID = 1L;
	
	//this section of code creates the window,
	//sets its dimensions, makes it visible,
	//and allows the objects in it to scale properly
	public GameWindow(){
		GameScreen screen = new GameScreen();
		Canvas canvas = new Canvas();
		canvas.setSize(screen.getScreenSize());
		canvas.setIgnoreRepaint(true);
		canvas.requestFocus();
		
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		this.setVisible(true);
		
		this.setResizable(false);
		
		this.setTitle("Mt. Olympus Defense");
		
		this.add(screen);
		
		this.add(canvas);
		
		this.pack();
		
		this.setLocationRelativeTo(null);
		
		canvas.createBufferStrategy(2);
		screen.setBuffer(canvas.getBufferStrategy());
		
		screen.start();
		
		this.setIgnoreRepaint(false);
		
	}
	
	public static void main(String args[]){
		//when program starts, create a game window
		new GameWindow();
		
		
		
	}

}

Is there something is this class that needs to be changed?


Thanks for your help,

xw

Link to post
Share on other sites

Try to add key listener to your window instead binding it to jpanel you adding (1), or request focus for jpanel after you add it to window (2).

 

1) To bind listener handler of screen to window instead doing in in GameScreen constructor do it in GameWindow constructor by this.addKeyListener(screen);. You don't need addKeyListener in your GameScreen constructor anymore.

 

2) To request focus, in your GameWindow constructor add screen.requestFocusInWindow(); at the end just before } . You still need addKeyListener in your GameScreen constructor.

 

(You may already figured out by reading above that your JPane is not getting focus, and window (JFrame) is focused by default, so JPane is not getting any keystrokes.)

Link to post
Share on other sites

12 hours ago, espurritado said:

keyPressed() is a method that comes from the keyListener interface, there's no need to call it, it's called by itself when a key is pressed

 

 

 

I would try, instead of repainting the window through the actionPerformed, doing it on the keyPressed() after you determine which key has been pressed

Oh, didn't know. I suspected that might be the case, but I asked anyway. Eh...

I haven't used Java in ages, and I've never used LWJGL.

i5 4670k @ 4.2GHz (Coolermaster Hyper 212 Evo); ASrock Z87 EXTREME4; 8GB Kingston HyperX Beast DDR3 RAM @ 2133MHz; Asus DirectCU GTX 560; Super Flower Golden King 550 Platinum PSU;1TB Seagate Barracuda;Corsair 200r case. 

Link to post
Share on other sites

On 12/06/2016 at 10:34 PM, Nineshadow said:

Oh, didn't know. I suspected that might be the case, but I asked anyway. Eh...

I haven't used Java in ages, and I've never used LWJGL.

Suggestion based on my experience trying to make games in LWJGL: Use libgdx. Saves you all this nasty work.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×