as3 I try to make player reflect from wall by opposite degrees - actionscript-3

Now my player move opposite way from the block wall except from the right side.
I had trace the value of x/y modify and find that x is always positive.
that make the object alway move to left.
I don't understand why because it work with y.
Is this bug or my code wrong
very thank you.
//------------------------0
var wallAngle:Number;
wall.addEventListener(Event.ENTER_FRAME, reflect);
function reflect(e:Event):void
{
if (mcPlayer.hitTestObject(wall)){
wallAngle = getAngle(mcPlayer.x, mcPlayer.y, wall.x, wall.y)
mcPlayer.y -= 5*(Math.sin(wallAngle*(Math.PI/180)));
mcPlayer.x -= 5*(Math.cos(wallAngle*(Math.PI/180)));
trace("sin "+ String(Math.sin(wallAngle*(Math.PI/180))));
trace("cos "+ String(Math.cos(wallAngle*(Math.PI/180))));
}
}
function getAngle (x1:Number, y1:Number, x2:Number, y2:Number):Number
{
var dx:Number = x2 - x1;
var dy:Number = y2 - y1;
return (Math.atan2(dy,dx));//return Redians
}

Related

Making objects chase another (AS3)

So i have an object that i want to chase another object. Everything is working fine, however i tried to implement an easeTo function to make it so that the object doesn't take the most direct route to the x,y locations of the object it is chasing. This also works but the thing that is really pissing that i can't fix is the fact that the objects speed changes depending how far away from the object it is chasing is. For example, if the object being chased is on the far right of the stage and the chaser spawns on the far left, it will go really fast towards the object on the right and slow down as it gets closer. I would love for it to go at a consistent speed. Any suggestions?
Thanks
Here is my code
private function easeTo(cur:Point, target:Point, ease:Number):Point{
var dx:Number = target.x - cur.x;
var dy:Number = target.y - cur.y;
var finalResult:Point = new Point(); //create a var to hold the result
finalResult.x = cur.x + (dx * ease);
finalResult.y = cur.y + (dy * ease);
return finalResult;
}
public function chase(xValue:Number, yValue:Number):void{
//store current x and y in a point var
var curPos:Point = new Point (x,y);
//store the mouse x and y in a var
var targetPos:Point = new Point(xValue, yValue);
var nextPos:Point = easeTo(curPos, targetPos, 0.001);
this.x = nextPos.x;
this.y = nextPos.y;
}
So the (xValue:Number, yValue:Number) is the x and y values of the object it is chasing being passed into the chase function.
I would suggest using Math.min (when dx or dy is negative) and Math.max (when dx or dy is positive) with a value you define to be your max speed
ie:
var maxSpeed:Number = 20;
if (dx >= 0){
dx = Math.max(dx,maxSpeed)
}else{
dx = Math.min(dx,maxSpeed)
}
repeat for dy

rotating sprite from it's current angle as3

i created an object that is rotated with the mouse, however each time after rotating, when mouse is clicked again the object "jump" right to it's new angle i would like that the object will continue to rotate from it's current location no matter where the mouse being clicked.
this is my code that rotates the object.
public function _mouseclick(me:MouseEvent):void
{
addEventListener(Event.ENTER_FRAME, UpdateGame);
IsButtonClicked = true;
}
public function UpdateGame(e:Event):void
{
if (IsButtonClicked)
{
var dist_Y:Number = mouseY - PlayerSprite.y ;
var dist_X:Number = mouseX - PlayerSprite.x ;
var angle:Number = Math.atan2(dist_Y, dist_X);
var degrees:Number = angle * 180/ Math.PI;
PlayerSprite.rotation = degrees;
}
}
how can i reset the angle to the current sprite angle and prevent that "jump"?
It looks like maybe you are trying to make some sort of knob or dial. Finding the angle between the mouse and sprite and applying it the way you are, will always face that direction. I think you are looking for something a little more simple.
First I would set up 2 variables, one to be the amount to increment the rotation, the other to store the mouse position.
var increment:int = 5;
var mousePos:Point;
Then in your mouse click function:
mousePos = new Point( mouseX, mouseY );
Lastly in your UpdateGame():
private function UpdateGame( e:Event ):void {
if ( IsButtonClicked ) {
var increment:int = 5;
if ( mousePos.y < mouseY ) {
spr.rotation += increment;
}
else {
spr.rotation -= increment;
}
mousePos = new Point( mouseX, mouseY );
}
}
That seems to be more the effect you are looking for. In this case when you move the mouse up, the sprite rotates counter clockwise. Moving the mouse down, rotates it clockwise.
If you want to change the rotation smoothly, you want to base it on the change from last rotation as the delta.
The delta is based on the initial rotation from mouse click relative to the current rotation.
current_rotation += (atan2 - last_rotation);
last_rotation = atan2;
And the full pseudo example.
private var current_rotation:Number;
private var last_rotation:Number;
private var mouse_down:Boolean;
public function MouseClick(e:MouseEvent):void
{
var dX:Number = Mouse.X - 400;
var dY:Number = Mouse.Y - 300;
var atan2:Number = Math.atan2(dY, dX);
last_rotation = atan2;
mouse_down = true;
}
public function UpdateGame(e:Event):void
{
if (mouse_down)
{
var dX:Number = Mouse.X - 400;
var dY:Number = Mouse.Y - 300;
var atan2:Number = Math.atan2(dY, dX);
current_rotation += (atan2 - last_rotation);
last_rotation = atan2;
}
}

AS3 Missile Logic

I want to create a simple missile object, which moves at a set speed and rotates towards a specific target at a given rotation speed. However, I'm having trouble figuring out the math of it. This is my code so far:
private function enterFrame(e:Event):void {
// Rotate the missile towards the target.
var targetAngle:Number = getAngle(target.x, target.y, x, y);
if (targetAngle < 0) {
targetAngle += 360;
}
if (targetAngle - turnSpeed > rotation) {
rotation += turnSpeed;
} else if (targetAngle + turnSpeed < rotation) {
rotation -= turnSpeed;
} else {
rotation = targetAngle;
}
// Set the target point to move to based on angle and speed.
var newX:Number = x + Math.sin(degreesToRadians(rotation)) * speed;
var newY:Number = y + Math.cos(degreesToRadians(rotation)) * speed;
// Move to new location
x = newX;
y = newY;
}
private function getAngle (x1:Number, y1:Number, x2:Number, y2:Number):Number {
var dx:Number = x2 - x1;
var dy:Number = y2 - y1;
return (Math.atan2(dy,dx) * 180) / Math.PI;
}
private function degreesToRadians(degrees:Number):Number {
return degrees * Math.PI / 180;
}
I've been trying to debug it using trace and such, but I can't seem to figure out where the problem is, most likely because there are many problems and I can't tell if I've fixed one because the others are masking it. I suspect that the issue(s) lie somewhere in the rotation calculations, since I'm pretty sure that the movement part is working as it should, but I can't say for sure.
At any rate, whatever I do, the missiles always seem to fly off in random directions, sometimes tracking towards straight up, or straight down, or just looping around after nothing in particular.

Draw random way in ActionScript

I'd like to move an AS 3 movieclip randomly. This is what I currently have, bound to the ENTER_FRAME event. This obviously moves the movieclip from the left upper to the right lower edge, so I need some kind of switch to add/substract the target positions.
function movePsycho(e:Event):void {
e.target.y += Math.random()*2;
e.target.x += Math.random()*2;
if (e.target.y >= stage.height || e.target.x >= stage.width)
e.target.removeEventListener(Event.ENTER_FRAME, movePsycho);
}
You don't need add/substract thing. You just have to make sure not only you get positive values out of your random, but negatives too, so it runs to all sides.
Try changing your random generating lines to this:
e.target.y += Math.random()*10 - 5;
e.target.x += Math.random()*10 - 5;
This will work if you want to make it move in a 5px radius.
I just realized you may want to generate a new random point on the screen, then move to that point and when your object reaches the destination generate another random point to go to. So if that's the case, try this:
mc.addEventListener(Event.ENTER_FRAME, onFrame);
var dirX:int = mc.x;
var dirY:int = mc.y;
function generateRandomPoint():void
{
dirX = Math.random() * stage.stageWidth;
dirY = Math.random() * stage.stageHeight;
}
function onFrame(e:Event):void
{
mc.x += (dirX - mc.x) * 0.1;
mc.y += (dirY - mc.y) * 0.1;
if(Math.abs(dirX - mc.x) < 1 || Math.abs(dirY - mc.y) < 1)
generateRandomPoint();
}
i don't know actionscript but you may find help with this
http://www.actionscript.org/forums/showthread.php3?t=270725

as3 rotational drag / acceleration

Sprite.rotation+=10;
Sprite.rotation*=0.97;
because in as3 the system goes from 180 to -180 I don't know how to apply a drag to a constantly rotating object if it moves either direction. Do I have to convert to radians somehow and then do something? I am pretty bad with math.
I'm not sure "drag" makes sense with the code you've posted. What you've shown would slowly wind the object back to 0 rotation.
If you want a drag/acceleration effect, create a separate variable with your acceleration factor, which you apply every frame. Then, you can apply a factor to that variable to slow rotation down/speed it up.
Something like:
private var _rotationAcceleration:Number = 0;
private var _dragFactor:Number = 0.97;
private var _clip:Sprite;
private function startSpin():void {
_rotationAcceleration = 10.0;
}
private function enterFrameListener(event:Event):void {
_clip.rotation += _rotationAcceleration;
_rotationAcceleration *= _dragFactor;
}
I think you're looking for this:
private function updateRotation():void
{
var _dx:Number = _player.x - stage.mouseX; // rotate _player mc to mouse
var _dx:Number = _player.y - stage.mouseY; // rotate _player mc to mouse
// which way to rotate
var rotateTo:Number = getDegrees(getRadians(_dx, _dy));
// keep rotation positive, between 0 and 360 degrees
if (rotateTo > _player.rotation + 180) rotateTo -= 360;
if (rotateTo < _player.rotation - 180) rotateTo += 360;
// ease rotation
var _trueRotation:Number = (rotateTo - _player.rotation) / 5; // rotation speed 5
// update rotation
_player.rotation += _trueRotation;
}
public function getRadians(delta_x:Number, delta_y:Number):Number
{
var r:Number = Math.atan2(delta_y, delta_x);
if (delta_y < 0)
{
r += (2 * Math.PI);
}
return r;
}
public function getDegrees(radians:Number):Number
{
return Math.floor(radians/(Math.PI/180));
}
It actually does goes from 180 to -180 (contrary to what Reuben says), but higher/lower values get automatically corrected to that range (i.e. 181 is converted to -179)... one way to work with this is to use an auxiliary variable for your math (animation or whatever) and then assign it to the rotation, say:
myVar+=10;
myVar*=.97;
clip.rotation=myVar;