Hover state for tiles in memory game Javascript - javascript

I have JavaScript code for a memory game for Khan Academy and I have no idea how to make a tile change color when the mouse is over it. As a test I tried to draw a star on a tile when the mouse was over it in the "if (tiles[i].isUnderMouse(mouseX, mouseY))" in the mouseClicked function but of course that only worked when the mouse is clicked and because the tiles are in a draw function the star would be put behind the new set of tiles after the next click. I don't really even know where to start to do this. Can anyone help me?
//Card face down image variable
var fdImage = image(getImage("avatars/questionmark"), this.x, this.y, this.width, this.width);
var Tile = function(x, y, face) {
this.x = x;
this.y = y;
this.face = face;
this.width = 70;
};
Tile.prototype.drawFaceDown = function() {
fill(214, 247, 202);
strokeWeight(2);
rect(this.x, this.y, this.width, this.width, 10);
image(getImage("avatars/questionmark"), this.x, this.y, this.width, this.width);
this.isFaceUp = false;
};
Tile.prototype.drawFaceUp = function() {
fill(214, 247, 202);
strokeWeight(2);
rect(this.x, this.y, this.width, this.width, 10);
image(this.face, this.x, this.y, this.width, this.width);
this.isFaceUp = true;
};
Tile.prototype.isUnderMouse = function(x, y) {
if ( x >= this.x && x <= this.x + this.width &&
y >= this.y && y <= this.y + this.width ) {
}
return x >= this.x && x <= this.x + this.width &&
y >= this.y && y <= this.y + this.width;
};
// Global config
var NUM_COLS = 5;
var NUM_ROWS = 4;
// Declare an array of all possible faces
var faces = [
//saplings
getImage("avatars/leafers-seed"),
getImage("avatars/leafers-seedling"),
getImage("avatars/leafers-sapling"),
getImage("avatars/leafers-tree"),
getImage("avatars/leafers-ultimate"),
getImage("avatars/piceratops-seed"),
getImage("avatars/piceratops-seedling"),
getImage("avatars/piceratops-sapling"),
getImage("avatars/piceratops-tree"),
getImage("avatars/piceratops-ultimate"),
getImage("avatars/aqualine-seed"),
getImage("avatars/aqualine-seedling"),
getImage("avatars/aqualine-sapling"),
getImage("avatars/aqualine-tree"),
getImage("avatars/aqualine-ultimate"),
//figures
getImage("avatars/marcimus"),
getImage("avatars/mr-pants"),
getImage("avatars/mr-pink"),
getImage("avatars/old-spice-man"),
getImage("avatars/orange-juice-squid"),
getImage("avatars/purple-pi"),
getImage("avatars/spunky-sam"),
//robots
getImage("avatars/robot_female_1"),
getImage("avatars/robot_female_2"),
getImage("avatars/robot_female_3"),
getImage("avatars/robot_male_1"),
getImage("avatars/robot_male_2"),
getImage("avatars/robot_male_3"),
//important figures
getImage("creatures/Hopper-Happy"),
getImage("creatures/Hopper-Cool"),
getImage("creatures/Hopper-Jumping"),
getImage("creatures/OhNoes"),
getImage("creatures/BabyWinston"),
getImage("creatures/Winston"),
//rpg material
getImage("space/beetleship"),
getImage("space/healthheart"),
getImage("space/octopus"),
getImage("space/planet"),
getImage("space/rocketship"),
getImage("space/star"),
];
// Make an array which has 2 of each, then randomize it
var possibleFaces = faces.slice(0);
var selected = [];
for (var i = 0; i < (NUM_COLS * NUM_ROWS) / 2; i++) {
// Randomly pick one from the array of remaining faces
var randomInd = floor(random(possibleFaces.length));
var face = possibleFaces[randomInd];
// Push twice onto array
selected.push(face);
selected.push(face);
// Remove from array
possibleFaces.splice(randomInd, 1);
}
// Now we need to randomize the array
selected.sort(function() {
return 0.5 - Math.random();
});
// Create the tiles
var tiles = [];
for (var i = 0; i < NUM_COLS; i++) {
for (var j = 0; j < NUM_ROWS; j++) {
tiles.push(new Tile(i * 78 + 10, j * 78 + 40, selected.pop()));
}
}
background(255, 255, 255);
// Now draw them face up
for (var i = 0; i < tiles.length; i++) {
tiles[i].drawFaceDown();
}
var flippedTiles = [];
var delayStartFC = null;
var numTries = 0;
mouseClicked = function() {
for (var i = 0; i < tiles.length; i++) {
//
if (tiles[i].isUnderMouse(mouseX, mouseY)) {
//
if (flippedTiles.length < 2 && !tiles[i].isFaceUp) {
tiles[i].drawFaceUp();
flippedTiles.push(tiles[i]);
if (flippedTiles.length === 2) {
numTries++;
if (flippedTiles[0].face === flippedTiles[1].face) {
flippedTiles[0].isMatch = true;
flippedTiles[1].isMatch = true;
}
delayStartFC = frameCount;
loop();
}
}
}
}
var foundAllMatches = true;
for (var i = 0; i < tiles.length; i++) {
foundAllMatches = foundAllMatches && tiles[i].isMatch;
}
if (foundAllMatches) {
fill(0, 0, 0);
textSize(20);
text("You found them all in " + numTries + " tries!", 20, 375);
}
};
draw = function() {
if (delayStartFC && (frameCount - delayStartFC) > 30) {
for (var i = 0; i < tiles.length; i++) {
if (!tiles[i].isMatch) {
tiles[i].drawFaceDown();
}
}
flippedTiles = [];
delayStartFC = null;
noLoop();
}
};

In order to add a hover state to the tiles in this Khan Academy challenge, you must first add a new method to your Tile object
Tile.prototype.hoverState = function() {
fill(150, 247, 202);
strokeWeight(2);
rect(this.x, this.y, this.width, this.width, 10);
image(getImage("avatars/leaf-green"), this.x, this.y, this.width, this.width);
this.isFaceUp = false;
};
Afterwards you will need to use mouseMoved like this:
mouseMoved = function() {
for (var i = 0; i < tiles.length; i++) {
if (tiles[i].isUnderMouse(mouseX, mouseY) && !tiles[i].isFaceUp) {
tiles[i].hoverState();
} else if (tiles[i].isFaceUp) {
tiles[i].drawFaceUp();
} else {
tiles[i].drawFaceDown();
}
}
};

Related

is there any way to create multiple buttons in p5.js?

i want to create an option like button in p5.js web editor.how can i achieve it i want to build a simulation where user can click on that button to select input' i want to create multiple buttons or when anyone clicks the button more options comes out
var img1
let posX=0
let posY=0
let button;
const rightwall=350;
function preload(){
img1=loadImage("https://raw.githubusercontent.com/Rabbid76/PyGameExamplesAndAnswers/master/resource/icon/Bird64.png")
}
function setup() {
createCanvas(600, 600);
button =createButton('CLICK ME');
button.position(250,300);
button.mousePressed(changeBG);
noLoop()
}
function changeBG() {
let val = random(255);
background(val);
if (playAnim) {
noLoop();
playAnim = false;
} else {
loop();
playAnim = true;
}
}
function draw() {
background(220);
fill('red');
rect(320,75,170,160)
fill('grey');
rect(posX,170,70,30)
image(img1,posX,posY-280,180,200)
posX = constrain(posX+1,0,rightwall-30)
posY = constrain(posX-1,posY,height-20)
if (posX == rightwall-30) {
posX=0
posY=0
}
}```
The following demo will create a drop down list which will run in p5.js Web Editor. This is the first conversion to p5.js and has not been extensively tested.
// Drop Down List parts => a.)display field, b.)arrow, c.)listItems
// Syntax: List(x, y, w, h, itemH, txtSize)
let list;
let selectedItem = -1;
let drop = false;
let items = ["Apples", "Peaches", "Oranges", "Bananas", "Pears" ];
let itemY = [];
class List {
constructor(x, y, w, h, itemH, txtSize) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.itemH = itemH;
this.txtSize = txtSize;
this.arrwX = this.x + this.w;
this.arrwY = this.y;
this.arrwH = this.h;
}
press(mx, my) {
// arrow touches
if ((mx >= this.arrwX) && (mx <= this.arrwX+this.arrwH) && (my >= this.arrwY) && (my <= this.arrwY+this.arrwH)) {
if (drop == true) {
drop = false;
} else {
drop = true;
}
} // list touches
if (drop) {
if (items.length > 0) {
for (let j = 0; j < items.length; j++) {
if ((mx >= this.x) && (mx <= this.x + this.w) && (my >= itemY[j] ) && (my <= itemY[j] + this.itemH)) {
selectedItem = j;
drop = false;
}
}
}
}
}
displayFieldString(title) {
fill(255); // background color
rect(this.x, this.y, this.w, this.h);
fill(0); // text color
textSize(this.txtSize);
text(title, this.x + 10, this.y + this.txtSize);
}
display() {
if (selectedItem == -1) {
this.displayFieldString("Select item:");
} else {
this.displayFieldString(items[selectedItem]);
}
// arrow
fill(255); // arrow background color
rect(this.arrwX, this.arrwY, this.arrwH, this.arrwH);
fill(0, 255, 0); // arrow color
triangle(this.arrwX+5, this.arrwY+5, this.arrwX+this.arrwH-5, this.arrwY+5, this.arrwX+this.arrwH/2, this.arrwY+this.arrwH-5);
// listItems
if ((items.length > 0) && (drop)) {
for (let j = 0; j < items.length; j++) {
itemY[j] = (this.y + this.h) + j*this.itemH;
fill(255);
rect(this.x, itemY[j], this.w, this.itemH);
fill(0);
textSize(this.txtSize);
text(items[j], this.x + 10, itemY[j] + this.txtSize);
}
}
if (!drop) {
rect(this.x, this.y + this.h, this.w, 0);
}
}
}
function setup() {
createCanvas(500, 400);
list = new List(100, 100, 120, 24, 24, 16);
}
function draw() {
background(220);
list.display();
}
function mousePressed() {
list.press(mouseX, mouseY);
}

Why the nextButton/startButton does not work?

I am working on a project on Khan Academy in which I have to create a game with at least 3 levels. I have developed most of the game but when I tried to proceed from one level to next the game somehow stops.
Here is the full project:
Project Link
/**
* Contains 3 levels
*
*
* Changed Ground
* Brown rectangle is replaced with Dirt Block.
*
* Scoring system changed
* Collecting Good sticks gets 1 point.
* Collecting Bad sticks gets -1 point. (i.e. loses point).
* Hitting rocks will lose 1 point.
*
**/
var level = 0;
var nosOfSticks = 5;
var target = 0;
var speed = 1;
var endLevel = false;
var buttonClicked = false;
var levelButtonEnabled = false;
var startButtonEnabled = true;
var Beaver = function(x, y) { // Beaver Constructor
this.x = x;
this.y = y;
this.img = getImage("creatures/Hopper-Happy");
this.sticks = 0;
};
Beaver.prototype.draw = function() { // Draw function to draw beaver
fill(255, 0, 0);
this.x = constrain(this.x, 0, width-40);
this.y = constrain(this.y, 0, height-50);
image(this.img, this.x, this.y, 40, 40);
};
Beaver.prototype.hop = function() { // Hop function to make beaver hop
this.img = getImage("creatures/Hopper-Jumping");
this.y -= speed * 5;
};
Beaver.prototype.hopLeft = function() {
this.img = getImage("creatures/Hopper-Jumping");
this.x -= speed * 5;
};
Beaver.prototype.hopRight = function() {
this.img = getImage("creatures/Hopper-Jumping");
this.x += speed * 5;
};
Beaver.prototype.fall = function() { // fall function makes beaver fall on the ground
this.img = getImage("creatures/Hopper-Happy");
this.y += speed * 5;
};
Beaver.prototype.checkForStickGrab = function(stick) { // function that checks sticks grab
if ((stick.x >= this.x && stick.x <= (this.x + 40)) &&
(stick.y >= this.y && stick.y <= (this.y + 40))) {
stick.y = -400;
this.sticks++;
}
};
Beaver.prototype.checkForBadStickGrab = function(badstick) { // function that checks badsticks grab
if ((badstick.x >= this.x && badstick.x <= (this.x + 40)) &&
(badstick.y >= this.y && badstick.y <= (this.y + 40))) {
badstick.y = -400;
this.sticks--;
}
};
Beaver.prototype.checkForRockHit = function(rock) { // function that checks rocks hit
if ((rock.x >= this.x - 40 && rock.x <= (this.x + 40)) &&
(rock.y >= this.y - 30 && rock.y <= (this.y + 40))) {
rock.x = -400;
this.sticks--;
}
};
// Drawing Sticks
var Stick = function(x, y) { // Stick constructor
this.x = x;
this.y = y;
};
Stick.prototype.draw = function() { // Draw function to draw sticks
fill(0, 0, 0);
rectMode(CENTER);
rect(this.x, this.y, 5, 40);
};
var Badstick = function(x, y) { // Bad Sticks constructor
Stick.call(this, x, y);
};
//Badstick.prototype = Object.create(Stick);
Badstick.prototype.draw = function() { //Draw function to draw badsticks
fill(255, 0, 13);
rectMode(CENTER);
rect(this.x, this.y, 5, 40);
};
// Drawings Rocks
var Rock = function(x, y) { // rocks constructor
this.x = x;
this.y = y;
this.img = getImage("cute/Rock");
};
Rock.prototype.draw = function(x, y) { // function to draw rocks
fill(0, 0, 0);
image(this.img, this.x, this.y, 40, 40);
};
var beaver = new Beaver(200, 300);
var sticks = [];
for (var i = 0; i < nosOfSticks; i++) {
sticks.push(new Stick(i * 100 + 400, random(20, 260)));
}
var badSticks = [];
for (var i = 0; i < nosOfSticks/2; i++) {
badSticks.push(new Badstick(i * 200 + 400, random(20, 270)));
}
var rocks = [];
for ( var i = 0; i < nosOfSticks * 0.375; i++) {
rocks.push(new Rock(random(0, 375), i * random() - (i * 100)));
}
var grassXs = [];
for (var i = 0; i < 25; i++) {
grassXs.push(i*20);
}
var blockXs = [];
for (var i = 0; i < 25; i++) {
blockXs.push(i*20);
}
var Button = function (x, y, w, h, color, text, size, font, textcolor, best) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.color = color;
this.text = text;
this.size = size;
this.font = font;
this.textcolor = textcolor;
this.best = best;
};
Button.prototype.draw = function() {
rectMode(CORNER);
fill(this.color);
rect(this.x, this.y, this.w, this.h);
fill(this.textcolor);
stroke(this.textcolor);
textFont(this.font, this.size);
text(this.text, this.x + (this.w/2 - this.w/2.5), this.y + (this.h/2 + this.size/2.5));
/*textFont(this.font, this.size / 2);
text("Best : " + this.best, this.x + 10, this.y + 90);*/
};
Button.prototype.clicked = function() {
if(mouseIsPressed && mouseX >= this.x && mouseX <= this.x + this.w && mouseY >= this.y && mouseY <= this.y + this.h ) {
return true;
}
};
var nextButton = new Button(315, 360, 75, 30, color(0, 255, 0), "Next Level", 12, "Aerial Bold", color(0, 0, 0));
var startButton = new Button(315, 360, 75, 30, color(0, 255, 0), "Start Again", 12, "Aerial Bold", color(0, 0, 0));
var playButton = new Button(140, 250, 120, 50, color(0, 0, 0), "PLAY", 40, "Aerial Bold", color(255, 255, 255));
var level1Button = new Button(30, 120, 100, 100, color(0, 0, 0), "Level 1", 25, "Aerial Bold", color(255, 255, 255));
var level2Button = new Button(140, 120, 100, 100, color(0, 0, 0), "Level 2", 25, "Aerial Bold", color(255, 255, 255));
var level3Button = new Button(250, 120, 100, 100, color(0, 0, 0), "Level 3", 25, "Aerial Bold", color(255, 255, 255));
var drawWin = function() {
fill(255, 0, 0);
textSize(36);
text("YOU WIN!!!!", 100, 200);
nextButton.draw();
};
var drawLoss = function() {
fill(255, 0, 0);
textSize(36);
text("YOU LOSE!!!!", 100, 200);
startButton.draw();
};
var movement = function() {
if (keyIsPressed) {
if(keyCode === UP) {
beaver.hop();
} /*else if(keyCode === LEFT) {
beaver.hopLeft();
} else if(keyCode === RIGHT) {
beaver.hopRight();
} */
} else { beaver.fall();}
};
var drawScore = function() {
fill(0, 255, 0);
textSize(18);
text("Score: " + beaver.sticks, 10, 390);
};
var isWin = function() {
if(beaver.sticks >= target) {
drawWin();
speed = 1;
return true;
}
};
var isLoss = function() {
if (beaver.sticks < target ) {
speed = 1;
drawLoss();
return true;
}
};
var drawBackground = function() {
//static
speed = 1;
background(227, 254, 255);
stroke(0, 0, 0);
rectMode(CORNER);
rect(0, height*0.90, width, height*0.10);
for (var i = 0; i < grassXs.length; i++) {
image(getImage("cute/GrassBlock"), grassXs[i], height*0.85, 35, 20);
image(getImage("cute/DirtBlock"), grassXs[i], height*0.85, 35, 60);
grassXs[i] -= speed;
if (grassXs[i] <= - 20) {
grassXs[i] = width;
}
}
};
var drawSticks = function() {
for (var i = 0; i < sticks.length; i++) {
sticks[i].draw();
beaver.checkForStickGrab(sticks[i]);
sticks[i].x -= speed;
}
};
var drawBadSticks = function() {
for (var i = 0; i < badSticks.length; i++) {
badSticks[i].draw();
beaver.checkForBadStickGrab(badSticks[i]);
badSticks[i].x -= speed;
}
};
var drawRocks = function() {
for (var i = 0; i < rocks.length; i++) {
rocks[i].draw();
beaver.checkForRockHit(rocks[i]);
rocks[i].y += speed;
}
};
var drawLevel = function() {
speed = 1;
drawBackground();
if (level === 1) {
target = 1;
drawSticks();
}
if (level === 2) {
target = 1;
drawSticks();
drawBadSticks();
}
if (level === 3) {
target = 1;
drawBadSticks();
drawSticks();
drawRocks();
}
beaver.draw();
movement();
drawScore();
if (sticks[nosOfSticks - 1].x < -5) {
isWin();
isLoss();
}
};
var drawLevels = function() {
level = "l";
background(0, 0, 0);
level1Button.draw();
level2Button.draw();
level3Button.draw();
if (level1Button.clicked() && level === "l") {
level = 1;
drawLevel();
} else if (level2Button.clicked() && level === "l") {
level = 2;
drawLevel();
} else if (level3Button.clicked() && level === "l") {
level = 3;
drawLevel();
}
};
var drawStart = function() {
level = 0;
background(0);
text("Hoppy Beaver", 75, 50);
text("Extreme", 120, 100);
playButton.draw();
if (playButton.clicked() && level === 0) {
levelButtonEnabled = false;
drawLevels();
}
};
//drawStart();
mouseClicked = function() {
if (nextButton.clicked() || startButton.clicked()) {
if (beaver.sticks >= 1) {
if (level === 0) {
level = 1;
sticks = [];
draw();
isWin = false;
}
if (level === 1) {
level = 2;
sticks = [];
draw();
isWin = false;
}
if (level === 2) {
level = 3;
sticks = [];
draw();
isWin = false;
}
if (level === 3) {
level = 1;
sticks = [];
isWin = false;
draw();
}
} else if (beaver.sticks < 1) {
if (level === 1) {
level = 1;
sticks = [];
drawLevel();
isLoss = false;
}
if (level === 2) {
level = 2;
sticks = [];
drawLevel();
isLoss = false;
}
if (level === 3) {
level = 3;
sticks = [];
drawLevel();
isLoss = false;
}
}
}
};
draw = function() {
speed = 1;
if (level === 1) {
drawLevel();
} else if (level === 2) {
drawLevel();
} else if (level === 3) {
drawLevel();
} else if (level === "l") {
drawLevels();
} else { drawStart(); }
};
welcome to stackoverflow. The problem with your code is this bit right here in the drawLevel function.
if (sticks[nosOfSticks - 1].x < -5) {
isWin();
isLoss();
}
At the start of your program you initialize the sticks array with some stick objects in line 124. When level 1 ends and the next button is clicked, you set the sticks array to an empty array sticks=[] in the mouseClicked function.However, you never re-add anything into the sticks array. Thus, when that block of code runs, the element at position nosOfSticks-1 is undefined, leading to your problem.My suggestion is to make a for loop after sticks=[] to refill the sticks array just like in line 124.
Good Luck!
Also, take a look at this guide for debugging help, how to debug small programs.

HTML Canvas & JavaScript - Redefining Object on Selection

The script below draws an image on the left side of the screen and a selection box in the right. It then attempts to redefine the image drawn on the left on each new selection in the selection box on the right by making the imageID dependent on the selection. However, as you can see below, whatever number you select on the right the image remains the same (1) because whilst it might be redrawn, it is not redefined on selection. What I would like to happen is that on selection in the box on the right the number in the image changes with the selection box such that it always correlates with the selection. In other words, when you click on 2 the image changes to the 2nd image in images. I have found two ways of doing this but they are both flawed:
1: Define img in paint's render function. This works but it makes everything run very slowly and the hover animations on the image stop working as expected.
2: Define img in the makeSelectionInfo function. This also works but the hover animations completely stop working if this is done.
I apologise for the long code but I couldn't condense it any more. For the sake of brevity I have only included images for numbers between 1 & 5. Any help will be appreciated.
var c=document.getElementById('game'),
canvasX=c.offsetLeft,
canvasY=c.offsetTop,
ctx=c.getContext('2d');
images=['https://i.stack.imgur.com/KfN4z.jpg',
'https://i.stack.imgur.com/MyQS1.png',
'https://i.stack.imgur.com/3Vlfj.jpg',
'https://i.stack.imgur.com/u3NLH.jpg',
'https://i.stack.imgur.com/XnLwl.png'];
var curvedRect = function(text, x, y, w, h) {
this.text = text;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.hovered = false;
this.clicked = false;
}
curvedRect.prototype.makeCurvedRect = function() {
var delta=0, theta=0, yRotation=this.y;
if (this.hovered) {
delta = 3;
shadowColor = '#000000';
shadowBlur = 20;
shadowOffsetX = 5;
shadowOffsetY = 5;
theta = -0.01;
} else {
delta = 0;
theta = 0;
shadowColor = '#9F3A9B';
shadowBlur = 0;
shadowOffsetX = 0;
shadowOffsetY = 0;
}
var x = this.x-delta;
var y = yRotation-delta;
var w = this.w+(2*delta);
var h = this.h+(2*delta);
var img=new Image();
img.src=images[this.text];
ctx.rotate(theta);
ctx.beginPath();
ctx.lineWidth='8';
ctx.strokeStyle='white';
ctx.moveTo(x+10, y);
ctx.lineTo(x+w-10, y);
ctx.quadraticCurveTo(x+w, y, x+w, y+10);
ctx.lineTo(x+w, y+h-10);
ctx.quadraticCurveTo(x+w, y+h, x+w-10, y+h);
ctx.lineTo(x+10, y+h);
ctx.quadraticCurveTo(x, y+h, x, y+h-10);
ctx.lineTo(x, y+10);
ctx.quadraticCurveTo(x, y, x+10, y);
ctx.shadowColor = shadowColor;
ctx.shadowBlur = shadowBlur;
ctx.shadowOffsetX = shadowOffsetX;
ctx.shadowOffsetY = shadowOffsetY;
ctx.stroke();
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.drawImage(img, x+2.5, y+2.5, w-5, h-5);
ctx.rotate(-theta);
}
curvedRect.prototype.hitTest = function(x, y) {
return (x >= this.x) && (x <= (this.w+this.x)) && (y >= this.y) && (y <= (this.h+this.y));
}
var selectionForMenu = function(id, text, y) {
this.id = id;
this.text = text;
this.y = y;
this.hovered = false;
this.clicked = false;
this.lastClicked = false;
}
function makeTextForSelected(text, y) {
ctx.font='bold 12px Noto Sans';
ctx.fillStyle='white';
ctx.textAlign='center';
ctx.fillText(text, 200, y);
}
function makeSelectionInfo(text) {
makeTextForSelected(text, 375);
}
selectionForMenu.prototype.makeSelection = function() {
var fillColor='#A84FA5';
if (this.hovered) {
if (this.clicked) {
if (this.lastClicked) {
fillColor='#E4C7E2';
} else {
fillColor='#D5A9D3';
}
} else if (this.lastClicked) {
fillColor='#D3A4D0';
makeSelectionInfo(this.text);
} else {
fillColor='#BA74B7';
}
} else if (this.lastClicked) {
fillColor='#C78DC5';
makeSelectionInfo(this.text);
} else {
fillColor='#A84FA5';
}
ctx.beginPath();
ctx.fillStyle=fillColor;
ctx.fillRect(400, this.y, 350, 30)
ctx.stroke();
ctx.font='10px Noto Sans';
ctx.fillStyle='white';
ctx.textAlign='left';
ctx.fillText(this.text, 410, this.y+19);
}
selectionForMenu.prototype.hitTest = function(x, y) {
return (x >= 400) && (x <= (750)) && (y >= this.y) && (y <= (this.y+30)) && !((x >= 400) && (y > 450));
}
var Paint = function(element) {
this.element = element;
this.shapes = [];
}
Paint.prototype.addShape = function(shape) {
this.shapes.push(shape);
}
Paint.prototype.render = function() {
ctx.clearRect(0, 0, this.element.width, this.element.height);
for (var i=0; i<this.shapes.length; i++) {
try {
this.shapes[i].makeSelection();
}
catch(err) {}
try {
this.shapes[i].makeCurvedRect();
}
catch(err) {}
}
ctx.beginPath();
ctx.fillStyle='white';
ctx.fillRect(0, 0, 750, 25);
ctx.stroke();
for (var i=0; i<this.shapes.length; i++) {
try {
this.shapes[i].makeBox();
}
catch(err) {}
}
ctx.beginPath();
ctx.fillStyle='#BC77BA';
ctx.fillRect(0, 450, 750, 50);
ctx.stroke();
ctx.font='bold 10px Noto Sans';
ctx.fillStyle='#9F3A9B';
ctx.textAlign='center';
ctx.fillText('Phrase Practice', 365, 17);
for (var i=0; i<this.shapes.length; i++) {
try {
this.shapes[i].makeInteractiveButton();
}
catch(err) {}
}
}
Paint.prototype.setHovered = function(shape) {
for (var i=0; i<this.shapes.length; i++) {
this.shapes[i].hovered = this.shapes[i] == shape;
}
this.render();
}
Paint.prototype.setClicked = function(shape) {
for (var i=0; i<this.shapes.length; i++) {
this.shapes[i].clicked = this.shapes[i] == shape;
}
this.render();
}
Paint.prototype.setUnclicked = function(shape) {
for (var i=0; i<this.shapes.length; i++) {
if (shape.constructor.name==this.shapes[i].constructor.name) {
this.shapes[i].clicked = false;
if (shape instanceof selectionForMenu) {
this.shapes[i].lastClicked = this.shapes[i] == shape;
}
}
}
this.render();
}
Paint.prototype.select = function(x, y) {
for (var i=this.shapes.length-1; i >= 0; i--) {
if (this.shapes[i].hitTest(x, y)) {
return this.shapes[i];
}
}
return null
}
imageID = 0;
var paint = new Paint(c);
var img = new curvedRect(imageID, 112.5, 100, 175, 175);
var selection = [];
for (i=0; i<=30; i++) {
selection.push(new selectionForMenu(i, i, 25+(i*30)));
}
paint.addShape(img);
for (i=0; i<30; i++) {
paint.addShape(selection[i])
}
paint.render();
var clickedShape=0;
var i=0;
function mouseDown(event) {
var x = event.x - canvasX;
var y = event.y - canvasY;
var shape = paint.select(x, y);
if (shape instanceof selectionForMenu) {
imageTextID = shape.id;
if (i==0) {
clickedShape=shape;
i=1;
} else if (i==1) {
i=0;
}
}
paint.setClicked(shape);
}
function mouseUp(event) {
var x = event.x - canvasX;
var y = event.y - canvasY;
var shape = paint.select(x, y);
if (clickedShape instanceof selectionForMenu) {
if (x>400 && y>25 && y<450) {
paint.setUnclicked(shape);
} else if (shape && !(shape instanceof selectionForMenu)) {
paint.setUnclicked(shape);
}
}
}
function mouseMove(event) {
var x = event.x - canvasX;
var y = event.y - canvasY;
var shape = paint.select(x, y);
paint.setHovered(shape);
}
c.addEventListener('mousedown', mouseDown);
c.addEventListener('mouseup', mouseUp);
c.addEventListener('mousemove', mouseMove);
canvas {
z-index: -1;
margin: 1em auto;
border: 1px solid black;
display: block;
background: #9F3A9B;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>uTalk Demo</title>
</head>
<body>
<canvas id="game" width = "750" height = "500"></canvas>
</body>
</html>
Fixed your code here https://jsfiddle.net/0wq0hked/2/
You can diff to see what I changed, but basically you weren't initializing and adding the multiple curvedRect to the Paint.shapes array. I also added the images as an attribute of curvedRect.
I also had to add a visible parameter to your shapes, as your mouse hover Paint.select function was not functioning properly. The way yours works, shapes that share the same (x,y) do not allow other shapes from being hovered even when they are not visible. Thus multiple shapes occupying the image area to the left stopped the hover from working properly. I suppose you could keep your Paint.select and instance/remove shapes when they are to be drawn, but you do not have shape removal functionality as far as I can tell.
Also, you call render on every event, this is a bad idea. Take a look at requestAnimationFrame and try drawing at the screen refresh rate rather than on user input.

p5.js Collision Detection

I'm trying to use p5.js's p5.collide2D library to execute some actions. I have a main pulsing module that pulses size-wise to music playing in my sketch, and then as it hits certain shapes I have displaying, I want it to reference the different functions I've set up to transform the main module visually.
Currently in this sketch I'm trying to get the Circle2 function to draw when touchX + touchY collides with the maroon circle. I thought I was using the library correctly, but maybe not. Any help would be great. Thanks!
var circles = [];
var squares = [];
var sizeProportion = 0.2;
//additional shapes
var r = 0;
var velocity = 1;
var fillColor = color(0, 0, 0);
var hit = false;
var startTime;
var waitTime = 3000;
var drawCircles;
var drawSquares;
function preload() {
sound = loadSound('assets/findingnemoegg.mp3');
}
function setup() {
createCanvas(windowWidth, windowHeight);
amplitude = new p5.Amplitude();
sound.loop();
sound.play();
startTime = millis();
}
function draw() {
background(255);
// other shapes + information
r = r + velocity;
if ((r > 256) || (r < 0)) {
velocity = velocity * -1;
}
noStroke();
fill(144, 12, 63, r);
ellipse(100, 100, 80, 80);
// drawing circles
circles.push(new Circle1(touchX, touchY));
for (var i = 0; i < circles.length; i++) {
circles[i].display();
if (circles[i].strokeOpacity <= 0) { // Remove if faded out.
circles.splice(i, 1); // remove
}
}
//collisions
if (pointTouchcircle2(touchX, 100, 100)) { // <- collision detection
//call upon Circle2 function and have the main module draw that
} else {
//stay the same.
}
}
//starting circles
function Circle1(x, y) {
this.x = x;
this.y = y;
this.size = 0;
this.age = 0;
this.fillOpacity = 20
this.strokeOpacity = 30
this.display = function() {
var level = amplitude.getLevel();
this.age++;
if (this.age > 500) {
this.fillOpacity -= 1;
this.strokeOpacity -= 1;
}
var newSize = map(level, 0, 1, 20, 900);
this.size = this.size + (sizeProportion * (newSize - this.size));
strokeWeight(10);
stroke(152, 251, 152, this.strokeOpacity);
fill(23, 236, 236, this.fillOpacity);
ellipse(this.x, this.y, this.size);
}
}
//maroon circles
function Circle2(x, y) {
this.x = x;
this.y = y;
this.size = 0;
this.age = 0;
this.fillOpacity = 20
this.strokeOpacity = 30
this.display = function() {
var level = amplitude.getLevel();
this.age++;
if (this.age > 500) {
this.fillOpacity -= 1;
this.strokeOpacity -= 1;
}
var newSize = map(level, 0, 1, 20, 900);
this.size = this.size + (sizeProportion * (newSize - this.size));
strokeWeight(10);
stroke(173, 212, 92, this.strokeOpacity);
fill(144, 12, 63, this.fillOpacity);
ellipse(this.x, this.y, this.size);
}
}
//collision functions
function pointTouchcircle2(touch, x, y) {
if (hit = collidePointCircle(touchX,touchY,100,100,50)) {
return true
} else {
return false
}
}

JavaScript small game example

Learning Javascript and stack in small game example.
So why println(beaver.holes) has "NaN" value ??? It must be normal number without flouting point.
var Beaver = function(x, y) {
this.x = x;
this.y = y;
this.img = getImage("creatures/Hopper-Happy");
this.sticks = 0;
};
Beaver.prototype.draw = function() {
fill(255, 0, 0);
this.y = constrain(this.y, 0, height-50);
image(this.img, this.x, this.y, 40, 40);
};
Beaver.prototype.hop = function() {
this.img = getImage("creatures/Hopper-Jumping");
this.y -= 5;
};
Beaver.prototype.fall = function() {
this.img = getImage("creatures/Hopper-Happy");
this.y += 5;
};
Beaver.prototype.checkForStickGrab = function(stick) {
if ((stick.x >= this.x && stick.x <= (this.x + 40)) &&
(stick.y >= this.y && stick.y <= (this.y + 40))) {
stick.y = -11;
this.sticks++;
}
};
Beaver.prototype.checkForHoleDrop = function(hole) {
if ((hole.x >= this.x && hole.x<=(this.x +40)) &&
(hole.y >=this.y && hole.y <= (this.y + 40))) {
hole.y = -11;
this.holes++;
}
};
var Stick = function(x, y) {
this.x = x;
this.y = y;
};
var Hole = function(x,y) {
this.x = x;
this.y = y;
};
Hole.prototype.draw = function() {
rectMode(CENTER);
noStroke();
fill(120, 144, 204);
ellipse(this.x,this.y, 51,19);
fill(0, 40, 71);
ellipse(this.x,this.y, 40,15);
};
Stick.prototype.draw = function() {
fill(89, 71, 0);
rectMode(CENTER);
rect(this.x, this.y, 5, 40);
};
var beaver = new Beaver(37, 300);
var sticks = [];
for (var i = 0; i < 40; i++) {
sticks.push(new Stick(i * 44 + 300, random(44, 260)));
}
// holes var
var holes = [];
for (var i = 0;i< 10; i ++) {
holes.push(new Hole(random(33,400)*i + 306, 378));
}
var grassXs = [];
for (var i = 0; i < 25; i++) {
grassXs.push(i*18);
}
draw = function() {
// static
background(227, 254, 255);
fill(130, 79, 43);
rectMode(CORNER);
rect(0, height*0.90, width, height*0.10);
for (var i = 0; i < grassXs.length; i++) {
image(getImage("cute/GrassBlock"), grassXs[i], height*0.85, 20, 20);
grassXs[i] -= 1;
if (grassXs[i] <= -32) {
grassXs[i] = width;
}
}
// making holes
for (var i = 0; i < holes.length; i++) {
holes[i].draw();
beaver.checkForHoleDrop(holes[i]);
holes[i].x -=2;
}
for (var i = 0; i < sticks.length; i++) {
sticks[i].draw();
beaver.checkForStickGrab(sticks[i]);
sticks[i].x -= 2;// value turn speed of sticks
}
So here if we print beaver.holes on screen it will be give us NaN value.
textSize(18);
text("Score: " + beaver.sticks, 20, 30);
textSize(18);
text("Score: " + beaver.holes, 105, 30);
if (beaver.sticks/sticks.length >= 0.95) {
textSize(36);
text("YOU WIN!!!!", 100, 200);
}
if (beaver.hole >41) {
textSize(36);
text("YOU LOSE!!!",100,200);}
//println(beaver.holes/holes.length);
if (keyIsPressed && keyCode === 0) {
beaver.hop();
} else {
beaver.fall();
}
beaver.draw();
};
Looks like holes was never initialized for beaver prototypes.
Try modifying the constructor function to look like so.
var Beaver = function(x, y) {
this.x = x;
this.y = y;
this.img = getImage("creatures/Hopper-Happy");
this.sticks = 0;
this.holes = 0;
};
Performing a ++ operation on an undefined variable returns a NaN result.

Categories

Resources