0

I'm trying to implement a KeyListener in a Space Invaders game in Java to move the ship (by now, it's just a red rectangle).

I think it's fine implemented, but i can't make it works.

Here is the ship's one:

import java.awt.Color;  
import java.awt.Graphics;  

public class Nave{

int x, y;
int AnchoNave = 40, AltoNave = 40;  // WIDTH_SHIP and HIGH_SHIP
Finestra f;                         // WINDOW
int velocidad = 4, v = 0;           // VELOCITY
Joc j;

Nave(Finestra f, int x, int y){
    this.f = f;
    this.x = x;
    this.y = y;
}

void pintaNave(Graphics g){

    g.setColor(Color.RED);
    g.drawRect(x, y, AnchoNave, AltoNave);
    g.setColor(Color.RED);
    g.fillRect(x, y, AnchoNave, AltoNave);

}

void movimiento(){  // this is not in the loop now.

    x+=velocidad;
    if (x>f.AMPLE-AnchoNave-10){
        x=0;
    }  

}  

}

Here is the Window's one:

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.*;
import javax.swing.JFrame;

public class Finestra extends JFrame implements ActionListener,  KeyListener{

Image im;
Graphics g;
int AMPLE=600,ALT=500;     // WIDTH and HIGH
Joc j;

Nave nave;                 // Nave = SHIP
int velocidad = 10;        // VELOCITY

public static void main(String[] args) {
    new Finestra();        // Finestra = WINDOW
}

Finestra(){

    super("-+- Space Invaders -+-");
    setVisible(true);
    setSize(AMPLE,ALT);
    im=this.createImage(AMPLE, ALT);
    g=im.getGraphics();
    j=new Joc(this);
    j.playing();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false);

    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);
}

public void update(Graphics g) {
    paint(g);
}

public void paint(Graphics g) { 
    g.drawImage(im, 0,0, null); 
}


@Override
public void actionPerformed(ActionEvent e) {
    j.nave.x =j.nave.x + j.nave.v;
    repaint();  
}  

@Override
public void keyPressed(KeyEvent e) {
    int tecla = e.getKeyCode();
    if (tecla == KeyEvent.VK_RIGHT)
        j.nave.v = +10;
    if (tecla == KeyEvent.VK_LEFT)
        j.nave.v = -10;
    }

@Override
public void keyReleased(KeyEvent e) {
    j.nave.v = 0;
}

@Override
public void keyTyped(KeyEvent e) {}

}

And finally this is the class that contains the loop of the game:

import java.awt.Color;
import java.awt.Graphics;

public class Joc{


Finestra f;                 // WINDOW
Enemigos c1[];              // ENEMIES
Nave nave;                  // SHIP

Joc(Finestra f){            // JOC = GAME
    this.f=f;
}
void playing() {
    initicalitzaJoc();
    do {
        moviments();           // MOVEMENTS
        detectaColisions();    // COLLISION DETECTION
        pintarPantalla(f.g);   // PAINT SCREEN
        f.repaint();

        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }           
    }while(true);
}

private void detectaColisions() { 
} 

private void moviments() {  
    for(int i=0;i<c1.length;i++)
        c1[i].movimiento(); 
}

private void initicalitzaJoc() {        

    c1 = new Enemigos[15];                 // ENEMIES

    for (int i=0; i<5; i++)
        c1[i] = new Enemigos(f, 100+i*80, 100, 5);
    for (int i=5; i<10; i++)
        c1[i] = new Enemigos(f, 100+(i-5)*80, 150, 5);
    for (int i=10; i<15; i++)
        c1[i] = new Enemigos(f, 100+(i-10)*80, 200, 5);

    // Nave del jugador:                    // PLAYER'S SHIP
    nave = new Nave(f,300-40/2, 500-40-5);

}

void pintarPantalla(Graphics g) {   

    g.setColor(Color.WHITE);
    g.fillRect(0, 0, 600,500);

    for (int i=0; i<5; i++)         
        c1[i].pinta(g,1);;
    for (int i=5; i<10; i++)
        c1[i].pinta(g,3);
    for (int i=10; i<15; i++)
        c1[i].pinta(g,6);       

    nave.pintaNave(g);

}

}

I don't know where the mistake could be, maybe in the loop... i don't know.

The question is how can i fixed it to can move the ship using the keyboard? This Space Invaders is a homework, I'm obliged to use the KeyListener... How can I make it works ?

Manuel Gijón
  • 138
  • 1
  • 11
  • It's not fix, it doesn't work. – Manuel Gijón Feb 16 '16 at 19:28
  • *"It's not fix, it doesn't work."* Oh right, yeah I meant good one on fixing the edits I suggested. A couple more tips: 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) Tip: Add @trashgod (or whoever, the `@` is important) to *notify* the person of a new comment. (I doubt they noticed the edit in which you have to use `KeyListener` for homework.) – Andrew Thompson Feb 17 '16 at 17:23

2 Answers2

1

I'have found the answer.

The problem was that the class "Finestra" ejecute the function "playing" (so the loop starts) before reading the keys.

It's enough chasing the order:

Finestra(){

    super("-+- Space Invaders -+-");
    setVisible(true);
    setSize(AMPLE,ALT);
    im=this.createImage(AMPLE, ALT);
    g=im.getGraphics();
    j=new Joc(this);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false);

    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);
    System.out.println("hola");
    j.playing();  // enter the loop after reading the keys.
}
Manuel Gijón
  • 138
  • 1
  • 11
0

Looking at your key event handler:

@Override
public void keyPressed(KeyEvent e) {
  int tecla = e.getKeyCode();
  if (tecla == KeyEvent.VK_RIGHT)
    j.nave.v = +10;
  if (tecla == KeyEvent.VK_LEFT)
    j.nave.v = -10;
}

It changes a variable called 'v' on your ship (nave).

Then your movimiento (presumably 'move') method on your ship uses another variable, velocidad. It completely ignores v!

Delete the variable v and just use velocidad.

Also, you only ever call movimiento on your enemy ships, never on your player's ship! So naturally, it never moves.

NickJ
  • 9,380
  • 9
  • 51
  • 74
  • Thanks but it doesn`t work. The "movimiento" method just make the ship moves uncontrollably, that`s why i was using a new variable "v" to control the new movement (in fact, the "movimiento" is not in the movimients method that is in the loop). – Manuel Gijón Feb 16 '16 at 16:26