• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
cagdassalur

[as3] Trigonometry is confusing

20 posts in this topic

Hi, first time posting here. I'm having problems with some trigonometry calculations in as3. Here's the swf file, i can move the ship forwards and backwards but things get weird when i try to move it sideways.

 

Here's the code;

//this moves the ship forward
vx += Math.cos(rotation* Math.PI / 180) * 3;
vy += Math.sin(rotation* Math.PI / 180) * 3;

//and this should move the ship to its right
vx += Math.cos((rotation+90)* Math.PI / 180) * 3;
vy += Math.sin((rotation+90)* Math.PI / 180) * 3;

 

I have no idea what i'm doing with these stuff i just took the calculations from a tutorial. Why this isnt working?

 

Thanks in advance!

 

ps: Here's some additional info;

//ship's location is updated like this in every tick
x+=vx;
y+=vy;

//and i calculate the angle of the ship like this;
rotation = (Math.atan2(y-stageRef.mouseY,x-stageRef.mouseX)*180/Math.PI)+180;

 

 

1

Share this post


Link to post
Share on other sites

Hi there smile.png

Your mathematics is perfectly legitimate here, everything is as it should be at a glance.


It might be fixed ( it's a bit "meh" ) by making sure you calculate the angle at each tick BEFORE doing the movement.

Hope it helps. biggrin.png

Daniel Kruyt

2

Share this post


Link to post
Share on other sites

what's the problem, the swf appears to behave perfectly correctly.

 

your constantly pointing the ship at the mouse, so when you go to move right, you do move right, but then you rotate the ship to face the mouse, move, rotate....etc

 

if you want to be able to move linearly from a position left or right, then when u need to offset what you are looking at but the distance you've moved left/right.

 

 

edit: alternativly, only set the ship to face the mouse when the mouse moves, this would allow the ship to move left/right, but when you move your mouse, the ship snaps back to looking at the mouse.

Edited by slicer4ever
1

Share this post


Link to post
Share on other sites

I think you probably don't want to spiral outwards when moving right or left.

 

You can do that fairly easily with the setup you have now... have a forward/backward speed stored, and a clockwise/counterclockwise one too, that act independently.

 

Since you always face the centre point, do moving forwards and backwards as you do now, but when you have a clockwise/counterclockise component to your velocity, rotate around the focus point the correct amount of degrees to match the given speed. You can work out how many degrees to travel since you know moving 360 degrees would be a speed of 2 * PI * r where r is the radius of the circle you travel around (i.e. distance between the ship and the focus point).

 

Does that make sense?

Edited by Paradigm Shifter
1

Share this post


Link to post
Share on other sites

what's the problem, the swf appears to behave perfectly correctly.

 

If you plan on making games it's well worth your time to look up some basic trig and see what those functions are doing and why.

 

I also don't see a problem here. Can you explain more precisely what it's not doing correctly?

 

I updated it yesterday but its still broken. I don't want the ship to move away from the mouse when i'm only pressing "a" or "d" buttons.

 

 

 

Nature of Code book was super helpful for me here - 

http://natureofcode.com/ 

He's got some really great vector math and physics stuff I found super useful.  

 

I'ts seems nice and cheap gonna check it out thanks!

 

 

 

Since you always face the centre point, do moving forwards and backwards as you do now, but when you have a clockwise/counterclockise component to your velocity, rotate around the focus point the correct amount of degrees to match the given speed. You can work out how many degrees to travel since you know moving 360 degrees would be a speed of 2 * PI * r where r is the radius of the circle you travel around (i.e. distance between the ship and the focus point).

 

Does that make sense?

 

Uhm.. I'm not very good at english and when its combined with trigonometry it makes no sense to me. I cant understand the last sentence. I can calculate the distance between two points but i dont know what should i do with it.

 

 

Edit: By the way sorry for the late response i was waiting to get a mail from gamedev.net informing me when i got some answers, it didnt happen.

 

Edit2: I uploaded the source here if it helps. Some parts are in turkish but i can translate the source if needed.

Edited by cagdassalur
0

Share this post


Link to post
Share on other sites

Rotate around in a circle centred on the focus point but keep the same distance away.

 

You can work out the angle you are at with respect to the centre of the circle using atan2.

 

Then set your new position to be the same distance away from the focus point but offset the angle by an amount based on the speed you are moving at and the radius (distance from the centre).

 

If you are 100 units away from the centre point (call this r), a complete circle would be 2 * PI * r = 200PI circumference. You want to move 10 units, so you move 10 / (200 * PI) = 1/(20 * PI) of a circle = 0.0159 of a full circle i.e. 0.0159 * 360 degrees = 5.72 degrees.

Edited by Paradigm Shifter
0

Share this post


Link to post
Share on other sites

You can work out the angle you are at with respect to the centre of the circle using atan2.

 

Dont i know the angle already? From the rotation variable?

0

Share this post


Link to post
Share on other sites

Yep, you do.

 

Now you just adjust the angle and calculate where you would be if you moved along the circumference of the circle at your desired speed. Your new position will be

 

x = circleCentre.x + cos(newAngle) * circleRadius

y = circleCentre.y + sin(newAngle) * circleRadius

 

and then just rotate the ship to point towards the centre again.

0

Share this post


Link to post
Share on other sites

I updated the part to look like this;

 

 

vx+= mouse.x+Math.cos(rotation)*distance;
vy+= mouse.y+Math.sin(rotation)*distance;
 
But it's doing that strange thing getting closer and moving away from the mouse afterwards. Couldn't i calculate how much it'll move away and add that to the velocity?
 
When i use just update x,y coordinates its moving very fast while still closing in to the cursor. So i used vx and vy.
0

Share this post


Link to post
Share on other sites

I'd just limit the maximum angle you can move by if you are too close to the cursor, or if you move the cursor too close to the ship move it a bit further away in the direction of the mouse pointer, you get problems with your ship flipping around already when you move beyond the mouse cursor when moving forwards...

 

Updating your velocity in 2d is going to give you the same thing you had earlier, spiralling away from the centre point.

1

Share this post


Link to post
Share on other sites

Okay, so here's what you've got right now...

if(key.isDown(Keyboard.A)) {
  vy -= -uzaklik*Math.sin(degreesToRadians(rotation+90)) * 1;
  vx -= -uzaklik*Math.cos(degreesToRadians(rotation+90)) * 1;
}
else if(key.isDown(Keyboard.D)) {	
  vy += -uzaklik*Math.sin(degreesToRadians(rotation+90)) * 1;
  vx += -uzaklik*Math.cos(degreesToRadians(rotation+90)) * 1;
}

if(key.isDown(Keyboard.W)) {
  vy += Math.sin(degreesToRadians(rotation)) * GameConstants.speed;
  vx += Math.cos(degreesToRadians(rotation)) * GameConstants.speed;
}
else if(key.isDown(Keyboard.S)) {
  vy -= Math.sin(degreesToRadians(rotation)) * GameConstants.speed;
  vx -= Math.cos(degreesToRadians(rotation)) * GameConstants.speed;
}


 

Some basic trig information:

 

Imagine a 90 degree triangle with its bottom side laying on the x axis. The bottom side is 'x', the right-hand side is 'y' and the hypotenuse is 'r'.

 

The angle which sits at the origin is 'theta'. We'll say that the hypotenuse, 'r', has a length of one unit. This is a 'unit triangle' and has the following properties:

 

The sine of theta is the length of 'y'.

The cosine of theta is the length of 'x'.

 

Okay, so...  Say the ship is at [10, 5] and the mouse is at [0, 0] and the user presses the 'a' button. We want to maintain the same 'r' but move the ship some distance to its left (clockwise around the mouse - subtract from theta).

 

First let's get 'r':

 

dx = 10 - 0

dy = 5 - 0

100 + 25 = 125

sqrt(125) = 11.18

r = 11.18

 

Now let's get theta (in radians):

 

atan2(5, 10) = 0.46

 

Reduce it by a little in order to create a clockwise change:

 

0.46 - 0.05 = 0.41

 

So now we can calculate a new unit triangle with that angle:

 

x = cos(0.41) = 0.917

y = sin(0.41) = 0.399

 

Remember our hypotenuse, 'r', has length 11.18, so we multiply the unit triangle lengths by this amount and get

 

x = 10.8206

y = 4.7082

 

Which is our new offset position from the mouse.

 

This is all in Cartesian space, though. I don't know if as3 uses Cartesian coordinates or if it has the origin at the upper-left corner. If it's the latter then remember to negate the y value before calculating and negate it again when done.

 

 

That said, your problem here is that you're calculating velocities rather than positions. You're going to get some swerve from that. How about instead you have an orbital velocity 'rv' and use that as the amount to add or subtract from theta each frame?

Edited by Khatharr
1

Share this post


Link to post
Share on other sites

I'd just limit the maximum angle you can move by if you are too close to the cursor, or if you move the cursor too close to the ship move it a bit further away in the direction of the mouse pointer, you get problems with your ship flipping around already when you move beyond the mouse cursor when moving forwards...

 

Updating your velocity in 2d is going to give you the same thing you had earlier, spiralling away from the centre point.

 

Exactly. I think im starting the figure out the problem here. Now it doesn't sound much like gibberish when i read something about trigonometry in english.

 

that said, your problem here is that you're calculating velocities rather than positions. You're going to get some swerve from that. How about instead you have an orbital velocity 'rv' and use that as the amount to add or subtract from theta each frame?

 

Surely i can do that, But im having problems with which variable i use are fixed at that frame and which i can change(and how). For example i calculate theta but you are saying i need to change that directly. And for the theta calculation part why you didn't used the mouse locations with ship coordinates? or did you and i missed it because they were (0,0)? From what i understand theta is the angle of the ship from origin, shouldn't i somehow include mouse coordinates too?

 

Oh and in as3 origin is at top-left.

 

 

By the way thanks for all the answers you guys keep posting i haven't got any help from forums in my country. You guys are the best! 

0

Share this post


Link to post
Share on other sites

The ship location should be relative to the mouse location before you start the trig.

 

If the mouse is at 10,10 and the ship is at 20, 15 then for the start triangle x is 10 and y is 5.

 

The trig functions all work on the cartesian grid, where x increases to the right and y increases toward the sky. So start out by getting the mouse position and the ship position in as3 coordinates and then calculate the triangle dimensions:

 

mouse_x = 320

mouse_y = 240

ship_x = 10

ship_y = 10

 

starting_triangle_x = ship_x - mouse_x = -310

starting_triangle_y = mouse_y - ship_y = 230

 

Get theta:

 

angle = atan2(starting_triangle_y, starting_triangle_x)

 

adjust theta by your orbital velocity:

 

angle += rv

 

Get the unit lengths for the new triangle:

 

new_triangle_x = cos(angle)

new_triangle_y = sin(angle)

 

Get the radius:

 

radius = sqrt(starting_triangle_x^2 + starting_triangle_y^2)

 

Scale the triangle:

 

new_triangle_x *= radius

new_triangle_y *= radius

 

Now apply the positions relative to the mouse:

 

ship_x = mouse_x + new_triangle_x

ship_y = mouse_y - new_triangle_y

 

I'm not entirely sure if you'll run into quadrant problems. I'll have to check that when I get back home. Now that I'm thinking about it, the mouse moving around during play could drag the ship all over the place. I don't think this is what you want either.

 

This would be a lot simpler if orbit had no momentum. -.-

 

I guess you could generate a [theta, r] vector velocity for the ship, then generate a new vector from the input, add them together, apply them and then multiply the vector by your friction value.

 

Alternatively, on the first frame that a direction is pressed you fix the motion angle and just keep moving that direction until the input changes?

Edited by Khatharr
0

Share this post


Link to post
Share on other sites

I did this after you wrote the calculations;

 

 

 

starttrx=x-mouse.x;
starttry=mouse.y-y;
angle=Math.atan2(starttry,starttrx);
angle+=vo;
newtrx=Math.cos(angle);
newtry=Math.sin(angle);
uzaklik=Math.sqrt(starttrx*starttrx+starttry*starttry);
newtrx*=uzaklik;
newtry*=uzaklik;


x=mouse.x+newtrx;
y=mouse.y-newtry;
 

 

And i set the angular velocity(vo) to change when pressed a button, but it's moving crazy fast and still closing in to the cursor after some time. However when i adopted these stuff from another sample angular motion tutorial, the rotation and movement with W/S buttons works. But the ship is moves with cursor. If cursor moves 5 pixels to the right ship moves with it. And the further the ship is to the cursor it moves faster.

 

 

 

var angle:Number=0;
var r:int=50;


var rad:Number = angle * (Math.PI / 180);
x = mouse.x + r * Math.cos(rad);
y = mouse.y + r * Math.sin(rad);

if(A.pressed) angle-=3;
if(W.pressed) r-=5;
 

 

here's the updated swf with the code above.

 

Why this is so hard to achieve? Am i too strange for trying to make this kind of controls? Should i change the mechanics to something a bit easier to do?

 

edit: I tried another control system you can try it by pressing "4" and it swictches to "control 1". How is that for example?

Edited by cagdassalur
0

Share this post


Link to post
Share on other sites
Yeah, that's what I meant when I said that it'd follow the cursor. You could make it so that it only runs that when the orbital velocity is zero or else use velocity vectors and deal with the 'spiraling away' problem. TBH it's kind of a weird control scheme, yes. The alternate method seems a lot more natural. To change the speed in the first method just reduce the amount that you're changing the angle by. I'm not getting any in/out behavior when I rotate though?

The alternate method seems overly fast as well, though.
0

Share this post


Link to post
Share on other sites

Yeah, that's what I meant when I said that it'd follow the cursor. You could make it so that it only runs that when the orbital velocity is zero or else use velocity vectors and deal with the 'spiraling away' problem. TBH it's kind of a weird control scheme, yes. The alternate method seems a lot more natural. To change the speed in the first method just reduce the amount that you're changing the angle by. I'm not getting any in/out behavior when I rotate though?

The alternate method seems overly fast as well, though.

 

What in/out behavior? That stopped with the last piece of code. And yeah since that controls somehow close to working i can see how its strange and confusing for the player. I'll stick with the other controls. Thanks for all the help, at least trigonometry is kinda less confusing for me now. 

 

Oh and that's just temporary testing speed i'm gonna nerf it after adding some enemies.

0

Share this post


Link to post
Share on other sites

could your mouse idea be the problem in your calc?

 

Have you thought to take into account the deminsions of your window for the mouse?

 

I think your trig maybe is not the problem?

 

you maybe need to subtract the window.width - mouse.x  (also take into account the windows position on the screen)

 

get relative mouse movement versus the position and width/hight of your window, not just the screen

 

and center the mouse coordinates at the start.

0

Share this post


Link to post
Share on other sites

//maybe this trig example could help you in some way

//example of model matrix rotation

 

Obj3d::RotateModel(int index, float x,float y,float z)
{


if(index >= 0 && index <= Facesets){

xyz__ center;
center = GetCenter(&Model_[index]);

#ifdef stub
cout<<"center x: "<<center.x<<" y: "<<center.y<<" z: "<<center.z<<endl;
system("pause");
#endif

xyz__ matrix;
xyz__ hyp;
xyz__ Angle;

 

for(int i = 0; i < Model_[index].nFaces;++i){
for(int w = 0;w<3;++w){

//a/b = atan(A)
//length a  b
matrix.x = Model_[index].Object[VERTEX][i][w][0] - center.x;
matrix.y = Model_[index].Object[VERTEX][i][w][1] - center.y;
matrix.z = Model_[index].Object[VERTEX][i][w][2] - center.z;


if(matrix.z != 0) Angle.x =  ( atan( (matrix.y / matrix.z)) / (0.017453292) );else Angle.x = 0;
if(matrix.x != 0) Angle.y =  ( atan( (matrix.z / matrix.x)) / (0.017453292) );else Angle.y = 0;
if(matrix.x != 0) Angle.z =  ( atan( (matrix.y / matrix.x)) / (0.017453292) );else Angle.z = 0;

if(Angle.x)
hyp.x = matrix.y / sin(Angle.x *0.017453292);
if(Angle.y)
hyp.y = matrix.z / sin(Angle.y *0.017453292);
if(Angle.z)
hyp.z = matrix.y / sin(Angle.z *0.017453292);


#ifdef stub
cout<<"atan("<<matrix.y<<"/"<<matrix.z<<") = " <<Angle.x<<endl;
system("pause");
#endif


//x rotation
if(x != 0 && Angle.x != 0 ){
Model_[index].Object[VERTEX][i][w][1] = (hyp.x * sin( (x + Angle.x) * 0.017453292 ) + center.y);
Model_[index].Object[VERTEX][i][w][2] = (hyp.x * cos( (x + Angle.x) * 0.017453292 ) + center.z);
}
//y rotation
if(y != 0 && Angle.y != 0 ){
Model_[index].Object[VERTEX][i][w][2] = (hyp.y * sin( (y + Angle.y) * 0.017453292 ) + center.z);
Model_[index].Object[VERTEX][i][w][0] = (hyp.y * cos( (y + Angle.y) * 0.017453292 ) + center.x);

}
//z rotation
if(z != 0 && Angle.z != 0){
Model_[index].Object[VERTEX][i][w][1] = (hyp.z * sin( (z + Angle.z) * 0.017453292 ) + center.y);
Model_[index].Object[VERTEX][i][w][0] = (hyp.z * cos( (z + Angle.z) * 0.017453292 ) + center.x);
}
}} 
return 1; 
}else

return 0;
}

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0