I'm new to graphics and was wondering how I would go about creating an object boundary for my game.
Right now I have an object following my mouse. This works fine for my boundary when my ship has a rotation.z of 0. However, when I rotate the ship, the boundary has odd behavior.
I tried getting the world position of the ship and simply checking the x and y boundaries. However, the world position seems to give me a different x and y when I rotate. How can I
go about creating a boundary that works for all the rotations of my ship.
Here's my game(collisions turned off for purpose of help): http://www.cis.gvsu.edu/~chaua/CS371/WebGLProject/home.html
The behavior I'd like occurs when you don't rotate the ship.
Rotate the ship with left/right mouse.
Relevant code snippets(in render loop):
if(mouseLeftDown)
ship.rotation.z += leanSpeed;
if(mouseRightDown)
ship.rotation.z += -leanSpeed;
....
....
targetX = ((lastMouseX / window.innerWidth) * 2 - 1) * 90;
targetY = -((lastMouseY / window.innerHeight) * 2 - 1) * 60;
var worldPosition = (new THREE.Vector3()).getPositionFromMatrix(ship.matrixWorld);
if(worldPosition.x + targetX <= (randSpawnWidth/2)-500 && worldPosition.x + targetX >= -(randSpawnWidth/2)+500)
ship.translateX(targetX);
if(worldPosition.y + targetY <= (randSpawnHeight/2)-500 && worldPosition.y + targetY >= -(randSpawnHeight/2)+500)
ship.translateY(targetY);
I would appreciate any help. Thanks!
Related
the drawing algorithm which I currently use:
a_max = Pi*2 (float)(num_segments - 1.0f)/(float)num_segments;
for (unsigned int i = 0; i<=num_segments;i++)
{
const float a = (float)i / (float)num_segments * a_max;
SetPixel(centre.x + cos(a) *radius, centre.y +sin(a) *radius);
}
Works fine, but it starts drawing at (centre.x+radius, centre.y). I would like to have it to start at the top , because I want to draw a compass and zero degree is at the top, not on the right, so that I don't have to make a hacky solution.
Try rotating 90 degrees to the left before you start drawing, this should solve it for you.
A compass not only starts at "north" instead of "east" but also goes clockwise instead of counter-clockwise.
For this case, just swap sin(a) and cos(a):
x = centre.x + sin(a) * radius
y = centre.y + cos(a) * radius
I'm not sure what to search for or how to ask the question as I can't draw. Please bear with me.
If I have a rectangle with circular end caps. I want to remove some of the edges of the rectangle so there is a smooth path all round. Kinda like of you were to stretch the ends, the middle gets thinner.
I was trying to work out the chord of a larger, outer circle until I got stuck trying to work out where the circles should touch.
I can see some relationships for trigonometry, but my brain just won't go the extra mile.
Can anyone please help point me in the right direction.
Thanks.
Here is the answer:
// Small value for CSG
Delta = 0.01;
2Delta = 2 * Delta;
$fa=1; $fs=$fa;
module roudedArm(xl=50, yt=10, zh=5, in=2, bh=0.8) {
EndRadius = yt/2; // size of outer ends
EndSpacing = xl-yt; // distance between end point radii
ArmConcavity = in; // how much in does it go in on each side
ArmThickness = zh; // height in z
// Negative curve to narrow the Arm (calculated by pythagoras)
ArmCurveRadius = (pow((EndSpacing / 2), 2) - 2 * EndRadius * ArmConcavity + pow(ArmConcavity, 2)) / (2 * ArmConcavity);
// The orthogonal distance between the middle of the Arm the point it touches the round pillar sections
ArmSectionLength = (EndSpacing / 2) * ArmCurveRadius / (ArmCurveRadius + EndRadius);
// end points
lbxcylinder(r=EndRadius, h=ArmThickness);
translate([EndSpacing, 0, 0]) lbxcylinder(r=EndRadius, h=ArmThickness);
// inner curve
difference()
{
translate([EndSpacing / 2 - ArmSectionLength, -EndRadius -ArmThickness, 0])
translate([ArmSectionLength, (EndRadius + ArmThickness),0])
lbxcube([ArmSectionLength * 2, 2 * (EndRadius + ArmThickness), ArmThickness], bh=bh);
// Cut out Arm curve
translate([EndSpacing / 2, ArmCurveRadius + EndRadius - ArmConcavity, -Delta])
lbxcylinder(r = ArmCurveRadius, h = ArmThickness + 2Delta, bh=-bh);
translate([EndSpacing / 2, -(ArmCurveRadius + EndRadius - ArmConcavity), -Delta])
lbxcylinder(r = ArmCurveRadius, h = ArmThickness + 2Delta, bh=-bh);
}
}
module lbxcube(size, bh=0.8) {
// don't support bevelling in demo
translate([-size[0]/2, -size[1]/2, 0]) cube(size);
}
module lbxcylinder(r, h, bh=0.8) {
// don't support bevelling in demo
cylinder(r=r, h=h);
}
roudedArm(xl=50, yt=10, zh=5, in=2, bh=0.8);
Thanks to Rupert and his Curvy Door Handle on Thingiverse.
I am learning game programming with Phaser and I am currently building a simple breakout game.
When the ball hits the paddle I use the following code to determine the new x velocity of the ball:
if (ball.x < paddle.x)
{
// Ball is on the left-hand side of the paddle
diff = paddle.x - ball.x;
ball.body.velocity.x = (-10 * diff);
}
else if (ball.x > paddle.x)
{
// Ball is on the right-hand side of the paddle
diff = ball.x -paddle.x;
ball.body.velocity.x = (10 * diff);
}
else
{
// Ball is perfectly in the middle
// Add a little random X to stop it bouncing straight up!
ball.body.velocity.x = 2 + Math.random() * 8;
}
This code is originally taken I believe from stackoverflow, although I cannot remember from which post I'm afraid.
The problem with this is that when the ball goes left or right at an angle, it appears faster on screen than if it goes straight up. The more pronounced the angle, the faster it goes and appears.
Does anyone know how to solve this problem?
Regards
Crouz
The speed of the ball is given by a combination of the horizontal (x) speed and vertical (y) speed, as given by Pythagoras' theorem:
z2 = x2 + y2
where overall speed would be z.
If you increase x without decreasing y appropriately, then the overall speed will also increase.
If you want the speed to remain the same, then you need to adjust y as well. Example pseudo-code:
speed = sqrt(x^2 + y^2)
x = 2 + random()*8
y = sqrt(speed^2 - x^2)
You could incorporate this into your code by calculating speed before any adjustments are made, and then adjusting y afterwards:
// Calculate overall speed
var speed = Math.sqrt(
Math.pow(ball.body.velocity.x, 2) +
Math.pow(ball.body.velocity.y, 2)
);
if (ball.x < paddle.x)
{
// Ball is on the left-hand side of the paddle
diff = paddle.x - ball.x;
ball.body.velocity.x = (-10 * diff);
}
else if (ball.x > paddle.x)
{
// Ball is on the right-hand side of the paddle
diff = ball.x -paddle.x;
ball.body.velocity.x = (10 * diff);
}
else
{
// Ball is perfectly in the middle
// Add a little random X to stop it bouncing straight up!
ball.body.velocity.x = 2 + Math.random() * 8;
}
// Adjust y to maintain same overall speed
ball.body.velocity.y = Math.sqrt(
Math.pow(speed, 2) -
Math.pow(ball.body.velocity.x, 2)
);
This will always result in a positive y, so you might need to negate it depending on which direction (up or down) you want it to be moving.
Given a line made up of several points, how do I make the line smoother/ curvier/ softer through adding intermediate points -- while keeping the original points completely intact and unmoved?
To illustrate, I want to go from the above to the below in this illustration:
Note how in the above picture, if we start at the bottom there will be a sharper right turn. In the bottom image however, this sharp right turn is made a bit "softer" by adding an intermediate point which is positioned in the middle of the two points, and using averages of the angles of the other lines. (Differently put, imagine the lines a race car would drive, as it couldn't abruptly change direction.) Note how, however, none of the original points was "touched", I just added more points.
Thanks!! For what it's worth, I'm implementing this using JavaScript and Canvas.
with each edge (e1 & e2) adjacent to each 'middle' edge (me) do
let X = 0.5 x length(me)
find 2 cubic bezier control points by extending the adjacent edges by X (see algorithm below)
get midpoint of cubic bezier (by applying formula below)
insert new 'midpoint' between me's two coordinates.
FloatPoint ExtendLine(const FloatPoint A, const FloatPoint B, single distance)
{
FloatPoint newB;
float lenAB = sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
newB.X = B.x - (B.x - A.x) / lenAB * distance;
newB.Y = B.Y - (B.Y - A.Y) / lenAB * distance;
return newB;
}
Edit: Formula for Bezier Curve midpoint: p(0.5) = 0.125(p0) + 0.375(p1) + 0.375(p2) + 0.125(p3)
The following code found elsewhere here does the job for me, in the specific context of JavaScript-Canvas which I'm using -- but please see Angus' answer for a more general approach:
var max = points.length;
context.beginPath();
var i = 0;
context.moveTo(points[i].x, points[i].y);
for (i = 1; i < max - 2; i++) {
var xc = (points[i].x + points[i + 1].x) * .5;
var yc = (points[i].y + points[i + 1].y) * .5;
context.quadraticCurveTo(points[i].x, points[i].y, xc, yc);
}
context.quadraticCurveTo(points[max - 2].x, points[max - 2].y, points[max - 1].x,points[max - 1].y);
context.closePath();
context.stroke();
I'm trying to figure out the right way to continuously animate the frameRotation of a layer-backed NSView.
In particular, I'm basically trying to re-create how the new Launchpad animates when you click and hold an icon. The event handling isn't the problem, it's the actual repeating animation.
So far, I've used NSTimer to animate the frameRotation back and forth using the view's animator proxy. While this works, it seems to be resource intensive and I'm sure NSAnimation could be used for this.
I'm just wondering if someone can point me in the right direction here.
EDIT: This doc here: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/AnimationGuide/Articles/ViewAnimations.html#//apple_ref/doc/uid/TP40003593-DontLinkElementID_7
only discusses the view's frame rect and alpha value. So I'm not sure how to use this for frameRotation
Kind regards,
Alec
Simple answer is you can't with NSViewAnimation, but you can with CABasicAnimation.
Here is what I came up with:
Add this animation to the view's layer:
- (CABasicAnimation *)rockingAnimation {
float diff = 0.065 - .055;
float startValue = (((float) (arc4random() % ((unsigned)RAND_MAX + 1)) / RAND_MAX) * diff) + 0.055;
float endValue = (((float) (arc4random() % ((unsigned)RAND_MAX + 1)) / RAND_MAX) * diff) - 0.055;
float duration = (((float) (arc4random() % ((unsigned)RAND_MAX + 1)) / RAND_MAX) * diff) + 0.085;
CABasicAnimation *rockAnimation = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
[rockAnimation setFromValue:[NSNumber numberWithFloat:startValue]];
[rockAnimation setToValue:[NSNumber numberWithFloat:endValue]];
[rockAnimation setDuration:duration];
[rockAnimation setRemovedOnCompletion:YES];
[rockAnimation setFillMode:kCAFillModeForwards];
[rockAnimation setAutoreverses:YES];
[rockAnimation setRepeatCount:10000];
return rockAnimation;
}
This gets a pretty good result.