Problem KeyBindings scheinen unsachgemäß zu arbeiten und wissen nicht warum | Java
Ich mache ein Spiel für ein Abschlussprojekt in einer meiner Klasse und ich arbeite an der Keybinding. Die Keybindings funktionieren einfach nicht wie sie sollen. Lassen Sie mich erklären:
So ist das Ziel, Ihren Charakter ein "Quadrat" auf einmal zu bewegen, während Sie sich in Richtung zum Ausgang bewegen (schwarzer Punkt). Jedes Mal, wenn Sie die Tastenkombination für die angegebene Richtung (A, S, D, W) drücken, sollte das "Terrain" überprüft und Sie zu diesem bewegt werden, wenn es sich um "Floor" handelt.
Seitennotiz: Ich muss noch hinzufügen, Gelände zu entfernen, weil ich die Bewegung zuerst richtig funktionieren muss.
Zurück zur Erklärung: Also das größte Problem ist, dass, wenn ich eine Tastatur zum ersten Mal trifft, es das Zeichen drei "Quadrate" von der ursprünglichen Position entfernt. Dann ist jede Bewegung danach willkürlich und wird den Spieler manchmal außer Reichweite bringen. Ich habe es so eingerichtet, dass es den Standort des Players jedes Mal ausdruckt, wenn eine Tastenkombination aktiviert wird (siehe unten stehenden Code). Ich habe das Gefühl, dass ich etwas falsch gemacht habe, als ich das erste Mal etwas mit der Tastatur verbunden habe.
Hier eines der Ausdrucke, die mein Programm gab mir für die Bewegung meines Charakters:
E:\StackOverflow\KeyBindings>java gamePanelMain
Player Start X: 0
Player Start Y: 0
Direction: Right, New X: 3
Direction: Right, New Y: 0
Direction: Right, New X: 9
Direction: Right, New Y: 0
Direction: Right, New X: 12
Direction: Right, New Y: 0
Direction: Down, New X: 12
Direction: Down, New Y: 3
Direction: Down, New X: 12
Direction: Down, New Y: 6
Direction: Down, New X: 12
Direction: Down, New Y: 8
Direction: Left, New X: 10
Direction: Left, New Y: 8
Direction: Left, New X: 7
Direction: Left, New Y: 8
Direction: Left, New X: 4
Direction: Left, New Y: 8
Direction: Down, New X: 4
Direction: Down, New Y: 11
Direction: Down, New X: 4
Direction: Down, New Y: 13
Direction: Down, New X: 4
Direction: Down, New Y: 17
Direction: Right, New X: 7
Direction: Right, New Y: 17
Direction: Right, New X: 17
Direction: Right, New Y: 17
Direction: Right, New X: 20
Direction: Right, New Y: 17
Direction: Right, New X: 23
Direction: Right, New Y: 17
Direction: Down, New X: 23
Direction: Down, New Y: 20
Direction: Down, New X: 23
Direction: Down, New Y: 23
Direction: Up, New X: 23
Direction: Up, New Y: 21
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 24
at gamePanel.right(gamePanel.java:259)
at gamePanel.changeCoord(gamePanel.java:192)
at gamePanel$1.actionPerformed(gamePanel.java:46)
at javax.swing.Timer.fireActionPerformed(Unknown Source)
at javax.swing.Timer$DoPostEvent.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Wie Sie es ist völlig zufällig und die Bewegung sehen kann, ist nicht so mit einem Zufallsgenerator oder irgendetwas verbunden. Außerdem muss ich noch hinzufügen, dass der Code außerhalb des zulässigen Bereichs liegt, aber ich mache mir mehr Sorgen darüber, diese Bewegung zuerst zu korrigieren.
Jetzt schaute ich auf einen Beitrag auf Tastenkürzel (Can't repaint my JFrame/JPanel) und versuchte, die Technik auf mein Spiel für die Tastenbindeoperation anzuwenden. Ich weiß nicht, was ich falsch gemacht habe, ist Teil des Problems.
Hier ist der Code, den ich nur für das Keybinding hinzugefügt:
public enum Direction{
UP,
LEFT,
DOWN,
RIGHT;
}
private Set<Direction>movement;
public gamePanel()
{
setBounds(115,93,480,480);//sets the size and location of gamePanel (x,y,w,h)
setFocusable(true);
movement = new HashSet<>(4);
addKeyPressedBinding(KeyEvent.VK_A, "left.pressed", new MoveAction(movement, Direction.LEFT, true));
addKeyReleasedBinding(KeyEvent.VK_A, "left.released", new MoveAction(movement, Direction.LEFT, false));
addKeyPressedBinding(KeyEvent.VK_D, "right.pressed", new MoveAction(movement, Direction.RIGHT, true));
addKeyReleasedBinding(KeyEvent.VK_D, "right.released", new MoveAction(movement, Direction.RIGHT, false));
addKeyPressedBinding(KeyEvent.VK_W, "up.pressed", new MoveAction(movement, Direction.UP, true));
addKeyReleasedBinding(KeyEvent.VK_W, "up.released", new MoveAction(movement, Direction.UP, false));
addKeyPressedBinding(KeyEvent.VK_S, "down.pressed", new MoveAction(movement, Direction.DOWN, true));
addKeyReleasedBinding(KeyEvent.VK_S, "down.released", new MoveAction(movement, Direction.DOWN, false));
Timer timer = new Timer(100, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
changeCoord();
}
});
timer.start();
System.out.println("Player Start X: " + pcX);
System.out.println("Player Start Y: " + pcY + "\n");
}
protected void addKeyBinding(int keyCode, String name, Action action){
addKeyBinding(KeyStroke.getKeyStroke(keyCode, 0), name, action);
}
protected void addKeyPressedBinding(int keyCode, String name, Action action) {
addKeyBinding(KeyStroke.getKeyStroke(keyCode, 0, false), name, action);
}
protected void addKeyReleasedBinding(int keyCode, String name, Action action) {
addKeyBinding(KeyStroke.getKeyStroke(keyCode, 0, true), name, action);
}
protected void addKeyBinding(KeyStroke keyStroke, String name, Action action) {
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = getActionMap();
inputMap.put(keyStroke, name);
actionMap.put(name, action);
}
//Later in the code after the generation and painting of the map...............
public void changeCoord() {
if (movement.contains(Direction.UP)) {
up();//checks position and moves player if it is "safe"
System.out.println("Direction: Up, New X: " + pcX);
System.out.println("Direction: Up, New Y: " + pcY + "\n");
} else if (movement.contains(Direction.DOWN)) {
down();//checks position and moves player if it is "safe"
System.out.println("Direction: Down, New X: " + pcX);
System.out.println("Direction: Down, New Y: " + pcY + "\n");
}
if (movement.contains(Direction.LEFT)) {
left();//checks position and moves player if it is "safe"
System.out.println("Direction: Left, New X: " + pcX);
System.out.println("Direction: Left, New Y: " + pcY + "\n");
} else if (movement.contains(Direction.RIGHT)) {
right();//checks position and moves player if it is "safe"
System.out.println("Direction: Right, New X: " + pcX);
System.out.println("Direction: Right, New Y: " + pcY + "\n");
}
repaint();
}
public class MoveAction extends AbstractAction{
private Set<Direction> movement;
private Direction direction;
private boolean pressed;
public MoveAction(Set<Direction> movement, Direction direction, boolean pressed) {
this.movement = movement;
this.direction = direction;
this.pressed = pressed;
}
@Override
public void actionPerformed(ActionEvent e) {
if (pressed) {
movement.add(direction);
} else {
movement.remove(direction);
}
}
}
Frage Bin ich etwas falsch mit dem Keybinding Prozess zu tun? Und wenn ja, wie repariere ich es? Wenn nicht, was habe ich falsch gemacht?
Hier finden Sie einige Arbeitscode, wenn Sie mit ihm herum würden sich gerne:
Hauptklasse
import javax.swing.JFrame;
public class gamePanelMain{
public static void main(String[] args){
JFrame frame = new JFrame();
gamePanel panel = new gamePanel();
frame.add(panel);
frame.setSize(520,540);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
panel.mapGen();
}//end main
}
Code, der alles
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.image.*;
import javax.swing.Timer;
public class gamePanel extends JPanel
{
public enum Direction{
UP,
LEFT,
DOWN,
RIGHT;
}
private Set<Direction>movement;
public gamePanel()
{
setBounds(115,93,480,480);//sets the size and location of gamePanel (x,y,w,h)
setFocusable(true);
movement = new HashSet<>(4);
addKeyPressedBinding(KeyEvent.VK_A, "left.pressed", new MoveAction(movement, Direction.LEFT, true));
addKeyReleasedBinding(KeyEvent.VK_A, "left.released", new MoveAction(movement, Direction.LEFT, false));
addKeyPressedBinding(KeyEvent.VK_D, "right.pressed", new MoveAction(movement, Direction.RIGHT, true));
addKeyReleasedBinding(KeyEvent.VK_D, "right.released", new MoveAction(movement, Direction.RIGHT, false));
addKeyPressedBinding(KeyEvent.VK_W, "up.pressed", new MoveAction(movement, Direction.UP, true));
addKeyReleasedBinding(KeyEvent.VK_W, "up.released", new MoveAction(movement, Direction.UP, false));
addKeyPressedBinding(KeyEvent.VK_S, "down.pressed", new MoveAction(movement, Direction.DOWN, true));
addKeyReleasedBinding(KeyEvent.VK_S, "down.released", new MoveAction(movement, Direction.DOWN, false));
Timer timer = new Timer(100, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
changeCoord();
}
});
timer.start();
System.out.println("Player Start X: " + pcX);
System.out.println("Player Start Y: " + pcY + "\n");
}
protected void addKeyBinding(int keyCode, String name, Action action){
addKeyBinding(KeyStroke.getKeyStroke(keyCode, 0), name, action);
}
protected void addKeyPressedBinding(int keyCode, String name, Action action) {
addKeyBinding(KeyStroke.getKeyStroke(keyCode, 0, false), name, action);
}
protected void addKeyReleasedBinding(int keyCode, String name, Action action) {
addKeyBinding(KeyStroke.getKeyStroke(keyCode, 0, true), name, action);
}
protected void addKeyBinding(KeyStroke keyStroke, String name, Action action) {
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = getActionMap();
inputMap.put(keyStroke, name);
actionMap.put(name, action);
}
private Random tGenerator = new Random();//initialize a random number generator
int tmin = 1;
int tmax = 20;
int floor = 0; //initializes the variable floor to zero for later use
int dirt = 1; //initializes the variable dirt to one for later use
int stone = 2; //initializes the variable stone to two for later use
int width = 24; // width of playing area
int height = 24; //height of playing area
int x, y; // my x & y variables for coordinates
int[][] coords = new int[width][height]; //my array that I want to store the coordinates for later use in painting
int[] terrain = {floor, dirt, stone}; //my terrain that will determine the color of the paint
public void mapGen() //what should mark/generate the JPanel
{
for(x = 0; x < width; x++)
{
for(y = 0; y < height; y++)
{
int t = tGenerator.nextInt(tmax - tmin + 1) + tmin; // random generator for terrain
if(t <= 10)
{
coords[x][y] = terrain[floor]; //should mark the coordinates as floor
}
if(t >= 12 && t <=16)
{
coords[x][y] = terrain[stone]; //should mark the coordinates as stone
}
if(t >=17 && t <= 19)
{
coords[x][y] = terrain[dirt]; //should mark the coordinates as dirt
}
}
}
coords[0][0] = terrain[0]; // sets coordinate 0,0 to floor
coords[23][23] = terrain[0]; // sets coordinate 24,24 to floor
}//end mapGen
public int pcY = 0;
public int pcX = 0;
@Override
public void paintComponent(Graphics g)//what will paint each 20x20 square on the grid what it is assigned
{
super.paintComponent(g);
for(int x = 0; x < width; x++)
{
for(int y = 0; y < height; y++)
{
if(coords[x][y] == terrain[floor])// paints floor color at marked coordinates
{
g.setColor(new Color(249,249,249));
g.fillRect((x*20), (y*20), 20, 20);
}
if(coords[x][y] == terrain[dirt])// paints dirt color at marked coordinates
{
g.setColor(new Color(121,85,58));
g.fillRect((x*20), (y*20), 20, 20);
}
if(coords[x][y] == terrain[stone])// paints stone color at marked coordinates
{
g.setColor(new Color(143,143,143));
g.fillRect((x*20),(y*20),20,20);
}
}
}
g.setColor(Color.red);//creates the player "model"
g.fillOval((pcX*20),(pcY*20),20,20);
g.setColor(Color.black);
g.fillOval((23*20),(23*20),20,20);
}//end paintComponent
public void changeCoord() {
if (movement.contains(Direction.UP)) {
up();
System.out.println("Direction: Up, New X: " + pcX);
System.out.println("Direction: Up, New Y: " + pcY + "\n");
} else if (movement.contains(Direction.DOWN)) {
down();
System.out.println("Direction: Down, New X: " + pcX);
System.out.println("Direction: Down, New Y: " + pcY + "\n");
}
if (movement.contains(Direction.LEFT)) {
left();
System.out.println("Direction: Left, New X: " + pcX);
System.out.println("Direction: Left, New Y: " + pcY + "\n");
} else if (movement.contains(Direction.RIGHT)) {
right();
System.out.println("Direction: Right, New X: " + pcX);
System.out.println("Direction: Right, New Y: " + pcY + "\n");
}
repaint();
}
public class MoveAction extends AbstractAction{
private Set<Direction> movement;
private Direction direction;
private boolean pressed;
public MoveAction(Set<Direction> movement, Direction direction, boolean pressed) {
this.movement = movement;
this.direction = direction;
this.pressed = pressed;
}
@Override
public void actionPerformed(ActionEvent e) {
if (pressed) {
movement.add(direction);
} else {
movement.remove(direction);
}
}
}
public void up(){
if(coords[pcX][pcY--] == terrain[floor]){
coords[pcX][pcY] = coords[pcX][pcY--];
}
else if(coords[pcX][pcY--] == terrain[dirt]){
coords[pcX][pcY] = coords[pcX][pcY--];
}
else if(coords[pcX][pcY--] == terrain[stone]){
coords[pcX][pcY] = coords[pcX][pcY--];
}
}
public void down(){
if(coords[pcX][pcY++] == terrain[floor]){
pcY++;
}
else if(coords[pcX][pcY++] == terrain[dirt]){
pcY++;
}
else if(coords[pcX][pcY++] == terrain[stone]){
pcY++;
}
}
public void right(){
if(coords[pcX++][pcY] == terrain[floor]){
pcX += pcX+1;
}
else if(coords[pcX++][pcY] == terrain[dirt]){
pcX++;
}
else if(coords[pcX++][pcY] == terrain[stone]){
pcX++;
}
}
public void left(){
if(coords[pcX--][pcY] == terrain[floor]){
pcX--;
}
else if(coords[pcX--][pcY] == terrain[dirt]){
pcX--;
}
else if(coords[pcX--][pcY] == terrain[stone]){
pcX--;
}
}
}// end gamePanel
tut Bitte versuchen Sie und behalten Sie alle Erklärungen a s so "dumbled" wie möglich, da ich noch lerne und den ganzen Programmiersprache noch nicht recht verstehe.
@ Andrew Thompson Oops, sorry lassen Sie mich für Sie ganz schnell – TheMrBaggins
Mögliche Duplikat umformatieren [KeyListener, keyPressed gegen keyTyped] (http://stackoverflow.com/questions/7071757/keylistener-keypressed-versus-keytyped) – bns
@ Ich habe mir diesen Beitrag angesehen und es scheint mein Problem nicht anzugehen. Wieder bin ich neu in der Tastatur, also vermisse ich vielleicht etwas – TheMrBaggins