【问题标题】:Using WASD and arrow keys simultaneously同时使用 WASD 和方向键
【发布时间】:2013-02-12 03:13:20
【问题描述】:

我正在使用 Processing(在 Java 上运行)开发一个两人游戏。一位用户将使用 WASD 键控制他的角色,而另一位用户将使用箭头键控制移动。我遇到的问题是当按下箭头时使用keyPressed 否定WASD,反之亦然。我已经搞砸了很长时间。有谁知道解决方法或注意到我做错了什么?

//global variables
int wide = 600; //canvas width
int tall = 600; //canvas height
int s = 50; //player size
float speed = 2.5; //player movement speed

//colors
int redColor = #CB4646; //player 1 color
int blueColor = #4652CB; //player 2 color
int backgroundColor = #DBE3B3; //background color
float player1X = 600/3-s;  //HOW COME width/3 DOESN'T WORK??????????
float player2X = 600*2/3;
float playerY = 600/2-(s/2);

//players
Player player1 = new Player(player1X, playerY, s, speed, "wasd", redColor); //player 1
Player player2 = new Player(player2X, playerY, s, speed, "arrows", blueColor); //player 2

//setup
void setup(){
  background(backgroundColor);
  size(wide, tall);
  smooth();
  println(player2.controls);
}

//draw
void draw(){
  background(backgroundColor);
  player1.usePlayer();
  player2.usePlayer();
}

class Player{

   //class variables
   float x; // x position
   float y; // y position
   int s; //size
   float speed; //speed
   String controls; //controls
   int colors; //player color
   char keyControls [] = new char [4];

   //construct
   Player(float tempX, float tempY, int tempS , float tempSpeed, String tempControls, int tempColors){
     x = tempX; 
     y = tempY; 
     s = tempS; 
     speed = tempSpeed; 
     controls = tempControls; 
     colors = tempColors; 
   }

   void usePlayer(){

     // draw player
     fill(colors);
     rect(x, y, s, s);

     //move player
     keyPressed();

     //wraparound
     boundaries();

   }

   void keyPressed(){

     //sets controls for wasd
     if(controls == "wasd"){ 
          if(key == 'w' || key == 'W'){ 
            y -= speed; //move forwards
          }
          if(key == 's' || key == 'S'){
            y += speed; //move backwards
          }
            if(key == 'd' || key == 'D'){
            x += speed; //move right
          }
          if(key == 'a' || key == 'A'){
            x -= speed; //move left
          }
         }

      //sets controls for arrows 
      if(controls == "arrows"){ 
        if(key == CODED){
          if(keyCode == UP){ 
            y -= speed; //move forwards
          }
          if(keyCode == DOWN){
            y += speed; //move backwards
          }
            if(keyCode == RIGHT){
            x += speed; //move right
          }
          if(keyCode == LEFT){
            x -= speed; //move left
          }
         }  
        }  
       }

    //pacman style wraparound
    void boundaries(){
     if(x == width) x = 2;
     if(y == height) y = 2;
     if(x == 0) x = width-s;
     if(y == 0) y = height-s;
    }
}

【问题讨论】:

  • 这是否与键盘不能一次注册超过 2-6 个(取决于哪些)键有关?
  • @Patashu,我不这么认为,因为当我同时按两个时它不起作用。
  • 请注意,这实际上不是 Java 问题,而是处理问题。 Processing 是一个非常特殊的 API,其编程模型与 Java 略有不同(它被重写为 java 以便在 JVM 中离线使用,但在浏览器中在线使用时它被重写为 JavaScript)
  • @Mike'Pomax'Kamermans 感谢您提供的信息,我不知道!以后我将避免发布带有 Java 标记的处理问题。

标签: java keyboard processing 2d-games


【解决方案1】:

独立跟踪您的密钥,不要依赖事件全局变量。

boolean[] keys = new int[255];

void keyPressed() {
  keys[keyCode] = true;
}

void keyReleased() {
  keys[keyCode] = false;
}

void draw() {
  updatePlayers();
  drawStuff();
}

void updatePlayers() {
  if(keys[LEFT]) { p1.move(-1,0); }
  if(keys[RIGHT]) { p1.move(1,0); }
  if(keys[UP]) { p1.move(0,-1); }
  if(keys[DOWN]) { p1.move(0,1); }

  if(keys['a']) { p2.move(-1,0); }
  if(keys['d']) { p2.move(1,0); }
  if(keys['w']) { p2.move(0,-1); }
  if(keys['s']) { p2.move(0,1); }
}

请注意,这必须是一系列 if 语句,因为您要处理所有按下的键。如果有人左右握持,p1会左右移动。

另请注意,此示例代码不会过滤您为特殊键获得的高于 255 的代码,因此您可能希望在事件处理程序的开头放置“if(keyCode>255) return” .

【讨论】:

  • 我在遵循这背后的逻辑时遇到了一些麻烦。很抱歉,我是一般处理和编程的新手,非常感谢您的帮助。您是否建议我删除 usePlayer 方法并将其替换为接收我的 speed float 作为参数并递增到 xy 的 move 方法?我只是在想象如何将其转换为我的 Player 类时遇到了一些问题。另外,我收到关于此代码keys[keyCode] = true; 的错误消息cannot convert from boolean to int
  • 是的:使用一些明确的逻辑将播放器移动某个左/右和上/下值,并根据当前注册为向下的每个键确定该值。所以在你绘制你的玩家之前,你会处理所有在这一帧中按下的键,然后你调用玩家的绘制函数。另外,“无法转换...”错误是因为我很傻,不小心告诉你使用 int[] 而不是 boolean[] >_>
  • 非常感谢您的帮助!我刚刚将这个逻辑应用到我的程序中,它完美地移动了箭头键。它会记录同时按下的两个键并沿对角线移动!但是,我无法让 WASD 键正常工作。我认为这与您关于它们是 key 而不是 keyCode 值这一事实的建议有关。让他们俩都工作会是什么样子?
【解决方案2】:

key 是全局变量吗?我没有看到它被传递给播放器。如果它是全局的,那么它一次只能持有一个键,这就排除了同时控制两个玩家。

【讨论】:

    【解决方案3】:

    这是我用来处理同时按键(沿对角线移动)的 Arduino/处理代码。它修复了@Brannon 所示的boolean[] cannot be cast to int[] 错误问题,并使用keyCodes 而不是key。

    import processing.serial.*;
    ​
    boolean[] keys = new boolean[255];
    Serial port;
    ​
    void setup() { 
     port = new Serial(this, Serial.list()[1], 9600);
    ​
    }
    ​
    void draw() {
    
      // loop through boolean array and see which ones (index = keyCode)
      // are true, then write to them.
      for(int i = 0; i < 255; i++) {
        if(keys[i]) { 
          if (i == 87) { port.write('w'); }
          if (i == 65) { port.write('a'); }
          if (i == 83) { port.write('s'); }
          if (i == 68) { port.write('d'); }
        } 
      }
    }
    ​
    void keyPressed() {
      keys[keyCode] = true;
    }
    ​
    void keyReleased() {
      keys[keyCode] = false;
    }
    

    【讨论】:

      猜你喜欢
      • 2017-11-04
      • 2022-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多