Hey everyone so I am having some trouble with this. So I have an Array of Barrel Movie clips that are added to the stage and a movie clip called Circle that when comes in contact with any of the barrels in the array the barrel that it is currently hittesting starts to rotate. It rotates on its registration point which is centered. So in my ENTER_FRAME event is where I have everything setup for the barrel to rotate and hit Test etc...
This is how the circle is added to the barrels:
if (!circleFired)
{
circle.x = globalFirePoint.x;
circle.y = globalFirePoint.y;
currentCannon.addChildAt(circle, 0);
}
Now what I am trying to accomplish is when the user taps the screen the circle Movie clip is shot from the Barrel. Right now I have the circle shooting from the barrel in the angle that its supposed to shoot but instead of going in a straight line from the angle it shoots it shoots and starts to curve really quickly in the clockwise position that the barrel is rotating in.
Here is the code I have that is sort of working besides that one problem:
var dX:Number = globalFirePoint.x;
var dY:Number = globalFirePoint.y;
var angle:Number = Math.atan2(dY, dX);
if (circleFired)
{
circle.x += Math.sin(deg2rad(angle -90)) * velocity;
circle.y += Math.cos(deg2rad(angle - 90)) * velocity;
}
so the globalFirePointis this:
globalFirePoint = localToGlobal(new Point(currentCannon.mcFirePoint.x, currentCannon.mcFirePoint.y));
Its the starting point I want the circle to shoot from.
Here is the deg2rad Function:
private function deg2rad(num:Number):Number
{
var radians:Number = num * (Math.PI / 180);
return radians;
}
I know that I need sin and cos to calculate the angle correct? Is the math wrong? Why is the circle curving when the circle shoots from the globalFirePoint? What can I do to make it go in a straight line?
Any help would be appreciated thanks!
Does globalFirePoint change on each ENTER_FRAME event? If so then the calculated angle is going to change as well, leading to the curve you are experiencing.
One way to fix this is to only calculate globalFirePoint when the user presses the screen. Then on every ENTER_FRAME event instead of re-calculating globalFirePoint, use the already calculated globalFirePoint that won't change unless the user presses the screen when the circle is in a barrel.
You should only calculate the angle when the user presses the screen as well. There is no need to calculate it on every ENTER_FRAME event, since the only time you're interested in the angle is when the circle is shot from a barrel.
Related
I'm making a top down shooter game. I've got my character moving. All I want to do next is make a bullet shoot from the center of my character to the direction my cursor is at. How would i go about doing this?
I'm really struggling to think of the code i need to make this work.
This will involve simple vector math. There are tons of resources online about this. Here's the basic gist:
1) First, calculate the angle (in radians) between your character and your target (in this case the mouse location). You can use Math.atan2() to perform this calculation.
var angle:Number = Math.atan2(mouseY - playerY, mouseX - playerX);
2) Next, use that angle to create a vector (x,y delta) which represents the direction of travel for your bullet. You use Math.cos() and Math.sin() to compute the x and y value:
var speed:Number = 5;
var vector:Point = new Point(Math.cos(angle) * speed, Math.sin(angle) * speed);
3) Now you can update the bullets position each frame by that vector:
bullet.x += vector.x;
bullet.y += vector.y;
4) And if you want to make your bullet sprite point in the direction of travel, convert that angle to degrees and set the bullet sprite's rotation:
var degrees:Number = angle * (180 / Math.PI);
bullet.rotation = degrees;
Note that for the purpose of the math here, 0 degrees is considered to be right-facing along the x-axis, not up-facing like you might naturally think of 0 degrees (at least I do). What this means is your sprites unrotated orientation should be facing right-ward.
I'm building a simple space shooter game
using Tweener class I wrote a code that fires a bullet from the hero spaceship current position to the mouse current position
var fire = new Bullet();
addChild(fire);
fire.x = ship.x + (ship.width * 0.5);
fire.y = ship.y
Tweener.addTween(fire, {x:_me.currentTarget.mouseX, y:_me.currentTarget.mouseY, time: 5} );
the problem is this code makes the bullet stop at the last mouse position
and I want the bullet to continue moving in the same direction until it's outside of the stage.
theoretically, the most simple way would be to input x.y position of the mouse as if it was at the same angle but outside of the stage
but how can i get those x,y coordinates??
determine the angle of the bullet.
using the angle, consider the origin of the bullet the center of a circle and the first point as a coordinate at the edge of the circle.
for the bullet to follow the same path, its just a larger circle, so the radius will increase.
the angle will be the same and so will the origin.
I think what you you want is to find a point one the same straight line with (fire.x, fire.y) , (_me.currentTarget.mouseX, _me.currentTarget.mouseY). And the point's x would be stage width.
So assume target point is A(stage.width, targetY)
We get
(targetY - mouseY)/(targetX - mouseX) = (mouseY - fire.y)/(mouseX - fire.x)
So
targetY = (mouseY - fire.y)/(mouseX - fire.x)*(targetX - mouseX) + mouseY;
Hero mouseX is _me.currentTarget.mouseX, mouseY is _me.currentTarget.mouseY
You can set targetX = stage.width + 10, then targetY
So you can get targetY, and do another tween
Tweener.addTween(fire, {x:targetX, y:targetY , time: 5} );
I have my player movieclip on the stage, and when the mouse is clicked a bullet is fired and projected at the correct angle to point itself at the mouse location. I also want a "mirroring" enemy, that fires at the complete opposite direction when the player does.
For example, when the player shoots upwards, the enemy should shoot down. Likewise, shooting to the right will cause the enemy to shoot to the left.
Is there a formula to convert the rotation in degrees to it's complete opposite?
Using Matrix is a very simple and exact solution. just multiple a or c with -1 ( to flip vertical and horizontal ).
Sample code:
var _tmpMatrix:Matrix = sprite.transform.matrix;
_tmpMatrix.a *= -1;
if ( _tmpMatrix.a < 0 ) {
_tmpMatrix.tx = sprite.width + sprite.x;
} else {
_tmpMatrix.tx = 0;
}
sprite.transform.matrix = _tmpMatrix;
Wouldn't adding or subtracting 180 degrees point in the opposite direction?
or
obj.scaleX = -1;
will do the same thing. =)
First of all sorry for some english mistakes. Portuguese is my first language(I am from Brazil)
Im trying to make a space game from scratch in AS3 and the way to move the ship is like in the game Air Traffic Chief.
I succeed at some point. But when the ship is very fast it start to shake and its not very smooth and clean as I want.
Here is what i have done: http://megaswf.com/s/2437744
As the code is very big so I pasted in pastebin: pastebin.com/1YVZ23WX
I also wrote some english documentation.
This is my first game and my first post here. I really hope you guys can help me.
Thanks in advance.
Edit:
As the code is very big i will try to clarify here.
When the user MouseDown and MouseMove the ship every coordinate is passed to an array.
When the user MouseUP this array is passed to a function that fix the array.
For example: If the distance between two coordinates is greater than 5px, the function creates a coordinate in the middle of the two coordinates.
if I take this function off the problem seen to be solved. But if the user move the mouse very slow it still happens. It also creates a problem that i was trying to solve with that function. as the distance of the two coordinates are very big when the ship arrive in one coordinate most of the line path disappear.
I uploaded a version without the function that fixes the array. http://megaswf.com/s/2437775
I think there is 2 ways for solving this problem
1- Try to fix the noise in the array of coordinates 2- Take off the function that create an coordinate between two points and try to fix the problem of the line path disappear.
Here is the 2 important functions:
this function moves the ship
private function mover():void
{
if (caminhoCoords[0]!=null) // caminhoCoords is the array that contain the path
{
var angulo:Number = Math.atan2(this.y - caminhoCoords[0][1], this.x - caminhoCoords[0][0]);
this.rotation = angulo / (Math.PI / 180);
this.x = this.x - velocidade * (Math.cos(angulo));
this.y = this.y - velocidade * (Math.sin(angulo));
var testex:Number = Math.abs(this.x - caminhoCoords[0][0]); //test to see the distance between the ship and the position in the array
var testey:Number = Math.abs(this.y - caminhoCoords[0][1]);
if (testey<=velocidade+2 && testex<=velocidade+2) // if is velocidade+2 close then go to the next coordnate
{
caminhoCoords.shift();
}
}
}
This function draw the line:
private function desenhaCaminho():void //draw the black Path
{
if(caminhoCoords.length>=1)
{
caminho.graphics.clear();
caminho.graphics.lineStyle(1, 0x000000, 1,true);
caminho.graphics.moveTo(caminhoCoords[0][0],caminhoCoords[0][1]);
for (var i:int = 1; i < caminhoCoords.length; i++)
{
caminho.graphics.lineTo(caminhoCoords[i][0], caminhoCoords[i][1]);
}
}else
{
caminho.graphics.clear();
}
}
Every time the ship arrive in one coordinate is take that coordinate off the array and redraw the array.
Is there a better way of doing that?
I believe if you set your registration point of the plane to the centre and use .snapto(path), it will improve the action.
Judging from just the look of the stuttering, I would guess you need to smooth out the "line" a fair bit. It's probably picking up a lot of noise in the line, which is then translated into the rotation of the plane. Either smooth out the rotation/position of the plane, or the line itself.
Hey gang. Stumped on something.
I have a disc I am rotating with the mouse with event.MOUSE_MOVE, like a jog wheel on some audio equipment. Everything almost works as expected, but the problem I am experiencing is that the disc always jumps to the point where the user clicks on the disc. I need the point on the disc that the user clicks on to remain under the mouse while the user spins the disc but I can't seem to come up with the correct math to make it happen. Here's the code i am using:
var xd = (_knob.x - _stageRef.stage.mouseX);
var yd = (_knob.y - _stageRef.stage.mouseY);
var radAngle = Math.atan2(yd, xd);
_knob.rotation = int(radAngle * 360/(Math.PI * 2) - 90);
_knob is a vector circle wrapped in a movieclip, with the circle centered on the movieclip's reg point. _stageRef represents the main stage.
Any help would be awesome. I've scoured the interweb and can't come up with anything.
Thx!
You are setting _knob rotation to the angle between _knob and mouse cursor. So if rotation was 0, and angle 45, rotation becomes 45, therefore it jumps. What you need is measure changes in this angle, not setting it instantly:
var _mouseAngle:Number;
function getMouseAngle():Number
{
var xd = (_knob.x - _stageRef.stage.mouseX);
var yd = (_knob.y - _stageRef.stage.mouseY);
return Math.atan2(yd, xd);
}
function onMouseDown(event:MouseEvent):void
{
_mouseAngle = getMouseAngle();
}
function onMouseMove(event:MouseEvent):void
{
var newAngle:Number = getMouseAngle();
_knob.rotation += (newAngle - _mouseAngle) * 180.0 / Math.PI; //EDIT: forgot to convert into degrees
_mouseAngle = newAngle;
}
(Code not tested)