Mouse position, camera and player movement

Hi, i started working on my player movements and i realise that i have a issue with the the coordinates of my mouse when i’m using a camera method.

Here is my code:

Player player;
LimitOfTheWorld limitoftheworld;
PVector view;
int mode;
int worldSize = 500;



void setup(){
  surface.setResizable(true);
  size(250,250);
  PVector pos = new PVector(250,250);
  PVector pos2 = new PVector(10,10);
  player = new Player(pos);
  limitoftheworld = new LimitOfTheWorld(pos2);
  rect(worldSize,worldSize,0,0);
}

void draw(){
  background(255);
  text("mousex: " + mouseX + "mousey: " + mouseY,20,20);
  switch(mode){
    case 0: // FLAT
    break;
    case 1: // TRACK
    translate(width/2, height/2);  // center screen on 0,0
    translate(-view.x, -view.y);   // recenter screen on view
    break;
  }
  
  pushMatrix();
  noFill();
  player.update();
  PVector target = new PVector(mouseX,mouseY);
  player.pointMouse(target);
  view = PVector.lerp(player.position,player.position,0.0);
  limitoftheworld.display();   //player.display();
  player.display2();
  popMatrix();
}

void keyReleased() {
  if (key == CODED) {
    if (keyCode == CONTROL) {
      mode = (mode+1)%2;
    }
  }
}
class LimitOfTheWorld{
  PVector position;
  float r;

  LimitOfTheWorld(PVector pos2){
    position = pos2.get();
    r = 450;
  }
  
  void display(){
    noFill();
    rect(position.x,position.y,r,r);
    stroke(5);
  }
}
class Player{
  
  PVector position;
  float r;
  PVector velocity;
  PVector acceleration;
  float maxspeed;
  float maxforce;
  
  Player(PVector pos){
    position = pos.get();
    r = 6;
    acceleration = new PVector(0, 0);
    velocity = new PVector(0, 0);
    velocity.mult(5);
    maxspeed = 1;
    maxforce = 0.15;
  }
  
  void display2() {
    float theta = velocity.heading2D() + radians(90);
    fill(127);
    stroke(0);
    pushMatrix();
    translate(position.x, position.y);
    rotate(theta);
    beginShape(TRIANGLES);
    vertex(0, -r*2);
    vertex(-r, r*2);
    vertex(r, r*2);
    endShape();
    popMatrix();
    text("x: " + position.x + "y: " + position.y, position.x+2, position.y);
    int dir = round(4 * (velocity.heading2D() + radians(90)) /  TWO_PI + 4) % 4;
      switch(dir) {
        case 0:
          text("north",10,10);
          break;
        case 1:
          text("east",10,10);
          break;
        case 2:
          text("south",10,10);
          break;
        case 3:
          text("west",10,10);
          break;
      }
  }
  
  void pointMouse(PVector target){
    PVector desired = PVector.sub(target,position);
    desired.setMag(maxspeed);
    PVector steer = PVector.sub(desired,velocity);
    steer.limit(maxforce);
    applyForce(steer);
  }
  
  void update() {
    velocity.add(acceleration);
    velocity.limit(maxspeed);
    position.add(velocity);
    acceleration.mult(0);
  }

  void applyForce(PVector force) {
     acceleration.add(force);
  }
}

So, my issue is:
when i don’t use the camera method(when i press control), everything works fine, the coordinates of my mouse are correct and my player follow the mouse. But when i use the camera method, it keep the coordinates based on the screen and of course it doesn’t work.

My question is, how can i manage to have the coordinates of my mouse based on my world not the screen ?

1 Like

give some modification on pointMouse
consider this

void pointMouse(PVector target) {
    PVector desired = PVector.sub(target, position);
    if (mode == 1) {
      desired = PVector.sub(new PVector(mouseX, mouseY), new PVector(width/2, height/2));
    } 
    desired.setMag(maxspeed);
    PVector steer = PVector.sub(desired, velocity);
    steer.limit(maxforce);
    applyForce(steer);
  }
1 Like

Thanks it work perfectly for my player. Did you know a way to “change” the coordinates of the mouse so it will be based on the world not the screen ? i dont know if I express myself well

if i add a simple method to show the position of my mouse with a red dot, when i use my camera, the position is clearly not correct

Player player;
LimitOfTheWorld limitoftheworld;
PVector view;
int mode;
int worldSize = 500;
PVector mouseCam;

void setup(){
  surface.setResizable(true);
  size(250,250);
  PVector pos = new PVector(250,250);
  PVector pos2 = new PVector(10,10);
  player = new Player(pos);
  limitoftheworld = new LimitOfTheWorld(pos2);
  rect(worldSize,worldSize,0,0);
}

void draw(){
  background(255);
  text("mousex: " + mouseX + "mousey: " + mouseY,20,20);
  mouseCam = PVector.sub(new PVector(mouseX, mouseY), new PVector(width/2, height/2));
  text("mousexcam: " + mouseCam.x + "mouseycam: " + mouseCam.y,20,30);
  switch(mode){
    case 0: // FLAT
    break;
    case 1: // TRACK
    translate(width/2, height/2);  // center screen on 0,0
    translate(-view.x, -view.y);   // recenter screen on view
    break;
  }
  
  pushMatrix();
  noFill();
  player.update();
  PVector target = new PVector(mouseX,mouseY);
  player.pointMouse(target);
  view = PVector.lerp(player.position,player.position,0.0);
  limitoftheworld.display();   //player.display();
  player.display2();
  popMatrix();
}

void keyReleased() {
  if (key == CODED) {
    if (keyCode == CONTROL) {
      mode = (mode+1)%2;
    }
  }
}

void mousePressed(){
  if(mousePressed == true){
    fill(255,0,0);
    ellipse(mouseX,mouseY,10,10);
  }
}

have you try something like this to get mouse world coordinate?

float mouseWx = player.position.x - width/2 + mouseX;
float mouseWy = player.position.x - height/2 + mouseY;

it doesn’t work, sorry i don’t know if its a wierd question , i dont have a lot of experience in coding

I believe your World would have a pair of coordinates x & y, and a pair for its dimensions width & height, right?

So you can use the formula from the link below in order to know whether the mouse coordinates are inside your World:

1 Like

Thanks i check that now

i don’t know if i understand the code you gave me, i modify it so you can see the issue i have

float px = 0;      // point position (move with mouse)
float py = 0;

float sx = 200;    // square position
float sy = 100;
float sw = 200;    // and dimensions
float sh = 200;
//added
PVector view;
int mode;
Player player;


void setup() {
  surface.setResizable(true); //added
  
  size(600,400);
  //noCursor();

  strokeWeight(5);    // thicker stroke = easier to see
  
  PVector pos = new PVector(250,250); //added
  player = new Player(pos); //added
  
}


void draw() {
  background(255);

  // update point to mouse coordinates
  px = mouseX;
  py = mouseY;

  // draw the point
  stroke(0);
  point(px,py);
  
  //added
  switch(mode){
    case 0: // FLAT
    break;
    case 1: // TRACK
    translate(width/2, height/2);  // center screen on 0,0
    translate(-view.x, -view.y);   // recenter screen on view
    break;
  }
  
  pushMatrix();
  noFill();
  player.update();
  PVector target = new PVector(mouseX,mouseY);
  player.pointMouse(target);
  view = PVector.lerp(player.position,player.position,0.0);
  
  boolean hit = pointRect(px,py, sx,sy,sw,sh);
  if (hit) {
    fill(255,150,0);
  }
  else {
    fill(0,150,255);
  }
  noStroke();
  rect(sx,sy, sw,sh);

  // draw the point
  stroke(0);
  point(px,py);
  player.display2();
  popMatrix();
  
}


// POINT/RECTANGLE
boolean pointRect(float px, float py, float rx, float ry, float rw, float rh) {

  // is the point inside the rectangle's bounds?
  if (px >= rx &&        // right of the left edge AND
      px <= rx + rw &&   // left of the right edge AND
      py >= ry &&        // below the top AND
      py <= ry + rh) {   // above the bottom
        return true;
  }
  return false;
}


void keyReleased() {
  if (key == CODED) {
    if (keyCode == CONTROL) {
      mode = (mode+1)%2;
    }
  }
}
class Player{
  
  PVector position;
  float r;
  PVector velocity;
  PVector acceleration;
  float maxspeed;
  float maxforce;
  
  Player(PVector pos){
    position = pos.get();
    r = 6;
    acceleration = new PVector(0, 0);
    velocity = new PVector(0, 0);
    velocity.mult(5);
    maxspeed = 1;
    maxforce = 0.15;
  }
  
  void display2() {
    float theta = velocity.heading2D() + radians(90);
    fill(127);
    stroke(0);
    pushMatrix();
    translate(position.x, position.y);
    rotate(theta);
    beginShape(TRIANGLES);
    vertex(0, -r*2);
    vertex(-r, r*2);
    vertex(r, r*2);
    endShape();
    popMatrix();
    text("x: " + position.x + "y: " + position.y, position.x+2, position.y);
    int dir = round(4 * (velocity.heading2D() + radians(90)) /  TWO_PI + 4) % 4;
      switch(dir) {
        case 0:
          text("north",10,10);
          break;
        case 1:
          text("east",10,10);
          break;
        case 2:
          text("south",10,10);
          break;
        case 3:
          text("west",10,10);
          break;
      }
  }
  
  void pointMouse(PVector target){
    PVector desired = PVector.sub(target,position);
    if(mode == 1){
      desired = PVector.sub(new PVector(mouseX, mouseY), new PVector(width/2, height/2));
    }
    desired.setMag(maxspeed);
    PVector steer = PVector.sub(desired,velocity);
    steer.limit(maxforce);
    applyForce(steer);
  }
  
  void update() {
    velocity.add(acceleration);
    velocity.limit(maxspeed);
    position.add(velocity);
    acceleration.mult(0);
  }

  void applyForce(PVector force) {
     acceleration.add(force);
  }
}

my problem is: when i lanch the “camera” by pressing control, i dont have the right coordinate for my mouse. In fact i have two dot

1 Like

You can better streamline your World by using the Java’s class Rectangle:
Docs.Oracle.com/en/java/javase/11/docs/api/java.desktop/java/awt/Rectangle.html

And calling its method contains(), passing the coordinate pair mouseX & mouseY as its arguments:
Docs.Oracle.com/en/java/javase/11/docs/api/java.desktop/java/awt/Rectangle.html#contains(int,int)

Here’s a very basic sketch that has a class called World, which in turn instantiates a Rectangle, and stores it in its field named area:

/**
 * Rectangle World (v1.0)
 * GoToLoop (2019/Jul/20)
 *
 * https://Discourse.Processing.org/t/
 * mouse-position-camera-and-player-movement/12837/10
 */

import java.awt.Rectangle;
World world;

void setup() {
  size(800, 600);
  world = new World(World.OFFSET, World.OFFSET, World.WIDTH, World.HEIGHT);
}

void draw() {
  clear();
  fill(world.isMouseInside()? World.INSIDE : World.OUTSIDE);
  world.display();
}

class World {
  static final int WIDTH = 500, HEIGHT = 400, OFFSET = 100;
  static final color INSIDE = #FF0000, OUTSIDE = #0000FF;

  final Rectangle area = new Rectangle();

  World(final int x, final int y, final int w, final int h) {
    area.setBounds(x, y, w, h);
  }

  World display() {
    rect(area.x, area.y, area.width, area.height);
    return this;
  }

  boolean isMouseInside() {
    return area.contains(mouseX, mouseY);
  }
}
2 Likes

thanks but it doesn’t solve my issues with my camera.

clearly i did not explain my problem properly.

Player player;
LimitOfTheWorld limitoftheworld;
PVector view;
int mode;
int worldSize = 500;

void setup(){
  surface.setResizable(true);
  size(250,250);
  PVector pos = new PVector(250,250);
  PVector pos2 = new PVector(10,10);
  player = new Player(pos);
  limitoftheworld = new LimitOfTheWorld(pos2);
  rect(worldSize,worldSize,0,0);
}

void draw(){
  background(255);
  text("mousex: " + mouseX + "mousey: " + mouseY,20,20);
  switch(mode){
    case 0: // FLAT
    break;
    case 1: // TRACK
    translate(width/2, height/2);  // center screen on 0,0
    translate(-view.x, -view.y);   // recenter screen on view
    break;
  }
  
  if(mousePressed == true){
    fill(255,0,0);
    ellipse(mouseX,mouseY,10,10);
  }
  
  pushMatrix();
  noFill();
  player.update();
  PVector target = new PVector(mouseX,mouseY);
  player.pointMouse(target);
  view = PVector.lerp(player.position,player.position,0.0);
  limitoftheworld.display();   player.display2();
  popMatrix();
}

void keyReleased() {
  if (key == CODED) {
    if (keyCode == CONTROL) {
      mode = (mode+1)%2;
    }
  }
}
class LimitOfTheWorld{
  PVector position;
  float r;

  LimitOfTheWorld(PVector pos2){
    position = pos2.get();
    r = 450;
  }
  
  void display(){
    noFill();
    rect(position.x,position.y,r,r);
    stroke(5);
  }
}
class Player{
  
  PVector position;
  float r;
  PVector velocity;
  PVector acceleration;
  float maxspeed;
  float maxforce;
  
  Player(PVector pos){
    position = pos.get();
    r = 6;
    acceleration = new PVector(0, 0);
    velocity = new PVector(0, 0);
    velocity.mult(5);
    maxspeed = 1;
    maxforce = 0.15;
  }
  
  void display2() {
    float theta = velocity.heading2D() + radians(90);
    fill(127);
    stroke(0);
    pushMatrix();
    translate(position.x, position.y);
    rotate(theta);
    beginShape(TRIANGLES);
    vertex(0, -r*2);
    vertex(-r, r*2);
    vertex(r, r*2);
    endShape();
    popMatrix();
    text("x: " + position.x + "y: " + position.y, position.x+2, position.y);
    int dir = round(4 * (velocity.heading2D() + radians(90)) /  TWO_PI + 4) % 4;
      switch(dir) {
        case 0:
          text("north",10,10);
          break;
        case 1:
          text("east",10,10);
          break;
        case 2:
          text("south",10,10);
          break;
        case 3:
          text("west",10,10);
          break;
      }
  }
  
  void pointMouse(PVector target){
    PVector desired = PVector.sub(target,position);
    if(mode == 1){
      desired = PVector.sub(new PVector(mouseX, mouseY), new PVector(width/2, height/2));
    }
    desired.setMag(maxspeed);
    PVector steer = PVector.sub(desired,velocity);
    steer.limit(maxforce);
    applyForce(steer);
  }
  
  void update() {
    velocity.add(acceleration);
    velocity.limit(maxspeed);
    position.add(velocity);
    acceleration.mult(0);
  }

  void applyForce(PVector force) {
     acceleration.add(force);
  }
}

So, if you run this sketch without pressing control, when you press the mouse, the red dot is on the mouse so its perfect.
But, when you press control and the camera activates, if you press the mouse, the red dot is not on the mouse.

I’m looking for a solution to force the coordinate of the red dot to be right about the world and the mouse (sorry my english is not perfect)

oh my bad :frowning:
this is actually

float mouseWx = player.position.x - width/2 + mouseX;
float mouseWy = player.position.y - height/2 + mouseY;

a typed position.x for both.
now, it will give you the mouse world coordinates

try this

if (mousePressed == true) {
    fill(255, 0, 0);
    float mouseWx = player.position.x - width/2 + mouseX;
    float mouseWy = player.position.y - height/2 + mouseY;
    ellipse(mouseWx, mouseWy, 10, 10);
  }
2 Likes

amazing ! thanks a lot :slight_smile: its was my fault i did not explain myself prolerly.

Thanks a lot

1 Like