Is there a way to check if the mouse is clicked on a certain element in p5.js - javascript

So what I am trying to do is make a clicker game, yet when I use the standard:
let Coins = 0;
function setup() {
createCanvas(400, 400)
}
//draws the circle
function draw() {
background(100)
circle(200, 200, 50)
//creates the text to show the amount of coins
text(Coins, 200 - (textWidth(Coins) / 2), 150)
}
//detects when the mouse is pressed
function mouseClicked() {
//changes the number of coins
Coins = Coins + 1
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>
I can click anywhere and it will count up the Coins, but I want it so that if the mouse is On the shape/element it will then count.
I don't want to use the "If (mouseX => width / 2)" but just know when the mouse is over/hovering over the element.

In p5js you need to implement "hit testing" yourself. In this case you can do so by checking if the distance between the mouse and the center of the coin is less than the radius of the coin.
let Coins = 0;
function setup() {
createCanvas(400, 400)
}
let coinPosition = new p5.Vector(200, 200);
let coinRadius = 25;
//draws the circle
function draw() {
background(100)
push()
if (dist(mouseX, mouseY, coinPosition.x, coinPosition.y) <= coinRadius) {
fill('gold')
}
circle(coinPosition.x, coinPosition.y, coinRadius * 2)
// restore the previous fill value
pop()
//creates the text to show the amount of coins
text(Coins, 200 - (textWidth(Coins) / 2), 150)
}
//detects when the mouse is pressed
function mouseClicked() {
if (dist(mouseX, mouseY, coinPosition.x, coinPosition.y) <= coinRadius) {
//changes the number of coins
Coins = Coins + 1
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>

Related

Vertices in p5.beginShape() not connecting

Essentially I would like for all these disparate lines to be connected in one single path.
I am using vector.add() because I would like a cumulative result. Maybe that's the issue?
Or perhaps it's how I'm accessing the previous element of the array?
Please take a look at this snippet:
let lifespan = 200;
let genes = [];
let previous;
let prevpos;
function setup(){
createCanvas(window.innerWidth, window.innerHeight);
background(255);
genes[0] = createVector(50,50);
stroke(0);
strokeWeight(1);
beginShape(LINES)
vertex(genes[0].x, genes[0].y);
for (let i = 1; i < lifespan; i++) {
previous = genes[i-1];
genes[i] = previous.add(createVector(random(-10,10),random(-10,10)));
// vertex(previous.x, previous.y);
vertex(genes[i].x, genes[i].y);
}
endShape()
}
function draw(){
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id='sketch'> </div>
<script language="javascript" type="text/javascript" src="https://cdn.jsdelivr.net/npm/p5#1.4.0/lib/p5.min.js"></script>
<script src="sketch.js"></script>
<script>
</script>
</body>
</html>
I thought I had tried this already but I just needed to uncomment a line.
beginShape(LINES)
vertex(genes[0].x, genes[0].y);
for (let i = 1; i < lifespan; i++) {
previous = genes[i-1];
genes[i] = previous.add(createVector(random(-10,10),random(-10,10)));
vertex(previous.x, previous.y); //<-- uncomment this
vertex(genes[i].x, genes[i].y);
}
endShape()

Trying to figure out why balloon pop game is not resetting clickCount

I have followed along with video from video number 76 of the Udemy "last Intro to Programming Course". I have moved code that was included all in one function to another function called "draw" I have reviewed the video multiple times and I cannot see any difference between my code and the video. The goal of the code is to reset the clickCount back to zero. Here is the code. Help would be greatly appreciated everything is working except resetting of the balloon size and clickCount with each timeout:
let startButton = document.getElementById('start-button')
let inflateButton = document.getElementById('inflate-button')
let clickCount = 0
let height = 120
let width = 100
let inflationRate = 20
let maxsize = 300
let popCount = 0
function startGame() {
startButton.setAttribute("disabled", "true")
inflateButton.removeAttribute("disabled")
setTimeout(() => {
console.log("it's been 3 seconds")
inflateButton.setAttribute("disabled", "true")
startButton.removeAttribute("disabled")
clickCount = 0
height = 120
width = 100
draw()
}, 3000)
}
function inflate() {
clickCount++
height += inflationRate
width += inflationRate
if (height >= maxsize) {
console.log("pop the balloon")
popCount++
height = 0
width = 0
}
draw()
}
function draw() {
let balloonElement = document.getElementById("balloon")
let clickCountElem = document.getElementById("click-count")
let popCountElem = document.getElementById('pop-count')
balloonElement.style.height = height + "px"
balloonElement.style.width = width + "px"
clickCountElem.innerText = clickCount.toString()
popCountElem.innerText = popCount.toString()
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Balloon Pop</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div>
<button id="start-button" onclick="startGame()" >START GAME</button>
</div>
<button id="inflate-button" onclick="inflate()" disabled="true">Inflate <span id="click-count"> </span></button>
<div>
<span>Balloons Popped</span>
<span id="pop-count"></span>
</div>
<div id="balloon" class="balloon" ></div>
<script src="main.js"></script>
</body>
</html>
I figured this out by looking at the source tab in dev tools. For whatever reason all of the lines weren't being saved or loaded to Chrome from VSCode. What I did was copy all the code from VSCode and pasted it into Notepad, saved and then refreshed. All is working fine now.

How to detect overlap in Phaser.js?

I am new to Phaserjs, and I am trying to make a shooting game. I want the damage function to fire when a bullet touches plane2, that is the green plane. Can somone please tell me what am I doing wrong here?
Here is my code:
var config = {
type: Phaser.AUTO,
width: 800,
height: 800,
parent:"game",
physics: {
default: 'arcade',
arcade: {
debugging:true,
gravity: {y: 0}
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
var plane1
var plane2
var hp;
var botHp;
function preload (){
this.load.setBaseURL('https://shoot.abaanshanid.repl.co/assets');
this.load.image("bg", "bg.jpg");
this.load.image("plane1", "plane1.png");
this.load.image("plane2", "plane2.png");
this.load.image("bullet", "bullet.png");
}
function create (){
this.background = this.add.image(400, 400, "bg");
plane1 = this.physics.add.sprite(400,700,"plane1");
plane2 = this.physics.add.sprite(400,100,"plane2");
plane1.enableBody = true;
}
function update(){
keys = this.input.keyboard.createCursorKeys();
if (keys.left.isDown) {
plane1.x = plane1.x - 7.5;
}else if(keys.right.isDown){
plane1.x = plane1.x + 7.5;
}else if(keys.space.isDown){
var bullet = this.physics.add.sprite(plane1.x,600,"bullet");
bullet.enableBody = true;
setInterval(function(){
bullet.y = bullet.y - 25;
},50);
this.physics.overlap(bullet,plane2,this.damage);
}
}
function damage(){
console.log("less HP")
}
var game = new Phaser.Game(config);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/3.54.0/phaser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/3.54.0/phaser-arcade-physics.min.js"></script>
</head>
<body>
<div id="game"></div>
<script defer src="script.js"></script>
</body>
</html>
Here is the link to the game if needed https://shoot.abaanshanid.repl.co/
This works:
this.physics.add.overlap(bullet,plane2,damage);
but its kinda laggy. Id try to destroy bullet on impact and i also found:
this.physics.add.collider(bullet,plane2,damage);

Baffled by NaN - HTML CANVAS JS

I'm trying to create a timer within an object - however when trying to increment the counter by the time that's passed I'm getting a NaN error. The error stops if I replace the deltaTime argument with a constant, but then the jump time would vary depending upon the end users machine and work load.
class Actor {
constructor() {
this.jumpCounter = 0
this.jumpTimer = function (deltaTime) {
console.log(this.jumpCounter);
this.jumpCounter += deltaTime;
console.log(deltaTime)
}
}
}
let canvas = document.getElementById('gameScreen');
let ctx = canvas.getContext("2d");
var lastTime = 0;
const GAME_WIDTH = 600;
const GAME_HEIGHT = 600;
actor = new Actor;
function gameLoop(timestamp) {
let deltaTime = timestamp - lastTime;
lastTime = timestamp;
ctx.fillStyle = 'rgba(155, 200, 155, 0.3)'
ctx.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
actor.jumpTimer(deltaTime)
requestAnimationFrame(gameLoop);
}
gameLoop();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Game Sandbox</title>
<style>
#gameScreen {
border: 1px solid;
}
</style>
</head>
<body>
<canvas id="gameScreen" width="600" height="600"></canvas>
<script></script>
</body>
</html>
As the error resulted from there being on timestamp on the first run through of the code this fixed the issue:
this.jumpTimer = function (deltaTime) {
if (!deltaTime) return;
console.log(this.jumpCounter);
this.jumpCounter += deltaTime;
console.log(deltaTime)
}

HTML5 Canvas Image doesn't move

I have a problem. I'm using HTML5 and Javascript to draw a box onto a canvas. This box is supposed to move up and down, but after it gets rendered for the first time, it doesn't want to re-render at the new position. This is the code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="sl" lang="sl">
<head>
<title>Spletna stran Portfolio - Domaca stran</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
<link rel="stylesheet" href="css/style.css" type="text/css" media="all" />
<script>
var isMoving = true;
var gradienty = 0;
var gradientheight = 100;
var gradientyVel = 1;
var gradientImage = new Image();
gradientImage.src = "grafika/gradient.gif";
function main() {
var c = document.getElementById("menuCanvas");
var ctx = c.getContext("2d");
ctx.drawImage(gradientImage, 0, gradienty);
if(isMoving == true) {
gradienty += gradientyVel;
if((gradienty+gradientheight)==c,height || gradienty<=0) {
gradientyVel *= -1;
}
}
}
function mainLoop() {
setInterval(main(), 10);
}
</script>
</head>
<body onload="mainLoop()">
<canvas id="menuCanvas" width="195" height="400"></canvas>
</body>
</html>
I have no clue why the box isn't moving. It's like after I draw it for the first time it won't draw again the next time. Also, I use mainLoop() function as my main loop. Every 10 miliseconds I basically call the main() function, which does the drawing and the logic.
Any help would be much appreciated. :)
A few coding problems:
You need to give your image time to load, then start the animation
var gradientImage = new Image();
gradientImage.onload=function(){
setInterval(main, 20);
}
gradientImage.src = "house16x16.png";
setInterval takes in a function pointer (no parentheses):
setInterval will fire only as fast as 16ms, so your 10ms value is too small
setInterval(main, 20);
Here's revised code and a Demo: http://jsfiddle.net/m1erickson/U6K9j/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var c=document.getElementById("menuCanvas");
var ctx=c.getContext("2d");
var isMoving = true;
var gradienty = 0;
var gradientheight = 100;
var gradientyVel = 1;
var gradientImage = new Image();
gradientImage.onload=function(){
setInterval(main, 20);
}
gradientImage.src = "house16x16.png";
function main() {
ctx.clearRect(0,0,c.width,c.height);
ctx.drawImage(gradientImage, 0, gradienty);
if(isMoving == true) {
gradienty += gradientyVel;
if((gradienty+gradientheight)==c.height || gradienty<=0) {
gradientyVel *= -1;
}
}
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="menuCanvas" width=300 height=300></canvas>
</body>
</html>
You're calling main and then passing the RESULT to setInterval. Just change
function mainLoop() {
setInterval(main(), 10);
}
to
function mainLoop() {
setInterval(main, 10);
}
That'll get you started, but you'll also need to clear the canvas in between draws. (As you'll notice if you run this)

Categories