How to direct sound in p5.js - Binaural sound - javascript

I' m try trying to direct the sound,
how to direct the sound where the circle is? Taking into account that the circle will have to change position (I would like to replace the opposite sound with a binaural sound, and I don't know if there is an easier way to do it)
The code only works on mobile.
thanks in andavance.
https://editor.p5js.org/matteomuiafrate1999/sketches/P7XX_n-RS?fbclid=IwAR1D3dGhW_zvqlRuU-_kTAP-mzrg9urKv1bSXu9Qd72WA-Swu6lVHtCwoU8

It's not entirely clear what you are asking, but if you want to adjust how much of a particular sound comes from which channel (Right vs Left) based on spacial arrangement you can use a Panner3D.
let osc, pan;
let playing = false;
let direction = 0;
function setup() {
createCanvas(windowWidth, windowHeight);
angleMode(DEGREES);
osc = new p5.Oscillator('sine');
osc.freq(261.625565);
osc.disconnect();
pan = new p5.Panner3D();
pan.process(osc);
pan.setFalloff(Math.min(width, height) / 2, 1);
// By default the sound source will be omni-directional
pan.panner.coneInnerAngle = 60;
pan.panner.coneOuterAngle = 360;
// You can also adjust how quite the sound outside the
// outer code is with coneOuterGain which defaults to 0
}
function doubleClicked() {
if (!playing) {
playing = true;
osc.start();
osc.amp(0.3, 0.1);
} else {
playing = false;
osc.amp(0, 0.1);
}
}
function mouseMoved() {
if (pan) {
pan.set(mouseX - width / 2, 0, mouseY - height / 2, 0.1);
}
}
function mouseDragged() {
mouseMoved();
}
function draw() {
background(100);
circle(width / 2, height / 2, 20);
arc(mouseX, mouseY, 40, 40, direction - 20, direction + 20);
if (mouseIsPressed) {
direction = (direction + 3) % 360;
pan.orient(cos(direction), 0, sin(direction), 0.1);
}
}
<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>

Related

P5 play and how to create a game over screen after more than three enemy sprites have gone past the player and reached the bottom of the screen

I have a game made with the p5.js play library where a player sprite shoots out bullets and takes out with these bullets an oncoming stream of enemy sprites. I wanted to have the game set to game over after 3 enemy sprites have reached down the bottom of the screen past the player and wasn't sure how to approach doing that.
let y = 0;
let spr;
let enemies;
let player;
let bullets = [];
let bullet;
let bulletsprite;
let score = 0;
function setup() {
createCanvas(600, 600);
bulletsprites = new Group()
enemies = new Group()
for(i = 0; i < 60; i++){
spr = createSprite(
random(width), y, random(10, 40), random(10, 40));
spr.shapeColor = color(random(255), random(255), random(255), random(255));
spr.velocity.y = random(0.7, 2);
enemies.add(spr);
}
player = createSprite(50, 50, 40, 40);
player.shapeColor = color(255);
}
function draw() {
background(30);
player.velocity.x =
(mouseX-player.position.x)*0.1;
player.velocity.y =
(mouseY-player.position.y)*0.1;
textSize(72);
textAlign(CENTER, CENTER);
drawSprites();
if (enemies.length > 0) {
text(score, width/2, height/2);
}
else {
text("you win!", width/2, height/2);
}
bulletsprites.overlap(enemies, getScore)
}
function mousePressed() {
//bullets positions setting
let bullet = {
x: mouseX,
y: mouseY,
};
bullets.push(bullet);
bulletsprite = createSprite(bullet.x, bullet.y, 10);
bulletsprite.velocity.y = -4;
bulletsprites.add(bulletsprite)
}
function getScore(bullets, enemies) {
enemies.remove();
score += 1;
}
make a counter which adds up every time an enemy reaches the bottom.
make a pause variable
make a gameOver function which will pause your game if the counter reaches 3.
put all the functions like enemies moving and game motions within a if(pause==false){} statement on your main loop.
in the gameOver function make whatever you want to end the game, it can be an animation, a menu, a black screen with a text, buttons, etc...
call this function in your "main loop"
sorry for not using code, I don't use p5 but the logical part is the important part :) good luck.

Game froze in <canvas> js

I`m writing a pong game on js and html using canvas. Besides main body of the game I have the starting menu with "play button"(all the buttons are just images i counted their coordinates and just use ), then next menu where user chooses the background and then eventually game itself and then after reaching 3 points by user or computer the game ends and there's a win or fail window appering where you can press the "back to menu" button and go back to the very first menu with "play button" and start everything again. Program does everything okay when you first launch it but after you for example lose and go back to main menu, choose the background, game starts aaaaaaand when ball reaches 2 points the game get frozen and sometimes after minute or so somehow loads the menu with backgrounds. I really have no idea what's wrong and why it gets frozen and strangely on the second time you play. Please help me ;((
PS. Im just a beginner idk how to insert the images here in stackoverflow
const canvas = document.getElementById("pongping");
const context = canvas.getContext('2d');
/////////////1)function to draw the rect
function drawPryamokutnik(x,y,w,h,color) {
context.fillStyle = color;
context.fillRect(x,y,w,h);
}
//////////////////////2)рисуем круг ///////////////////////////////////////////////////////////////////////////////
function drawKolo(x,y,radius,color) {
context.fillStyle = color;
context.beginPath();
context.arc(x, y, radius, 0, Math.PI * 2, false);
context.closePath();
context.fill();
}
///////////////////////3)drawText/////////////////////////////////////////////
function drawText(text,x,y,color){
context.fillStyle = color;
context.font = "80px Arial";
context.fillText(text,x,y);
}
///////////////////////4)создаем пластинку пльзователя//////////////////////////////////////////////////////////////
const rectleft = {
x:20,
y:canvas.height/2-100,
width: 25,
height: 200,
color: "WHITE",
score:0
};
///////////////////////5)создаем пластинку компьютера//////////////////////////////////////////////////////////////
const rectright = {
x:canvas.width-45,
y:canvas.height/2-100,
width: 25,
height: 200,
color: "WHITE",
score:0
};
///////////////////////6)создаем шайбу/////////////////////////////////////////////////////////////////////////////
const ball = {
x: canvas.width/2,
y: canvas.height/2,
speed: 5,
radius: 20,
velocityX: 5,
velocityY: 5,
colour:"WHITE"
};
//////////////////////8)создаем разделительную сетку///////////////////////////////////////////////////////////////
const net = {
x:canvas.width/2-1,
y:0,
width: 2,
height:10,
color:"WHITE"
};
//////////////////////9)создаем функцию сетки/////////////////////////////////////////////////////////////////////
function drawNet(){
for(let i=0; i<=canvas.height;i+=15)
{
drawPryamokutnik(net.x,net.y+i,net.width,net.height,net.color)
}
}
//drawPryamokutnik(0,0,canvas.width, canvas.height, "BLACK");
//drawText("so you wanna die young?",200,300,"WHITE");
canvas.addEventListener("mousemove",moovePaddle);
function moovePaddle(etv){
let rect=canvas.getBoundingClientRect();
rectleft.y=etv.clientY-rect.top-rectleft.height/2;
}
function update(){
ball.x += ball.velocityX;
ball.y += ball.velocityY;
let computerLevel= 0.1;
rectright.y+=(ball.y-(rectright.y+rectright.height/2))*computerLevel;
if (ball.y + ball.radius > canvas.height || ball.y - ball.radius < 0) {
ball.velocityY = -1 * ball.velocityY;
}
let player = (ball.x>canvas.width/2)? rectright:rectleft;
if(colission(ball,player)){
let collidePoint = ball.y - (player.y + player.height / 2);
collidePoint = collidePoint /(player.height / 2);
let angleRead = Math.PI/4 * collidePoint;
let direction = (ball.x < canvas.width / 2) ? 1 : -1;
ball.velocityX = direction * ball.speed * Math.cos(angleRead);
ball.velocityY = direction * ball.speed * Math.sin(angleRead);
ball.speed += 1;
}
if (ball.x - ball.radius < 0 ){
rectright.score++;
ResetBall();
}
else if(ball.x+ball.radius>canvas.width)
{rectleft.score++;
ResetBall();}
}
function ResetBall() {
ball.x=canvas.width/2;
ball.y=canvas.height/2;
ball.speed=5;
ball.velocityX=-ball.velocityX;
}
function colission(b,p){
b.top=b.y-b.radius;
b.bottom=b.y+b.radius;
b.left=b.x-b.radius;
b.right=b.x+b.radius;
p.top=p.y;
p.bottom=p.y+p.height;
p.left=p.x;
p.right=p.x+p.width;
return b.right>p.left && b.bottom>p.top && b.left<p.right && b.top < p.bottom;
}
function render(){
const back = new Image();
if(backchek===1)
{back.src = "back1.png";}
if(backchek===2)
{back.src = "back2.png";}
if(backchek===3)
{back.src = "back3.png";}
context.drawImage(back, 0, 0);
//drawPryamokutnik(0,0,canvas.width,canvas.height,"BLACK");
drawNet();
drawText(rectleft.score,canvas.width/4,canvas.height/5,"WHITE");
drawText(rectright.score,3*canvas.width/4,canvas.height/5,"WHITE");
drawPryamokutnik(rectleft.x,rectleft.y,rectleft.width,rectleft.height,rectleft.color);
drawPryamokutnik(rectright.x,rectright.y,rectright.width,rectright.height,rectright.color);
drawKolo(ball.x,ball.y,ball.radius,ball.colour);
}
let slide;
function game() {
slide=1;
menu();
if(startcheck===true)
{backchoose();
slide=2;
if(backchek===1||backchek===2||backchek===3)
{render();
update();
if(rectright.score>2)
{
losing();
slide=3;
// startcheck=false;
if(backagain===true)
{slide=1;
game();
}}
if(rectleft.score>2)
{//startcheck=false;
winning();
slide=3;
if(backagain===true)
{slide=1;
game();
}}
}
}
}
let framePerSecond=65;
setInterval(game,1000/framePerSecond);
function menu(){
const menuu = new Image();
menuu.src = "menu.png";
context.drawImage(menuu, 0, 0);
}
function losing(){
const lose = new Image();
lose.src = "lose.png";
context.drawImage(lose, 0, 0);
}
function winning(){
const win = new Image();
win.src = "win.png";
context.drawImage(win, 0, 0);
}
function backchoose(){
const backk = new Image();
backk.src = "back choose .png";
context.drawImage(backk, 0, 0);
}
let backchek;
let backagain=false;
let startcheck=false;
canvas.addEventListener("mousedown", clicked, false);
function clicked(e){
e.preventDefault();
let rectt=canvas.getBoundingClientRect();
const x = e.clientX;
const y = e.clientY - rectt.top;
let xprtr;
let yprtr;
let hipot;
let yby;
let xby;
let yey;
let xex;
if(x===496 && y===471&& slide===1)
{startcheck=true;
//backagain=false;
}
if(x>496){xprtr=x-496;}
if(x<496){xprtr=496-x;}
if(y>471){yprtr=y-471;}
if(y<471){yprtr=471-y;}
hipot=yprtr*yprtr+xprtr*xprtr;
if(hipot<=10609&&slide===1)
{startcheck=true;}
if(slide===2&&(y>217&&y<430&&x>75&&x<404)){backchek=1;}
if(slide===2&&(y>217&&y<430&&x>585&&x<924)){backchek=2;}
if(slide===2&&(y>508&&y<773&&x>344&&x<675)){backchek=3;}
if(slide===3&&y>519&&(y<702&&x>224&&x<768))
{backagain=true;
backchek=0;
startcheck=false;
rectright.score=0;
rectleft.score=0;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Pong20</title>
</head>
<body>
<canvas id="pongping" width="1000" height="800"></canvas>
<script src="pongping.js"></script>
</body>
Does anything pop up in the console? That might give some hint as to what is going wrong.
I noticed that in your game() function you are recursively calling game(). This may cause a recursive overflow.
At the same time, you have setInterval calling game again and again. I recommend you delete the lines:
let framePerSecond=65;
setInterval(game,1000/framePerSecond);
and replace them with
window.requestAnimationFrame(game)
This will still initialize your game properly, but it will also not block the thread, so users can still interact with the page as expected. It may not keep the proper frame rate that you're expecting, but that function passes a timestamp to the function it calls, so you could keep track of the time since last call and update movements based on that. Check out this example.
then inside your game function, replace every call to
game()
with
window.requestAnimationFrame(game)
This will hopefully stop your game from crashing.
https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

Im trying to detect circle only at real-time webcam, and draw circle on it

I trying to detect circle only on real-time webcam video and trying to draw circle border on my targeted circle, but right now I can draw a circle on output on a random target, please help me to get the circle target. I'm developing this code in javascript and using opencv.js. That random detection also detecting on video bottom only not in any other places.
function processVideo() {
try {
if (!streaming) {
// clean and stop.
src.delete();
dst.delete();
dstC1.delete();
dstC3.delete();
return;
}
let begin = Date.now();
// start processing.
cap.read(src);
cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY);
cv.blur(dst, dstC1, ksize, anchor, cv.BORDER_DEFAULT); // blur the image to avoids noise
cv.Canny(dstC1, dstC1, 50, 100, 3, false); // black and white border
let contours = new cv.MatVector();
let hierarchy = new cv.Mat();
cv.findContours(dstC1, contours, hierarchy, cv.RETR_CCOMP, cv.CHAIN_APPROX_SIMPLE, offset = new cv.Point(0, 0));
let cnt = contours.get(0);
let contoursColor = new cv.Scalar(255, 255, 255);
let circleColor = new cv.Scalar(255, 0, 0);
let circle = cv.minEnclosingCircle(cnt);// this one for circle
cv.drawContours(dstC1, contours, 0, contoursColor, 1, 8, hierarchy, 100);
for (let i = 0; i < 4; i++) {
cv.circle(dstC1, circle.center, circle.radius, circleColor, 3);
}
cv.imshow('canvasOutput', dstC1);
let delay = 1000/FPS - (Date.now() - begin);
setTimeout(processVideo, delay);
} catch (err) {
utils.printError(err);
}
};

My Game loop accelerates and character leaves a trail

The code:
// create stuff
var ghObj = {
x : 0,
y : 0
}
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var ghost = new Image();
ghost.src = "ghost.png"
//define variables
var ghostMove = function () {
ghObj.x+=(Math.floor(Math.random() * 9 - 4))
console.log(ghObj.x)
ghObj.y+=(Math.floor(Math.random() * 9 - 4))
}
var ghostCheck = function () {
if (ghObj.x<0) {
ghObj.x=0
}
if (ghObj.x>390) {
ghObj.x=390
}
if (ghObj.y<0) {
ghObj.y=0
}
if (ghObj.y>390) {
ghObj.y=390
}
}
var drawIm = function (sprite, position) {
ctx.save();
ctx.translate(position.x, position.y);
ctx.drawImage(sprite, 0, 0, sprite.width, sprite.height, 0, 0, sprite.width, sprite.height);
ctx.restore();
};
// begin "game" when ghost is loaded
ghost.onload = function() {
mainLoop()
}
// main loop
function() {
ghostMove()
ghostCheck()
drawIm(ghost, ghObj)
setInterval(mainLoop, 1000)
}
sorry if its a bit long.
what's supposed to happen is the ghost moves randomly round the screen at a steady rate.
instead, it moves randomly but increasingly quickly and leaves copies of itself everywhere.
Isn't the restore function supposed to clear the screen each time?
have i got the game loop wrong?
thanks in advance.
function mainLoop(){
setInterval(mainLoop,100);
}
I think the error is obvious. I recommend to use setTimeout or requestAnimationFrame instead... And this should remove the duplicates i think its an optical ilusion
...

Make identical objects move independently in Javascript Canvas

So I am trying to make a simple space game. You will have a ship that moves left and right, and Asteroids will be generated above the top of the canvas at random X position and size and they will move down towards the ship.
How can I create Asteroid objects in seperate positions? Like having more than one existing in the canvas at once, without creating them as totally seperate objects with seperate variables?
This sets the variables I would like the asteroid to be created on.
var asteroids = {
size: Math.floor((Math.random() * 40) + 15),
startY: 100,
startX: Math.floor((Math.random() * canvas.width-200) + 200),
speed: 1
}
This is what I used to draw the asteroid. (It makes a hexagon shape with random size at a random x coordinate)
function drawasteroid() {
this.x = asteroids.startX;
this.y = 100;
this.size = asteroids.size;
ctx.fillStyle = "#FFFFFF";
ctx.beginPath();
ctx.moveTo(this.x,this.y-this.size*0.5);
ctx.lineTo(this.x+this.size*0.9,this.y);
ctx.lineTo(this.x+this.size*0.9,this.y+this.size*1);
ctx.lineTo(this.x,this.y+this.size*1.5);
ctx.lineTo(this.x-this.size*0.9,this.y+this.size*1);
ctx.lineTo(this.x-this.size*0.9,this.y);
ctx.fill();
}
I included ALL of my code in this snippet. Upon running it, you will see that I currently have a ship that moves and the asteroid is drawn at a random size and random x coordinate. I just need to know about how to go about making the asteroid move down while creating other new asteroids that will also move down.
Thank You for all your help! I am new to javascript.
// JavaScript Document
////// Variables //////
var canvas = {width:300, height:500, fps:30};
var score = 0;
var player = {
x:canvas.width/2,
y:canvas.height-100,
defaultSpeed: 5,
speed: 10
};
var asteroids = {
size: Math.floor((Math.random() * 40) + 15),
startY: 100,
startX: Math.floor((Math.random() * canvas.width-200) + 200),
speed: 1
}
var left = false;
var right = false;
////// Arrow keys //////
function onkeydown(e) {
if(e.keyCode === 37) {
left = true;
}
if(e.keyCode === 39) {
right = true;
}
}
function onkeyup(e) {
if (e.keyCode === 37) {
left = false;
}
if(e.keyCode === 39) {
right = false;
}
}
////// other functions //////
//function to clear canvas
function clearCanvas() {
ctx.clearRect(0,0,canvas.width,canvas.height);
}
// draw the score in the upper left corner
function drawscore(score) {
var score = 0;
ctx.fillStyle = "#FFFFFF";
ctx.fillText(score,50,50);
}
// Draw Player ship.
function ship(x,y) {
var x = player.x;
var y = player.y;
ctx.fillStyle = "#FFFFFF";
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(x+15,y+50);
ctx.lineTo(x-15,y+50);
ctx.fill();
}
// move player ship.
function moveShip() {
document.onkeydown = onkeydown;
document.onkeyup = onkeyup;
if (left === true && player.x > 50) {
player.x -= player.speed;
}
if (right === true && player.x < canvas.width - 50) {
player.x += player.speed;
}
}
// Draw Asteroid
function drawasteroid() {
this.x = asteroids.startX;
this.y = 100;
this.size = asteroids.size;
ctx.fillStyle = "#FFFFFF";
ctx.beginPath();
ctx.moveTo(this.x,this.y-this.size*0.5);
ctx.lineTo(this.x+this.size*0.9,this.y);
ctx.lineTo(this.x+this.size*0.9,this.y+this.size*1);
ctx.lineTo(this.x,this.y+this.size*1.5);
ctx.lineTo(this.x-this.size*0.9,this.y+this.size*1);
ctx.lineTo(this.x-this.size*0.9,this.y);
ctx.fill();
}
// move Asteroid
function moveAsteroid() {
//don't know how I should go about this.
}
// update
setInterval (update, 1000/canvas.fps);
function update() {
// test collisions and key inputs
moveShip();
// redraw the next frame of the animation
clearCanvas();
drawasteroid();
drawscore();
ship();
}
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>My Game</title>
<script src="game-functions.js"></script>
<!--
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
-->
</head>
<body>
<canvas id="ctx" width="300" height="500" style="border: thin solid black; background-color: black;"></canvas>
<br>
<script>
////// Canvas setup //////
var ctx = document.getElementById("ctx").getContext("2d");
</script>
</body>
</html>
You want to make the creation of asteroids dynamic...so why not set up a setInterval that gets called at random intervals as below. You don't need a separate declaration for each Asteroids object you create. You can just declare a temporary one in a setInterval function. This will instantiate multiple different objects with the same declaration. Of course you need to store each object somewhere which is precisely what the array is for.
You also have to make sure that asteroids get removed from the array whenever the moveAsteroid function is called if they are off of the canvas. The setInterval function below should be called on window load and exists alongside your main rendering setInterval function.
You are also going to have to change your moveAsteroid function a bit to be able to point to a specific Asteroids object from the array. You can do this by adding the Asteroids object as a parameter of the function or by making the function a property of the Asteroids class and using this. I did the latter in the example below.
var astArray = [];
var manageAsteroidFrequency = 2000;
var Asteroids {
X: //something
Y://something
speed:1
move: function() {
this.X -= speed;
}
}
var mainRenderingFunction = setInterval( function() {
for (var i = astArray.length-1 ; i > -1; i --){
if(astArray[i].Y < 0){
astArray.splice(i, 1)
}else{
astArray[i].move;
}
}
}, 40);
var manageAsteroids = setInterval( function () {
if (astArray.length < 4){
var tmpAst = new Asteroids();
astArray.push(tmpAst);
}
manageAsteroidFrequency = Math.floor(Math.random()*10000);
}, manageAsteroidFrequency);

Categories