# keyPressed()



## Honkisponk (28. Jun 2009)

hi, ich bins nochmal

hab ein dickes problem und hock hier schon stunden rum und finde einfach keine lösung 

also ich will ein kleines Volleyball spiel programmieren. Wenn man auf die Pfeiltasten drückt soll die Figur springen, oder halt gehen. Wenn ich nach oben drücke, springt meine figur und kommt dann wieder auf ihre startposition zurück. Mein Problem ist jetzt, dass wenn ich "Pfeiltaste nach oben" gedrückt halte, meine Figur nach oben fliegt ^^

wie kann ich also bei der Methode keyPressed realisieren, das er nach dem ersten tastdruck sozusagen abricht. (und die figur gleich wieder runterkommt)

hab sogar dieses forum hier ewig lang durchsucht und da stand nur etwas von boolean flags, aber ich hab keine ahnung wie ich sowas machen soll. 

Ich bin hier echt am verzweifeln


----------



## Marco13 (28. Jun 2009)

Wie machst du denn im Moment die Bewegung nach oben? Mit einen eigenen Thread, der gestartet wird?


----------



## Honkisponk (28. Jun 2009)

nein. hab das vom tutorial von quaxil, 

wär jetzt ein bischen lang wenn ich das genau schreiben würde, aber im grunde genommen wird einfach von der y position der figur ein bestimmter wert (eine variable namens speed) abgezogen.

wenn ich die taste loslasse (also keyReleased()), dann wird die y-position einfach wieder auf einen startwert gesetzt (y-position wo die figur ursprünglich stand).


----------



## Marco13 (28. Jun 2009)

Ach so, da wird nichts "animiert": Wenn du die taste drückst, wird irgendwo eine Variable verändert, die bewirkt, dass die Figur weiter oben gezeichnet wird?!

Das mit dem Flag wäre ein Ansatz

```
class Bla
{
    private boolean isInAir = false;

    public void keyPressed(...)
    {
        if (isInAir) 
        {
            // Bin schon in der Luft, kann nicht springen...
            return;
        }

        figurPosition += 100;
        isInAir = true;
    }

    public void keyReleased(...)
    {
        if (isInAir)
        {
            figurPosition -= 100;
            isInAir = false;
        }

    }
```
dass man damit praktisch beliebig lange "fliegen" kann ist nochmal eine andere Sache...  aber ... jo. Wenn das nicht passt, beschreib' nochmal die Intention genauer, ggf. kann man das dann auch mit Quaxli's Tutorial abgleichen...


----------



## Honkisponk (28. Jun 2009)

```
package volley;

import java.awt.*;

public interface Drawable {
	
	public void drawObject(Graphics g);

}
------------------------------------------------
package volley;

public interface Movable {
	
	public void doLogic(long delta);
	
	public void move(long delta);
	
}
------------------------------------------------
package volley;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.swing.*;

public class GamePanel extends JPanel implements Runnable, KeyListener {

	private static final long serialVersionUID = 1L;
	boolean game_running = true;
	boolean started = false;
	boolean once = false;
	long delta = 0;
	long last = 0;
	long fps = 0;
	boolean up = false;
	boolean left = false;
	boolean right = false;
	int speed = 50;
	BufferedImage background;
	Heli copter;
	Vector<Sprite> actors;
	
	double startPoint = 0;
	
	public static void main(String[] args) {
		new GamePanel(800,600);
	}
	
	public GamePanel(int w, int h) {
		this.setPreferredSize(new Dimension(w,h));
		JFrame frame = new JFrame("Volley");
		frame.setLocation(0,0);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.addKeyListener(this);
		frame.add(this);
		frame.pack();
		frame.setVisible(true);
		doInitializations();
	}
	
	private void doInitializations() {
		
		last = System.nanoTime();
		
		actors = new Vector<Sprite>();
		BufferedImage[] heli = loadPics("volley/pics/figur.gif", 1);
		background = loadPics("volley/pics/background.gif", 1)[0];
		copter = new Heli(heli,100,450,100,this);
		actors.add(copter);
		startPoint = copter.getY();
		
		if(!once) {
			once = true;
			Thread t = new Thread(this);
			t.start();
		}
	}
	
	public void run() {
		while(game_running) {
			
			if(isStarted()) {
				computeDelta();
				doLogic();
				moveObjects();
				checkKeys();
			}
			
			repaint();
			
			try {
				Thread.sleep(10);
			}
			catch(InterruptedException e) {
				
			}
		}
	}
	
	private void doLogic() {
		for(Movable mov:actors) {
			mov.doLogic(delta);
		}
	}
	
	private void moveObjects() {
		for(Movable mov:actors) {
			mov.move(delta);
		}
	}
	
	private void computeDelta() {
		delta = System.nanoTime() - last;
		last = System.nanoTime();
		
		fps = ((long) 1e9) / delta;
	}
	
	private void checkKeys() {
		
		if(up){
			copter.setVerticalSpeed(-speed);
		}
		
		if(right){
			copter.setHorizontalSpeed(speed);
		}
		
		if(left){
			copter.setHorizontalSpeed(-speed);
		}
		
		if(!up){
			copter.setVerticalSpeed(0);
		}
		
		if(!left&&!right){
			copter.setHorizontalSpeed(0);
		}
	}
	
	public void paintComponent(Graphics g) {
		
		super.paintComponent(g);
		g.drawImage(background, 0, 0, this);
		g.setColor(Color.red);
		g.drawString("FPS: " + Long.toString(fps), 20, 10);
		
		if(!isStarted()) {
			return;
		}
		
		if(actors!=null) {
			for(Drawable draw:actors) {
				draw.drawObject(g);
			}
		}
	}
	
	private BufferedImage[] loadPics(String path, int pics) {
		
		BufferedImage[] anim = new BufferedImage[pics];
		BufferedImage source = null;
		
		URL pic_url = getClass().getClassLoader().getResource(path);
		
		try{
			source = ImageIO.read(pic_url);
		}
		catch(IOException e) {
		}
		
		for(int x=0;x<pics;x++){
			anim[x] = source.getSubimage(x*source.getWidth()/pics, 0, 
					source.getWidth()/pics, source.getHeight());
		}
		
		return anim;
	}
	
	public void keyPressed(KeyEvent e) {
		
		
		if(e.getKeyCode()==KeyEvent.VK_UP){
			up = true;
		}

		if(e.getKeyCode()==KeyEvent.VK_LEFT){
			left = true;
		}

		if(e.getKeyCode()==KeyEvent.VK_RIGHT){
			right = true;
		}
	}

	public void keyReleased(KeyEvent e) {
		
		if(e.getKeyCode()==KeyEvent.VK_UP){
			up = false;
			copter.setY(startPoint);
		}

		if(e.getKeyCode()==KeyEvent.VK_LEFT){
			left = false;
		}

		if(e.getKeyCode()==KeyEvent.VK_RIGHT){
			right = false;
		}
		
		if(e.getKeyCode()==KeyEvent.VK_ENTER){
			if(!isStarted()) {
				doInitializations();
				setStarted(true);
			}
		}
		
		if(e.getKeyCode()==KeyEvent.VK_ESCAPE){
			if(isStarted()) {
				setStarted(false);
			}else {
				setStarted(false);
				System.exit(0);
			}
		}
		
	}

	public void keyTyped(KeyEvent e) {
	}
	
	public boolean isStarted() {
		return started;
	}

	public void setStarted(boolean started) {
		this.started = started;
	}
	
}
-----------------------------------------------------------------------------------------
package volley;

import java.awt.Graphics;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

public abstract class Sprite extends Rectangle2D.Double implements Drawable, Movable {
	
	long delay;
	long animation = 0;
	GamePanel parent;
	BufferedImage[] pics;
	int currentpic = 0;
	protected double dx;
	protected double dy;
	
	public Sprite(BufferedImage[] i, double x, double y, long delay, GamePanel p) {
		pics = i;
		this.x = x;
		this.y = y;
		this.delay = delay;
		this.width = pics[0].getWidth();
		this.height = pics[0].getHeight();
		parent = p;
	}
	
	public void drawObject(Graphics g) {
		g.drawImage(pics[currentpic], (int) x, (int) y, null);
	}
	
	public void doLogic(long delta) {
		animation += (delta/1000000);
		if(animation > delay) {
			animation = 0;
			computeAnimation();
		}
	}
	
	private void computeAnimation() {
		
		currentpic ++;
		
		if(currentpic >= pics.length) {
			currentpic = 0;
		}
		
	}

	public void move(long delta) {
		
		if(dx != 0) {
			x += dx*(delta/1e9);
		}
		if(dy != 0) {
			y += dy*(delta/1e9);
		}
	}
	
	public void setVerticalSpeed(double d) {
		this.dy = d;
	}
	public void setHorizontalSpeed(double d) {
		this.dx = d;
	}
	public double getVerticalSpeed() {
		return dy;
	}
	public double getHorizontalSpeed() {
		return dx;
	}
	
	public void setX(double i){
		x = i;
	}
	
	public void setY(double i){
		y = i;
	}
	

}
-------------------------------------------------
package volley;

import java.awt.image.BufferedImage;

public class Heli extends Sprite {

	public Heli(BufferedImage[] i, double x, double y, long delay, GamePanel p) {
		super(i, x, y, delay, p);
	}
	
	public void doLogic(long delta) {
		super.doLogic(delta);
		
		if(getX()<0){
			setHorizontalSpeed(0);
			setX(0);
		}
		
		if(getX()+getWidth()>parent.getWidth()){
			setX(parent.getWidth()-getWidth());
			setHorizontalSpeed(0);
		}
		
		if(getY()<0){
			setY(0);
			setVerticalSpeed(0);
		}
		
		if(getY()+getHeight()>parent.getHeight()){
			setY(parent.getHeight()-getHeight());
			setVerticalSpeed(0);
		}
	}

}
```
--------------------------------------------------------------------------------------------------



hier mal mein kompletter code, deine lösung hat irgendwie nicht gefuntzt,

ich will eigentlich nur, dass wenn ich z.B. die pfeiltaste nach oben gedrückt halte, nur einmal die methode KeyPressed() aufgerufen wird. Als ob ich nur 1x nach oben gedrückt hätte. Es soll also egal sein ob ich jetzt die taste gedrückt halte oder nur einmal drücke, die figur soll immer wieder nach unten kommen (das nach unten kommen ist schon programmiert)

hoffe das ist jetzt klarer. ^^

ps: ne ist nix animiert, das ist ein ganz normales standbild ^^


----------



## André Uhres (28. Jun 2009)

Versuch's mal so (ich habe den boolean "upPending" eingeführt):

```
package volley;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.swing.*;

public class GamePanel extends JPanel implements Runnable, KeyListener {

    private static final long serialVersionUID = 1L;
    boolean game_running = true;
    boolean started = false;
    boolean once = false;
    long delta = 0;
    long last = 0;
    long fps = 0;
    boolean up = false;
    boolean left = false;
    boolean right = false;
    int speed = 50;
    BufferedImage background;
    Heli copter;
    Vector<Sprite> actors;
    double startPoint = 0;
    private boolean upPending;

    public static void main(String[] args) {
        new GamePanel(800, 600);
    }

    public GamePanel(int w, int h) {
        this.setPreferredSize(new Dimension(w, h));
        JFrame frame = new JFrame("Volley");
        frame.setLocation(0, 0);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.addKeyListener(this);
        frame.add(this);
        frame.pack();
        frame.setVisible(true);
        doInitializations();
    }

    private void doInitializations() {

        last = System.nanoTime();

        actors = new Vector<Sprite>();
        BufferedImage[] heli = loadPics("volley/pics/figur.gif", 1);
        background = loadPics("volley/pics/background.jpg", 1)[0];
        copter = new Heli(heli, 100, 450, 100, this);
        actors.add(copter);
        startPoint = copter.getY();

        if (!once) {
            once = true;
            Thread t = new Thread(this);
            t.start();
        }
    }

    public void run() {
        while (game_running) {

            if (isStarted()) {
                computeDelta();
                doLogic();
                moveObjects();
                checkKeys();
            }

            repaint();
            Runnable reset = new Runnable() {

                public void run() {
                    if (up) {
                        upPending = true;
                        up = false;
                        copter.setY(startPoint);
                    }
                }
            };
            SwingUtilities.invokeLater(reset);
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
            }
        }
    }

    private void doLogic() {
        for (Movable mov : actors) {
            mov.doLogic(delta);
        }
    }

    private void moveObjects() {
        for (Movable mov : actors) {
            mov.move(delta);
        }
    }

    private void computeDelta() {
        delta = System.nanoTime() - last;
        last = System.nanoTime();

        fps = ((long) 1e9) / delta;
    }

    private void checkKeys() {

        if (up) {
            copter.setVerticalSpeed(-2000);
        }

        if (right) {
            copter.setHorizontalSpeed(speed);
        }

        if (left) {
            copter.setHorizontalSpeed(-speed);
        }

        if (!up) {
            copter.setVerticalSpeed(0);
        }

        if (!left && !right) {
            copter.setHorizontalSpeed(0);
        }
    }

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);
        g.drawImage(background, 0, 0, this);
        g.setColor(Color.red);
        g.drawString("FPS: " + Long.toString(fps), 20, 10);

        if (!isStarted()) {
            return;
        }

        if (actors != null) {
            for (Drawable draw : actors) {
                draw.drawObject(g);
            }
        }
    }

    private BufferedImage[] loadPics(String path, int pics) {

        BufferedImage[] anim = new BufferedImage[pics];
        BufferedImage source = null;

        URL pic_url = getClass().getClassLoader().getResource(path);

        try {
            source = ImageIO.read(pic_url);
        } catch (IOException e) {
        }

        for (int x = 0; x < pics; x++) {
            anim[x] = source.getSubimage(x * source.getWidth() / pics, 0,
                    source.getWidth() / pics, source.getHeight());
        }

        return anim;
    }

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            if (upPending) {
                up = false;
                copter.setY(startPoint);
            } else {
                up = true;
            }
        }

        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            left = true;
            up = false;
            copter.setY(startPoint);
        }

        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            right = true;
            up = false;
            copter.setY(startPoint);
        }
    }

    public void keyReleased(KeyEvent e) {

        if (e.getKeyCode() == KeyEvent.VK_UP) {
            upPending = false;
            up = false;
            copter.setY(startPoint);
        }

        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            left = false;
        }

        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            right = false;
        }

        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            if (!isStarted()) {
                doInitializations();
                setStarted(true);
            }
        }

        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            if (isStarted()) {
                setStarted(false);
            } else {
                setStarted(false);
                System.exit(0);
            }
        }

    }

    public void keyTyped(KeyEvent e) {
    }

    public boolean isStarted() {
        return started;
    }

    public void setStarted(boolean started) {
        this.started = started;
    }
}
```


----------



## Honkisponk (28. Jun 2009)

cool danke dir, musste zwar den code an einer stelle umändern, aber jetzt funktioniert es ^^, auch wenn er ein bischen aprupt nach unten kommt , aber das werd ich hoffentlich noch hinkriegen 

also vielen vielen danke, ohne dich wär ich da nie drauf gekommen


----------

