I'm working with a game where you juggle a ball and to keep the ball in the air you need to apply forces to the ball.
I'm thinking if you touch right under the ball (180 degrees) and the maximum radius the more power you will kick away with the ball. So for an example if you touch the ball at 160 degrees and radius 6 you will be given less power than if you hit the ball at 170 degrees and radius 8,5.
How should I tackle it?
I would start by using several values:
Direction(int). on the right side direction is defined as 0, top 90,left 180,bottom 270; You can use it to describe an angle.
Force(double). a constant value to describe how much force is applied.
Point(int,int) to describe a point on your canvas.
~~~~~~~~~~~~~~~~~~~~~~~~~~
You can then add several useful calculations as:
int Distance(Point,Point): Math.hypot(x1-x2,y1-y2) [This is the source code giving the distance between two points]
The final movement can be done in several ways. I'd probably do it like this:
Per Tick:
Get current force. Add gravity force (9.81 in angle 270)
Per Click:
Take the position of the click and the position of the ball.
Calculate distance.
Calculate angle (Trigonometrics)
Finally calculate the force and add it.
How to add force?
Take angle.
Take "power".
Use more trigonometrics to calculate this.
I hope this helped you a bit. Sry for the format
Related
I am making a game, and I got the player to move, but when the player turns at a diagonal (Up, then up-right, for example), it's not as smooth as I want it to be.
Here's a picture showing the issue:
The player lines indicate the player's path.
How can I achieve this effect?
I'm thinking of maybe generating a bezier curve for the player to follow, but I don't know how I would get the player to follow it.
You are correct in your assumption of using a bezier curve. I would suggest (if you don't have it already) writing an Update method which you use to control the player movement on a frame-by-frame basis. In other words; a method which runs in a separate thread and triggers position updates for the player you want to move along the curve. It would act as a queue, only executing movements etc when a given amount of time has elapsed.
As for how to get the player to move along the curve, I would calculate multiple points along the curve, let's say 25 per curve. Have each point, point to the next point. These will act like waypoints - the player is given the instruction to move to the next waypoint over a short amount of time. So if you wanted to move your player along the whole curve within 5 seconds, the player would need to 'jump' from one waypoint to another every 0.2 seconds.
If you wanted the movement to be less 'jerking', you would need to write linear interpolation which would in effect further calculate smaller divisions of waypoints between each of the curve waypoints.
You can find many helpful methods for the items described above, here
In the image below, the blue blobs are waypoints.
Alternative (Simpler) Curve Approach
An alternative approach to using a bezier curve is to do a very simple smooth curve: In the case of turning right; start off with two values- Xfactor = 0, and Yfactor = 10. For this example, I assume that the speed of movement around the curve is 10 units (it could be pixels for example). For each frame, you add Xfactor and Yfactor to the players current position. You also subtract a constant (let's say 0.5 units) from the Yfactor and add it to the Xfactor. You keep going until the Xfactor equals 10 and Yfactor equals 0. This should cause the player to 'move' through 90 degrees. In order to get the player to move through 45 degrees, you would keep going until the Xfactor equals 5, as this would be half of 10. To keep the player moving in that direction, you would need to keep adding the Xfactor and Yfactor to the player position on each frame/update. Again, to make the player turn, you change the Xfactor and Yfactor over time.
I want to launch projectiles from the bottom-right corner of the screen towards the left side of the screen. Now, I want the projectiles to fly with random velocities and angles according to the screen dimensions, just like that. Now, I know this is very simple but from some reason I can't manage to make this work.
Here is what I have tried so far:
My first try - Launch function
private void launchProjectile() {
projectiles.peek().getBody().applyForce(projectiles.peek().getBody().getWorldVector(new Vector2(MathUtils.random(-20,-1*SCALAR_HEIGHT),
MathUtils.random(2*SCALAR_HEIGHT,8*SCALAR_HEIGHT)).scl(MathUtils.random(3*SCALAR_HEIGHT,5*SCALAR_HEIGHT))),
projectiles.peek().getBody().getWorldCenter(), true);
Gdx.app.log("System", String.valueOf(SCALAR_HEIGHT));
}
Here is my second try - Launch function
private void launchProjectile() {
float xVelocity;
float yVelocity;
xVelocity = (float) MathUtils.random(0,0)*SCALAR_WIDTH/2;
yVelocity = (float) MathUtils.random(20,20)*SCALAR_HEIGHT;
velocityProjectile.set(xVelocity,yVelocity); // Sets the velocity vector to the above values
velocityProjectile.sub(projectiles.peek().getBody().getPosition());
velocityProjectile.nor(); // Normalize the vector - Now it's fine and ready!
// Sets the start velocity of the projectile Trajectory to the current velocity
projectiles.peek().getBody().setLinearVelocity(velocityProjectile.scl(18+SCALAR_HEIGHT));
}
In both tries, the projectile flies way more than I need and it doens't take in consideration the screen size like it should.
Can you guys please tell me what is the right way to do this?
Thanks!!
Start with this page: http://www.iforce2d.net/b2dtut/projected-trajectory
In the "How fast should it be launched to reach a desired height?" section, you can see how much vertical velocity will be required to make the projectile reach the top of the screen. So you would pick a random number less than that, to make sure it doesn't go off the top of the screen.
Next, in the "How high will it go?" section, you can see the formula to find out how many time steps it will take for the projectile to reach maximum height. It will then take the same amount of time to come back down to the starting height. For example, let's say it would take 60 time steps to reach maximum height. That means it would take 120 time steps to fall down again to the same height as it started. Then you can set the horizontal part of the launch velocity so that it cannot go outside the screen in 120 time steps.
I am making a side scroller shooting game. I currently have my character shooting horizontally to the right. I would like to get him shoot anywhere on the screen.
I understand that I should use atan2 to figure what angle my bullet will be shot at but I am confuse how to implement it into my game.
My question is how do I call my coordinates of the touch on the screen into atan2? Do I place this in my touch command codes or the class for my projectile. Lastly do I need to do another atan2 for speed?
First you need the vector of your player
P = (a, b)
And the position of your shooting point
T = (x, y)
This then gives us a vector from P to T, (x - a, y - b). By taking
angle = atan2 (y-b, x-a)
From there, it depends how you are implementing your shooting.
To reiterate, all atan2 does is finds the angle, so
do I need to do another atan2 for speed
depends on whether you want to have the projectile moving at a different speed depending on angle. In fact, you only really need the angle if you are rotating your projectile, otherwise you can just move it along the vector (if it is a circle, doesn't matter what way it is facing!)
You don't need any trigonometry and you should not use it, as it is slow, inaccurate and full of sign (+/-) cases to get wrong.
You can probably do everything you need with linear algebra. Use vectors, not angles.
I'm working on an Android game and would like to implement a 2D grid to visualize the effects of gravity on the playing field. I'd like to distort the grid based on various objects on my playing field. The effect I'm looking for is similar to the following from the Processing library:
Except that my grid will be simpler- 2D, and viewed strictly from the top, as if looking down at the playfield.
Can someone point me to an algorithm for drawing such a grid?
The one idea that I came up with was to draw the lines as if they were "particles"- start at one end of the screen and draw the line in multiple segments, treating each segment as a particle, calculating the effect of gravity at each segment's location.
The application is intended to run on Android.
Thanks
I would draw each line as a separate segment, as you mentioned. If the grid is sparse, it might be fastest.
If you are viewing the grid from above, you would need to calculate x and y coordinate displacements. The easiest way would be to actually do displacement along the z axis and then fake perspective with x_result = x/z and y_result = y/z . You set z=1 and make sure to vary it only relatively slightly (+- 0.1 for instance).
Your z should be proportional to the sum of 1/(distance to the sphere)^2. This simulates how gravity works - it tapers off with square of the distance. Great news - square of the distance means to calculate delta_x^2 + delta_y^2 - so you save yourself that square root calculation == faster.
Lets say I have an angle... what would be a reasonable way to go about finding the next point of where the ball would be?
Variables: bSpeed, bAngle, Ball.x, Ball.y
You knwon when you do c^2 = a^2 + b^2... is there a way you could find how long c^2 could be and actually "draw" it out and then use speed to go only part of that... with that find a^2 and b^2 so you can actually have a x and a y to draw the ball...
Thanks ahead of time! (BTW, I don't need code... just reasoning and wisdom)
Your 4 variables are effectively a vector - where the vector is a measure of both direction and magnitude/velocity (i.e. what you've represented as bSpeed and bAngle). Using this representation means that Ball.x and Ball.y simply become the horizontal and vertical components of the vector.
Given a vector called v1 we can calculate the movement in the x and y axis as follows...
xVelocityOfBall = v1.magnitude * cos(v1.angle);
yVelocityOfBall = v1.magnitude * sin(v1.angle);
GPWiki (Games Programming Wiki) is a great resource for anything maths/physics for games development. Here's a handy link to their vector page
delta_x = speed*cos(angle)
delta_y = speed*sin(angle)
new_x = x+delta_x
new_y = y+delta_y
and then you need just change speed and angle of ball in the case of wall strike)
Open up your textbooks on Sin, Cos and Tan since you're using bAngle. Specifically you'll probably be looking Sin for the vertical motion and Cos for the horizontal motion. Depending on where you've defined degree 0 to face.
Also, you could consider caching the horizontal and vertical speeds since Sin and Cos are expensive
You probably will need to consider the physics of the movement that the pong player is moving also. For example, if a player's paddle is speeding to the left as it contacts the ball, the ball will need to speed up wrt to the left direction. This represents transfer of momentum in physics. The general system of equations in the x and y directions will always be:
mass*velocity (in x) = the sum of the mass*velocity of all objects in x
mass*velocity (in y) = the sum of the mass*velocity of all objects in y
generally speaking sine you always have the speed of the ball in x and y all you need to do is determine the masses of both the ball and the paddles (i suppose that's up to you but I suggest making them the same for ease of calculation).
In terms of solving for the angle, it's very simple, you would just make sure the reflection is equal. If the ball is approaching a paddle (or wall) from a 60 degree incident, then the bounce should also be at a 60 degree incident.
First, convert the angle to a vector using the sin and cos functions. This tells you the relative x-speed and y-speed of the ball. Then, to find out how far the ball actually went, multiply these numbers by the ball's speed and time-of-flight. Finally, add to the ball's starting position. This gives you the ball's ending position.
In a pong game, the ball may hit an object, in which case you need to correct for the change in velocity.