keyPressed and keyReleased with java(eclipse)

Hi i found the code “Player Move” from @GoToLoop and i have several questions.

i put some of my question in the code:

static final int DIAM = 48, SPD = 4, FPS = 60;
static final color BG = 0350;
 
Player p;
 
void setup() {
  size(800, 600);
 
  smooth(3);
  frameRate(FPS);
  ellipseMode(CENTER);
 
  fill(Player.INK);
  stroke(Player.OUTLINE);
  strokeWeight(Player.BOLD);
 
  p = new Player(width>>1, height>>1, DIAM, SPD);
}
 
void draw() {
  background(BG);
  p.move();
  p.display();
}
 
void keyPressed() { //is there a way to use it in java ?
  p.setMove(keyCode, true);
}
 
void keyReleased() { //is there a way to use it in java ?
  p.setMove(keyCode, false);
}

class Player {
  static final color INK = #008000, OUTLINE = 0;
  static final float BOLD = 2.0;
 
  boolean isLeft, isRight, isUp, isDown;
  int x, y;
  final int d, v;
 
  Player(int xx, int yy, int dd, int vv) {
    x = xx; //position x
    y = yy; //position y
    d = dd; //DIAM ?
    v = vv; //SPD ?
  }
 
  void display() {
    ellipse(x, y, d, d);
  }
 
  void move() {
    int r = d>>1;  //what the purpose of the r here ?
    x = constrain(x + v*(int(isRight) - int(isLeft)), r, width  - r);  
    //in java i get the error: The operator - is undefined for the argument type(s) float, boolean
    y = constrain(y + v*(int(isDown)  - int(isUp)),   r, height - r);
  }
  
  //in java i can't "link" the isUp,isDown,isRight and isLeft between move() and setMove()
 
  boolean setMove(int k, boolean b) {  
    switch (k) {
    case +'W':
    case UP:
      return isUp = b;
  
    case +'S':
    case DOWN:
      return isDown = b;
  
    case +'A':
    case LEFT:
      return isLeft = b;
  
    case +'D':
    case RIGHT:
      return isRight = b;
  
    default:
      return b;
    }
  }
}

i get that this code is very versatile but i don’t understand all the process involve inside.
Can someone help me to understand it ?
Thanks for your times

1 Like

i wonder if i ask a dumb question or a hard one

I believe you’ve got it from here perhaps: :question:

What do you mean by that? This sketch is already cross-mode. :negative_squared_cross_mark:

That is, the same code runs on both offline Java Mode (Processing’s IDE) & online JavaScript Mode (Pjs): ProcessingJS.org

DIAM stands for diameter and SPD stands for speed. :racing_car:

d >> 1 gets the half of d, which stands for diameter btW. Thus r is radius. :green_circle:

B/c the sketch is using the default ellipseMode(CENTER);:

The default mode is ellipseMode(CENTER) , which interprets the first two parameters of ellipse() as the shape’s center point, while the third and fourth parameters are its width and height.

And the coordinate pair origin of an ellipse() is its CENTER, knowing the RADIUS of it is essential for collision checks: :heavy_check_mark:

In this specific sketch, the collision check is to constrain() the ellipse() within the sketch’s rectangular canvas when we move it: :face_with_monocle:
x = constrain(x + v*(int(isRight) - int(isLeft)), r, width - r);

Again I don’t get what you mean. B/c we can totally copy & paste the whole code in Processing IDE’s Java Mode in order to run it offline. :coffee:

1 Like

BtW, you can find a variant of this sketch at the links below: :link:

OpenProcessing.org/sketch/718355
OpenProcessing.org/sketch/717760

1 Like

Oopsie! Just now I’ve noticed the end of your thread title better: “Java (Eclipse)”! :woozy_face:

When using Eclipse and other similar IDEs, we need to use real Java syntax in files w/ “.java” extension. :coffee:

Processing’s IDE (PDE) uses “.pde” files. Although it recognizes “.java” files too. :innocent:

If you wanna, I can convert the class Player to actual Java syntax inside file “Player.java”. :nerd_face:

But b/c I don’t have Eclipse, I won’t be able to test if it’s actually compilable outside PDE. :see_no_evil:


I’ve just converted class Player to proper Java syntax in its own “Player.java” file: :coffee:

Player.java:

package sketches.classes;

import processing.core.PApplet;
import static processing.core.PApplet.constrain;
import static processing.core.PApplet.parseInt;
import static processing.core.PConstants.*;

public class Player {
  public static final int INK = 0xff008000, OUTLINE = 0;
  public static final float BOLD = 2f;

  protected final PApplet p;
  protected boolean isLeft, isRight, isUp, isDown;

  public int x, y;
  public final int d, v;

  public Player(PApplet pa, int xx, int yy, int dd, int vv) {
    p = pa;
    x = xx;
    y = yy;
    d = dd;
    v = vv;
  }

  public void display() {
    p.circle(x, y, d);
  }

  public void move() {
    final int r = d >> 1;
    x = constrain(x + v*(parseInt(isRight) - parseInt(isLeft)), r, p.width - r);
    y = constrain(y + v*(parseInt(isDown) - parseInt(isUp)), r, p.height - r);
  }

  public boolean setMove(final int k, final boolean b) {
    switch (k) {
    case 'W':
    case UP:
      return isUp = b;

    case 'S':
    case DOWN:
      return isDown = b;

    case 'A':
    case LEFT:
      return isLeft = b;

    case 'D':
    case RIGHT:
      return isRight = b;

    default:
      return b;
    }
  }
}

What’s still left is the main “Player_Move.pde” file: :neutral_face:

Player_Move.pde:

/**
 * Player Move (v1.3.1)
 * by GoToLoop (2014/Dec/07)
 *
 * Discourse.Processing.org/t/
 * keypressed-and-keyreleased-with-java-eclipse/12994/5
 *
 * Forum.Processing.org/two/discussion/8511/movement-code-messed-up#Item_6
 * Studio.ProcessingTogether.com/sp/pad/export/ro.91tcpPtI9LrXp
 */

//package sketches.main;

import sketches.classes.Player;

static final int DIAM = 48, SPD = 4, FPS = 60;
static final color BG = 0350;

Player p;

void setup() {
  size(800, 600);

  smooth(3);
  frameRate(FPS);
  ellipseMode(CENTER);

  fill(Player.INK);
  stroke(Player.OUTLINE);
  strokeWeight(Player.BOLD);

  //p = new Player(width >> 1, height >> 1, DIAM, SPD);
  p = new Player(this, width >> 1, height >> 1, DIAM, SPD);
}

void draw() {
  background(BG);
  p.move();
  p.display();
}

void keyPressed() {
  p.setMove(keyCode, true);
}

void keyReleased() {
  p.setMove(keyCode, false);
}

A very quick way to convert it to Java syntax is by using PDE’s “Export Application” option (hit CTRL+SHIFT+E). :bulb:

The “Player_Move.pde” will be output as “Player_Move.java”. :wink:

I believe you can move it to Eclipse and hopefully very little or even no changes will be needed. :new_moon:

2 Likes

Hi sorry for the delay,

yes exactly.

well that is my big problem, keyPressed() work but keyReleased() didn’t and i can’t find a way to “activate” it in eclipse with java. I think it because i didn’t find the right import (sorry i don’t know how to say that) like “import processing.core.PApplet;” (i know it’s not this one its just an example).

ok now its more clear for me thanks.

thanks for the convertion :slight_smile: i will test it soon as i found a way to activate keyReleased()

what does parseInt ? it work (perseInt) btw thanks :slight_smile:

to make an example :

i have 3 class: Game class who launch World class, World class who launch Player class

in my player class i have:

	public void PlayerMvt(PApplet p){
		if(p.keyPressed){ //boolean 
			if(p.key == PConstants.CODED){
				if(p.keyCode == PConstants.UP){
					position.y -= 10;
				}
				if(p.keyCode == PConstants.DOWN){
					position.y += 10;
				}
				if(p.keyCode == PConstants.LEFT){
					position.x -= 10;
				}
				if(p.keyCode == PConstants.RIGHT){
					position.x += 10;
				}
			}
		}
	}

As you can see, i can use keyPressed in that case but if i tried to use keyReleased in the same way it doesn’t work. i have the choice to make a boolean for keyPressed but not for keyRealeased.

if i try to make the method (correct me if i don’t use the right word please)


public void keyReleased(){
     //something
}

eclipse didn’t recognize it as a specific processing method, for him it’s just another method. if i change the name he dont care. like :


public void keyReleasedblabla(){ //no error because eclipse did not realise its a processing method
     //something
}

Am i clear ?

1 Like

Most callbacks such as keyReleased(), mousePressed(), and even setup() & draw(), all of them belong to class PApplet:
Processing.GitHub.io/processing-javadocs/core/processing/core/PApplet.html#keyPressed--

In order for them to be actually called back, they have to belong to some PApplet subclass, whose instance(s) had also been launched by method PApplet.runSketch() or PApplet.main():
Processing.GitHub.io/processing-javadocs/core/processing/core/PApplet.html#main-java.lang.String:A-

Like I’ve already advised you on my previous reply:

When the PDE compiles a sketch, it concatenates all “.pde” files as 1 “.java” file, wrapping them all up inside a PApplet subclass.

Then the PDE’s preprocessor transpiles that unified code into proper actual Java syntax, which can finally be compiled & run by Java.

And when we use the PDE’s export feature, we can find that transpiled “.java” file inside sketchFolder\application.windows64\source\.

I did that for my sketch “Player_Move”. And this is the output “Player_Move.java” file I’ve got:

Player_Move.java:

import processing.core.*; 
import processing.data.*; 
import processing.event.*; 
import processing.opengl.*; 

import sketches.classes.Player; 

import java.util.HashMap; 
import java.util.ArrayList; 
import java.io.File; 
import java.io.BufferedReader; 
import java.io.PrintWriter; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.IOException; 

public class Player_Move extends PApplet {

/**
 * Player Move (v1.3.1)
 * by GoToLoop (2014/Dec/07)
 *
 * Discourse.Processing.org/t/
 * keypressed-and-keyreleased-with-java-eclipse/12994/5
 *
 * Forum.Processing.org/two/discussion/8511/movement-code-messed-up#Item_6
 * Studio.ProcessingTogether.com/sp/pad/export/ro.91tcpPtI9LrXp
 */

//package sketches.main;



static final int DIAM = 48, SPD = 4, FPS = 60;
static final int BG = 0350;

Player p;

public void setup() {
  

  
  frameRate(FPS);
  ellipseMode(CENTER);

  fill(Player.INK);
  stroke(Player.OUTLINE);
  strokeWeight(Player.BOLD);

  //p = new Player(width >> 1, height >> 1, DIAM, SPD);
  p = new Player(this, width >> 1, height >> 1, DIAM, SPD);
}

public void draw() {
  background(BG);
  p.move();
  p.display();
}

public void keyPressed() {
  p.setMove(keyCode, true);
}

public void keyReleased() {
  p.setMove(keyCode, false);
}

  public void settings() {  size(800, 600);  smooth(3); }

  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "Player_Move" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}

Eclipse may now use the file above the exact way it is or w/ some very little adjustments.

1 Like

sorry i don’t have much time, i come back when i tested it.

Thanks for your help

Hi, i have finally some time to work on my code.

First, i did not try what you said, i dont get it and its overwelming for me.
But i think i found a way and of course i have an error (but its a start, i think).

here what i use as an example (why ? because its very basic):

player player;
void settings(){
  size(800,800);
  player = new player(400,400,3,50);
}

void draw(){
  background(255);
  player.update();
}

void keyPressed(){
  player.keyp();
}

void keyReleased(){
  player.keyr();
}
class player{
  int x,y,spd,size;
  boolean[] keys=new boolean[5];
  
player(int x1,int y1,int spd1,int size1){
  x=x1;
  y=y1;
  spd=spd1;
  size=size1;
}

void update(){
  if(keys[1]==true){
    y=y-spd;
  }
  if(keys[2]==true){
    x=x-spd;
  }
  if(keys[3]==true){
    y=y+spd;
  }
  if(keys[4]==true){
    x=x+spd;
  }
  rect(x,y,size,size);
}


void keyp(){
  if(key=='z'){
    keys[1]=true;
  }
  if(key=='q'){
    keys[2]=true;
  }
  if(key=='s'){
    keys[3]=true;
  }
  if(key=='d'){
    keys[4]=true;
  }
}

void keyr(){
  if(key=='z'){
    keys[1]=false;
  }
  if(key=='q'){
    keys[2]=false;
  }
  if(key=='s'){
    keys[3]=false;
  }
  if(key=='d'){
    keys[4]=false;
  }
}

}

here is my code (i tried to make as simple as i can)
my main class where everything is launch:

import mechanisme.World2;
import processing.core.PApplet;
import entity.Player2;



public class Game extends PApplet{
	
	public static void main(String[] args){
		PApplet.main("Game");
	}
	
	public void settings(){
		size(1200,900);
	}
	
	World2 world2;
	Player2 player2;
	
	public void setup(){
		world2 = new World2(this);
		surface.setResizable(true);
	}
	
	public void keyPressed(){
		player2.keyP();
	}
	
	public void keyReleased(){
		player2.keyR();
	}
	
	public void draw(){
		world2.makeWorld();
		world2.runWorld();
		world2.launchPrey();
		world2.launchPredator();
		world2.run();
		world2.displayAll(); //here i placed my PlayerMvt()
		world2.GUIAdmin();
		//player2.mvtComplex();
	}
	
}
package entity;

import java.util.ArrayList;

import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PImage;
import processing.core.PVector;


public class Player2 extends PApplet {
	PApplet parent;
	ArrayList<PVector> player2;
	/////test mvt complex
	boolean[] keys=new boolean[5];
	boolean isLeft, isRight, isUp, isDown = false;
//
///rest of my code
///
	public void PlayerMvt(PApplet p){
		if(p.keyPressed){
			if(p.key == PConstants.CODED){
				if(p.keyCode == PConstants.UP){
					position.y -= 20;
				}
				if(p.keyCode == PConstants.DOWN){
					position.y += 20;
				}
				if(p.keyCode == PConstants.LEFT){
					position.x -= 20;
				}
				if(p.keyCode == PConstants.RIGHT){
					position.x += 20;
				}
			}
		}
	}
		
	public void mvtComplex(){
		if(keys[1] == true || isUp == true){
			position.y -= 20;
		}
		if(keys[2] == true || isLeft == true){
			position.x -= 20;
		}
		if(keys[3] == true|| isDown == true){
			position.y += 20;
		}
		if(keys[4] == true || isRight == true){
			position.x += 20;
		}
	}
	
	public void keyP(){
		//p.keyPressed();
		if(parent.key=='z'){
		    keys[1]=true;
		    isUp = true;
		}
		if(parent.key=='q'){
			keys[2]=true;
			isLeft = true;
		}
		if(parent.key=='s'){
		    keys[3]=true;
		    isDown = true;
		}
		if(parent.key=='d'){
			keys[4]=true;
			isRight = true;
		}
	}
	
	
	public void keyR(){
		//p.keyReleased();
		if(parent.key=='z'){
		    keys[1]=false;
		    isUp = false;
		}
		if(parent.key=='q'){
		    keys[2]=false;
		    isLeft = false;
		}
		if(parent.key=='s'){
			keys[3]=false;
			isDown = false;
		}
		if(parent.key=='d'){
			keys[4]=false;
			isRight = false;
		}
	}

}

when i launch my program, i got this error if i press any key:

java.lang.NullPointerException
at Game.keyPressed(Game.java:28)
at processing.core.PApplet.keyPressed(PApplet.java:3064)
at processing.core.PApplet.handleKeyEvent(PApplet.java:2939)
at processing.core.PApplet.dequeueEvents(PApplet.java:2610)
at processing.core.PApplet.handleDraw(PApplet.java:2448)
at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1557)
at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:316)

if i launch my program whit my player2.mvtComplex() in the draw()
i got this error instantly:

java.lang.NullPointerException
at Game.draw(Game.java:43)
at processing.core.PApplet.handleDraw(PApplet.java:2437)
at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1557)
at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:316)

I dont show all my code because its huge and everything work perfectly except the part i show you.

Did you guys have any ideas what i do wrong ?

I can see you initialize field world2 here: world2 = new World2(this);

But I can’t spot where you would do the same for field player2?! :confused:

Here’s an article w/ very good tips about NullPointerException in Java:

2 Likes

i dont, i only put Player2 player2; to test the keyPressed and keyReleased method.
If i try to initialize it i have a bug

i’m completly lost, i try every way i found in this forum and nothing work for me

the only thing that work is that:

	public void PlayerMvt(PApplet p){
		if(p.keyPressed){
			if(p.key == PConstants.CODED){
				if(p.keyCode == PConstants.UP){
					position.y -= 20;
				}
				if(p.keyCode == PConstants.DOWN){
					position.y += 20;
				}
				if(p.keyCode == PConstants.LEFT){
					position.x -= 20;
				}
				if(p.keyCode == PConstants.RIGHT){
					position.x += 20;
				}
			}
		}
	}

but its only work for keyPressed so my movement are buggy and i can’t find a way to have a keyReleased

i check the link you send but i don’t find what’s wrong with my code

i ref to this first code and

  • -a- made it for me readable and runable in processing IDE
  • -b- made a working registered class from it but failed about the key register
    so need to still call them from main
  • -c- find from G4P a other way to register the key event

-A-

Player player;

void settings() {
  size(800, 800);
  player = new Player(400, 400, 3, 50);
}

void draw() {
  background(255);
  player.draw();
}

void keyPressed() {
  player.keyPressed();
}

void keyReleased() {
  player.keyReleased();
}

//__________________________________________________________CLASS PLAYER
class Player {
  int x, y, spd, size;
  boolean[] keys=new boolean[4];

  Player(int x, int y, int spd, int size) {
    this.x=x;
    this.y=y;
    this.spd=spd;
    this.size=size;
    println("use key [q] UP [s] LEFT [d] RIGHT [z] DOWN");
  }

  void draw() {
    if (keys[0]) y+=spd;       //q   UP
    if (keys[1]) y-=spd;       //z   DOWN
    if (keys[2]) x-=spd;       //s   LEFT
    if (keys[3]) x+=spd;       //d   RIGHT
    rect(x, y, size, size);
  }

  void keyPressed() {
    if (key=='z') keys[0]=true;
    if (key=='q') keys[1]=true;
    if (key=='s') keys[2]=true;
    if (key=='d') keys[3]=true;
  }

  void keyReleased() {
    if (key=='z') keys[0]=false;
    if (key=='q') keys[1]=false;
    if (key=='s') keys[2]=false;
    if (key=='d') keys[3]=false;
  }
}

-B-

Player player;

void settings() {
  size(800, 800);
  player = new Player(this, 400, 400, 3, 50);
}

void draw() {
  background(255);
}

void keyPressed() {
  player.keyPressed();
}

void keyReleased() {
  player.keyReleased();
}

//__________________________________________________________CLASS PLAYER
public class Player {
  PApplet pa;
  int x, y, spd, size;
  boolean[] keys=new boolean[4];

  Player(PApplet pa, int x, int y, int spd, int size) {
    this.pa = pa;
    this.x=x;
    this.y=y;
    this.spd=spd;
    this.size=size;

    pa.registerMethod("draw", this);
    println("use key [q] UP [s] LEFT [d] RIGHT [z] DOWN");
  }

  void draw() {
    if (keys[0]) y+=spd;       //q   UP
    if (keys[1]) y-=spd;       //z   DOWN
    if (keys[2]) x-=spd;       //s   LEFT
    if (keys[3]) x+=spd;       //d   RIGHT
    pa.rect(x, y, size, size);
  }
  // registering and NOT calling did not work.
  void keyPressed() {
    if (key=='z') keys[0]=true;
    if (key=='q') keys[1]=true;
    if (key=='s') keys[2]=true;
    if (key=='d') keys[3]=true;
  }

  void keyReleased() {
    if (key=='z') keys[0]=false;
    if (key=='q') keys[1]=false;
    if (key=='s') keys[2]=false;
    if (key=='d') keys[3]=false;
  }
}


-C-

// try to also register the key thing 
// by copy from:
// libraries\G4P\src\g4p_controls\GTextField.java
// Copyright (c) 2012 Peter Lager

import processing.event.KeyEvent;

Player player;

void settings() {
  size(800, 800);
  player = new Player(this, 400, 400, 3, 50);
}

void draw() {
  background(255);
}

//__________________________________________________________CLASS PLAYER
public class Player {
  PApplet pa;
  int x, y, spd, size;
  boolean[] keys=new boolean[4];

  Player(PApplet pa, int x, int y, int spd, int size) {
    this.pa = pa;
    this.x=x;
    this.y=y;
    this.spd=spd;
    this.size=size;

    pa.registerMethod("draw", this);
    pa.registerMethod("keyEvent", this);
    println("use key [q] UP [s] LEFT [d] RIGHT [z] DOWN");
  }

  void draw() {
    if (keys[0]) y+=spd;       //q   UP
    if (keys[1]) y-=spd;       //z   DOWN
    if (keys[2]) x-=spd;       //s   LEFT
    if (keys[3]) x+=spd;       //d   RIGHT
    pa.rect(x, y, size, size);
  }


  public void keyEvent(KeyEvent e) {   //@quark
    int keyCode = e.getKeyCode();
    char keyChar = e.getKey();
    boolean shiftDown = e.isShiftDown();
    boolean ctrlDown = e.isControlDown();
    int keyID = e.getAction();
    if (keyID == KeyEvent.PRESS) keyPressedProcess(keyCode, keyChar, shiftDown, ctrlDown);
    if (keyID == KeyEvent.RELEASE) keyReleasedProcess(keyCode, keyChar, shiftDown, ctrlDown);
  }

  protected void keyPressedProcess(int keyCode, char keyChar, boolean shiftDown, boolean ctrlDown) {
    //println(keyChar);
    if (keyChar=='z') keys[0]=true;
    if (keyChar=='q') keys[1]=true;
    if (keyChar=='s') keys[2]=true;
    if (keyChar=='d') keys[3]=true;
  }
  protected void keyReleasedProcess(int keyCode, char keyChar, boolean shiftDown, boolean ctrlDown) {
    //println(keyChar);
    if (keyChar=='z') keys[0]=false;
    if (keyChar=='q') keys[1]=false;
    if (keyChar=='s') keys[2]=false;
    if (keyChar=='d') keys[3]=false;
  }
}

hope the 3 examples might help you with your problem ( also code styling ).

3 Likes

Hi, @kll thanks for your response, the third example work !
Can you explain to me how does it work ? It is a code made by @quark ? (You put his name in comment)
Is it possible to use other keys with this method ? Like arrow keys ? (i just see it yes i can, dumb question)

What do you mean by “readable and runable in processing IDE” its from my processing IDE, it’s just two differents tabs.

The second option did not work with Eclipse (for me) it’s like Eclipse did not realise or get what the keyPressed() and keyReleased() does.

Thanks guys for your time and responses !

1 Like

I have read through this topic and it is a little confusing but it appears that you want a player object to respond to keyboard events and want to move the player using the arrow keys. You also want the code to work in Eclipse.

The following code works in Eclipse note that all Processing methods such as settings, setup, draw, keyPressed, mouseMoved etc. must be declared public in Java or they won’t work.

First file: PlayerMoveWithArrows.java

import processing.core.PApplet;

public class PlayerMoveWithArrows extends PApplet {

	/*
	 *  This next method is only required for Eclipse.
	 *  To run this is Eclipse select from the menus 
	 *  Run > Run As > Java Application
	 */
	public static void main(String[] args) {
		PApplet.main(new String[] { PlayerMoveWithArrows.class.getName() } );
	}

	Player player;

	public void settings() {
		size(800, 800);
	}

	public void setup() {
		size(800, 800);
		player = new Player(this, 400, 400);
	}

	public void draw() {
		background(255);
		player.draw();
	}

}

Second file: Player.java

import processing.core.*;
import processing.event.*;

public class Player {
	PApplet pa;
	float x, y;
	float speed = 5.0f;

	Player(PApplet pa, float x, float y) {
		this.pa = pa;
		this.x = x;
		this.y = y;
		pa.registerMethod("keyEvent", this);
	}

	void draw() {
		// save current transformations so we can change them safely
		pa.pushMatrix();
		// Save current drawing attributes
		pa.pushStyle();
		pa.fill(255, 255, 0);
		pa.stroke(0, 0, 255);
		pa.strokeWeight(2);
		pa.translate(x, y);
		pa.ellipse(0, 0, 20, 20);
		// Restore previous graphics attributes
		pa.popStyle();
		// Restore previous transformations
		pa.popMatrix();
	}

	// This method will be called whenever Processing gets a keyboard
	// event because it was registered in the constructor
	public void keyEvent(KeyEvent event) {
		PApplet.println(event.getAction(), pa.key);
		switch(event.getAction()) {
		case KeyEvent.PRESS:
			keyPressed(event);
			break;
		case KeyEvent.RELEASE:
			keyReleased(event);
			break;
		case KeyEvent.TYPE:
			keyTyped(event);
			break;
		}
	}

	public void keyPressed(KeyEvent ke) {
		PApplet.println("Key pressed  : " + ke.getKey() +
				"   Key code : " + ke.getKeyCode());
		switch(ke.getKeyCode()) {
		case 38: // Up arrow
			PApplet.println("UP");
			y -= speed;
			break;
		case 40: // Down arrow
			y += speed;
			break;
		case 39: // right arrow
			x += speed;
			break;
		case 37: // left arrow
			x -= speed;
			break;
		}
	}

	public void keyReleased(KeyEvent ke) {
		PApplet.println("Key released : " + ke.getKey() +
				"   Key code : " + ke.getKeyCode());
	}

	public void keyTyped(KeyEvent ke) {
		PApplet.println("Key pressed  : " + ke.getKey()	+
				"   Key code : " + ke.getKeyCode());
	}
}
3 Likes

yes, might be good idea
while your

  • qsdz set best for 4 fingers also with 2 hands
  • up down left right best for 3 finger right hand
  • or both with combine both key sets

( and a little rewrite )

// register the key event see: / libraries\G4P\src\g4p_controls\GTextField.java / Copyright (c) 2012 Peter Lager

Player player;

public void setup() {
  player = new Player(this, width/2, height/2, 3, 10);
}

public void draw() {
  background(255);
}

//__________________________________________________________CLASS PLAYER
public class Player {
  PApplet pa;
  int x, y, spd, size;
  int  [] bkeys = {0, 0, 0, 0};          // 0 stop / 1 move by spd
  byte [] skeys = {'q', 'z', 's', 'd'};  // key chars                            left hand
  int  [] ckeys = {38, 40, 37, 39};      // UP DOWN LEFT RIGHT Arrow key keyCode right hand

  Player(PApplet pa, int x, int y, int spd, int size) {
    this.pa = pa;
    this.x=x;
    this.y=y;
    this.spd=spd;
    this.size=size;

    pa.registerMethod("draw", this);
    pa.registerMethod("keyEvent", this);
    println("use keys ( or Arrow ) [q] UP [s] LEFT [d] RIGHT [z] DOWN");
  }

  public void draw() {
    x = constrain(x += spd*( bkeys[3]-bkeys[2] ), 0, width-size);
    y = constrain(y += spd*( bkeys[1]-bkeys[0] ), 0, height-size);
    pa.square(x, y, size);
  }

  public void keyEvent(KeyEvent e) {   // from @quark
    int keyCode = e.getKeyCode();
    char keyChar = e.getKey();
    int keyID = e.getAction();
    if (keyID == KeyEvent.PRESS  ) keyPressedProcess(keyCode, keyChar);
    if (keyID == KeyEvent.RELEASE) keyReleasedProcess(keyCode, keyChar);
  }

  protected void keyPressedProcess(int keyCode, char keyChar) {
    for (int i = 0; i<4; i++) if ( keyChar == skeys[i] || keyCode == ckeys[i] ) bkeys[i] = 1;
  }
  protected void keyReleasedProcess(int keyCode, char keyChar) {
    for (int i = 0; i<4; i++) if ( keyChar == skeys[i] || keyCode == ckeys[i] ) bkeys[i] = 0;
  }
}


i find both very responsive also for diagonal walking…

1 Like