Gleichzeitige Tastendrücke?

Verjigorm

Top Contributor
Hallo,

bin dabei ein kleines Hindernisspielchen programmieren.
Funktioniert auch soweit ganz gut, man kann eine "Figur" an 2D-Hindernissen vorbeinavigieren (hoch, runter, links, rechts)
Nun habe ich 2 Figuren, die sich durch diese Hindernisse bewegen müssen und habe dabei folgendes Problem:

Meine erste Figur reagiert aus w,a,s,d und die zweite soll auf die Pfeiltasten reagieren.
Soweit habe ich per Input/Actionmap alle Aktionen definiert und jede Figur an sich lässt sich steuern.
Wenn nun aber 2 gleichzeitig auf der Tastatur rumdrücken, so bewegt sich immer nur jeweil die Figur, die als letztes eine Taste drückt.

Also Bsp:
Spieler 1 hält w gedrückt und die Figur rennt grade aus.
Spieler 2 drückt nun irgendeine Richtungstaste, so rennt seine Figur los, während Figur 1 anhält. Spieler 1 muss dann erneut seine Tasten drücken und blockiert damit Spieler 2 und so weiter.
es wird ein wilder Kampf um jede gedrückte Taste ;)

Ich möchte erreichen, dass beide Spieler unabhängig von einander agieren können, wie realisiere ich das?
Ich hoffe mein Problem ist klar geworden :)
(Mal überlegen, wie ich daraus ein KSKB machen könnte.)

mfg Verjigorm
 
T

Tomate_Salat

Gast
Quellcode wäre nicht schlecht, wie du den Figuren sagst, dass sie sich bewegen sollen.

leider habe ich derzeit keine Zeit das lokal durchzutesten, deswegen gibts nur Theorie:

Interessant wäre hier auch, welche Events zurückgegeben werden, wenn ein Spieler blockiert wird. Die könnte man auf Abweichungen prüfen
 
G

Gast2

Gast
Du hast für jede Taste einen boolean (als beispiel mal: taste_w, taste_s, taste_a, taste_d).
Wird jetzt eine Taste gedrückt (keyPressed) setzt du den entsprechenden boolean und true, wird die taste losgelassen (keyReleased) wieder auf false.
Damit errreichst du dann dass mehrere Tasten gleichzeitig gedrückt werden können.

In deiner Spielelogik fragst du dann einfach nur ab ob taste_w == true.

Ein wenig Code wäre nicht schlecht.
 

Verjigorm

Top Contributor
Also ich habe mal versucht die eigentliche Frage in einem KSKB zu simulieren:

Java:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;


public class KeyPressedTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{
		JFrame frame = new JFrame();
		JPanel panel = new JPanel();
		final JTextArea area1 = new JTextArea();
		final JTextArea area2 = new JTextArea();
		
		area1.setEditable(false);
		area2.setEditable(false);
		
		panel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "w");
		panel.getActionMap().put("w", new AbstractAction() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) 
			{
				area1.append("w pressed\n");
			}
		});
		
		
		panel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "s");
		panel.getActionMap().put("s", new AbstractAction() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) 
			{
				area2.append("s pressed\n");
			}
		});
		
		panel.setLayout(new GridLayout(1,2));
		panel.add(new JScrollPane(area1));
		panel.add(new JScrollPane(area2));
		
		frame.setContentPane(panel);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);		
		frame.setSize(200,400);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}

}

folgendes Szenario:
1) man lässt "w" gedrückt: die linke Textarea wird konstant gefüllt
2) man drückt (hält gedrückt) nun zusätzlich "s": Der erste "Listener" stoppt und es wird nur noch auf den Druck von "s" reagiert.

Ich möchte aber, das beide simultan be/verarbeitet werden.
Ist das überhaupt möglich?

mfg Verjigorm
 
G

Gast2

Gast
Ja so wie ich im Post vorher schon gesagt habe

Java:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;


public class Main extends Thread {
    static boolean s_pressed = false;
    static boolean w_pressed = false;
    static final JTextArea area1 = new JTextArea();
    static final JTextArea area2 = new JTextArea();
    /**
     * @param args
     */
    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();

        area1.setEditable(false);
        area2.setEditable(false);

        KeyListener k = new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_W) {
                    w_pressed = true;
                } else if (e.getKeyCode() == KeyEvent.VK_S) {
                    s_pressed = true;
                }
            }

            public void keyReleased(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_W) {
                    w_pressed = false;
                } else if (e.getKeyCode() == KeyEvent.VK_S) {
                    s_pressed = false;
                }
            }
        };

        area1.addKeyListener(k);
        area2.addKeyListener(k);
        
        panel.setLayout(new GridLayout(1,2));
        panel.add(new JScrollPane(area1));
        panel.add(new JScrollPane(area2));

        frame.setContentPane(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(200,400);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        new Main().start();
    }

    public void run() {
        while (true) {
            if (s_pressed) {
                area2.append("s pressed\n");
            }
            if (w_pressed) {
                area1.append("w pressed\n");
            }
            try {
                sleep(50);
            } catch (InterruptedException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

Ist zwar keine sehr elegante Lösung, aber ich denke es sollte klar werden wie man sowas basteln kann.
 
G

Gast2

Gast
Du Programmierst doch ein Spiel, da wirst du doch irgendwo ne Schleife laufen haben die deine game logic ausführt, DORT baust du dann z.b. ne methode checkKeys(); ein die die Tastendrücke abfragt ;)
 

eliot

Bekanntes Mitglied
Die Spielelogik wird bisher nur durch Tastendrücke beeinflusst ;)

Autsch!
Üblich ist eigentlich ein Game Loop, der z.B. so aufgebaut ist:
Code:
while(!gameOver){
  updateWorld();
  renderWorld();
  sleep(x);
}
An dieser Stelle darf ich folgendes Buch empfehlen: Killer Game Programming - Killer Game Programming in Java
Ein sehr gutes und auch unterhaltsames Buch! Die vorgestellten Techniken gelten
auch für andere Programmiersprachen.

regards
eliotmc
 

Verjigorm

Top Contributor
Nix autsch, ich kenne das Buch auch.
Und bei einem rein statischen Spiel in dem sich ausschliesslich Veränderungen durch Tastendruck ergeben braucht man keine Gameloop. Es gibt sonst nix dynamisches, was aktualisiert werden müsste
 

eliot

Bekanntes Mitglied
Nix autsch, ich kenne das Buch auch.
Und bei einem rein statischen Spiel in dem sich ausschliesslich Veränderungen durch Tastendruck ergeben braucht man keine Gameloop. Es gibt sonst nix dynamisches, was aktualisiert werden müsste

Ok, wenn sich ansosnten die Welt nicht ändert, kannst du es wirklich
an den Tastendrücken festmachen.
Ich wollte nur sicher gehen, viele machen den Fehler dass sie ein dynamisches Spiel
über Tastendrücke timen.
 

Ähnliche Java Themen

Neue Themen


Oben