THREE.js - making a little squishy 3D ball - javascript

I am new to THREE.js. I have some questions...
can someone help me with simple squishing this ball when he contacts the border and change direction? or maybe just scaling the ball from angle of contacting border point? to make this ball little more realistic
some code: Making rotating 3d sphere with velocity
code from this theme:
THREE.js - moving a 3D ball with a rotation
for (var y = 0; y < 16; y++)
for (var x = 0; x < 16; x++)
if ((x & 1) != (y & 1)) ctx.fillRect(x * 16, y * 16, 16, 16);
var ballTex = new THREE.Texture(canv);
ballTex.needsUpdate = true;
Sorry for my bad English!

If the ball is rolling when it hits an edge, it'd be really difficult to create a believable squish by using the .scale attribute, since that only affects its scaling along the x, y, or z axis.
The best way to realistically achieve this effect is to use a physics engine to detect collisions and morph the geometry accordingly. There's already an example of this on the Three.js website. You can look at its source code to follow along. Just keep in mind it uses Ammo.js as its physics engine, so you'd need to learn how to use the Ammo API if you want to make modifications.

Related

How to use vertex buffer objects in webgl to position particles

Hello I am a bit new to 3d programming. I am trying to improve the efficiency of a particle system that I am simulating with liquid fun.
Currently I am drawing the particle system this way:
for (var j = 0; j < maxParticleSystems; j++) {
var currentParticleSystem = world.particleSystems[j];
var particles = currentParticleSystem.GetPositionBuffer();
var maxParticles = particles.length;
for (var k = 0; k < maxParticles; k += 2) {
context.drawImage(particleImage, (particles[k] * mToPx) + offsetX, (particles[k + 1] * mToPx) + offsetY);
context.fill();
}
}
This basically draws each particle one at a time which is very slow. I have been doing some reading and I read about Position Buffer objects in webGL. How would I use one to draw these?
This is arguably too broad a question for Stack Overflow. WebGL is just a rasterization API which means there's an infinite number of ways to render and/or compute particles with it.
Some common ways
Compute particle positions in JavaScript, Render with POINTS in WebGL
Compute particle positions in JavaScript, Render with quads in WebGL (rendering quads lets you orient the particles)
Compute particle positions based on time alone in a shader, render POINTS.
Compute particle positions based on time alone in a shader, render quads
Compute particle positions in shaders with state by reading and writing state to a texture through a framebuffer
And hundreds of other variations.
Particle system using webgl
Efficient particle system in javascript? (WebGL)

How to rotate an array of canvas rectangles

I'm creating a Pentomino puzzle game for a final project in a class I'm taking. I've created all dozen of the required puzzle pieces and can drag those around here. And I've tried this code to rotate the array (without using canvas.rotate() & located at the very bottom of the fiddle), it basically swaps the X & Y coordinates when drawing the new piece:
var newPiece = targetPiece;
pieces.splice(pieces.indexOf(targetPiece), 1);
targetPiece = null;
console.log(newPiece);
var geometry = [];
for (var i = 0; i < newPiece.geometry.length; i++) {
geometry.push([newPiece.geometry[i][3], newPiece.geometry[i][0]]);
}
var offset = [newPiece.offset[1], newPiece.offset[0]];
console.log(geometry);
console.log(offset);
newPiece.geometry = geometry;
newPiece.position = geometry;
newPiece.offset = offset;
pieces.push(newPiece);
console.log(pieces);
for (var j = 0; j < pieces.length; j++) {
draw(pieces[j]);
}
This doesn't work properly, but has promise.
In this fiddle, I've isolated the problem down to a single piece and tried to use canvas.rotate() to rotate the array by double clicking, but what's actually happening is it's rotating each piece of the array (I think), which results in nothing happening because each block of the array is just a 50x50 rectangle and when you rotate a square, it still looks just like a square.
function doubleClickListener(e) {
var br = canvas.getBoundingClientRect();
mouse_x = (e.clientX - br.left) * (canvas.width / br.width);
mouse_y = (e.clientY - br.top) * (canvas.height / br.height);
var pieceToggle = false;
for (var i = 0; i < pieces.length; i++) {
if (onTarget(pieces[i], mouse_x, mouse_y)) {
targetPiece = pieces[i];
rotate(targetPiece);
}
}
}
function rotate() {
targetPiece.rotationIndex = targetPiece.rotationIndex === 0 ?
1 : targetPiece.rotationIndex === 1 ?
2 : targetPiece.rotationIndex === 2 ?
3 : 0;
for (var j = 0; j < pieces.length; j++) {
draw(pieces[j]);
}
}
Just FYI, I've tried creating the puzzle pieces as individual polygons, but could not figure out how to capture it with a mousedown event and move it with mousemove, so I abandoned it for the canvas rectangle arrays which were relatively simple to grab & move.
There's a brute force solution to this, and a total rewrite solution, both of which I'd rather avoid (I'm up against a deadline-ish). The brute force solution is to create geometry for all possible pieces (rotations & mirroring), which requires 63 separate geometry variants for the 12 pieces and management of those states. The rewrite would be to use fabric.js (which I'll probably do after class is over because I want to have a fully functional puzzle).
What I'd like to be able to do is rotate the array of five blocks with a double click (don't care which way it goes as long as it's sequential 90° rotations).
Approaching a usable puzzle:
With lots of help from #absolom, here's what I have, you can drag with a mouse click & drag, rotate a piece by double clicking it, and mirror a piece by right clicking it (well, mostly, it won't actually rotate until you next move the piece, I'm working on that). The Z-order of the pieces are manipulated so that the piece you're working with is always on top (it has to be the last one in the array to appear on top of all the other pieces):
Pentominoes II
The final solution
I've just handed the game in for grading, thanks for all the help! There was a lot more tweaking to be done, and there are still some things I'd change if I rewrite it, but I'm pretty happy with the result.
Pentominoes Final
Quick & Dirty:
The quick & dirty solution is when 2+ pieces are assembled you create a single image of them (using an in-memory canvas). That way you can move / rotate the 2-piece-as-1-image as a single entity.
More Proper:
If the 2+ piece assembly must later be disassembled, then you will need the more proper way of maintaining transformation state per piece. That more proper way is to assign a transformation matrix to each piece.
Stackoverflow contributor Ken Fyrstenberg (K3N) has coded a nice script which allows you to track individual polygons (eg your rects) using transformation matrices: https://github.com/epistemex/transformation-matrix-js
Does this code do what you need? The rotate method looks like this now:
function rotate(piece) {
for (i = 0; i < piece.geometry.length; i++) {
var x = piece.geometry[i][0];
var y = piece.geometry[i][2];
piece.geometry[i][0] = -y;
piece.geometry[i][3] = x;
}
drawAll();
}
I simplified how your geometry and positioning was handled too. It's not perfect, but it can gives you some hints on how to handle your issues.
Please note that this solution works because each piece is composed of blocks with the same color and your rotations are 90 degrees. I only move the blocks around to simulate the rotation but nothing is rotated per-se. If you build your pieces differently or if you need to rotate at different angles, then you would need to go with another approach like transformation matrices.
UPDATE
Here is a better solution: fiddle

Gravity in 2d games(360 degrees)

Hello all I am trying to make a game with the Phaser game engine and would like to implement some sort of 360 gravity. Essentially I just want the player to be able to rotate around the sphere. I was wondering what would be the best way to do this in phaser. I know that you can set objects gravities but you can only do so in the x and y direction. Any help is greatly appreciated!
you should use the concept of vectors for this.
like you want as a planet attracts towards another sun in a orbit.
then define
function Vector(x, y){
this.x = x || 0;
this.y = y || 0;
}
and these are pseudo codes
get acceleration vector direction by
vector(sun.position.x-planet.position.x,sun.position.y-planet.position.y)
then
planet.velocity.x+=acceleration.x
planet.velocity.y+=acceleration.y
for further using vector you can try
http://www.metanetsoftware.com/technique/tutorialA.html

CraftyJS how to calculate vector between 2 sprites?

I am a noob in game programming and not so good at Maths, I am trying to write a 1945 style shooting game, all been good so far but I am in a bottle neck that I cannot figure out how to make enemy aim at the player.
Lets say I have enemy sprite and player sprite, how do I find out the angle and the path? This sounds like calculating vector between 2 points, I have been reading the documentation and particularly this link http://craftyjs.com/api/Crafty-math-Vector2D.html
I just cannot figure out how to do it, I have tried the following
var enemyV = Crafty.math.Vector2D(enemy.x, enemy.y);
var playerV = Crafty.math.Vector2D(player.x, player.y);
var angle = enemyV.angleTo(playerV);
The value of angle is always between -3 to 3, which doesn't seem the right angles at all.
I hope someone who has CraftyJS experience can help me out here.
angleTo function returns radian value, so running this will give the actual angle degreex Crafty.math.radToDeg(radianValue)
To aim the player and make the bullet travel at that direction you just get the difference between 2 points
bullet.x - player.x'bullet.y - player.y' then apply a incremental rate such as below (
bullet.x_diff = (target.x - bullet.x)*0.02;
bullet.y_diff = (target.y - bullet.y)*0.02;
then inside enterframe loop:
this.x += this.x_diff;
this.y += this.y_diff;
Once you get the idea, you should normalize your diff by dividing by the distance between the points.

Collision detection on a canvas in JavaScript

I'm working on a game for a university assignment. The idea is that you defend the centre circle from the incoming asteroids (lines) by drawing a line (click, drag & release to draw a line) which blocks them. An asteroid hitting a line should destroy both the asteroid the line.
The problem I'm currently having is that the collision isn't being detected.
I have arrays of objects of both lines & asteroids. The lines consist of simply start & end x & y, the asteroids consist of a random speed & a random angle (their incoming angle) - the context is rotated, the asteroid drawn, & then it reset for the next line.
To detect collision, I use getImageData & check in front of the asteroids however many pixels the line will progress in that iteration (basically, their speed) & if the colour is red, it will destroy the asteroid - I haven't got round to destroying the line yet, will tackle that hurdle when I come to it (suggestions are welcome though).
function asteroids_draw() {
for (var i = 0; i < asteroids.length; i++) {
// Drawing setup
context.save();
context.translate(width / 2, height / 2);
context.rotate(asteroids[i].angle);
// Detecting close asteroids
if ((asteroids[i].distance - asteroids[i].speed) < planet.size) {
asteroids.splice(i, 1);
game_life_lost();
context.restore();
return;
} else if ((asteroids[i].distance - asteroids[i].speed) < 150){
asteroids[i].colour = '#FF0000';
}
// Scanning ahead for lines
for (var j = 0; j < asteroids[i].speed; j++) {
if (context.getImageData(asteroids[i].distance - j, 0, 1, 1).data[0] == 255) {
asteroids.splice(i, 1);
context.restore();
return;
}
}
// Drawing asteroid
context.beginPath();
context.moveTo(asteroids[i].distance -= asteroids[i].speed, 0);
context.lineTo(trig, 0);
context.strokeStyle = asteroids[i].colour;
context.stroke();
context.closePath();
context.restore();
}
}
The problem is, the asteroids never collide with the lines & I can't for the life of me see why, or see another simple way of doing it. Any advice would be much appreciated, thanks in advance.
I think your problem is that when you rotate the context, previously drawn items(lines) don't get rotated, only objects drawn after the rotation are rotated. See this page for more info.
You could try performing your asteroid/line intersection test before you translate and rotate the canvas, and use cosine and sine to find the x and y coordinates of the pixels you want to get image data from.
var pixelLocation =
[Math.cos(asteroids[i].angle) * j, Math.sin(asteroids[i].angle) * j];
if (context.getImageData(pixelLocation[0], pixelLocation[1], 1, 1).data[0] == 255) {
Just make sure your angle is in radians before passing to cos and sin.
I thought about the problem some more, & realised this method of doing things definitely isn't the best way. It should be doable without a view - a la Model View Controller design pattern. The best way to solve it would be to use maths!
There's simple maths for the intersection of two lines, but this needs intersection of two lines in a range. I found an algorithm which simplifies this further, using eight coordinates - the start x & y & the end x & y of the two lines.
I've posted the results. Thanks for the help.

Categories