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.
Related
I'm creating a script that rotates a THREE.js camera arround based on a mobile phones gyroscope input. It's currently working pretty well, except that every time I rotate my phone over a quadrant, the camera will turn 180 degrees instead of continuing as intended. This is the code that I currently use:
private onDeviceOrientation = ( event ) => {
if( event.alpha !== null && event.beta !== null && event.gamma !== null ) {
let rotation = [
event.beta,
event.alpha,
event.gamma
],
this.orientation = new THREE.Vector3(rotation[0], rotation[1], rotation[2]);
this.viewer.navigation.setTarget(this.calcPosition());
}
};
private calcPosition = () => {
const camPosition = this.viewer.navigation.getPosition(),
radians = Math.PI / 180,
aAngle = radians * - this.orientation.y,
bAngle = radians * + this.orientation.z,
distance = this.calcDistance();
let medianX = Math.cos(bAngle) * Math.sin(aAngle);
let medianY = Math.cos(bAngle) * Math.cos(aAngle);
let nX = camPosition.x + (medianX * distance),
nY = camPosition.y + (medianY * distance),
nZ = camPosition.z + Math.sin(bAngle) * distance;
return new THREE.Vector3(nX, nY, nZ);
};
window.addEventListener('deviceorientation', this.onDeviceOrientation, false);
Soafter doing some research I found that I need to use a Quaternion prevent the switchen when going into a new quadrant. I have no experience with Quaternions, so I was wondering what the best way would be to combine the two Vector3's in the code above into a singel Quaternion.
[Edit]
I calculate the distance using this method:
private calcDistance = (): number => {
const camPosition = this.viewer.navigation.getPosition();
const curTarget = this.viewer.navigation.getTarget();
let nX = camPosition.x - curTarget.x,
nY = camPosition.y - curTarget.y,
nZ = camPosition.z - curTarget.z;
return Math.sqrt((nX * nX) + (nY * nY) + (nZ * nZ));from squared averages
};
And I follow the MDN conventions when working with the gyroscope.
[Edit #2]
Turns out I had my angle all wrong, I managed to fix it by calculating the final position like this:
let nX = camPosition.x - (Math.cos(zAngle) * Math.sin(yAngle)) * distance,
nY = camPosition.y + (Math.cos(zAngle) * Math.cos(yAngle)) * distance,
nZ = camPosition.z - (Math.cos(xAngle) * Math.sin(zAngle)) * distance;
Here is the closest I can give you to an answer:
First of all, you don't need a quaternion. (If you really find yourself needing to convert between Euler angles and quaternions, it is possible as long as you have all the axis conventions down pat.) The Euler angle orientation information you obtain from the device is sufficient to represent any rotation without ambiguity; if you were calculating angular velocities, I'd agree that you want to avoid Euler angles since there are some orientations in which the rates of change of the Euler angles go to infinity. But you're not, so you don't need it.
I'm going to try to summarize the underlying problem you're trying to solve, and then tell you why it might not be solvable. 🙁
You are given the full orientation of the device with a camera, as yaw, pitch, and roll. Assuming yaw is like panning the camera horizontally, and pitch is like tilting the camera vertically, then roll is a degree of freedom that doesn't change affect direction the camera is pointing, but it does affect the orientation of the images the camera sees. So you are given three coordinates, where two have to do with the direction the camera is pointing, and one does not.
You are trying to output this information to the camera controller but you are only allowed to specify the target location, which is the point in space that the camera is looking. This is to be specified via three Cartesian coordinates, which you can calculate from the direction the camera is pointing (2 degrees of freedom) and the distance to the target object (one degree of freedom).
So you have three inputs and three outputs, but only two of those have anything to do with each other. The target location has no way to represent the roll direction of the camera, and the orientation of the camera has no way to represent the distance to some target object.
Since you don't have a real target object, you can just pick an arbitrary fixed distance (1, for example) and use it. You certainly don't have anything from which to calculate it... if I follow your code, you are defining distance in terms of the target location, which is itself defined in terms of the distance from the previous step. This is extra work for no benefit at best (the distance drifts around some initial value), and numerically unstable at worst (the distance drifts toward zero and you lose precision or get infinities). Just use a fixed value for distance and make it simple.
So now you probably have a system that points a camera in a direction, but you cannot tell it what the roll angle is. That means your camera controller is apparently just going to choose it for you based on the yaw and pitch angles. Let's say it always picks zero degrees (that would be the least crazy thing it could do). This will cause discontinuities when the roll angle and yaw angle line up (when the pitch is at ±90°): Imagine pointing a physical camera at the northern horizon and yawing around westward, past the western horizon, and settling on the southern horizon. The whole time, the roll angle of the camera is 0°, so there's no problem. But now imagine pointing it at the northern horizon, and pitching upward, past the zenith, and continuing to pitch backward until you are facing the southern horizon. Now the camera is upside down; the roll angle is 180°. But if the camera controller doesn't change the roll angle from 0°, then it will do a nonphysical "flip" right when you pass the zenith. The problem is that there really is no way to synthesize a roll angle based purely on position and not have this happen. We've just demonstrated that there are two ways to move your camera from pointing north to pointing south, where the roll angle is completely different at the end.
So you're stuck, I guess. Well, maybe not. Can you rotate the image from the camera based on the roll angle of the device orientation? That is, add the roll back into the displayed image? If so, you may have a solution. Let's say the roll angle of the camera controller is always at zero. Then you just rotate the image by the desired roll angle (something derived from beta I guess?) and you're done. If the camera controller has some other convention for choosing the roll angle, you will need to figure that out, undo it, and add the roll angle back on.
Without the actual system in front of me I probably can't help you debug your way to a solution. So I think this is where my journey with this question must end. Good luck!
Summary:
You don't need a quaternion
Pick a fixed distance to your simulated target
Add the roll angle by rotating the image before displaying it
Good luck!
I am working on creating a simple snow simulation, but I am failing horribly on the math. Basically, when a snowflake is initialized, it's x position is set randomly somewhere on the svg canvas. Then from there, it falls straight down. It should be simulating a sine wave (the x coordinates should move like a sine wave).
I haven't done trig since last year so i'm a bit rusty. Math.sin() takes radians I believe, so I multiply by 180, then divide by pi to convert to degrees?
Assume x is the current x position of a snowflake, and width is the width of the canvas.
x += (Math.sin(((x/width)*(180/Math.PI)))*width)
It kind of works, but it is all over the place. I have a vague idea of what i'm doing, but I can't seem to push the math from my brain to code.
Here's a JSFiddle:
What am I doing incorrectly?
It should be:
x += A*Math.sin(F*(y/Height)*2*Math.PI);
where A is the amplitude, i.e. how many pixels you want the flake to shift left and right (note that total shift will be 2*A). F is the frequency, or how often you want the flake to shift left and right (I'd set it at random between 2 and 10 for each flake).
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
I have recently started playing with canvas after seeing how easy it can be. My first project was just to keep a circle in its boundaries as it moves around. I made a few more things involving the movement of circles and now...
I'm currently working on bouncing two circles off of each other when they hit. You can see the example of that here: http://jsfiddle.net/shawn31313/QQMgm/7/
However, I would like to use a little more real world physics. At the moment, when the circles hit each other they just reverse their path.
As shown here:
// Dont be confused, this is just the Distance Formula
// We compare the distance of the two circles centers to the sum of the radii of the two
// circles. This is because we want to check when they hit each other on the surface
// and not the center.
var distance = Math.sqrt(Math.pow(c1.x - c2.x, 2) + Math.pow(c1.y - c2.y, 2));
var r1 = c1.rad;
var r2 = c2.rad;
if (distance < r1 + r2) {
// Change the slope of both circle
// I would like to figure out a more effecience way of bouncing the circles back
// However, I have no idea how to determine the angle the ball was struck,
// and with that information bounce it off at that angle
c1.xi = -c1.xi; // path is reversed
c1.yi = -c1.yi;
c2.xi = -c1.xi;
c2.yi = -c1.yi;
}
However, I would like the circles to go in opposite direction determined by the point and angle of intersection.
I am only in the 9th grade and not sure how the formula for something like this would look. But I know that it is possible because this kind of physics is present in many games. An example would be an 8-ball game. When the balls hit each other, they move across the table according to how the balls hit each other.
I would appreciate any tips on how to do this or if I should wait until I have a stronger understanding of Physics and Math in general.
too bad we can't draw a very simple scheme.
As far as physics is concerned, you know that the total momentum is conserved, see
http://en.wikipedia.org/wiki/Momentum
There is a good illustration and formulas here http://en.wikipedia.org/wiki/Elastic_collision#Two-_and_three-dimensional
You can simplify formulas if the two object have the same weight.
so now, let's consider the reference frame in which c2 is fixed and center in (0,0).
c1 velocity in this reference would be :
c1.xfi=c1.xi-c2.xi
c1.yfi=c1.yi-c2.yi
Now you have a collision when the distance between the two is the sum of radius. Consider the tangent plane of the two circles.
You now have to decompose the velocity of c1 into a tangent component, which is conserved, and a perpendicular (following the line between c1 and c2), which is transfered to c2.
Then you need to go back to your original reference frame.
(sorry i didn't give you the exact formulas but they are on the links I provided)
If I were doing this myself, I would implement the motion using Newtons law of restitution. Essentially this is a coefficient that relates approach and separation speed of 2 particles before/after impact and it has a value that depends on the material properties of your particles.
Your analysis will essentially amount to identifying the point of impact, then breaking down the approach velocities into components that are parallel and perpendicular to the line of centres of the circle at the point of impact.
The momentum of the particles is conserved perpendicular to the line of centres (so the velocities in that direction remain unchanged by the collision) and the law of restitution applies to the velocities parallel to the line of centres. Thus if you fix the coefficient of restitution (it has to be between 0 and 1) to some value of your choice you can use this law to calculate the separation speeds along the line of centres of your particles after collision using the value of the approach speeds.
If your particles are all of the same mass and radius then the calculations become simpler. You can model elastic collisions by setting the coefficient to 1 (this indicates that separation speed of the particles is the same as the approach speed) which is probably the easiest place to start. By changing the value you will see different behaviour between particles after collisions.
Sorry not to be able to write this all down in formula for you, but this is not really the appropriate place for it. Living in the UK I have no idea what "9th grade" is so I can't assess if the above is too advanced for your current level of education. Here in the UK this type of problem would typically be covered at A-level mathematics education level.
Hopefully though it will give you an indication of the terms and topics that you can teach yourself/ research in order to achieve your goal.
I am trying to recreate this, and I have been fairly successful. I am having issues with the collision handling though. Although the collision handling seems to work, it has very strange behavior. Here is what I have so far. This is the code that handles collisions:
var dx = particle2.getX() - particle1.getX();
var dy = particle2.getY() - particle1.getY();
var angle = Math.atan2(dy, dx);
var newP2X = particle1.getX() + (particle1.getRadius() + particle2.getRadius()) * Math.cos(angle);
var newP2Y = particle1.getY() + (particle1.getRadius() + particle2.getRadius()) * Math.sin(angle);
particle2.setX(newP2X);
particle2.setY(newP2Y);
var p1Vxi = particle1.getVx();
var p1Vyi = particle1.getVy();
var p1Mass = particle1.getMass();
var p2Vxi = particle2.getVx();
var p2Vyi = particle2.getVy();
var p2Mass = particle2.getMass();
var vxf = (p1Mass * p1Vxi + p2Mass * p2Vxi) / (p1Mass + p2Mass);
var vyf = (p1Mass * p1Vyi + p2Mass * p2Vyi) / (p1Mass + p2Mass);
particle1.setVx(vxf);
particle1.setVy(vyf);
particle2.setVx(vxf);
particle2.setVy(vyf);
EDIT: I have tried to change it to inelastic collisions like suggested, but for some reason the balls collide erratically. Check it out here.
Any help is much appreciated!
First, intuitively, imagine throwing a beanbag onto a frozen pond. It hits, doesn't bounce at all (loses whatever vertical velocity it had), and slides along with the same transverse velocity it had. That's the kind of collision we're trying for.
Now the physics. Moving reference frames. A North-bound train passes a barn. In the reference frame of the farmer in the barn, the barn is stationary and the train is moving North (0˚) at 10 m/s. In the reference frame of a passenger in the train, the train is stationary and the barn is moving South (180˚) at 10 m/s. A bicyclist is riding East (90˚) at 5 m/s (in the farmer's reference frame); in the bicyclist's frame, the bicycle is stationary, the barn is moving West (270˚) at 5 m/s and the train is moving at 11.18 m/s, bearing 333.4˚. We can convert between different frames with ease.
Two things are colliding. The frame we are interested in is the frame in which total momentum is zero. This called the Center-of-Mass Frame. If the two masses are m1 and m2, and the velocities are v1 and v2, then the velocity of the center of mass (a point that is stationary in the center-of-mass frame, like the bicycle in the bicyclist's frame) is (m1v1 + m2v2)/(m1 + m2). We calculate the velocities of the two objects in this frame and proceed.
The objects collide. We draw a plane of contact-- in this case a line tangent to both circles at the moment of contact. This is an instantaneous construct, the same in all reference frames (that don't involve rotation). In the center-of-mass frame, each object will act as if this boundary were a stationary solid surface-- in this case a sheet of ice, with no bouncing. So we divide the velocity vector into two components, the one parallel to the surface of the ice and the one normal (perpendicular) to it; we retain the first and discard the second.
Then we convert back into the barn frame and we're done.