I'm working on a project and I need to add 3d sounds effects, like the sound is continually moving around the listener effects. Is it possible to achieve that with howlerjs i see that with howler i'm able to play a sound from specific coordinates/orientation but how to achieve surrounding/ambisonics sounds ?
Or another library in JavaScript to achieve that?
Thanks for your help.
Half a year late, but yeah that's entirely possible in howler.js, haven't used it myself but judging from the docs you can just update the position. there's some more libraries that do it that I've found, check here how 3dage does exactly what you want:
https://codepen.io/naugtur/pen/QgmvOB?editors=1010
var world = IIIdage.World({
tickInterval: 200
})
var annoyingFly = IIIdage.Thing({
is: ['fly'],
sounds: {
'buzzing constantly': {
sound: 'buzz',
times: Infinity
}
},
reacts: [
{
// to: world.random.veryOften(),
to: world.time.once(),
with: 'buzzing constantly'
}
]
})
// scene should create and expose a default world or accept one
var scene = IIIdage.Scene({
title: 'Annoying fly',
library: {
sounds: {
'buzz': {
src: ['https://webaudiogaming.github.io/3dage/fly.mp3']
}
}
},
world: world,
things: [ // scene iterates all things and spawns them into the world. same can be done manually later on.
annoyingFly({
pos: [-1, -15, 0],
dir: [1, 0, 0],
v: 1
})
]
}).load().run()
setTimeout(function () {
scene.dev.trace(IIIdage.dev.preview.dom())
}, 500)
setInterval(function rotateVector() {
var angleRad = 0.15
var d=scene.things[0].attributes.dir
var x=d[0], y=d[1]
var cosAngle = Math.cos(angleRad), sinAngle = Math.sin(angleRad)
scene.things[0].attributes.dir = [x * cosAngle - y * sinAngle, y * cosAngle + x * sinAngle, 0]
}, 500)
window.scene = scene
There's still some others that do similar stuff:
https://www.npmjs.com/package/songbird-audio
https://www.npmjs.com/package/ambisonics
Hope this pushes you in the right direction if you still want help with it.
Related
Before anything, I have no idea what I'm doing but I was wondering if it was possible to use vincentgarreaus' particles with names instead of patterns?
I managed to edit particle.js and add a function that randomly picks a name and it replaces the circles for the names but my problem is that while moving the names change too fast in the same particle. If I set it to static it works as intended but I want them moving.
Is it possible?
What I did is going to VG website > inspect element > ctrl P > particle.js > Line 426 and pasted this "code" > ctrl S to save
function PlayerSelector1() {
var word = ['player1', 'player2', 'player3', 'player4', 'player5', 'player6'];
var random = word[Math.floor(Math.random() * word.length)];
return random;
}
switch(p.shape){
case "circle":
var context = pJS.canvas.ctx.canvas.getContext("2d");
var xtxx = PlayerSelector1();
context.beginPath();
context.fillStyle = "black";
context.fillText(xtxx, p.x, p.y);
context.fill();
break;
I have nothing to offer for your help but you will have my eternal gratitude
You can't create text particles using particles.js natively, but you can use tsParticles instead which support text particles.
This is how you can achieve it:
// keeping your function, it's fine
function PlayerSelector1() {
var word = ["player1", "player2", "player3", "player4", "player5", "player6"];
var random = word[Math.floor(Math.random() * word.length)];
return random;
}
// basic particles configuration, used for example
tsParticles.load("tsparticles", {
background: {
color: "#000"
},
particles: {
number: {
value: 10
},
move: {
enable: true
},
size: {
value: 30
},
shape: {
type: "text",
options: {
text: {
value: PlayerSelector1()
}
}
}
}
});
For using tsParticles you can read the instructions on the GitHub repository
This is your working demo on CodePen, using the config shown above: https://codepen.io/matteobruni/pen/oNymXmy?editors=0010
Every time you call the tsParticles.load function, the player will change.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 3 months ago.
Improve this question
I have a game and I want to be able to have enemies pathfind to the player across a tilemap, is there a way to do this without programming my own a* algorithm? I've seen a couple supposedly still updated libraries for this, but neither of which have worked, they have both been broken with npm and not worked when added as a script. The libraries I've tried are Easystar and Navmesh.
Any suggestions would be great, and while Phaser support would be useful, pathfinding over a 2D array would still be a good solution for me. Thanks!
I never tried it myself (until now), but https://github.com/mikewesthad/navmesh is a great plugin and is very extensive.
... A JS plugin for fast pathfinding using navigation meshes, with optional wrappers for the Phaser v2 and Phaser v3 game engines. ...
p.s.: on this page you can find a list of available plugins for phaser https://phaserplugins.com/
Update:
After testing in on an simple an example it worked fine, just be careful not to miss any steps.
Here the steps needed:
get the latest plugin file phaser-navmesh-plugin.js (currently from https://github.com/mikewesthad/navmesh/releases/tag/2.1.0)
load it from the html file
<script src="phaser-navmesh-plugin.js"></script>
configure the plugin, in the config (there are other ways but this is the more convinient)
var config = {
...
plugins: {
scene: [
{
key: "PhaserNavMeshPlugin", // Key to store the plugin class under in cache
plugin: PhaserNavMeshPlugin, // Class that constructs plugins
mapping: "navMeshPlugin", // Property mapping to use for the scene, e.g. this.navMeshPlugin
start: true
}
]
},
scene: {
...
}
};
setup the map and the layer which should collide:
var map = this.make.tilemap({ data: [[0,1,0],[0,1,0],[0,1,0],[0,0,0]], tileWidth: 8, tileHeight: 8 });
var tiles = map.addTilesetImage('tile01');
var layer = map.createLayer(0, tiles, 0, 0);
// this is important, can also be multiple indices
layer.setCollision(1);
create navMesh, pass the map and the created layer with should have to collisions.
const navMesh = this.navMeshPlugin.buildMeshFromTilemap("mesh", map, [layer]);
when needed execute pathfinding (x/y positions are in pixels, not tilesId):
const path = navMesh.findPath({ x: 4, y: 4 }, { x: 17, y: 4 });
You can load the plugin in also in the preload function like this
this.load.scenePlugin({
key: 'PhaserNavMeshPlugin',
url: PhaserNavMeshPlugin,
sceneKey: 'navMeshPlugin'
});
Here the demo code with a mini path trace when done:
var config = {
scene: {
preload,
create,
}
};
var game = new Phaser.Game(config);
function preload() {
this.load.image('tile01', 'tile01.png');
this.load.scenePlugin({
key: 'PhaserNavMeshPlugin',
url: PhaserNavMeshPlugin,
sceneKey: 'navMeshPlugin'
});
}
function create() {
var map = this.make.tilemap({ data: [[0,1,0],[0,1,0],[0,1,0],[0,0,0]], tileWidth: 8, tileHeight: 8 });
var tiles = map.addTilesetImage('tile01');
var layer = map.createLayer(0, tiles, 0, 0);
layer.setCollision(1);
const navMesh = this.navMeshPlugin.buildMeshFromTilemap("mesh", map, [layer]);
const path = navMesh.findPath({ x: 4, y: 4 }, { x: 17, y: 4 });
if (!path) {
return;
}
let graphics = this.add.graphics();
graphics.lineStyle(2, 0xff0000, 1);
graphics.beginPath();
graphics.moveTo(path[0].x, path[0].y);
for (let idx = 1; idx < path.length; idx++) {
graphics.lineTo(path[idx].x, path[idx].y);
}
graphics.strokePath();
}
Is it possible to create a single gravity / force point in matter.js that is at the center of x/y coordinates?
I have managed to do it with d3.js but wanted to enquire about matter.js as it has the ability to use multiple polyshapes.
http://bl.ocks.org/mbostock/1021841
The illustrious answer has arisen:
not sure if there is any interest in this. I'm a fan of what you have created. In my latest project, I used matter-js but I needed elements to gravitate to a specific point, rather than into a general direction. That was very easily accomplished. I was wondering if you are interested in that feature as well, it would not break anything.
All one has to do is setting engine.world.gravity.isPoint = true and then the gravity vector is used as point, rather than a direction. One might set:
engine.world.gravity.x = 355;
engine.world.gravity.y = 125;
engine.world.gravity.isPoint = true;
and all objects will gravitate to that point.
If this is not within the scope of this engine, I understand. Either way, thanks for the great work.
You can do this with the matter-attractors plugin. Here's their basic example:
Matter.use(
'matter-attractors' // PLUGIN_NAME
);
var Engine = Matter.Engine,
Events = Matter.Events,
Runner = Matter.Runner,
Render = Matter.Render,
World = Matter.World,
Body = Matter.Body,
Mouse = Matter.Mouse,
Common = Matter.Common,
Bodies = Matter.Bodies;
// create engine
var engine = Engine.create();
// create renderer
var render = Render.create({
element: document.body,
engine: engine,
options: {
width: Math.min(document.documentElement.clientWidth, 1024),
height: Math.min(document.documentElement.clientHeight, 1024),
wireframes: false
}
});
// create runner
var runner = Runner.create();
Runner.run(runner, engine);
Render.run(render);
// create demo scene
var world = engine.world;
world.gravity.scale = 0;
// create a body with an attractor
var attractiveBody = Bodies.circle(
render.options.width / 2,
render.options.height / 2,
50,
{
isStatic: true,
// example of an attractor function that
// returns a force vector that applies to bodyB
plugin: {
attractors: [
function(bodyA, bodyB) {
return {
x: (bodyA.position.x - bodyB.position.x) * 1e-6,
y: (bodyA.position.y - bodyB.position.y) * 1e-6,
};
}
]
}
});
World.add(world, attractiveBody);
// add some bodies that to be attracted
for (var i = 0; i < 150; i += 1) {
var body = Bodies.polygon(
Common.random(0, render.options.width),
Common.random(0, render.options.height),
Common.random(1, 5),
Common.random() > 0.9 ? Common.random(15, 25) : Common.random(5, 10)
);
World.add(world, body);
}
// add mouse control
var mouse = Mouse.create(render.canvas);
Events.on(engine, 'afterUpdate', function() {
if (!mouse.position.x) {
return;
}
// smoothly move the attractor body towards the mouse
Body.translate(attractiveBody, {
x: (mouse.position.x - attractiveBody.position.x) * 0.25,
y: (mouse.position.y - attractiveBody.position.y) * 0.25
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.12.0/matter.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/matter-attractors#0.1.6/build/matter-attractors.min.js"></script>
Historical note: the "gravity point" functionality was proposed as a feature in MJS as PR #132 but it was closed, with the author of MJS (liabru) offering the matter-attractors plugin as an alternate. At the time of writing, this answer misleadingly seems to indicate that functionality from the PR was in fact merged.
Unfortunately, the attractors library is 6 years outdated at the time of writing and raises a warning when using a newer version of MJS than 0.12.0. From discussion in issue #11, it sounds like it's OK to ignore the warning and use this plugin with, for example, 0.18.0. Here's the warning:
matter-js: Plugin.use: matter-attractors#0.1.4 is for matter-js#^0.12.0 but installed on matter-js#0.18.0.
Behavior seemed fine on cursory glance, but I'll keep 0.12.0 in the above example to silence it anyway. If you do update to a recent version, note that Matter.World is deprecated and should be replaced with Matter.Composite and engine.gravity.
How can I cache SpriteSheets in EaselJS? I have a Sprite object and when I use user.hero.cache(0, 0, 30, 40); it stops playing animation (probably because I'm just caching the current frame, not the entire SpriteSheet image). So how can I cache it?
Here's my relevant EaselJS code:
data = {
images: ["Graphics/hero.png"],
frames: {
width: 30,
height: 40
},
animations: {
stand: 0,
run: [1, 2, "runLoop", 0.15],
runLoop: [3, 7, true, 0.15],
jump: [8, 10, "happy", 0.5],
happy: 11,
fall: 12,
stopFalling: [13, 14, "stand", 0.2],
almostFalling: [16, 19, true, 0.1]
}
};
user.hero.spriteSheet = new createjs.SpriteSheet(data);
user.hero = new createjs.Sprite(user.hero.spriteSheet, "stand");
user.hero.name = "hero";
user.hero.x = user.hero.safeX = 40 * 3;
user.hero.y = user.hero.safeY = 0;
user.hero.offset = 4;
user.hero.regX = user.hero.offset + 2;
user.hero.regY = user.hero.offset;
user.hero.width = 30 - (user.hero.offset * 2) - 10;
user.hero.height = 40 - (user.hero.offset * 2);
user.hero.xvel = user.hero.yvel = 0;
user.hero.cache(0, 0, 30, 40); // <--- This is the problem.
movableObjContainer.addChild(user.hero);
movableObj.push(user.hero);
Without cache:
With cache:
I've tried caching the data.image or user.hero.spriteSheet too, without success.
Is there any way to cache the SpriteSheet without compromising its animations?
When you cache the sprite, you are saving off how it looks at that instant.
Can you explain why you want to cache it? The only reason I can think of to cache it would be to apply filters. Each time you cache it, the contents are drawn to an off-screen canvas, which is then drawn in place of it. This makes a lot of sense if you have complex content, like a container or graphics, which do not change, but with the spritesheet, it means you are creating a new bitmap to draw a bitmap. The spritesheet itself is a great way to be filesize, network, and GPU-optimzed, so re-caching it is basically negating all those benefits.
If you want to cache anyways, you will need to re-cache it, or call updateCache() every time it changes. Here is an example using the ticker.
createjs.Ticker.on("tick", function() {
user.hero.updateCache();
// or
user.hero.cache(0,0,30,40)
}, this);
Here is a quick demo I did a while back using a few approaches for filters. It provides an example of constant re-caching, as well as an example where the entire spritesheet is cached to apply the filter once, and then that cached version is used for the sprite.
http://jsfiddle.net/lannymcnie/NRH5X/
So I have spritesheet i have almost looked everywhere nor i can find good tutorial neither i can get this thing to work .Can some one point it out for me that what's wrong here.?Coz none error is generated nor is anythign getting showed on the canvas .
var result = queue.getResult("avatar1");
var data=
{
images: [ result],
// The 5th value is the image index per the list defined in "images" (defaults to 0).
frames: [
// x, y, width, height, imageIndex, regX, regY
//head_south":{"x":120,"h":20,"y":138,"w":15}
[120,138,15,20],
[64,0,15,20,2],
],
animations: {
show: { frames: [0,1], next: true, frequency: 1 }
}
};
var sp = new createjs.SpriteSheet(data);
createjs.Ticker.setFPS(60);
var sprite_anim = new createjs.BitmapAnimation(sp,"show");
sprite_anim.x=100;
sprite_anim.y=100;
stage.addChild(this.sprite_anim);
sprite_anim.play("show");
sprite_anim.gotoAndPlay('show');
Do you update the stage with the ticker ? :
createjs.Ticker.addEventListener("tick", function(event) {
stage.update(event);
});
4 arguments [120,138,15,20], 5 arguments [64,0,15,20,2]
Arguments that are allowed are either 4 or 7.So changed back to 4.That was why it was generating error of" createjs type error '.
Thank everyone for your conern .Closing this question.