How do I make my character only stop on whole tiles?

I’ve managed to make my sprite move, and it currently moves 2 positions each press of the arrow key.
My map is made up of grids of 20x20 pixels, and I’d like my character to only stop on whole tiles, to prevent any collision bugs.
I can’t seem to figure out how to do this. I want the character to move to the next tile in the direction it was moving in, even if its only 2 tiles over the previous

Do you use keyPressed as a function? Then only ONE key press is registered, and not many.

You can add the width of one tile when the player starts at the middle of a tile

Yeah, I have each key press adjust x or y by 2. When I hold an arrow key down, I think it just treats it as multiple key presses

How do I make it so that when the key is released, the character will continue moving in the same direction until it’s in the middle of the next tile?
Would I use keyReleased, and then calculate where the character is, then move it?

Only add the width of a tile
instead of 2

I’ve found the easiest way to do simple on-grid movement is like this:

int px = 10, py = 10, ox = 0, oy = 0; 

void setup() {
  size(400, 400);

void draw() {
  for (int j = 0; j < 20; j++) {
    for (int i = 0; i < 20; i++) {
      rect(20*i, 20*j, 20, 20);

  ellipse(px+ox, py+oy, 18, 18);
  if (ox > 0) ox-=2;
  if (ox < 0) ox+=2;
  if (oy > 0) oy-=2;
  if (oy < 0) oy+=2;

void keyPressed() {
  if ( ox != 0 || oy != 0) {
  if ( keyCode == DOWN ) {
    py += 20;
    oy = -20;
  if ( keyCode == UP ) {
    py -= 20;
    oy = 20;
  if ( keyCode == LEFT ) {
    px -= 20;
    ox = 20;
  if ( keyCode == RIGHT ) {
    px += 20;
    ox = -20;

p for position, o for offset.
if there’s no offsets, a key press moves the circle to the correct new position, but then adjusts the offset so it looks like it still is where it was. The offsets, of course, shrink to 0 every frame, so the circle appears to move.


Is there any way to make the circle move by 2 pixels per frame while still making each tile 20x20?

1 Like

I guess so

For example use lerp()

OR Just let it move until it reaches the center of a cell

The circle in my example is moving two pixels per frame.
Each tile is 20x20 pixels.
The code I posted already does both of these things.

1 Like