user2789116
user2789116

Reputation: 125

Key Listener isn't working

I've been experimenting with creating a java game but I've hit a roadblock, I can't get java to listen to any of my keys even when I'm just using print statements to test it out. From what I understand I've implemented KeyListener correctly and added the key listener to the Applet but it still isn't working.

My main class:

import java.awt.*;
import javax.swing.*;


public class Container extends JApplet implements Runnable {
    private static final long serialVersionUID = 1L;

    public static Dimension size = new Dimension(720,560); //Size of Screen

    private static final int PIXELSIZE = 2;
    public static Dimension pixel = new Dimension(size.width/PIXELSIZE,
            size.height/PIXELSIZE); // Dimesions of screen in terms of pixels


    public static final String NAME = "Game";
    public static boolean isRunning = false;
    private Image screen;

    public static Level level;
    public static MainCharacter p1;

    public Container(){
        setPreferredSize(size);
        addKeyListener(p1);
    }

    public void start(){
        new Tile();
        level = new Level();
        p1 = new MainCharacter(20,40);

        isRunning = true;
        new Thread(this).start();
    }

    public void tick(){
        p1.tick();
    }

    public void render(){
        Graphics g = screen.getGraphics();
        g.setColor(new Color(130,160,255));
        g.fillRect(0, 0, pixel.width, pixel.height);
        level.render(g);
        p1.render(g);
        g = getGraphics();
        g.drawImage(screen, 0, 0, size.width, size.height, 
                0, 0, pixel.width, pixel.height, null);
        g.dispose();
    }

    public void run() {
        screen = createVolatileImage(pixel.width,pixel.height);
        while(isRunning){
            tick();
            render();
            try{
                Thread.sleep(5);
            }catch(InterruptedException e){}    
        }
    }

    public static void main(String[] args){
        Container container = new Container();
        JFrame frame = new JFrame();
        frame.add(container);
        frame.pack();
        frame.setTitle(NAME);
        frame.setResizable(true);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        container.start();
    }

    public static void right(){
        p1.right();
    }

    public static void left(){
        p1.left();
    }

}

My character class:

import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class MainCharacter extends Tall implements KeyListener{
public double fallSpeed = 1.5;
public double moveSpeed = 1.0;
public double xSpeed = 1;


public MainCharacter(int width, int height){
    setBounds(Container.pixel.width/2 - width/2,
            Container.pixel.height/2 - height/2,
            width, height);
}

public void tick(){
    if(Container.level.space[(int)(x+width)][(int)(y+height)] &&
            Container.level.space[(int)(x)][(int)(y+height)] &&
            Container.level.space[(int)(x+width)][(int)(y)] &&
            Container.level.space[(int)(x)][(int)(y)])
        y += fallingSpeed;
}

public void render(Graphics g){
    g.drawImage(Tile.tileset_terrain, (int)x, (int)y,
            (int)(x+width),(int)(y+height),
            Tile.CHARACTER[0]*Tile.TILE_SIZE,
            Tile.CHARACTER[1]*Tile.TILE_SIZE,
            Tile.CHARACTER[0]*Tile.TILE_SIZE +(int)width,
            Tile.CHARACTER[1]*Tile.TILE_SIZE + (int)height, null);
}

public void right(){
    x += xSpeed;
}

public void left(){
    x -= xSpeed;
}

@Override
public void keyPressed(KeyEvent e) {
    System.out.println("hey");

}

@Override
public void keyReleased(KeyEvent e) {
    System.out.println("hey");

}

@Override
public void keyTyped(KeyEvent e) {
    System.out.println("hey");
}
}

Upvotes: 1

Views: 179

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347334

KeyListeners are fickle. They require that the component they are registered to are not only focusable, but have keyboard focus.

It's recommend that instead, you should use Key Bindings instead

Upvotes: 2

martinez314
martinez314

Reputation: 12332

It looks like p1 is null when you add it as a KeyListener.

You add it as a KeyListener here:

public Container(){
    setPreferredSize(size);
    System.out.println(p1);  // try this...
    addKeyListener(p1);
}

But instantiate it here:

public void start(){
    new Tile();
    level = new Level();
    p1 = new MainCharacter(20,40);

    isRunning = true;
    new Thread(this).start();
}

Upvotes: 5

Related Questions