Working out a point to spawn a bullet from a ship - actionscript-3

I'm trying to work out where to spawn a bullet from my 40by40 pixel ship, at the moment the ship is facing north, the nose is 20 pixels away from the centre, so here is my code to try and work it out
if( rotate < 0 )
{
actRotate = 360 - (rotate * -1) ;
trace(actRotate);
}
else
{
actRotate = rotate;
}
//var rotateTemp:Number = this.rotation * (180 / Math.PI);
//this.x = xPos;
//this.y = yPos;
_speed_x = Math.sin(rotation*0.0174532925)*7.5;
_speed_y =- Math.cos(rotation*0.0174532925)*7.5;
var noseX:Number = xPos + (NoseOfShip * Math.cos(actRotate));
var noseY:Number = yPos + (NoseOfShip * Math.sin(actRotate));
this.x = noseX;
this.y = noseY;
Ok so let me just cover somethings, if i rotate my ship to the right by 90 it will give 90 as the value, if i rotate the ship by 180 degrees the value of rotate is -180, if i rotate the ship aniclockwise by 90 it is -90. Now i am really confused on why Flash CS6 does this :(, so I tried to create a convertor above as you can see, if rotate is minus, then just find out what it was ment to be. now this code only works if the ship is -90 (270) degrees.
if the ship is 0,90,-180(180) the bullet is fighted from the nose by to its left by 20 pixels. if someone could give me a hand it would be very helpful, also if you need anymore information please post here
Thank you.

Related

LibGdx Issue of coordinates

I have issue in my LibGdx program. I gave 800 height and 480 width to my camera. I am drawing target under coordinates :
randomTargetX = new Random().nextInt((350 - 100) + 1) + 100;
randomTargetY = new Random().nextInt((600 - 300) + 1) + 300;
But after clicking on target my cannonball don't overlap target rectangle.
I am doing this in Touch:
if (Gdx.input.justTouched()) {
touchX = Gdx.input.getX();
touchY = Gdx.input.getY();
camera.unproject(touch.set(touchX, touchY, 0));
if (touch.y>200) {
isTouched = true;
rectangleCannonBall.x = (width / 2) - 50 / 2;
rectangleCannonBall.y = 0;
double angle = 180.0 / Math.PI * Math.atan2(rectangleCannonBall.x - touch.x, touch.y - rectangleCannonBall.y);
spriteCannon.setRotation((float) angle);
}
}
Doesn't work.
It's a cannonball game:
First i am setting camera.
Randomly showing targets inside range of coordinates.
On touch unprojecting camera with Vector3 new position.
On touch calculating target position with cannon position and getting angle to rotate cannon.
After rotating cannon I fire ball towards target.
Now when I do Rectanglar1.overlaps(rec2) , it doesn't work because of both rectangles have different points but by visible both overlaps each other.
When I check coordinates of Rectangle of Target and Touch its different.
The line:
camera.unproject(touch.set(touchX, touchY, 0));
Doesn't do anything.
Try with:
touch = camera.unproject(touch.set(touchX, touchY, 0));

How do I constrain an angle from rotating in AS3?

I have a gun and a player. I want to constrain the angle of the gun so the player doesn't raise his gun up too much or too low. The player and gun turns to the right side when the mouse is facing the right, and if the mouse faces the left, the player and gun turns to the left. I want to constrain the gun between 160 and -160 when it faces right. And constrain the gun between 20 and -20 when it faces left. So it doesn't rotate over the constraining restriction.
I have a code that makes it rotate 360, but I'm not sure on how to stop it from rotating once it reaches a certain point.
if (parent != null)
{
var dx = MovieClip(parent).crosshair.x - x;
var dy = MovieClip(parent).crosshair.y - y;
var angle = Math.atan2(dy, dx)/Math.PI * 180;
rotation = angle;
}
Ok, here's what's happening:
Flash rotation at 0° faces strictly up. So the right side will be from 0° to 180° and left side will be from 0° to -180°. This is easy to separate because all right side > 0 and all left side < 0.
But, Math.atan2(dy, dx) calculates a different angle which cannot be directly assigned to object rotation. Instead of left and right side, it is < 0 on upper side and > 0 on lower side. If you calculate the rotation that way, it will be a mess.
So, the atan calculation must be shifted by 90° clockwise in order to match the Flash rotation. This is done by transforming the parameters and now it looks like Math.atan2(dx, -dy). After that the calculated angle and the rotation angle will match.
var angle:Number = Math.atan2(dx, -dy) / Math.PI * 180;
if (angle < 0) { // facing left
if (angle > -30) angle = -30;
if (angle < -150) angle = -150;
} else { // facing right
if (angle < 30) angle = 30;
if (angle > 150) angle = 150;
}
This is the solution without using -dy and instead using dy. (Code added by OP and I didn't check it :)
var angle = Math.atan2(dy, dx) / Math.PI * 180;
if (rotation > -180 && rotation < -90 || rotation > 90 && rotation < 180 )
{ // facing left
if (rotation > -150 && rotation < 0)
{
rotation = -150;
}
if (rotation < 120 && rotation > 0)
{
rotation = 120;
}
}
else
{
{ // facing right
if (rotation < -30)
{
rotation = -30;
}
if (rotation > 60)
{
rotation = 60;
}
}

AS3 Rotate an object around its center point

I want this object to rotate around its center rather than the top left corner.
The code looks like this:
switch (event.keyCode)
{
case 37:
car.rotation = -90;
car.x -= 5;
break;
So when i press the left key, the car turns left but as it is now it jumps up a bit because its rotating around the top corner.
Thanks
The following will rotate around center :
public function rotateAroundCenter(object:DisplayObject, angleDegrees:Number):void {
if (object.rotation == angleDegrees) {
return;
}
var matrix:Matrix = object.transform.matrix;
var rect:Rectangle = object.getBounds(object.parent);
var centerX = rect.left + (rect.width / 2);
var centerY = rect.top + (rect.height / 2);
matrix.translate(-centerX, -centerY);
matrix.rotate((angleDegrees / 180) * Math.PI);
matrix.translate(centerX, centerY);
object.transform.matrix = matrix;
object.rotation = Math.round(object.rotation);
}
It translates the center of the object to 0,0 then rotate it and then translate it back.
The easiest way to accomplish this is to add your car sprite/movieclip onto another sprite, where the x and the y coordinates are half the width and height properties. If the car is drawn in adobe flash you can also drag it to the top left, so that the center point is in the middle.

How to create an infinite wrapping orbiting background in Actionscript 3

So I have been searching for a way to have a background orbit around a centerpoint. I came across the greensock blitmask that does an amazing job of wrapping the bitmap data to do infinte scrolling effects. However, I can't figure out a way to use this blitmask to rotate the bitmap data and still have the wrapping effect. Below is a link to my SWF.
The image that moves is the one that I wish to wrap and have the infinite scrolling effect. The problem is dealing with repositioning after the image has moved off the screen since it has been rotated.
EDIT: I totally forgot about this issue and decided put it on the backburner for my game since it was taking too long to figure. I recently returned to this concept because I had an idea to make it work. Below is a link to the .SWF that shows what I was trying to accomplish. Though this example works, I dont feel its the best solution.
"WASD" control movement
Orbiting Background
I used some trigonometry to calculate the distance a star is from the player. If that star is beyond that distance, reposition it using it's angle * -1. The code for this is under the link.
var travelVal:Number = 0;
var turnVal:Number = 0;
var currentChild:DisplayObject;
var currentStar:Star;
var childIndex:int = 0;
var angle:Number = 0;
var distance:Number = 0;
if (controller.isKeyDown(Keyboard.A))
{
turnVal += TURN_SPEED;
}
if (controller.isKeyDown(Keyboard.D))
{
turnVal -= TURN_SPEED;
}
if (controller.isKeyDown(Keyboard.W))
{
travelVal += PLAYER_SPEED;
}
if (controller.isKeyDown(Keyboard.S))
{
travelVal -= PLAYER_SPEED
}
for (childIndex = 0; childIndex < numChildren; childIndex++)
{
currentChild = getChildAt(childIndex);
//if (currentChild != player && currentChild != debugOutput && currentChild != blackBkgd)
if(currentChild is Star)
{
currentStar = currentChild as Star;
//move this child based on the travel value
currentChild.y += travelVal * currentStar.speed;
//calculate the orbiting
distance = Math2.distanceBetweenObjects(player, currentChild);
angle = Math.atan2(currentChild.y - player.y, currentChild.x - player.x);
if (distance > STAGE_WIDTH ) angle = angle * -1;
//get orginal angle in radians
//angle = Math.atan2(currentChild.y - player.y , currentChild.x - player.x);
angle = Math2.radiansToDegress(angle);
angle += turnVal;
//currentStar.rotation = angle;
angle = Math2.degreesToRadians(angle);
currentChild.x = player.x + (distance * Math.cos(angle));
currentChild.y = player.y + (distance * Math.sin(angle));
}
}
In order to rotate around a certain centerpoint, you first translate by (-centerpoint.x,-centerpoint.y), then rotate around (0,0) and then translate back by (centerpoint.x,centerpoint.y).

Enemy rotates very strangely

I have this problem: there is this enemy which rotates to my player. While "orbiting" the enemy with my player I can see that the enemy is rotating towards my player.
And then the enemy suddenly turns around 360 degrees and facing to my player again. I don't know why it does this strange 360 degree turn but it happens every time when I orbit the enemy for a few seconds. I don't know where the problem might be.
tempEnemy.dX = tempEnemy.x - player.x;
tempEnemy.dY = tempEnemy.y - player.y;
tempEnemy.rotateTo = toDegrees(getRadians(tempEnemy.dX, tempEnemy.dY));
if(tempEnemy.frame < 0) tempEnemy.frame += 360;
if(tempEnemy.frame > 359) tempEnemy.frame -= 360;
tempEnemy.trueRotation = int((tempEnemy.rotateTo - tempEnemy.frame) / tempEnemy.rotateSpeed);
tempEnemy.vX += (player.x - tempEnemy.x) / tempEnemy._speed;
tempEnemy.vY += (player.y - tempEnemy.y) / tempEnemy._speed;
tempEnemy.vX *= tempEnemy.decay;
tempEnemy.vY *= tempEnemy.decay;
Update:
private function toDegrees(radians:Number):Number
{
var degrees:Number = Math.floor(radians * 180 / Math.PI);
//trace (degrees);
return degrees;
}
private function getRadians(deltaX:Number, deltaY:Number):Number
{
var radian:Number = Math.atan2(deltaY, deltaX);
if (deltaY < 0)
{
radian += (2 * Math.PI);
}
return(radian);
}
Without seeing your getRadians function, perhaps you're passing 360° calculating a reflex angle?
Maybe something like:
var degrees:Number = Math.atan2(tempEnemy.y - player.y, tempEnemy.x - player.x) * 180 / Math.PI;
var delta:Number = degrees - tempEnemy.rotation;
while (delta <= -180)
delta += 360;
while (delta > 180)
delta -= 360;
Compensate degrees with the resting angle of your enemy display object design.
It sounds like you've used a timeline tween. Either use a code tween, or grab the tween I used here http://flexdiary.blogspot.com/2010/04/sample-code-for-oop-timeline-insideria.html. I don't remember what exactly I did to make the timeline tween go full circle, rather than twisting back before restarting, but you should be able to export and reuse the tween.
If you want to use a code tween, you can either use Flash's built in tween classes or use a library like Tweensy.