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);
}
Related
I'm trying to convert this Daniel Shiffman tutorial from p5js to html5 canvas without a library:
var angle;
var axiom = "F";
var sentence = axiom;
var len = 100;
var rules = [];
rules[0] = {
a: "F",
b: "FF+[+F-F-F]-[-F+F+F]"
}
function generate() {
len *= 0.5;
var nextSentence = "";
for (var i = 0; i < sentence.length; i++) {
var current = sentence.charAt(i);
var found = false;
for (var j = 0; j < rules.length; j++) {
if (current == rules[j].a) {
found = true;
nextSentence += rules[j].b;
break;
}
}
if (!found) {
nextSentence += current;
}
}
sentence = nextSentence;
createP(sentence);
turtle();
}
function turtle() {
background(51);
resetMatrix();
translate(width / 2, height);
stroke(255, 100);
for (var i = 0; i < sentence.length; i++) {
var current = sentence.charAt(i);
if (current == "F") {
line(0, 0, 0, -len);
translate(0, -len);
} else if (current == "+") {
rotate(angle);
} else if (current == "-") {
rotate(-angle)
} else if (current == "[") {
push();
} else if (current == "]") {
pop();
}
}
}
function setup() {
createCanvas(400, 400);
angle = radians(25);
background(51);
createP(axiom);
turtle();
var button = createButton("generate");
button.mousePressed(generate);
}
This is my code and there is a problem with it that I am not able to debug... When I run the following code, I get the start of this tree with an error message prompting me to change rotate(-this.angle) to call the context. But when I fix the issue, the tree disappears & the rectangle in the "buildFlower()" function appears... why is this happening? :/ :
My code:
const init = () => {
const html = document.getElementsByTagName("html").item(0),
canvas = document.getElementsByTagName("canvas").item(0),
c = canvas.getContext("2d");
let flower;
const gui = new dat.GUI();
function line(x1, y1, x2, y2, color) {
c.strokeStyle = color;
c.beginPath();
c.moveTo(x1, y1);
c.lineTo(x2, y2);
c.stroke();
}
class Flower {
constructor(x, y, size) {
this.x = x;
this.y = y;
this.size = size;
this.angle = (Math.PI / 180) * 25;
this.axiom = "F";
this.sentence = this.axiom;
this.len = 100;
this.rules = [];
this.rules[0] = {
a: "F",
b: "FF+[+F-F-F]-[-F+F+F]",
};
}
generateLSystem() {
this.len *= 0.5;
let nextSentence = "";
for (let i = 0; i < this.sentence.length; i++) {
let current = this.sentence.charAt(i);
let found = false;
for (let j = 0; j < this.rules.length; j++) {
if (current == this.rules[j].a) {
found = true;
nextSentence += this.rules[j].b;
break;
}
}
if (!found) {
nextSentence += current;
}
}
this.sentence = nextSentence;
this.turtle();
}
turtle() {
c.resetTransform();
c.translate(100, getResolution().h);
for (let i = 0; i < this.sentence.length; i++) {
let current = [this.sentence.charAt(i)];
if (current == "F") {
line(0, 0, 0, -this.len);
c.translate(0, -this.len);
} else if (current == "+") {
c.rotate(this.angle);
} else if (current == "-") {
// WHEN I CHANGE THE LINE BELOW TO (`c.rotate`) THE ENTIRE THING DISAPPEARS.
rotate(-this.angle);
} else if (current == "[") {
current.push();
} else if (current == "]") {
current.pop();
}
}
}
buildFlower() {
c.beginPath();
c.rect(
getResolution().w / 2 - this.size / 2,
getResolution().h / 2 - this.size / 2,
this.size,
this.size
);
c.stroke();
}
}
const resize = () => {
canvas.width = w = window.innerWidth;
canvas.height = h = window.innerHeight;
console.log(`screen resolution: ${w}px × ${h}px`);
};
const getResolution = () => {
return { w: canvas.width, h: canvas.height };
};
const setup = () => {
c.clearRect(0, 0, getResolution().w, getResolution().h);
flower = new Flower(getResolution().w, getResolution().h, 200);
flower.generateLSystem();
gui.add(flower, "size", 0, 200);
gui.add(flower, "axiom");
};
setup();
const draw = (t) => {
c.fillStyle = "rgba(255, 255, 255, .5)";
c.fillRect(0, 0, w, h);
window.requestAnimationFrame(draw);
};
let w,
h,
last,
i = 0,
start = 0;
window.removeEventListener("load", init);
window.addEventListener("resize", resize);
resize();
window.requestAnimationFrame(draw);
};
window.addEventListener("load", init);
I've been trying for hrs and can't seem to debug :/
General suggestion: work in small sprints and run the code frequently to verify that it behaves as expected. The code here seems like it was built up in just a few long sprints without much validation for each component along the way. This apparently led to a buildup of complexity, causing confusion and subtle bugs.
Try to avoid premature abstractions like excessive functions and classes until the code is working correctly. At that point, the correct abstractions and cut points will be apparent.
Also, minimize the problem space by only introducing "bells and whistles"-type peripheral functionality once the core logic is working. When the basic drawing is failing, functionality like a GUI, resizing, a RAF loop and so forth just get in the way of progress. Add those after the basic drawing works.
The main reason for the disappearing drawing on the canvas is that resize() is called after setup(). When you resize the canvas, it wipes it clean. Call setup() after your initial resize() call:
window.removeEventListener("load", init);
window.addEventListener("resize", resize);
resize(); // <-- wipes the screen
setup(); // <-- draw after resize
window.requestAnimationFrame(draw);
You see a partial drawing showing up because your crash prevents the resize() from executing. This should be a big debug hint: some code after the drawing must be wiping it out.
The translation from p5's push() and pop() to HTML5 canvas doesn't appear correct:
} else if (current == "[") {
current.push();
} else if (current == "]") {
current.pop();
}
current is an array, but we don't want to mess with it. We're supposed to be pushing and popping the canvas context, not an array. These calls are context.save() and context.restore() in HTML5:
} else if (current === "[") {
c.save();
} else if (current === "]") {
c.restore();
}
A strange design choice is:
let current = [this.sentence.charAt(i)];
if (current == "F") {
Here, you've created an array of one element, then used coercion to compare it to a string. Always use === and don't create a one-element array unnecessarily:
// use const instead of let and [i] instead of charAt(i)
const current = this.sentence[i];
if (current === "F") {
I could analyze the design further and do a full rewrite/code review, but I'll leave it at this just to get you moving again and not belabor the point:
const init = () => {
const html = document.getElementsByTagName("html").item(0),
canvas = document.getElementsByTagName("canvas").item(0),
c = canvas.getContext("2d");
let flower;
// const gui = new dat.GUI();
function line(x1, y1, x2, y2, color) {
c.strokeStyle = color;
c.beginPath();
c.moveTo(x1, y1);
c.lineTo(x2, y2);
c.stroke();
}
class Flower {
constructor(x, y, size) {
this.x = x;
this.y = y;
this.size = size;
this.angle = (Math.PI / 180) * 25;
this.axiom = "F";
this.sentence = this.axiom;
this.len = 50;
this.rules = [];
this.rules[0] = {
a: "F",
b: "FF+[+F-F-F]-[-F+F+F]",
};
}
generateLSystem() {
this.len *= 0.5;
let nextSentence = "";
for (let i = 0; i < this.sentence.length; i++) {
let current = this.sentence[i];
let found = false;
for (let j = 0; j < this.rules.length; j++) {
if (current == this.rules[j].a) {
found = true;
nextSentence += this.rules[j].b;
break;
}
}
if (!found) {
nextSentence += current;
}
}
this.sentence = nextSentence;
this.turtle();
}
turtle() {
c.resetTransform();
c.translate(100, getResolution().h);
for (let i = 0; i < this.sentence.length; i++) {
const current = this.sentence[i];
if (current === "F") {
line(0, 0, 0, -this.len);
c.translate(0, -this.len);
} else if (current === "+") {
c.rotate(this.angle);
} else if (current === "-") {
c.rotate(-this.angle);
} else if (current === "[") {
c.save();
} else if (current === "]") {
c.restore();
}
}
}
buildFlower() {
c.beginPath();
c.rect(
getResolution().w / 2 - this.size / 2,
getResolution().h / 2 - this.size / 2,
this.size,
this.size
);
c.stroke();
}
}
const resize = () => {
canvas.width = w = window.innerWidth;
canvas.height = h = window.innerHeight;
console.log(`screen resolution: ${w}px × ${h}px`);
};
const getResolution = () => {
return { w: canvas.width, h: canvas.height };
};
const setup = () => {
c.clearRect(0, 0, getResolution().w, getResolution().h);
flower = new Flower(getResolution().w, getResolution().h, 200);
flower.generateLSystem();
//gui.add(flower, "size", 0, 200);
//gui.add(flower, "axiom");
};
const draw = (t) => {
c.fillStyle = "rgba(255, 255, 255, .5)";
c.fillRect(0, 0, w, h);
window.requestAnimationFrame(draw);
};
let w,
h,
last,
i = 0,
start = 0;
window.removeEventListener("load", init);
window.addEventListener("resize", resize);
resize();
setup();
window.requestAnimationFrame(draw);
};
window.addEventListener("load", init);
<canvas></canvas>
I am an extreme beginner in the field of P5.JS. I am way more knowledgeable in Java which will be apparent in my broken code. I have attempted a multitude of Java approaches to cycling through objects of the same class and applying methods to them. My attempt is to implement buttons that will move them forward as of now and once I understand that move on to more complicated interactions.
https://openprocessing.org/sketch/1564721 6
This is the link to the code I am attempting to fix it currently, but if you have any tips or advice for streamlining this please let me know.
var gridCellSizeX = 80;
var gridCellSizeY = 100;
var gridAlpha = 1000;
let img;
var gridCellSizeSlider;
turnValue = 1;
var count = 1;
var gameOn = true;
var forward = false;
function preload() {
img = loadImage('vagg02.jpg');
}
function setup() {
createCanvas(800, 600);
image(img, 0,0,800,500);
image( img ,0, 500, 800,100);
stroke(0, gridAlpha);
for (var x = 0; x < width; x += gridCellSizeX) {
line(x, 0, x, 500);
}
for (var y = 0; y < height; y += gridCellSizeY) {
line(0, y, width, y);
}
token1 = new token(15, 5, 100, 5000, 'reb', 1)
token2 = new token(15, 205, 100, 5000,'reb', 2 )
token3 = new token(15, 405, 100, 5000, 'reb', 3)
token4 = new token(735, 5, 100, 5000,'union', 4)
token5 = new token(735, 205, 100, 5000, 'union', 5)
token6 = new token(735, 405, 100, 5000, 'union', 6)
const tokens = new Array(token1, token2, token3, token4, token5, token6);
forwardButton = createButton('Move -->')
forwardButton.position(300, 525);
forwardButton.mousePressed(moveForward());
//button = createButton('Move -->'); button.position(300, 525); button.mousePressed();
button2 = createButton('Move Up');
button2.position(400, 525);
button2.mousePressed();
button3 = createButton('Move Down');
button3.position(500, 525);
button3.mousePressed();
button4 = createButton('Move <--');
button4.position(600, 525);
button4.mousePressed();
}
function draw() {
if(forward == true) token1.x =+ 500;
//for(let i = 0; gameOn == true; i++){ if(i > 6){ i = 0; }}
}
function mousePressed() {
if (mouseX >= 300 && mouseX <= 325 &&
mouseY >= 525 && mouseY <= 500){
token1.moveForward();
}
return false;
}
// new file token
class token {
constructor(xpos, ypos, t, a, s, turn) {
this.x = xpos;
this.y = ypos;
this.troopSize = t / 2;
this.accuracy = a / 100.0;
this.side = s;
this.moveTurn = turn;
this.loaded = true;
if(this.side == 'reb'){
fill('red');
rect(this.x, this.y, this.troopSize, 90)
}
if(this.side == 'union'){
fill('blue');
rect(this.x, this.y, this.troopSize, 90)
}
}
getToken(){
if(count > 6){
count = 1;
}
if(count == 1) {
return token1;
}
else if(count == 2){
return token2;
}
else if(count == 3){
return token3;
}
else if(count == 4){
return token4;
}
else if(count == 5){
return token5;
}
else if(count == 6){
return token6;
}
count++;
}
///////// Beginning of Basic Functions for the TOKEN CLASS
moveForward(){
if(this.side == 'reb'){
token1.x += 50;
redraw(token1);
}
if(this.side == 'union'){
this.x += -50;
redraw();
}
}
////
moveBackward(){
if(this.side == 'reb'){
this.x = this.x - 50;
}
if(this.side == 'union'){
this.x = this.x + 50;
}
}
/////
fire(){
if(loaded == true){
}
}
//////
load(){
}
///////
fixBayonet(){
}
////////
charge(){
}
///////// END of Basic Functions for the TOKEN CLASS
}
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.
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
}
}
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();
}
}
};