Phaser 3: Allow Particles to emit with flipped/mirrored image? - javascript

I have a particle emitter which emits multiple duplicates of the same image, as usual. However I'd like some of the particles to be flipped, either completely at a random amount, or sort of in the middle, so that particles falling to the left would be flipped and particles falling to the right won't be.
However I couldn't find anything regarding flipping particles without flipping ALL of them. I'd only like some to be flipped. Is this possible in any way?

There are serveral way's, I think the "fastest" would be just to use the scaleX property of the emiter.
this code flips about 10% of the particles ( 0.9 > Math.random() ), through multiplying it with -1, when it should be flipped.
Example Code:
this.add.particles('sparkle').createEmitter({
x: 200,
y: 100,
scaleX: {
onEmit: function () {
return ( 0.9 > Math.random() ) ? -1 : 1;
}
},
speed: { min: -100, max: 100 },
quantity: 0.1,
frequency: 1,
});
But I assume from a earlier question, that you have emitter with a "random scale" property. I that case you woud have to do something like this:
Example Code, for random scaled particles:
gameState.splash = this.add.particles('droplet').createEmitter({
x: gameState.height/2,
y: gameState.width/2,
scale: {
onEmit: function () {
// create random new scale
let newRandowmScale = Phaser.Math.FloatBetween(0.05, 0.3);
return ( 0.9 > Math.random() ) ? -1 * newRandowmScale : newRandowmScale;
}
},
speed: { min: -100, max: 100 },
...
});
UPDATE(SlowerFix): Example Code, for random scaled particles:
What the update does: save the current scale of the scaleX event and use it in the scaleY event. (it is hacky, but should work. I will see if there is a cleaner solution)
gameState.splash = this.add.particles('droplet').createEmitter({
x: gameState.height/2,
y: gameState.width/2,
scaleY:{
onEmit: function(particle){
// keep scale value positive
return Math.abs(particle.scaleX);
}
},
scaleX:{
onEmit: function(p){
let scale = Phaser.Math.FloatBetween(.2, .5);
return Math.random() > .9 ? scale * -1 : scale;
}
},
speed: { min: -100, max: 100 },
...
});

Related

How to create a random ground in matter.js

I am creating the ground of a game using a Perlin noise function. This gives me an array of vertices. I then add a vertex at the front that is {x:0 y: WORLD_HEIGHT} and another at the end of the array that is {x: WORLD_WIDTH y: WORLD_HEIGHT}. I am hoping that will give me a flat base with a random top.
How then do I add this into the matter.js world?
I am trying to create the ground using;
var terrain = Bodies.fromVertices(???, ???, vertexSets, {
isStatic: true
}, true);
but I don't know what to use for the ??? co-ordinates. I think they are supposed to represent the center of the object. However, I don't know what that is because it is noise. What I would like to do is specify the x & y of the first perlin noise vertex.
I am not even sure that given these vertices matter.js is creating a single body or multiple.
Is this the right way to approach it or there another way to do this? I am really struggling with the docs and the examples.
I use Matter.Body.setPosition(body, position) to override the center of mass and put the ground where I want it based on its bounds property.
const engine = Matter.Engine.create();
const render = Matter.Render.create({
element: document.body,
engine: engine,
});
const w = 300;
const h = 300;
const vertices = [
...[...Array(16)].map((_, i) => ({
x: i * 20,
y: ~~(Math.random() * 40),
})),
{x: w, y: 100},
{x: 0, y: 100},
];
const ground = Matter.Bodies.fromVertices(
w - 10, h - 10, // offset by 10 pixels for illustration
vertices,
{isStatic: true},
/* flagInternal =*/ true,
);
Matter.Body.setPosition(ground, {
x: w - ground.bounds.min.x,
y: h - ground.bounds.max.y + 110,
});
const {min: {x}, max: {y}} = ground.bounds;
console.log(x, y); // 10 120
Matter.Composite.add(engine.world, [ground]);
Matter.Render.run(render);
Matter.Runner.run(engine);
<script src="https://cdn.jsdelivr.net/npm/poly-decomp#0.3.0/build/decomp.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>
Without setPosition, you can see things jump around if you run this snippet a few times (just to reproduce OP's error with a concrete example):
const engine = Matter.Engine.create();
const render = Matter.Render.create({
element: document.body,
engine: engine,
});
const vertices = [
...[...Array(16)].map((_, i) => ({
x: i * 20,
y: ~~(Math.random() * 40),
})),
{x: 300, y: 100},
{x: 0, y: 100},
];
const ground = Matter.Bodies.fromVertices(
200, 100, vertices,
{isStatic: true},
/* flagInternal =*/ true,
);
Matter.Composite.add(engine.world, [ground]);
Matter.Render.run(render);
Matter.Runner.run(engine);
<script src="https://cdn.jsdelivr.net/npm/poly-decomp#0.3.0/build/decomp.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>
I'm not using Perlin noise and there are some internal vertices that aren't properly detected in the above examples, but the result should be the same either way.
should be integers, all width and height of the noise texture. values at those x, y integer places can be floats... no problem.
and same width and height should go to terrain and values at that places will be the height of the terrain.

Three.js and gsap scale animation

So I'm trying to do a mousemove event in three.js where the user would hover over a geometry and then it would scale.
So for the animations I am using GSAP as tween doesn't seem to be working for me. However, I keep getting this error when I want to scale my geometry:
I don't know why because in the official gsap documentation they use scale, without a plugin I believe. Here is an example from their website
gsap.to(".box", 1, {
scale: 0.1,
y: 60,
yoyo: true,
repeat: -1,
ease: "power1.inOut",
delay:1,
stagger: {
amount: 1.5,
grid: "auto",
from: "center"
}
});
Here is my code:
function init () {
/*------Bunch of three.js code and initialsation*/
window.addEventListener('mousemove',onMouseMove);
}
function onMouseMove(event) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera(mouse,camera);
var intersects = raycaster.intersectObjects(scene.children, true);
for(var i = 0; i < intersects.length; i++) {
gsap.to(intersects[i].object.scale, {duration: 1, scale: 0.8});
}
}
So I figured the answer. It seems that in three.js, the gsap scale property doesn't work so you need to make sure you're referring to scale before adding transformations, and then use x and y (or maybe z - I haven't tried) to increase or decrease the size.
This is the code that worked for me:
gsap.to(intersects[i].object.scale, {duration: .7, x: 1.2, y:1.2});

Tweenmax Scale with ThreeJS Mesh

Trying to incorporate a scale translation to my mesh[0] using TweenMax. I'm not having any problems with certain animations, such as rotation, or even scaling when I use 'mesh[0].set.scale' as the first argument. However, in this situation I'm getting 'Uncaught TypeError: Cannot assign to read only property 'scale' of object '#'' errors from the console.
I'm guessing that this is to do with the combination of using GSAP and ThreeJS, because I've tried out the same code in plain javascript and it works OK.
I've tried to include minimal code, so please let me know if more is needed!
const geometry = new THREE.IcosahedronBufferGeometry( 1, 0 );
materialRed = new THREE.MeshStandardMaterial({
color: 0xFF0000
});
mesh[0] = new THREE.Mesh( geometry, materialRed );
scene.add(mesh[0]);
TweenMax.to(mesh[0], 1,
{
scale: 2,
ease: Elastic.easeOut,
yoyo: true,
repeat: -1,
yoyoEase: Bounce.easeOut,
delay: 1,
}
);
Figured out my issue:
TweenMax.to(mesh[0].scale, 1,
{ x: 1.2,
y: 1.2,
z: 1.2,
yoyo: true,
repeat: -1,
});
Seems as if I was trying to manipulate the whole mesh, when I should have been focusing on the scale of the mesh. From here I can scale up and manipulate however.
Repeat method call has been updated:
https://greensock.com/docs/TimelineMax/repeat()
var t = Math.random() * 0.6 + 0.3;
TweenMax.to( box.scale, t, {
x: 1 + Math.random() * 3,
y: 1 + Math.random() * 20,
z: 1 + Math.random() * 3,
ease: Power2.easeInOut
} ).repeat(-1);
Demo:
https://codepen.io/MAKIO135/pen/vmBzMv?editors=0010

How to change texture in Gera library?

I'm learning Gera WebGL library, and I wonder how can I change the texture of mesh in it?
I'm creating the rotating box like that:
var cube = new Gera.Cube({
geometry: {
alpha: 1,
beta: 1,
gamma: 1,
delta: 1,
epsilon: 1,
dzeta: 1
},
position: {
x: 0,
y: 0,
z: -7
},
rotation: {
x: 1,
y: 0,
z: 1,
autostart: true,
angle: 45
},
texture: 'imagePath.jpg'
});
scene.add( cube );
But what if I want to change the texture after some action/event, what should I do?
There is less information in official spectification
The code above was taken from the index page, and some pretty sample from some playground scene
I have found the way, how to achieve the texture change.
You can do this with using the next code:
window.setTimeout( function() {
var image = new Image();
image.src = 'new-file-path.jpg';
image.onload = function( event ) {
var handledImage = event.target || event.srcElement;
cube.texture.image = handledImage;
};
}, 1000 );
The texture will be updated in 1 second.
Also, Gera right now doesn't provide CORS origin requests, so be careful with fetching image data, if you will try to fetch image from remote server it won't be updated, you should put your textures in localhost.

many very confusing problems with kinetic.js

i got some problems with understanding kinetic.js (the documentation is horrible for newbies...) i hope i can explain it with my bad english.
Problem 1: Everytime when i #reset my canvas it is not really resetting it. its more like its pushing another background image over the actual canvas and when i click on it it jumps back to the original...
function clearCanvas() {
context.clearRect(0, 0, 1000, 1000); //whole canvas
context.drawImage(buehneObj,0,0); //redraw the main background image
}
and call it with:
reset = document.getElementById('reset');
document.getElementById('reset').onclick =function(){clearCanvas();
}
Problem 2: the slider i build for scaling the image is not working at all but i dont see the problem... ...the variables are global and if i test alert it i see that values are existing...
standard jquery slider:
$('#scaleslider').slider({
animate: "fast",
step: 0.1,
value: 1,
min: 0.1,
max: 1,
slide: function(event,ui){groesse = ui.value} //global variable
});
i made it hidden(display:none) and on click "block"
var scaleslider = document.getElementById('scaleslider').style;
document.getElementById('resize').onclick =function(){ scaleslider.display ="block";}
and here's how kinetic parts look like (dragMotiv is my first start image) "groesse" is the variable for my x and y slider value(they can us the same so it scales correct):
var dragMotiv = new Kinetic.Image({
image: imageObj,
x: 250,
y: 300,
width: 330,
height: 263,
rotationDeg: 0,
scale: { x:groesse, y:groesse },
draggable: true,
dragBoundFunc: function(pos) {
var newY = pos.y < 290 ? 290 : pos.y > 305 ? 305 : pos.y;
var newX = pos.x < 250 ? 250 : pos.x > 390 ? 390 : pos.x;
return {
x: newX,
y: newY
};
}
});
Problem 3: Saving is not possible at all.
i uploaded it to my server to let you guys take a look at it. i know that there is one little thingy that i just dont see(i hope so).
http://manufaktur13.de/playground/canvas_kinetic.html
I think you should not clear the canvas, instead you should keep record what you have drown and remove those items, and redraw the layer.

Categories

Resources