I have spent the last few days working on a rubik's cube in Three JS. I am almost done with it, but am having a problem with proper nesting of groups. Basically I have all the cubies made up and when one of the center cubies on a face is clicked, all cubies on that face are added to a group and the group is rotated. The problem is when I try to readd the cubie to the scene they go back to their original location, not the new rotated one. Here is an example if the top face is clicked
else if(cubie.position.x == 0 && cubie.position.y == 12.5 && cubie.position.z == 0){
for(var i = scene.children.length - 1; i >=0; i--){
var cubie = scene.children[i];
if(cubie.position.y == 12.5){
group.add(cubie);
}
}
group.rotateOnAxis(new THREE.Vector3(0,-1,0), Math.PI/2);
}
and here is where I try to readd the cubie back to the scene
for(var i = group.children.length - 1; i >= 0; i--){
scene.add(group.children[i]);
}
scene.remove(group);
if I comment out both lines, then one complete rotation appears, but since the cubies are now apart of group I cant rotate them again. If I remove the first line, and leave remove(group) then obviously the row disappears, but if I leave both lines in, then the cube doesn't change at all as if when I readd the cubie to the scene it takes its original place back...I have tried everything I can think of. Any help would be greatly appreciated
I will post the entire code to pastebin if anyone needs it.
http://pastebin.com/vj6LgR0r
Related
I put this code for my sprite to reverse the position according to its direction but it reverses the position and it looks skinny. How to fix this?
key_left = keyboard_check(ord("A"))
key_right = keyboard_check(ord("D"))
key_jump = keyboard_check(vk_space)
var move = key_right - key_left
hspd = move * spd;
vspd = vspd + grv;
if (hspd != 0) {
image_xscale = sign(hspd)
}
The code's correct. You must have resized the sprite in the room editor, delete the instance and put it in again and don't resize it, it should work.
Also if you need it a little bigger you can (If 1.5 doesn't satisfy you, feel free to use a bigger number).
image_xscale = sign(hspd) * 1.5;
The code seem to be correct, have you tried setting the origin point at the center? By default the origin point is on the top-left, and once it's set at the center of your sprite, it won't change positions when turning around.
You can set the origin point at the sprite window.
I have 2 obj meshes.
They both have some common areas but not completely.
I displayed them both by adding them to screen ..
Just like a mesh on top of another.
But the lower mesh overlaps the top mesh
But what I want to acheive is the lower mesh should always stay below without overlapping and giving the space to the entire top mesh.
I went through this fiddle..Fiddle with renderorder
And I tried something with this like..
var objLoader1 = new OBJLoader2();
objLoader1.load('assets/object1.obj', (root) => {
root.renderOrder = 0;
scene.add(root);
});
var objLoader2 = new OBJLoader2();
objLoader2.load('assets/object2.obj', (root) => {
root.renderOrder = 1;
scene.add(root);
});
But I don't know for what reason the overlap still stays ..
I tried...
var objLoader1 = new OBJLoader2();
objLoader1.load('assets/object1.obj', (root) => {
objLoader1.renderOrder = 0;
scene.add(root);
});
var objLoader2 = new OBJLoader2();
objLoader2.load('assets/object2.obj', (root) => {
objLoader2.renderOrder = 1;
scene.add(root);
});
Then I tried going through this Fiddle .. Another Fiddle
But when I run in I get only the lower or the upper mesh .
But I want to see both without any overlaps..
var layer1 = new Layer(camera);
composer.addPass(layer1.renderPass);
layer1.scene.add(new THREE.AmbientLight(0xFFFFFF));
var objLoader1 = new OBJLoader2();
objLoader1.load('assets/object1.obj', (root) => {
layer1.scene.add(root);
});
var layer2 = new Layer(camera);
composer.addPass(layer2.renderPass);
layer2.scene.add(new THREE.AmbientLight(0xFFFFFF));
var objLoader2 = new OBJLoader2();
objLoader2.load('assets/object2.obj', (root) => {
layer2.scene.add(root);
});
I made the material depthTest to False
But Nothing Helped..
Can anyone help me achieve what I wanted ..
If anyone couldn't figure what I mean by overlapping see the image below..
And Thanks to anyone who took time and effort to go through and help me...
You can use polygonOffset to achieve your goal, which modifies the depth value right before a fragment is written to help move polygons off of eachother without visually changing the position:
material.polygonOffset = true;
material.polygonOffsetUnit = 1;
material.polygonOffsetFactor = 1;
Here is a fiddle demonstrating the solution:
https://jsfiddle.net/5s8ey0ad/1/
Here is what the OpenGL Docs have to say about polygon offset:
When GL_POLYGON_OFFSET_FILL, GL_POLYGON_OFFSET_LINE, or GL_POLYGON_OFFSET_POINT is enabled, each fragment's depth value will be offset after it is interpolated from the depth values of the appropriate vertices. The value of the offset is factor×DZ+r×units, where DZ is a measurement of the change in depth relative to the screen area of the polygon, and r is the smallest value that is guaranteed to produce a resolvable offset for a given implementation. The offset is added before the depth test is performed and before the value is written into the depth buffer.
You're experiencing z-fighting, which is when two or more planes occupy the same space in the depthBuffer, so the renderer doesn't know which one to render on top of the other. Render order alone doesn't fix this because they're both still on the same plane, regardless of which one gets drawn first. You have a few options to resolve this:
Move one of the beams ever so slightly up in the y-axis. A tiny fraction would give one priority over the other, and this distance may not be noticeable to the eye.
I saw your fiddle, and you forgot to add depthTest: false to your material. However, this will cause issues when depth-testing the rest of the shape, since some white is on top of the red, but also some red is on top of the white. The approach in the fiddle works only when it's a simple plane, not more complex geometries.
You can use a boolean operation that removes one shape from the other, like CSG.
I think you'd save yourself a lot of headache by using approach #1.
I would like to make my sprite stand still when not moving and animate when keys are pressed. I have a sprite with 8 images and an object that I have created where I assigned the sprite. I have added a key press and key release command and I have added a section where you can put your own custom code. However when I play the game the sprite is animating right away until I press a key and then he stops animating and moves in a still position. How can I fix this?
if image_index = 0
{
image_speed = 0;
}
else
{
image_index = 1;
image_speed = 1;
}
Your answer is in what you posted.
So in other words. If your going to do it this way. Why not just use 3 sprites one for stand one for left and one for right?
of if you insist on not doing that then just set image_index to 0 to start so
I have a very simple cube mesh:
var playerGeo = new THREE.BoxGeometry(5,5,5);
var playerMat = new THREE.MeshLambertMaterial({color: 0xFF1865});
var player = new THREE.Mesh(playerGeo, playerMat);
player.position.x = 0;
player.position.y = -50;
scene.add(player);
and in my render function (which uses reqestAnimationFrame) i have the following code which is meant to move the cube left/right based on wether the user presses the left/right key.
$("body").keydown(function(e) {
if(e.keyCode == 37) {
player.position.x -= 0.01;
}else if(e.keyCode == 39){
player.position.x += 0.01;
}
});
This works. However I noticed slightly weird behaviour, as at first if I press the left key, the cube will go left a tiny amount (what seems to be 0.01), but after quite a few times of pressing the arrow keys the distance in which the cube goes on each press seems to slowly increase. So the first time i press a left/right key, the cube will move left/right about a mm. Within about 10 presses left or right, it moves about a cm each press.
What is going on?
Please ask if you require more info!
Thanks
i am suspecting the position change is ok, but your projection is deformed
query the position after change for example open console and add
console.log("position before"+player.position.x);
if(e.keyCode == 37) {
player.position.x -= 0.01;
}else if(e.keyCode == 39){
player.position.x += 0.01;
}
console.log("position after"+player.position.x);
check if the change is 0.01 as planned
if it is and you are using perspective camera you have to set field of vision correctly to avoid fisheye effect
if neither of these are the the cause you have to provide more information...
I'm confused.
I've made a group of 10 sprites and added them to a THREE.Object3D() called fireworkGroup. I have another Object3D called explode. The tween loops through the sprites changing them from their initial position to explode.position.
for ( var i = 0; i < fireworkGroup.children.length; i ++ )
{
explode.position.x =(Math.random() - 0.5)*4;
explode.position.y =4;
explode.position.z =2;
var tweenLaunch = new TWEEN.Tween(fireworkGroup.children[i].position).to(explode.position, 4000).easing( TWEEN.Easing.Quartic.In);
tweenLaunch.start();
}
The tween is moving all the sprites from their start position to the same end position. So I thought this might be because "tweenLaunch" is being overwritten with a different explode.position each time as the tween is rendered so I'm only seeing the last one created in the loop. When I refresh the page they do all move to a different position, consistent with the Math.random().
But then why do all the sprites move to the explode.position? If "tweenLaunch" is being overwritten then why is it not moving only the last sprite?
Is it possible to have a loop with a tween in it that also changes?
Many Thanks.
I've managed to work out what was wrong by reading around the subject on Stackoverflow questions and answers, looking at a great particle example by stemkoski then trial and error.
view-source:http://stemkoski.github.io/Three.js/Particles.html
I used console.log to look at explode.position that I was using as the second position in the tween. It wasn't holding the values I wanted (a different Math.random on each loop).
So I created fireworkAttributes:
fireworkAttributes = { startPosition: [], explodePosition: [], nextPosition: [] };
and then cloned the sprite position in the function that created the sprites using:
fireworkAttributes.explodePosition.push( sprite.position.clone() );
then looped it in it's own function:
for (var i = 0; i < fireworkGroup.children.length; i++)
{
fireworkAttributes.explodePosition[i].x = (Math.random() - 0.5)*4;
fireworkAttributes.explodePosition[i].y = 4;
fireworkAttributes.explodePosition[i].z = 2;
}
then changed the code in the original question to:
for ( var a = 0; a < fireworkGroup.children.length; a ++ )
{
//need to use this new object as tweening to fireworkAttributes.explodePosition[a] does not work
explodeSite.position = fireworkAttributes.explodePosition[a];
var tweenLaunch = new TWEEN.Tween(fireworkGroup.children[a].position).to(explodeSite.position, 4000).easing( TWEEN.Easing.Quartic.In);
tweenLaunch.start();
}
There may be a more elegant way to do this and I will be working to clean up the code where possible but this does work.