Measuring change in X position of image

Hi all,

I am creating a game in processing and arduino. The game Character is a little red fish who can move inside his pool. I would like that the fish his head moves left when he is directed to move left by the controller. (and vise versa). I have tried to do this by using IF statements for the values of the X position of the controller, if the value is between the range of 0 and 512 (middle of controller) I want to draw a left fish, as then the controller is moved to the left. And if the value is between 512 and 1028 I will call the image in which the head of the fish is directed to the right.

Unfortunately this does not seem to work :frowning: so what I am now trying is to measure the X position of the Fish, and check weather this value of X is increasing or decreasing, so whether the position of this fish becomes more right or more left. And then with an IF statement I can call the correct images. However, I do not know how to measure whether this Xpos in my code in or de creasing. Anyone any idea?

I thought of saving the X position and compare it with the X position afterwards, and then check whether it is lower of higher. But I did not manage to make this work either…

Some tips or examples would be highly appreciated! Thanks!

Here is my code:

/*
 CREATIVE CHALLENGE 2: EGBERT THE FISH GAME_version_6
 DATE: 23_10_2022
 AUTHOR: TAISSIA VISSER
 
 REFERENCES:
 https://www.youtube.com/watch?v=jUmjbFsA2zw&ab_channel=Crazy-Logic
 https://processing.org/examples/interpolate.html
 
 INSPIRATION:
 
 */

// Importing the serial library.
import processing.serial.*;

// Declare serial communication port
Serial myPort;
String inString;
int[] data = {0, 0, 1};   // Array of data received from the serial port

// Declare game characters
PImage Campus;
PImage EgbertRight;
PImage EgbertLeft;
PImage Bottle;
PImage Corn;
PImage Bread;

boolean dataValid = false;

void setup() {
  size (1920, 1081);
  // printArray(Serial.list());
  String myPortName = Serial.list()[2];
  myPort = new Serial(this, myPortName, 9600);
  myPort.bufferUntil('\n');
  Campus = loadImage("Artboard 1.png");
  EgbertRight = loadImage("Egbertred2.png");
  EgbertLeft = loadImage ("Egbertred2.2.png");
  //Bottle = loadImage("plastic.png");
  //Corn = loadImage("corn.png");
  //Bread = loadImage("bread.png");
}

// initiating coordinate variables of joystick
int xPos;            // X data received through serial

int yPos;            // Y data received through serial

int Pressed;
float EgbertX;      // the X position of the Egbert Image
float EgbertY;      // the y position of the Egbert Image

void draw() {
  background(Campus);
  if (dataValid) {
    // mark new data is processed
    dataValid = false;
    // and process data

    // mapping the range of the X and Y input data of the Joystick to match the drawn pool
    // (I have found the correct X and Y coordinates by a mousepressed function to print the coordinates of every corner)
    //if (mousePressed){
    //println("X position is", mouseX, "and Y position is", mouseY);
    //}
    xPos = int(map(data[0], 0, 1023, 220, 1684));
    yPos = int(map(data[1], 0, 1023, 220, 855));
  }


  // translating the origin of egbert to the centre of the png of Egbert,
  // for correct mapping of the object. (Because the Png of Egbert has white space around it).
  float CentreEgbertX = xPos-((EgbertRight.width)/2);
  float CentreEgbertY = yPos-((EgbertRight.height)/2);

  // interpolating between the X of Y position of Egbert, and the movement of the joystick
  // moving 3% of the way to the joystick location each frame
  // to make sure the movement of the joystick is not so sensitive
  EgbertX = lerp(EgbertX, CentreEgbertX, 0.03);
  EgbertY = lerp(EgbertY, CentreEgbertY, 0.03);

  // the game character Egbert the fish is positioned at the X and Y coordinates
  // this data is received by the serial and was initialised with xPos and yPos.

  println(" x positie van egbert =", EgbertX);

  if (EgbertX >= -569 && EgbertX <= 153) {
    image(EgbertLeft, EgbertX, EgbertY);
  } else if (EgbertX >= 153 && EgbertX <= 893) {
    image(EgbertRight, EgbertX, EgbertY);
  }
  //image(Bottle, 100, 100);
  //image(Corn, 300, 300);
  //image(Bread, 400, 200);
}

// will get called every time data comes in
// storing the data string here
void serialEvent(Serial myPort) {
  String inString = myPort.readStringUntil('\n');
  if (inString != null) {
    // removing the whitespace
    inString = trim(inString);
    // Splitting the string at the commas and
    // seperating the variables out into an array
    data = int(split(inString, ","));
    // mark new data is available
    dataValid = true;
  }
  // println(inString);
}

1 Like

Hello @Ties2901,

I provided some code to help visualize the movement and determine change in direction.

I often write simple snippets of code with visualization and print statements in code during development.

This is a trickled down version of your code that may offer some insight:

/*
 CREATIVE CHALLENGE 2: EGBERT THE FISH GAME_version_6
 DATE: 23_10_2022
 AUTHOR: TAISSIA VISSER
 
 REFERENCES:
 https://www.youtube.com/watch?v=jUmjbFsA2zw&ab_channel=Crazy-Logic
 https://processing.org/examples/interpolate.html
 
 INSPIRATION:
 
 */
 
// Modified by glv to show the movement along x
// Comments removed
// Images removed
// fading added to help visualize movement

boolean dataValid = false;

int xPos = width/2;
int xLast;
float EgbertX;
int col;

void setup() 
  {
  size (600, 200);
  }

void draw() {
  fill(255, 10);             // With transparency
  rectMode(CORNER);
  rect(0, 0, width, height); // Overlay with rectangle with transparency
  
  if (frameCount%120 == 0)   // Every 2 seconds update fpr frameRate(60)
    {
    xPos = int(random(50, width-50)); 
    println(xLast, xPos);
    dataValid = true;
    }
  
  if (dataValid)
    {
    if (xLast > xPos)
      col = color(255, 0, 0);
    else
      col = color(0, 255, 0);
    dataValid = false;
    }      

  float CentreEgbertX = xPos;

  EgbertX = lerp(EgbertX, CentreEgbertX, 0.1);

  if (EgbertX >= 0 && EgbertX <= width/2) 
    {
    //image(EgbertLeft, EgbertX, EgbertY);
    fill(col);
    circle(EgbertX, 100, 30);
    
    fill(255, 255, 0);  
    circle(xPos, 100, 10);
    } 
  else if (EgbertX > width/2 && EgbertX <width) 
    {
    //image(EgbertRight, EgbertX, EgbertY);
    fill(col);
    rectMode(CENTER);
    rect(EgbertX, 100, 30, 30);
    
    fill(255, 255, 0);
    circle(xPos, 100, 10);
    }
  
  xLast = xPos;
  }

flowers.gif.mov

:)

1 Like

Hey glv,

Sorry for my late reply, I was working on some other parts of my code and wanted to leave the Left and Right Image for later. Many thanks for making it such a nice visual! I understand the concept now, but I am having some trouble with implementing it.

I will not use the framecount because my joystick will need to update the program continuesly ofcourse, for a smooth running game. But I tried to use the frame cound for printing the Xpos (position of joystick) and EgbertLastX. Which gave me an Array Index out of Bounds Exception.

Is it necessary to initiate these floats/ ints, BEFORE setup? Because I have initiated them in the setup.

This is what the code looks like (just the setup and draw functions and the booleans initiated before setup)

// moving left or right? 
boolean movingLeft; 
boolean movingRight;


//initializing an array of objects of the class Object.
Object[] objects;

//=======================================  SETUP  =======================================================

void setup() {
  size (1920, 1081);
  // printArray(Serial.list());

  for (int i= 0; i<food.length; i++) {
    // Loading all object images in the PImage array and placing them in the right index.
    // for every food, load one of the food images
    // start with the string food, then take whatever value i is, and take that to the file name
    // to load the right food image.
    //food[i] = loadImage("food"+i+".png");
    food[0] = loadImage("food0.png");
    food[1] = loadImage("food1.png");
    food[2] = loadImage("food2.png");
  }

  //Creating the array with a lenght of 20 objects which will appear in the game
  objects = new Object[20];
  // loop where 'i' goes through the length of the array
  for (int i=0; i<objects.length; i++) {
    // giving a random value between 0 and the length of the array, which will be
    // converted into an integer, which will give a random object out of the array
    int index = int(random(0, food.length));
    // the object stores a variable that indicates which image it will display
    objects [i] = new Object(food[index]);
  }

  String myPortName = Serial.list()[2];
  myPort = new Serial(this, myPortName, 9600);
  myPort.bufferUntil('\n');
  Campus = loadImage("Artboard 1.png");
  EgbertRight = loadImage("Egbertred2.png");
  EgbertLeft = loadImage ("Egbertred2.2.png");
}

// initiating coordinate variables of the joystick
float xPos;            // X data received through serial
float yPos;            // Y data received through serial

int Pressed;
float EgbertX;      // the X position of the Egbert Image
float EgbertY;      // the y position of the Egbert Image
float EgbertLastX;    // previous position of the Egbert Image

//=======================================  DRAW  ===================================================================

void draw() {
  background(Campus);

  // translating the origin of egbert to the centre of the png of Egbert,
  // for correct mapping of the object. (Because the Png of Egbert has white space around it).
  imageMode(CENTER);

  //calling display function from the object class, showing multiple objects
  //calling the dissappering function for all the objects
  for (int i=0; i<objects.length; i++) {
    objects[i].display();
    objects[i].dissappear();
  }

  if (dataValid) {
    // mark new data is processed
    dataValid = false;
    // and process data

    // mapping the range of the X and Y input data of the Joystick to match the drawn pool
    // (I have found the correct X and Y coordinates by a mousepressed function to print the coordinates of every corner)
    if (mousePressed) {
      println("X position is", mouseX, "and Y position is", mouseY);
    }
    xPos = int(map(data[0], 0, 1023, 220, 1684));
    yPos = int(map(data[1], 0, 1023, 220, 855));
  }

  // interpolating between the X of Y position of Egbert, and the movement of the joystick
  // moving 3% of the way to the joystick location each frame
  // to make sure the movement of the joystick is not so sensitive
  EgbertX = lerp(EgbertX, xPos, 0.03);
  EgbertY = lerp(EgbertY, yPos, 0.03);
  
  // MOVING left or right?
if (frameCount%120 == 0){
  println("xPos van de joystick is:",xPos,"EgbertLastX is:",EgbertLastX);
}

if (EgbertLastX<xPos){
  movingLeft = true;  
} if (movingLeft){
   image(EgbertLeft, EgbertX, EgbertY, SizeW, SizeH);
} else {
movingRight = true;
   image(EgbertRight, EgbertX, EgbertY, SizeW, SizeH);
}

  // the game character Egbert the fish is positioned at the X and Y coordinates
  // this data is received by the serial and was initialised with xPos and yPos.
  //println(" x positie van egbert =", EgbertX);
  // the sizeX and Y are dependend on initialization and on how many food objects it eats
 
EgbertLastX = xPos;

}