Rotating movieclip and changing to a particular frame (S.O.S) - actionscript-3

i would apreciate if someone help me with some coding.
i have this code that i previously get to rotate a movieclip with the mouse, and get to another frame, for a college work (we only did the tweens, just learned the basic coding) but i cant get no result.
import flash.events.Event;
import flash.events.MouseEvent;
knob_mc.addEventListener(MouseEvent.MOUSE_DOWN, rotate);
stage.addEventListener(MouseEvent.MOUSE_UP, endrotate );
var angle:Number=0
function rotate(e:Event):void
{
stage.addEventListener(MouseEvent.MOUSE_MOVE,rotate);
var position:Number = Math.atan2(mouseY - knob_mc.y,mouseX - knob_mc.x);
angle=(position/Math.PI) *180;
knob_mc.rotation = angle;
}
function endrotate(e:MouseEvent):void
{
knob_mc.removeEventListener(MouseEvent.MOUSE_DOWN, rotate);
stage.removeEventListener(MouseEvent.MOUSE_UP, menu);
stage.removeEventListener(MouseEvent.MOUSE_MOVE,rotate);
knob_mc.addEventListener(MouseEvent.MOUSE_DOWN,rotate);
}
function menu(e:MouseEvent):void
{
if ( angle >=1 && angle <= 100 )
{
gotoAndPlay(2);
}
else if (angle >=100 && angle < 340) {
gotoAndPlay(2);
}

You will need to put the code that adds the event listener for the rotate function somewhere outside the rotate callback. As it is, it is never being called.
function rotate(e:Event):void
{
var position:Number = Math.atan2(mouseY - knob_mc.y,mouseX - knob_mc.x);
angle=(position/Math.PI) *180;
knob_mc.rotation = angle;
}
stage.addEventListener(MouseEvent.MOUSE_MOVE,rotate);

Related

Problems getting keyboard input in AS3

So I'm workin on a flash project where I want keyboard input. In the stage there's an instance "Car" seen from above which is supposed to be rotate and drive direction of rotation. This is what I've put together so far in AS3:
//Required stuff
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.display.Stage;
import flash.display.MovieClip;
Car.addEventListener(Event.ENTER_FRAME, this.RunGame);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
//Variables
var keys:Array = []
var vDrive:Number = 3; //Car's current base speed
var vx:Number = 0; //Speed along x axis
var vy:Number = 0; //Speed along y axis
var vMax:Number = 30; //Top speed
var vRot:Number = 3; //Rotation speed
var vAcc:Number = 1.1; //Factor for acceleration
var vDeAcc:Number = 0.90; //Factor for de-acceleration
//Game Loop
RunGame();
function RunGame():void
{
// Drive forwards
if (keys[Keyboard.UP])
{
if (vDrive < vMax)
vDrive += vAcc;
}
// Reverse
if (keys[Keyboard.DOWN])
{
if (vDrive > vMax)
vDrive *= vAcc;
}
// Turn right
if (keys[Keyboard.RIGHT])
{
Car.rotation += vRot;
}
// Turn left venstre
if (keys[Keyboard.LEFT])
{
Car.rotation -= vRot;
}
//Movement
// Friction
vDrive *= vDeAcc;
//Calculating movement vector
vx = vDrive * Math.cos(toRad(Car.rotation));
vy = vDrive * Math.sin(toRad(Car.rotation));
//Update car position
Car.x -= vx ;
Car.y -= vy;
}
However, when I run the program, the arrow keys don't seem to do anything.
I also get the following compiler warnings for both "onKeyDown" and "onKeyUp":
Migration issue: The onKeyDown event handler is not triggered
automatically by Flash Player at run time in ActionScript 3.0. You
must first register this handler for the event using addEventListener
( 'keyDown', callback_handler)
Trying to add what it suggested just makes errors saying callback_handler ain't defined.
I'm now stuck trying to figure out how to make the keyboard input work. Anyone know?
You are currently missing the functions for the key listeners. You have added the listeners to the stage here:
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
Now you just need to create the functions:
function onKeyDown( e:KeyboardEvent ):void {
//add our key to the keys array
keys[e.keyCode] = e.keyCode;
}
function onKeyUp( e:KeyboardEvent ):void {
//if the key is in the keys array, set the value to null
keys[e.keyCode] = null;
}
But there is another problem here:
Car.addEventListener(Event.ENTER_FRAME, this.RunGame);
You do not need the this.RunGame, just RunGame will do, but you should get an error this method needs a parameter of type Event, so your RunGame() definition should look like this:
function RunGame(e:Event):void
Then you wouldn't call RunGame(), it is called each frame while tied to the event listener.
Edit: Please note that there are many ways to handle key events, my answer will work with your current implementation.

How to remove a function or event stop it from stage.addEventListener in as3

I´m trying to make object follow the mouse in as3.
My wish is when I roll over a movieclip(btn1) I want the function that make object follow the mouse(my_object) stop until I roll out of it.
HERE IS THE SCRIPT:
btn1.addEventListener(MouseEvent.ROLL_OVER, JD);
function JD(event:MouseEvent):void{
stage.removeEventListener(Event.ENTER_FRAME, follow_me);
}
btn1.addEventListener(MouseEvent.ROLL_OUT, kk);
function kk(event:MouseEvent):void{
play();
}
stage.addEventListener(Event.ENTER_FRAME,follow_me)
function follow_me(event:Event):void {
var dx:int = bracketL.x - mouseX;
var dy:int = bracketL.y - mouseY;
my_object.x -= dx / 9+5;
my_object.y -= dy /9;
}
Even I roll over the btn1, the my_object does not stop, it still follow the mouse !!
WHAT SHOULD I DO ?
Using a different approach for smoother animation, you could create a enter frame handler that checks for a paused state variable.
Each frame, your object is animated following the mouse cursor; however, if the mouse rolls over your button the object is paused from tracking the mouse.
Example SWF
CS6 FLA source code
CS5 FLA source code
Code:
import flash.events.Event;
import flash.events.MouseEvent;
var paused:Boolean = false;
addEventListener(Event.ENTER_FRAME, frameHandler);
button.addEventListener(MouseEvent.ROLL_OVER, buttonOverHandler);
button.addEventListener(MouseEvent.ROLL_OUT, buttonOutHandler);
function buttonOverHandler(event:MouseEvent):void
{
paused = true;
}
function buttonOutHandler(event:MouseEvent):void
{
paused = false;
}
function frameHandler(event:Event):void
{
if (!paused)
{
object.x -= (object.x - mouseX) * 0.1;
object.y -= (object.y - mouseY) * 0.1;
}
}

Bullets will only fire to the right?

I'm making a flash game for my course at college, I have been following a tutorial but been spinning it off for my own sake. One wall I hit is that when I fire a bullet, it will only fire to the right, with a little movement up or down, I have been trying to fix it for a while but nothing is happening and nothing works.
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class Wizard extends MovieClip {
private var dx:Number;
private var dy:Number;
private var Bulletspeed:int;
public var Angle:Number;
public var newAngle:Number;
var shotCoolDown:int;
const MAX_COOLDOWN=20;
public function Wizard() {
//constructor
//Shot cool down
shotCoolDown=MAX_COOLDOWN;
addEventListener(Event.ENTER_FRAME, update);
//set up an event listener for when the turret is added to stage
addEventListener(Event.ADDED_TO_STAGE, initialise);
}
function initialise(e:Event) {
//reduce shot cool down by one
shotCoolDown=shotCoolDown-1;
//add a click listener to the stage
stage.addEventListener(MouseEvent.CLICK, fire);
}
function fire(m:MouseEvent) {
//Able to shoot
if (shotCoolDown<=0) {
//resets cool down
shotCoolDown=MAX_COOLDOWN;
//spawn bullet
var B = new Bullet();
//set position and rotation of the bullet
B.rotation=rotation;
B.x=x;
B.y=y;
//add the bullet the the wizard
parent.addChild(B);
}
}
function update():void {
//Shot cool down
shotCoolDown--;
//Make the Wizard face the mouse
if (parent!=null) {
dx=stage.mouseX-this.x;
dy=stage.mouseY-this.y;
Math.abs(dx);
Math.abs(dy);
var Angle=Math.atan2(dy,dx);
var newAngle = Angle * (180 / Math.PI);
if ((0 < newAngle) && (newAngle <= 90)) {
gotoAndPlay("Right");
} else if ((90 < newAngle) && (newAngle <= 180)) {
gotoAndPlay("Down");
} else if ((-180 < newAngle) && (newAngle <= -90)) {
gotoAndPlay("Left");
} else if ((-90 < newAngle) && (newAngle <= 0)) {
gotoAndPlay("Up");
}
this.rotation=Angle;
}
}
}
}
That's the code for my player class, with things such as bullets firing and what not. I think I know the problem, I need to link it to the rest of the Wizard update. But I don't know how, here is my bullet class if needed.
package {
import flash.display.Sprite;
import flash.events.Event;
public class Bullet extends Sprite {
private var speed:int;
private var myCharacter:Wizard;
public function Bullet() {
//constructor
speed = 10;
addEventListener(Event.ENTER_FRAME, update);
}
function update (e:Event) {
//Move in the direction the bullet is facing
x=x+Math.cos(rotation/180*Math.PI)*speed;
y=y+Math.sin(rotation/180*Math.PI)*speed;
//Clears bullet once it leaves the stage
if (x<0 || x>500 || y<0 || y>500) {
//removes the update listner
removeEventListener(Event.ENTER_FRAME, update);
parent.removeChild(this);
}
}
}
}
You're setting the Wizard's rotation to Angle, which is in radians; the rotation is then passed on to the Bullet, which expects its rotation to be in degrees. It's probably better to set this.rotation=newAngle; at the end of update(), as the UIComponent class expects that value in degrees and uses it for rotating its drawing.

AS3 - If symbol's coordinates arrive here?

I'm using Flash Professional CS5.5 and I need to make an app where there is a ball (symbol) that moves using the accelerometer and I want that, when the ball coordinates A reach this coordinates B it goes to frame 2 (gotoAndPlay(2)). I have to find the ball coord first, right? How do I make this?
Here is the code I've now
c_ball.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
function fl_ClickToDrag(event:MouseEvent):void{
c_ball.startDrag();}
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
function fl_ReleaseToDrop(event:MouseEvent):void{
c_ball.stopDrag();}
would it work if, after retriving the coordinates?
function f_level (e) if (c_ball.x==100 && c_ball.y==100) {
gotoAndStop(2);}
MOUSE_UP and MOUSE_DOWN are not what you need if you're looking for Accelerometer data. You want the Accelerometer class and associated events.
Try something like this:
import flash.sensors.Accelerometer;
import flash.events.AccelerometerEvent;
var accel:Accelerometer = new Accelerometer();
accel.addEventListener(AccelerometerEvent.UPDATE, handleAccelUpdate);
Update handler:
function handleAccelUpdate(e:AccelerometerEvent):void{
//inside this function you now have access to acceleration x/y/z data
trace("x: " + e.accelerationX);
trace("y: " + e.accelerationY);
trace("z: " + e.accelerationZ);
//using this you can move your MC in the correct direction
c_ball.x -= (e.accelerationX * 10); //using 10 as a speed multiplier, play around with this number for different rates of speed
c_ball.y += (e.accelerationY * 10); //same idea here but note the += instead of -=
//you can now check the x/y of your c_ball mc
if(c_ball.x == 100 && c_ball.y == 100){
trace("you win!"); //fires when c_ball is at 100, 100
}
}
Now this will let you "roll" your MC off the screen so you're probably going to want to add some kind of bounds checking.
Check out this great writeup for more info:
http://www.republicofcode.com/tutorials/flash/as3accelerometer/
An easy and save way is to use colission detection, instead of testing for exectly one position ( what is hard to meet for users) you go for a target area :
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
public class Hittester extends Sprite
{
var ball:Sprite = new Sprite();
var testarea:Sprite = new Sprite();
public function Hittester()
{
super();
ball.graphics.beginFill(0xff0000);
ball.graphics.drawCircle(0,0,10);
testarea.graphics.beginFill(0x00ff00);
testarea.graphics.drawRect(0,0,50,50);
testarea.x = 100;
testarea.y = 100;
// if testarea should be invisble
/*testarea.alpha = 0;
testarea.mouseEnabled = false;
*/
ball.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
addChild(testarea);
addChild(ball);
}
private function startDragging( E:Event = null):void{
ball.startDrag();
stage.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
}
private function stopDragging( E:Event = null):void{
stage.removeEventListener(MouseEvent.MOUSE_UP, stopDragging);
ball.stopDrag();
test();
}
private function test():void{
if( ! ball.hitTestObject(testarea) ){
ball.x = 10;
ball.y = 10;
}
else{
// here goes next frame command ;)
}
}
}
}

Click and Dragging through frames AS3

I have a frame-by-frame animation. I want to be able to click and drag on the stage back and forth and traverse through the animation. I.e. I want to click and drag from left to right to make the animation go forwards and right to left to make the animation go backwards.
How would I achieve this?
I am making an assumption that there will be some maths involved in calculating mouse position and traversing to the correct frame, but how would I do this?
Here you are (edited version)
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.display.Sprite;
var clickedMouseX:int;
var clickedFrame:uint;
var backgroundClip:Sprite = getChildByName("background") as Sprite;
var clip:MovieClip = getChildByName("animation") as MovieClip;
clip.stop();
clip.mouseEnabled = false;
backgroundClip.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
backgroundClip.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
function onMouseDown(event:MouseEvent):void
{
backgroundClip.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
clickedMouseX = backgroundClip.mouseX;
clickedFrame = clip.currentFrame;
}
function onMouseUp(event:MouseEvent):void
{
backgroundClip.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
function onMouseMove(event:MouseEvent):void
{
var delta:int = backgroundClip.mouseX - clickedMouseX;
var wantedFrame:uint = (clickedFrame + delta * clip.totalFrames / backgroundClip.width) % clip.totalFrames;
while (wantedFrame < 1)
{
wantedFrame += clip.totalFrames;
}
clip.gotoAndStop(wantedFrame);
}
Cheers!
It should be a matter of mapping the length of your drag area to the length of the timeline:
stage.addEventListener(MouseEvent.MOUSE_MOVE, updateAnimation);
function updateAnimation(event:MouseEvent):void {
animation.gotoAndStop(Math.floor(mouseX/stage.stageWidth * animation.totalFrames));
}
Here's a commented version:
stage.addEventListener(MouseEvent.MOUSE_MOVE, updateAnimation);
function updateAnimation(event:MouseEvent):void {
//take the ratio between the mouse position and stage width -> //a number from 0.0 to 1.0
var mouseRatio:Number = mouseX/stage.stageWidth;
//'scale'/multiply that number to fit the animation frames -> from a maximum of 1.0 to animation's total frames
//also, we 'round down' because we need an integer for the frame number, not a fractional number
var frame:int = Math.floor(mouseRatio * animation.totalFrames);
animation.gotoAndStop(frame);
}
Also, not that MOUSE_MOVE gets triggered several frames per second. You could update on ENTER_FRAME and since you mentioned dragging, you could also have a variable to keep track if the mouse is pressed or released:
var mousePressed:Boolean;
stage.addEventListener(MouseEvent.MOUSE_DOWN, togglePressed);
stage.addEventListener(MouseEvent.MOUSE_UP, togglePressed);
stage.addEventListener(Event.ENTER_FRAME, update);
function togglePressed(event:MouseEvent):void {
mousePressed = event.type == MouseEvent.MOUSE_DOWN;
}
function update(event:Event):void {
if(mousePressed) animation.gotoAndStop(Math.floor(mouseX/stage.stageWidth * animation.totalFrames));
}
HTH