Extreme Novice needing assistance with mousePressed() event

205 Views Asked by At

I am VERY new to P5.js/processing (taking programming for artists). I am trying to make a crude game where an image (Jar Jar) bounces across the screen and another image (lightsaber) that moves with the mouse and when the mouse attached image goes over the bouncing image then the lightsaber will be mirrored and activate a sound. If this at all makes sense...

I have the bouncing image part down so far, but I am unable to make the mousePressed() function work. like I mentioned, I need the "lightsaber.png" to flip when the mouse is pressed. Also, when the mouse is pressed and is directly over the JarJar image, how would I add a score count and sound event?

Thank you! here is my code so far:

let jarJar;
let jarJarX=5;
let jarJarY=5;
let xspeed;
let yspeed;
let lightSaber;
function preload() {
  jarJar = loadImage('jarjar.png');
  lightSaber= loadImage ('lightSaber.png');
 
}
function setup() {
  createCanvas(700,700);
  xspeed=random (15,22);
  yspeed=random (15,22);
}

function draw() {
  background(0);
   image (lightSaber,mouseX,mouseY,100,100);
   image(jarJar,jarJarX,jarJarY, 140, 200);
 jarJarX= jarJarX+xspeed;
  if (jarJarX<=-300|| jarJarX>=width+200){
    xspeed=xspeed*-1;
  }
 jarJarY= jarJarY+yspeed;
  if (jarJarY<-200|| jarJarY>=height+200 ){
    yspeed=yspeed*-1;
  }
  //picture mirrors when mouse pressed
  if mouseClicked(){
    scale(-1,1);
    image(lightSaber);
  }

  
  //score counter coordinate with lightsaber hitting image 
  // 
}
2

There are 2 best solutions below

0
laancelot On

Let it be known that I'm not proficient at javaScript. This said, your question is quite simple so I can help anyway.

Some framework will have simple ways to mirror images. Processing likes to scale with a negative number. I re-coded some of your stuff to accommodate my changes. The main changes goes as follows:

  1. I added a method to draw the lightsaber so we can "animate" it (read: flip it for a couple frames when the user clicks around).

  2. I added a 'score' global variable to track the score, and a way for the user to see that score with the text method.

  3. I added a method called "intersect" which isn't very well coded as it's something I did back when I was a student (please don't hurt me, it works just right so I still use it from time to time). For more details on how simple collisions works, take some time to read this answer I wrote some time ago, there are nice pictures too!

  4. I added a mouseClicked method. This method will act like an event, which means that it will be triggered by a specific call (a left mouse button click in this case). This method contains the code to check for a collision between the squares which are the images. If there's an overlap, the score will increase and jarjar will run in another direction (this part is a bonus to demonstrate that this is the place where you can get creative about the collision).

I commented the code so you can get what I'm doing more easily:

let jarJar;
let jarJarX=5;
let jarJarY=5;
let xspeed;
let yspeed;
let lightSaber;
let flipLength;
let score = 0;

function preload() {
  jarJar = loadImage('jarjar.png');
  lightSaber= loadImage ('lightSaber.png');
}

function setup() {
  createCanvas(700, 700);
  runJarJarRun();
}

function draw() {
  background(0);
  drawLightSaber(); // this way I can deal with the lightsaber's appearance in a dedicated method
  image(jarJar, jarJarX, jarJarY, 140, 200);
  jarJarX= jarJarX+xspeed;
  if (jarJarX<=-300|| jarJarX>=width+200) {
    xspeed=xspeed*-1;
  }
  jarJarY= jarJarY+yspeed;
  if (jarJarY<-200|| jarJarY>=height+200 ) {
    yspeed=yspeed*-1;
  }

  //score counter coordinate with lightsaber hitting image
  textSize(30);
  fill(200, 200, 0);
  text('Score: ' + score, 10, 40);
}

function drawLightSaber() {
  if (flipLength) { // if the number is > 0 this will be true
    flipLength--; // measure how ling the saber is flipped in frames @ ~60 frames per second

    push(); // isolating the translate ans scale manpulations to avoid ruining the rest of the sketch
    translate(mouseX + 100, 0); // makes the coordinates so once flipped the lightsaber will still appear at the same location
    scale(-1.0, 1.0);    // flip x-axis backwards
    image (lightSaber, 0, mouseY, 100, 100);
    pop(); // ends the sequence started with 'push();'
  } else {
    image (lightSaber, mouseX, mouseY, 100, 100);
  }
}

function runJarJarRun() {
  xspeed=random (5, 10);
  yspeed=random (5, 10);
}

function mouseClicked() { // this method will trigger once when the left mouse button is clicked
  flipLength = 10;
  if (intersect(jarJarX, jarJarY, 140, 200, mouseX, mouseY, 100, 100)) {
    score++;
    runJarJarRun(); // as a bonus, jarjar will run in another direction on hit
    // you could totally put some more special effects, like a flash, a sound, some 'mesa ouchie bad!' text, whatever speaks to you
  }
}

function intersect(x1, y1, w1, h1, x2, y2, w2, h2) {
  let checkX = false;
  let checkY = false;

  if ( (x1<x2 && (x1+w1)>x2) || (x1<(x2+w2) && (x1+w1)>x2+w2) || (x1>x2 && (x1+w1)<(x2+w2)) ) {
    checkX = true;
  }
  if ( (y1<y2 && (y1+h1)>y2) || (y1<(y2+h2) && (y1+h1)>y2+h2) || (y1>y2 && (y1+h1)<(y2+h2)) ) {
    checkY = true;
  }

  return (checkX && checkY);
}

If there's something you don't understand, let me know in a comment and I'll be happy to elaborate. Good luck and have fun!

0
quiltedcomputer On

Hi and welcome to stack overflow. One thing to keep in mind when submitting here (or any forum where you're looking for help with code) is to post a minimal reproducible example. You'll be much more likely to get useful responses.

You'll also want to separate out your questions, as they each have multi-step responses.

Your first question is about how to get your sketch to display something when you press the mouse down. Your syntax isn't quite correct there. Here's a minimal example of how to check for a mouse held down.

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);

  if (mouseIsPressed == true) {
    ellipse(100, 100, 100, 100);
  }
}

Just a quick note that I tried to make this as 'novice-friendly' as possible. The == true is optional and not usually included.