无法使用以前的答案同时击键将两张图片同时发送到 "move"
Can't get two pictures to "move" at the same time with simultaneous keystrokes using previous answers
在这段代码中,我有一个图形(paintcomponent 图形),它有两个水箱。 paintcomponent 由变量控制,然后是 repaint()。现在,当只按下或按住一个按钮时,它可以完美地工作。但是,例如,如果我为 tank1 保留左侧,为 tank2 保留右侧,则最后一个键是 "wins" 的键:这是唯一出现的方向。
在我的代码中,您会发现我最近的大约 4 次尝试“迭代”添加到代码中。
基本设置是:键绑定→AbstractAction→...
上面没有省略号(…)的设置代表了最初的尝试。然后,在另一次尝试中,它被链接到一个线程。同样的结果。在另一次尝试中,将抽象操作设置为更改数组值,该数组值连接到每 20 秒检查一次的计时器。从那里分支出来的两次尝试是定时器与线程的连接,以及直接repaint放入定时器。
此时我唯一的其他选择是为每个组合进行单独的键绑定(即,按住左键和 D [D 移动 tank1] 将是键码 "LEFT D" 的键绑定,因此将是移动两者的单独事件)。然而,这会很麻烦,因为我还有可以改变角度的炮塔和可以发射的子弹……而且我想有一种更合适的方法来做到这一点。
如有任何帮助,我们将不胜感激。代码如下。
class OneMoveRightThread implements Runnable { //This is a thread that contains code to 'move' the tank1.
public void run(){
tankGraphic.TankOneMoveRight();
gameArea.repaint();
}
}
class OneMoveLeftThread implements Runnable { //thread to move tank2
public void run(){
tankGraphic.TankOneMoveLeft();
gameArea.repaint();
}
}
//Meow is a [0,0,0,0,0,0,0,0] (8 zeroes) array. When a button is clicked the value is set to 1 for the spot in the array.
ActionListener taskPerformer = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (meow[0] == 1){ //This attempt uses a timer to constantly check the array for potential movement. Still works for 1 movement at a time.
(new Thread(new OneMoveLeftThread())).start();
meow[0]=0;
}
if(meow[1]==1){
(new Thread(new OneMoveRightThread())).start(); //using code in threads by calling the thread. My hope was that this would fix it.
meow[1]=0;
}
if (meow[2]==1){ //TANK TWO MOVE LEFT using code in threads
tankGraphic.TankTwoMoveLeft();
gameArea.repaint();
meow[2]=0;
}
}
};
new Timer(delay, taskPerformer).start();
//This abstract action is a different part of the code.
Action doNothing = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
lifeBar1.setText("\n Player 1: " + player1Name + " \n Health: " + player1Health + " \n Bullets: A LOT!");
lifeBar2.setText("\n Player 2: " + player2Name + " \n Health: " + player2Health + " \n Bullets: A LOT!");
}
};
//TANK TWO BELOW
Action leftMove = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) { //This is code for "When LEFT arrow is pressed, set meow[2]=1"
//tankGraphic.TankTwoMoveLeft();
//gameArea.repaint();
meow[2]=1;
}
};
Action rightMove = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) { //This is code for when RIGHT arrow is pressed, move tank directly. This and the above have same erroneous result.
tankGraphic.TankTwoMoveRight();
gameArea.repaint();
}
};
Action angleLEFT = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
tankGraphic.TankTwoAngleLeft();
gameArea.repaint();
}
};
Action angleRIGHT = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
tankGraphic.TankTwoAngleRight();
gameArea.repaint();
}
};
//TANK ONE BELOW
Action leftMove2 = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
meow[0]=1;
}
};
Action rightMove2 = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
//(new Thread(new OneMoveRightThread())).start();
meow[1]=1;
}
};
Action angleLEFT2 = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
tankGraphic.TankOneAngleLeft();
gameArea.repaint();
}
};
Action angleRIGHT2 = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
tankGraphic.TankOneAngleRight();
gameArea.repaint();
}
};
//these two lines are irrelevant. They match the irrelevant abstractaction.
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("B"), "doNothing");
gameArea.getActionMap().put("doNothing",doNothing);
//below is the code for the keybindings.
//the names are reversed, below. (fire1 corresponds to tank two, but the right side of the keyboard)
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("LEFT"), "leftMove");
gameArea.getActionMap().put("leftMove",leftMove);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("RIGHT"), "rightMove");
gameArea.getActionMap().put("rightMove",rightMove);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("UP"), "angleLEFT");
gameArea.getActionMap().put("angleLEFT",angleLEFT);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("DOWN"), "angleRIGHT");
gameArea.getActionMap().put("angleRIGHT",angleRIGHT);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"), "leftMove2");
gameArea.getActionMap().put("leftMove2",leftMove2);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("D"), "rightMove2");
gameArea.getActionMap().put("rightMove2",rightMove2);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("W"), "angleLEFT2");
gameArea.getActionMap().put("angleLEFT2",angleLEFT2);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"), "angleRIGHT2");
gameArea.getActionMap().put("angleRIGHT2",angleRIGHT2);
//gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("E"), "fire2");
//gameArea.getActionMap().put("fire2",fire2);
//gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("SLASH"), "fire1");
//gameArea.getActionMap().put("fire1",fire1);
frame.requestFocus();
KeyboardAnimation.java
示例执行此操作。 class 显示了一种使用 Key Bindings
和 Swing Timer
添加动画的方法。每个按键绑定可以控制不同的图像和不同的Timer。
一个图像由 4 个箭头键控制,另一个由 "a, d, w, s" 键控制。
在这段代码中,我有一个图形(paintcomponent 图形),它有两个水箱。 paintcomponent 由变量控制,然后是 repaint()。现在,当只按下或按住一个按钮时,它可以完美地工作。但是,例如,如果我为 tank1 保留左侧,为 tank2 保留右侧,则最后一个键是 "wins" 的键:这是唯一出现的方向。
在我的代码中,您会发现我最近的大约 4 次尝试“迭代”添加到代码中。
基本设置是:键绑定→AbstractAction→...
上面没有省略号(…)的设置代表了最初的尝试。然后,在另一次尝试中,它被链接到一个线程。同样的结果。在另一次尝试中,将抽象操作设置为更改数组值,该数组值连接到每 20 秒检查一次的计时器。从那里分支出来的两次尝试是定时器与线程的连接,以及直接repaint放入定时器。
此时我唯一的其他选择是为每个组合进行单独的键绑定(即,按住左键和 D [D 移动 tank1] 将是键码 "LEFT D" 的键绑定,因此将是移动两者的单独事件)。然而,这会很麻烦,因为我还有可以改变角度的炮塔和可以发射的子弹……而且我想有一种更合适的方法来做到这一点。
如有任何帮助,我们将不胜感激。代码如下。
class OneMoveRightThread implements Runnable { //This is a thread that contains code to 'move' the tank1.
public void run(){
tankGraphic.TankOneMoveRight();
gameArea.repaint();
}
}
class OneMoveLeftThread implements Runnable { //thread to move tank2
public void run(){
tankGraphic.TankOneMoveLeft();
gameArea.repaint();
}
}
//Meow is a [0,0,0,0,0,0,0,0] (8 zeroes) array. When a button is clicked the value is set to 1 for the spot in the array.
ActionListener taskPerformer = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (meow[0] == 1){ //This attempt uses a timer to constantly check the array for potential movement. Still works for 1 movement at a time.
(new Thread(new OneMoveLeftThread())).start();
meow[0]=0;
}
if(meow[1]==1){
(new Thread(new OneMoveRightThread())).start(); //using code in threads by calling the thread. My hope was that this would fix it.
meow[1]=0;
}
if (meow[2]==1){ //TANK TWO MOVE LEFT using code in threads
tankGraphic.TankTwoMoveLeft();
gameArea.repaint();
meow[2]=0;
}
}
};
new Timer(delay, taskPerformer).start();
//This abstract action is a different part of the code.
Action doNothing = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
lifeBar1.setText("\n Player 1: " + player1Name + " \n Health: " + player1Health + " \n Bullets: A LOT!");
lifeBar2.setText("\n Player 2: " + player2Name + " \n Health: " + player2Health + " \n Bullets: A LOT!");
}
};
//TANK TWO BELOW
Action leftMove = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) { //This is code for "When LEFT arrow is pressed, set meow[2]=1"
//tankGraphic.TankTwoMoveLeft();
//gameArea.repaint();
meow[2]=1;
}
};
Action rightMove = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) { //This is code for when RIGHT arrow is pressed, move tank directly. This and the above have same erroneous result.
tankGraphic.TankTwoMoveRight();
gameArea.repaint();
}
};
Action angleLEFT = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
tankGraphic.TankTwoAngleLeft();
gameArea.repaint();
}
};
Action angleRIGHT = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
tankGraphic.TankTwoAngleRight();
gameArea.repaint();
}
};
//TANK ONE BELOW
Action leftMove2 = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
meow[0]=1;
}
};
Action rightMove2 = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
//(new Thread(new OneMoveRightThread())).start();
meow[1]=1;
}
};
Action angleLEFT2 = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
tankGraphic.TankOneAngleLeft();
gameArea.repaint();
}
};
Action angleRIGHT2 = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
tankGraphic.TankOneAngleRight();
gameArea.repaint();
}
};
//these two lines are irrelevant. They match the irrelevant abstractaction.
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("B"), "doNothing");
gameArea.getActionMap().put("doNothing",doNothing);
//below is the code for the keybindings.
//the names are reversed, below. (fire1 corresponds to tank two, but the right side of the keyboard)
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("LEFT"), "leftMove");
gameArea.getActionMap().put("leftMove",leftMove);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("RIGHT"), "rightMove");
gameArea.getActionMap().put("rightMove",rightMove);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("UP"), "angleLEFT");
gameArea.getActionMap().put("angleLEFT",angleLEFT);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("DOWN"), "angleRIGHT");
gameArea.getActionMap().put("angleRIGHT",angleRIGHT);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"), "leftMove2");
gameArea.getActionMap().put("leftMove2",leftMove2);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("D"), "rightMove2");
gameArea.getActionMap().put("rightMove2",rightMove2);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("W"), "angleLEFT2");
gameArea.getActionMap().put("angleLEFT2",angleLEFT2);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"), "angleRIGHT2");
gameArea.getActionMap().put("angleRIGHT2",angleRIGHT2);
//gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("E"), "fire2");
//gameArea.getActionMap().put("fire2",fire2);
//gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("SLASH"), "fire1");
//gameArea.getActionMap().put("fire1",fire1);
frame.requestFocus();
KeyboardAnimation.java
示例执行此操作。 class 显示了一种使用 Key Bindings
和 Swing Timer
添加动画的方法。每个按键绑定可以控制不同的图像和不同的Timer。
一个图像由 4 个箭头键控制,另一个由 "a, d, w, s" 键控制。