I want to rotate a JavaFX node 90 degrees in an animation along the y-axis.
public void rotateNode(Node node)
{
RotateTransition rotateTransition = new RotateTransition(Duration.seconds(3), node);
rotateTransition.setAxis(Rotate.Y_AXIS);
rotateTransition.setFromAngle(0);
rotateTransition.setToAngle(90);
rotateTransition.play();
}
That works fine, but actually I want the node to turn in the opposite direction so -90 degrees.
That's why I changed the line:
rotateTransition.setToAngle(90);
to
rotateTransition.setToAngle(-90);
but the node is still turning in the same direction.
Does somebody has any idea how to slove this problem.
Thanks
Related
I am trying to develop basic enemy AI on a simple platformer game after following Shaun Spalding's gamemaker 2 platformer tutorials on youtube. My code is the exact same as his on the tutorial but for some reason, when my enemy detects collision with the wall he turns around as he is suppose to and then detects another collision where there is none, causing him to turn around again.
This is my code:
// Horizontal collision
if (place_meeting(x+hsp, y, oWall)) {
show_debug_message(hsp)
while (!place_meeting(x+sign(hsp), y, oWall)) {
x += sign(hsp); // slows down I think
}
hsp = -hsp;
}
x += hsp;
The -hsp part is where he turns around. Somehow, he is detecting another collision as soon as he does so, even though the value of hsp is inverted. Can anyone possibly point me in the direction of why this may be occuring?
(Value of hsp initialized at 3 and never changed only for inversion).
Is it turning back to the wall after a short while, or is it stuck and is flickering to left and right rapidly? Both could involve that the collision point isn't updating well.
When I face with collision problems, I'll use a crosshair sprite, and draw it at the same position as where it should be colliding. that way I've a visible view of the 'collision point'.
Another cause could be the sprite's origin point, that determines at which position the x and y appears, and that the sprite by turning collides with the wall itself. Keep in mind that the origin point is at the center of it's collision mask, to avoid been stuck in a wall.
EDIT: Another possibility: the collision point still checks inside the sprite.
For that, you could also try using an offset that keeps the collision point away from the sprite collision, but to let that work, you'll need to keep the inverse direction away from your horizontal speed. Something like this:
// Horizontal collision
_offset = 15; //moves the collision point away to check in front of the sprite. value depends on the size of the sprite.
_dir = 1; //the direction, should only be 1 or -1
//hsp should no longer be used to inverse, use a new variable (like _dir) instead
collisionPoint = (hsp + offset) * _dir;
if (place_meeting(x + collisionPoint , y, oWall)) {
show_debug_message(collisionPoint)
while (!place_meeting(x+sign(collisionPoint), y, oWall)) {
x += sign(collisionPoint); // slows down I think
}
_dir = -_dir
}
x += hsp * _dir;
I am developing a game in cocos2d-x which has a ball sprite in it. I move the ball on a surface(wall) via touch events. Is it possible to rotate the ball naturally according to its velocity?
if i use ballSprite->runAction(..) in update(float dt) method then it doesn't rotate.
i use the following code:
void GameLayer::updateBall(float dt)
{
float deltaRotateX = 360.0f * _ballVelocityX;
_ballSprite->setRotation(90.0f- CC_RADIANS_TO_DEGREES(deltaRotateX));
}
But the ball doesn't naturally rotate. it discretely rotates.
it can't naturally rotate according to its velocity.
Thanks.
You question could mean a few things. Do you want to ball rotate while "rolling" on a surface? Do you want the ball to always rotate depending on the velocity it's moving at? Do you want the ball to rotate a certain way after bouncing off the wall? all of these have separate answers.
For your question I will assume that you want to drag the ball on your wall, and it must "roll" as it's moving. To achieve this behavior would be difficult to couple with velocity since you are "dragging" the ball and it's not being moved based on motion. So I would just update my rotation of my sprite with the delta the ball moved in my onTouchMoved function.
ballSprite->setRotation(ballSprite->getRotation() + touch->getDelta().distance);
This will cause your sprite to rotate as the player drags it across the screen.
try this,
Vec2 _lastBallPosition;//Declare this in your header file, it represents the las position of your ball
void GameLayer::updateBall(float dt)
{
if (!_lastBallPosition.equals(getPosition())) {
Vec2 delta=getPosition()-_lastBallPosition;
setRotation(getRotation()+ delta.length());
_lastBallPosition=getPosition();
}
}
Use CCPoint instead of Vec2 if your cocos2dx version is < 3.0
What is the proper way to add a sphere constraint to a cloth sim?
I am trying to add a sphere (or capsule) constraing to Skeel Lee's cloth simulation source code, but I am not sure how to do it properly.
I created a rather simple constraint which "kicks" the particle back out of the sphere in the opposite direction (opposite from the vector towards the center):
void SatisfySphereConstraints()
{
foreach (var simObj in this.simObjects)
simObj.CurrPosition += SphereConstraint(simObj.CurrPosition, _center, _radius);
}
Vector3 SphereConstraint(Vector3 position, Vector3 center, float radius)
{
var delta = position - center;
var distance = delta.Length();
if (distance < radius)
return (radius - distance) * delta / distance;
return Vector3.Zero;
}
And then I inserted the method in the existing code:
ApplyForces();
Integrate();
for (var i = 0; i < constraintIterations; i++)
{
foreach (Constraint constraint in constraints)
constraint.SatisfyConstraint();
SatisfySphereConstraints(); // <-- I added it here
}
The collision code works fairly well for situations like this (C is the center of the sphere, P is the current particle position, P' is the resolved position):
But the problem occurs if particles are moving very quickly, because then the particle basically jumps to the other side of the sphere (P1 is the previous position, P2 is the current position, P' is how I think it should be resolved), instead of returning back to the previous position:
Since this is a cloth simulation, the cloth basically jumps over the sphere in that case, instead of being "stopped" by the sphere.
Now, I could try to return in the direction of the previous point, but since the sphere might also be moving, I am not sure if P1 is even a valid position (and if it will make sense). Also, it seems to be more computationally expensive - is this how I am supposed to do it, or not?
Cloth like things snapping to the wrong side of an obstacle and getting stuck there is not too uncommon. Even more common is fast moving objects overlapping way too much when the collision is detected.
A common solution is, on detecting a collision, sub divide the previous step until the collision is less severe and then resolve it. I think you will find trying to detect how deep the collision is to be difficult in your case, but if you could limit the top speed of spheres in your system you could binary split the frames in which collisions occur a fixed number of times and assume it will be good enough?
if (it collides at time T and didn't at T-1)
if (it collides at T-0.5)
try T-0.75
else
try T-0.25
etc...
Are you prepared to accept that it will sometimes be wrong, or does it have to be always a good result?
I've searched far and wide, so if there's a similar question please forgive me but I just couldn't find it.
To put what I'm trying to do in context: I want to create an infinitely-generated field of stars that disappear as they go offscreen and reappear at the edge of the screen where the camera is moving. I'm working with a top-down view, so it must be pretty simple to achieve this, but alas I haven't a clue.
I'm using the following code to determine whether a star has gone off-screen and then replace it:
//update camera frustum
camera.projScreenMatrix.multiplyMatrices(
camera.projectionMatrix,
camera.matrixWorldInverse
);
camera.frustum.setFromMatrix(camera.projScreenMatrix);
//loop through stars
var stars=scene.stars.geometry.vertices;
for(var i=0;i<stars.length;i++) {
if(!camera.frustum.containsPoint(stars[i])) {
stars[i]=new THREE.Vector3(
// fill in the blank
);
scene.stars.geometry.verticesNeedUpdate=true;
}
}
Since I'm using a perspective camera, I know I'll need to somehow factor in camera.fov and other perspective elements, but as you can tell I'm no expert on the third dimension.
Assuming I have an angle or normalized vector telling me the direction the view is panning, how would I go about creating a vertex along the edge of the screen regardless of its Z position?
If I'm not clear enough, I'll be happy to clarify. Thanks.
I know this is an old question, but I came across it while looking for an answer and found a simple, trigonometry reliant method to get the left edge of the camera frustum, and I'm sharing it in case someone else might find it useful:
// Get half of the cameras field of view angle in radians
var fov = camera.fov / 180 * Math.PI / 2;
// Get the adjacent to calculate the opposite
// This assumes you are looking at the scene
var adjacent = camera.position.distanceTo( scene.position );
// Use trig to get the leftmost point (tangent = o / a)
var left = Math.tan( fov ) * adjacent * camera.aspect;
Basically, this gets the leftmost point, but if you don't multiply by the aspect ratio you should get a point in a circle around your camera frustum, so you could translate a point any direction away from the cameras focus and it would always be outside the frustum.
It works by assuming that the imaginary plane that is the camera is perpendicular to the line connecting the camera and its focus, so there is a straight angle. This should work if you want objects further away as well (so if you want them at a further point from the camera you just need to increase the distance between the focus and the camera).
Well, countless headaches and another question later, I've come up with a fairly makeshift answer. Just in case by some unlikely chance someone else has the same question, the following function plots a point on the scene relative to the camera's current view with whatever Z specified:
//only needs to be defined once
var projector=new THREE.Projector();
//input THREE.Vector3
function(vector) {
var z=vector.z;
vector.z=0;
projector.unprojectVector(vector,camera);
return camera.position.clone().add(
vector
.sub(camera.position)
.normalize()
.multiplyScalar(
-(camera.position.z-z)/vector.z
)
);
The x and y, in this case, both range from -1 to 1 for bottom-left to top-right. You can use position/window.Width and position/window.Height for extra precision (using mouse coordinates or what have you).
I'm trying to make a circle out of a Polygon (I know I could just use for example the shape renderer, but I need it like this).
The circle should consist out of 4 Nodes and 4 curved Edges.The nodes are rendered by a ShapeRenderer and are positioned like a "+", the edges by an edge renderer to curve them. Right now I have the problem, that the edges enter all the nodes on the sides, which is OK for the top and bottom node, but does not work for the left and the right node as they should enter the nodes on top and the bottom, and so I don't get a perfect circle but more something egg-shaped.
Does anybody know how I can change the position the edges enter the nodes or how to rotate this nodes for 90 degrees?
The method to set control points in EdgeRenderer looks very simple:
protected void getCurveControlPoints(EdgeItem eitem, Point2D[] cp,
double x1, double y1, double x2, double y2)
{
double dx = x2-x1, dy = y2-y1;
cp[0].setLocation(x1+2*dx/3,y1);
cp[1].setLocation(x2-dx/8,y2-dy/8);
}
Probably, you have to override it to set achieve the curve you want.
Please share your solution here for other, if that is the case.
OK, i was trying some stuff and came up mwith the following:
protected void getCurveControlPoints(EdgeItem eitem, Point2D[] cp,
double x1, double y1, double x2, double y2)
{
double dx = x2-x1, dy = y2-y1;
// cp[0].setLocation(x1+2*dx/3,y1);
// cp[1].setLocation(x2-dx/8,y2-dy/8);
cp[0].setLocation(x1+2*dx/3,y1);
cp[1].setLocation(x2,y2-dy/3);
}
This works for me, i'm not sure if it is a perfect circle, but i can't spot a difference.
I also dont really understand why it works, because I add 2*dx/3 to x1, but substracted only dy/3 from y2. Does anybody have a clue why this works?