Using p5.js to trigger an event when the mouse is clicked on a two-dimensional grid

I've been working in the p5js editor on a project where I am trying to visualize a 2D array using squares. The goal is to have a square change color via mousePressed() based on the mouse coordinates relative to the square. However, I'm encountering an issue where the square that changes color is not the one I expect.

After logging the node that I click, it appears to be correct. But the visualization of the 2D array seems to be off.

The grid consists of a 3x3 arrangement of square x's like this:

x x x

x x x

x x x

My expectation was that if I clicked on the top left and then the top middle square, they would change color to blue as follows:

o o x

x x x

x x x

However, when I actually click on the top left followed by the top middle square, the result is:

x o o

x x x

x x x

It seems that clicking on a square causes the adjacent square to change color instead of the intended one.

An example can be found in the p5.editor at the following link:

let arr = [];
function setup(){
  canvas = createCanvas(200, 200);
  for(var j = 0; j < 3; j++){
    var inArr = [];
    for(var i = 0; i < 3; i++){
          var rect = new Rect(i,j);
      inArr.push(rect);
    }
    arr.push(inArr)  
  }
}

function draw(){
  for(var i = 0; i < arr.length; i++){
    for(var j = 0; j < arr[i].length; j++){
     arr[i][j].show()
    }
  }
}
function mousePressed(){
  arr.forEach(function(e, index){
    e.forEach(function(d,index2){
      arr[index][index2].clicked()
    });
  });
}

function Rect(i,j){
  this.fill = 'red'
  this.i = i;
  this.j = j;
  this.x = i * 20
  this.y = j * 20
 
  this.clicked = function(){
    let x1 = this.x, x2 = x1 + 20,
        y1 = this.y, y2 = y1 + 20;
    
    if((mouseX>x1&&mouseX<x2)&&(mouseY>y1&&mouseY< y2)){
      console.log(this)
      this.fill = 'black'
    }
  }
 
  this.show = function(){
    rect(i*20,j*20,20,20)
    fill(this.fill)
    stroke('blue')
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>

Answer №1

The quads are not being drawn at the correct position. Instead of using (i*20, j*20), they should be positioned at (this.x, this.y):

function Rect(i,j){
    // [...]

    this.show = function(){
        fill(this.fill)
        stroke('blue')

        // rect(i*20,j*20,20,20)
        rect(this.x, this.y, 20, 20)
    }
}

Here is an example:

let arr = [];
function setup(){
    canvas = createCanvas(200, 200);
    for(var j = 0; j < 3; j++){
        var inArr = [];
        for(var i = 0; i < 3; i++){
            var rect = new Rect(i,j);
            inArr.push(rect);
        }
        arr.push(inArr)  
    }
}

function draw(){
    background(255);
    for(var i = 0; i < arr.length; i++){
        for(var j = 0; j < arr[i].length; j++){
            arr[i][j].show()
        }
    }
}
function mousePressed(){
    arr.forEach(function(e, index){
        e.forEach(function(d,index2){
            arr[index][index2].clicked()
        });
    });
}

function Rect(i,j){
    this.fill = 'red'
    this.i = i;
    this.j = j;
    this.x = i * 20
    this.y = j * 20

    this.clicked = function(){
        let x1 = this.x, x2 = x1 + 20,
            y1 = this.y, y2 = y1 + 20;

        if( mouseX > x1 && mouseX < x2 & 
        mouseY > y1 && mouseY < y2){
            console.log(this)
            this.fill = 'black'
        }
    }

    this.show = function(){
        fill(this.fill)
        stroke('blue')
        rect(this.x, this.y, 20, 20)
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible for Response.Redirect and OnBeforeUnload to cooperate effectively?

Is there a way to detect if the server-side code has sent a Response.Redirect in an OnBeforeUnload event? I need to alert the user before they navigate away from a page, but I don't want the prompt to appear when the server redirects. I'm dealin ...

Seamless Integration Between AngularJS and PHP Communication Platforms

Why is the output of the code in this link different when compared to if I write the following: angular.module('pageModule') .factory('pageService', function($http){ var pagesArray = new Array(); return{ pagesArray: pagesArra ...

Troubleshooting problem with JSON object and HTML paragraph formatting

Attempting to incorporate my JSON object value into <p> tags has resulted in an unexpected change in formatting. The output in the console.log appears as shown in this image LINE INTERFACE UNIT,OMNITRON DX-64 LIU Item ...

What is the process for obtaining jsonencode data in a Laravel application?

server control public function room_details(Request $request) { $data['room_number'] = $request->id; $data['result_set'] = Rooms::find($request->id); echo $data['result_set']; return view('room ...

Optimizing Website Performance with Turbolinks 5: Ensuring JavaScript Loads Efficiently

If you want to see a clear example of the problem I am facing, feel free to check out my sample application. Visit the site, click on a link to another page, then use your browser's back button to return to the previous page and navigate forward again ...

Issue with Bootstrap 3 Modal: Missing Title and Input Labels

I'm currently working on customizing a bootstrap template for my friend's church website. My goal is to create a simple web presence for them, and I am in the process of setting up a contact form. I want this form to appear as a modal where users ...

I am currently implementing pagination for my data and it is functioning properly. However, I have noticed that when I search for specific data, it always appears on

My issue arises when I attempt to paginate my data and then search for specific information. The problem is that even if I am on page 3, the search results always display on page 1, making it difficult for me to locate the relevant data. What I want is for ...

NPM encountered an issue that prevented it from scanning directories due to a permission denial with the error code E

Whenever I type "npm run build:prod" build:prod npm run build -- --configuration production --aot --optimization=false I encounter the following error: > <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="82e4e3ece1fbafece3 ...

Function defined as an AngularJS component

I am facing an issue where my component is not initializing when I create it with a function that returns a component object. Can someone please help me understand the difference between these two situations? Html: <div ng-app="demoApp"> <navb ...

Service running in the background in React Native

In the process of creating a React Native application, I am looking to retrieve data from the web every quarter of an hour. The method I choose should be capable of fetching data in the background while being compatible across multiple platforms. Is ther ...

Utilizing JSON compression techniques on both the client and server ends for more efficient data transfer

I'm searching for a tool that can compress JSON on the server side (using C#) and then decompress it on the client side, as well as vice versa. The entire data model for my webpage is in JSON format and I need to find a way to reduce its size. I' ...

image background not appearing in HTML, CSS, and JavaScript game

When working on a simple HTML, CSS, and JavaScript game, I decided to make a change in the CSS code. Instead of setting the background color to green as before, I opted to use an image with the following line: background-image: url(flappybird.png); I also ...

MongoDB Casting Error: Unable to convert "xxx" to ObjectId for field "_id"

My current challenge involves fetching files with a specific criteria: ShipmentRequest.find() .where('estatus').in(['Asignada','Inicio Carga','Fin Carga','En Transito','Entregada']) . ...

Events triggered by client-side interactions with ASP.NET controls

Below is the image code I'm working with: <asp:Image runat="server" ID="imgLogo" Style="border-width: 0px; max-width: 100%; max-height: 200px;" onerror="showInvalidImageMessage();" onload="imageChanged()"/> Even though I want to trigger a Java ...

Resetting md-radio-button choices within an Angular 2 application

My Angular app has a sorting filter using radio buttons via md-radio-group for users to choose how they want data displayed. The radio buttons work fine, but I'm struggling to clear them when the "Restore Defaults" button is clicked. This is the code ...

What is the best way to create a countdown timer with React

I've been attempting to create a countdown timer using React. The goal is to count down from 10 to 0 and then trigger a function once it reaches 0. After some searching, I came across an example that seemed ideal for me: https://codesandbox.io/s/0q45 ...

Using jQuery to store the last selected href/button in a cookie for easy retrieval

Recently, I've been working on a document that features a top navigation with 4 different links. Each time a link is clicked, a div right below it changes its size accordingly. My goal now is to implement the use of cookies to remember the last select ...

The amCharts dateFormatter is having trouble interpreting Unix time, also known as Epoch timestamps, accurately

When trying to use Unix time (1608713282) for my amChart source and display it as 12/23/20 04:30:00, I encountered an issue where it was showing up as 01/19/70 00:00:00 in the tooltip. I attempted to format it correctly on the chart and dateAxis using the ...

Three.js - Attempting to apply a texture to a plane consistently results in a black rendering

I'm having trouble applying a texture to a plane. The image I'm using is 256x256, but it's rendering black instead of showing the texture. Can anyone point out where I might be making a mistake? //set up the floor var floorTexture = new TH ...

Modifying the clone() property in three.js affects all the meshes in my project

I am looking to create 100 identical cubes with a gradual decrease in opacity for each cube. This is my current loop implementation: var geometry = new THREE.BoxGeometry(0.15,0.15,0.15); var material = new THREE.MeshNormalMaterial(); var cube = new THREE. ...