I have a project where a MovieClip gets copied when clicked and dragged. It is also possible to rotate and scale the MovieClip with arrow keys.
But this only rotates last MovieClip dragged, not last MovieClip clicked. So if I drag a new copy, the previous dragged copies are not able to rotate or scale.
How can I change this to only make the last MovieClip clicked able to rotate and scale, when arrow keys are pressed?
Here is some of the code used (taken and slightly modified from another post):
addEventListener(Event.ENTER_FRAME, moveObject);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHit);
stage.addEventListener(KeyboardEvent.KEY_UP, noKeyHit);
function keyHit(e:KeyboardEvent):void{
if(e.keyCode == Keyboard.LEFT) leftArrow = true;
if(e.keyCode == Keyboard.RIGHT) rightArrow = true;
if(e.keyCode == Keyboard.UP) upArrow = true;
if(e.keyCode == Keyboard.DOWN) downArrow = true;
}
function noKeyHit(e:KeyboardEvent):void{
if(e.keyCode == Keyboard.LEFT) leftArrow = false;
if(e.keyCode == Keyboard.RIGHT) rightArrow = false;
if(e.keyCode == Keyboard.UP) upArrow = false;
if(e.keyCode == Keyboard.DOWN) downArrow = false;
}
function moveObject(e:Event):void{
if(leftArrow) latestClone.rotation -=0.75;
if(rightArrow) latestClone.rotation +=0.75;
if(upArrow) latestClone.scaleY +=0.01
if(downArrow) latestClone.scaleY -=0.01;
}
Thank you
In your code you are scaling and rotating latestClone.
Somewhere outside of this code you are setting the value of latestClone.
If you want to rotate the latest clicked MovieClip, add an event listener to the click:
latestClone.addEventListener(MouseEvent.CLICK, onCloneClick);
function onCloneClick(e:MouseEvent):void
{
var target:MovieClip = e.currentTarget as MovieClip;
latestClone = target;
}
Related
Why Lib.current.stage gives me this error:
src/Main.hx:43: characters 2-35 : openfl.display.DisplayObject cannot be called
Edit: I have tried the following code.
Lib.current.stage.addEventLitener(
KeyboardEvent.KEY_DOWN,
function(e:KeyboardEvent) {
if (e.keyCode == Keyboard.W) up = true;
if (e.keyCode == Keyboard.A) left = true;
if (e.keyCode == Keyboard.D) right = true;
if (e.keyCode == Keyboard.S) down = true;
}
);
I think MovieClip implements Dynamic<MovieClip> so that any reference not in the class definition is assumed to be a MovieClip.
You've got a typo there on addEventLitener, missing an 's' which isn't in the class definition, so is assumed to be a MovieClip, which cannot be called.
I am at a lost, which is not surprising for a beginner to encounter. Im attempting to execute a smooth and seamless keyboard direction command. Issue occurs when keys are held which creates a delay and fragmented like movement. code is below and please be gentle im new at this =)
var dx:Number = 0;
paddle.addEventListener(Event.ENTER_FRAME, motion);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
function motion (event:Event):void{
paddle.x = dx
}
function keyPressed(event:KeyboardEvent):void{
if(event.keyCode == Keyboard.LEFT){
dx -= 20;
}
if(event.keyCode == Keyboard.RIGHT){
dx += 20;
}
}
You basically keep track of when the key is pressed on KEY_DOWN and reset it on KEY_UP. Then, in your ENTER_FRAME, you check if the key is pressed, and move your paddle.
Something like this:
var isLeftPressed:Boolean = false;
var isRightPressed:Boolean = false;
stage.addEventListener( KeyboardEvent.KEY_DOWN, this._onKeyDown );
stage.addEventListener( KeyboardEvent.KEY_UP, this._onKeyUp );
paddle.addEventListener( Event.ENTER_FRAME, this._onEnterFrame );
// called when a key is pressed
function _onKeyDown( e:KeyboardEvent ):void
{
if( e.keyCode == Keyboard.LEFT )
isLeftPressed = true;
if( e.keyCode == Keyboard.RIGHT )
isRightPressed = true;
}
// called when a key is released
function _onKeyUp( e:KeyboardEvent ):void
{
if( e.keyCode == Keyboard.LEFT )
isLeftPressed = false;
if( e.keyCode == Keyboard.RIGHT )
isRightPressed = false;
}
// called every frame
function _onEnterFrame( e:Event ):void
{
// get our direction based on what key is pressed, and move our paddle
var dirX:int = ( isLeftPressed ) ? -1 : ( isRightPressed ) ? 1 : 0;
paddle.x += 20 * dirX;
}
This can easily be generalised for any key (keep a Vector.<Boolean> using the keyCode as an index) - Check out the PushButtonEngine KeyboardManager for the general gist: https://github.com/PushButtonLabs/PushButtonEngine/blob/PBE2/src/com/pblabs/input/KeyboardManager.as
You should move the object when you have a key pressed by the user until KeyboardEvent.KEY_UP event is dispatched to know when the user releases the key. Here is an example of what you are looking for:
Moving Movieclips using Keys with Acstionscript 3
I wish that it helps you. Good luck!
I could not find topic like this and that is why I am posting this question. I have a side scrolling game with the character set up in positions with frame labels- animation states to stand, jump, run, kneel and fire. She is also made to fire bullets with separate class file. The problem is that right now she is firing bullets in all of the animation states. The question is how do I make this character fire the bullets only on the frame label fire. The frame label fire consists of 2 frames and I want the launching of the bullet to happen on the second frame. Which means that the keyboard space will be pressed for a second or two before it goes to this frame and then it will fire (like in real life).
I tried to connect the animation state to the bullets somehow and tried to put the condition in these lines of code somehow:
if(e.keyCode == Keyboard.SPACE){
if (Animation state "Fire (2)")
fireBullet();
}
But it did not work, it doesn't know what I am talking about. The class file for the bullet is separate and I don't think is relevant to the problem.
The rest of the timeline code is like this:
var bulletList:Array = new Array();
if(e.keyCode == Keyboard.SPACE){
fireBullet();
}
}
function fireBullet():void
{
var playerDirection:String;
if(player.scaleX < 0){
playerDirection = "left";
} else if(player.scaleX > 0){
playerDirection = "right";
}
var bullet:Bullet = new Bullet(player.x - scrollX, player.y - scrollY,
playerDirection xSpeed);
back.addChild(bullet);
Thank you. I hope that my question is clear.
There is addFrameScript, AS3's mystery function that can be useful in this situation. And that would look something like this:
playerAnimation.addFrameScript( insertFrameNumber, fireBullet );
addFrameScript runs the method passed as a parameter when the MovieClip reaches a certain frame.
I believe how you would want to use this in your current code:
player.addFrameScript( 5, fireBullet );
Then in your KEY_UP handler:
function keyUpHandler(e:KeyboardEvent):void{
if(e.keyCode == Keyboard.SPACE){
spacePressed = false;
player.gotoAndPlay("fire");
}
if(e.keyCode == Keyboard.LEFT){
leftPressed = false;
}
else if(e.keyCode == Keyboard.RIGHT){
rightPressed = false;
}
else if(e.keyCode == Keyboard.UP){
upPressed = false;
}
else if(e.keyCode == Keyboard.DOWN){
downPressed = false;
}
}
I'm working on a project in which a character walks forwards or backwards across the screen or shoots a rifle depending on whether the user presses one of the following keyboard keys: forward arrow (key 39), back arrow (key 37) or spacebar (key 32).
My problem is that when the user presses and holds the forward arrow key, the character's movieclip plays one instance of the walking forward animation, and then moves forward. I want the walking forward animation to play throughout the entire time the character is moving.
Here is my code:
import fl.transitions.Tween;
import fl.transitions.easing.*;
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveCharacter);
stage.addEventListener(KeyboardEvent.KEY_UP, stopCharacter);
var muzzlePosition:Number = new Number();
var bullet:Bullet = new Bullet();
function moveCharacter(e:KeyboardEvent):void {
switch (e.keyCode) {
case 39 :
if (sprite_Cicada.x<stage.stageWidth-150) {
sprite_Cicada.gotoAndPlay("walk-fwd");
sprite_Cicada.x+=5;
} else {
sprite_Cicada.x+=0;
sprite_Cicada.gotoAndPlay("push");
}
break;
case 37 :
if (sprite_Cicada.x>225) {
sprite_Cicada.x-=3;
sprite_Cicada.gotoAndPlay("walk-bkwds");
} else {
sprite_Cicada.x-=0;
sprite_Cicada.gotoAndPlay("standing");
}
break;
case 32 :
muzzlePosition=sprite_Cicada.x+sprite_Cicada.AK47.x+28;
addChild(bullet);
bullet.gotoAndStop("lead");
bullet.x=muzzlePosition;
bullet.y=328;
sprite_Cicada.gotoAndPlay("fireAK");
var shootBullet:Tween=new Tween(bullet,"x",None.easeOut,muzzlePosition,stage.stageWidth*2,.5,true);
if (bullet.x>stage.stageWidth+50) {
removeChild(bullet);
}
break;
}
}
function stopCharacter(e:KeyboardEvent):void {
sprite_Cicada.gotoAndPlay("standing");
}
Perhaps you can do
stage.addEventListener(KeyboardEvent.KEY_DOWN, keydown );
stage.addEventListener(KeyboardEvent.KEY_UP, keyup);
addEventListener(Event.ENTER_FRAME, movePerson);
function keydown(e:KeyboardEvent) {
if (e.keyCode == Keyboard.LEFT || e.keyCode == Keyboard.RIGHT) { per_mc.gotoAndStop(2) }
if (e.keyCode == Keyboard.LEFT) {leftkeyStatus = true; rightkeyStatus = false;}
if (e.keyCode == Keyboard.RIGHT) {leftkeyStatus = false; rightkeyStatus = true;}
}
function keyup(e:KeyboardEvent) {
if (e.keyCode == Keyboard.LEFT || e.keyCode == Keyboard.RIGHT) { per_mc.gotoAndStop(1) }
if (e.keyCode == (Keyboard.LEFT)) {leftkeyStatus = false;}
if (e.keyCode == (Keyboard.RIGHT)) {rightkeyStatus = false;}
}
function movePerson(e:Event) {
if (rightkeyStatus) {
sprite_Cicada.x-=3;
}
}
I'm really new at AS3, I used to be coding in AS2, but for more than a year I don't use Flash or ActionScript.
My problem is when I press left or right arrow which is defenied to move the character to right and left the animation just stop at the first frame. The idle animation works fine, but the walk animation starts and stop in frame 1 everytime I press the buttons.
vector.gotoAndPlay("parado");
var leftKeyDown:Boolean = false;
var rightKeyDown:Boolean = false;
var mainSpeed:Number = 7;
vector.addEventListener(Event.ENTER_FRAME, moveChar);
function moveChar(event:Event):void{
if(leftKeyDown){
if(vector.currentLabel!="andando"){
vector.x -= mainSpeed;
vector.scaleX=-1;
vector.gotoAndPlay("andando");
}
} else {
if(rightKeyDown){
if(vector.currentLabel!="andando") {
vector.x += mainSpeed;
vector.scaleX=1;
vector.gotoAndPlay("andando");
}
}
}
}
stage.addEventListener(KeyboardEvent.KEY_DOWN, checkKeysDown);
function checkKeysDown(event:KeyboardEvent):void{
if(event.keyCode == 37){
leftKeyDown = true;
}
if(event.keyCode == 39){
rightKeyDown = true;
}
}
stage.addEventListener(KeyboardEvent.KEY_UP, checkKeysUp);
function checkKeysUp(event:KeyboardEvent):void{
if(event.keyCode == 37){
leftKeyDown = false;
}
if(event.keyCode == 39){
rightKeyDown = false;
}
}
FYI: "parado" is my idle animation and "andando" is my walk animation.
It's not stopping at frame 1, it's just being sent back to frame 1 all the time. Consider what happens when you hold down the button for a few seconds:
rightKeyDown starts as false. No code in that branch is executed.
User holds the right arrow, rightKeyDown becomes true
moverChar checks rightKeyDown, sees it's true and sends the character to "andando".
moveChar runs again, sees rightKeyDown is true but the character is still at the "andando" frame, so it does nothing.
Character goes to frame after "andando".
moverChar runs, rightKeyDown is still true, but the frame is not at "andando" anymore, so it resets back to it.
And that repeats during all the time the user is holding down the key, so it appears to be stuck in frames 1 and 2
A few alternatives to fix this problem:
Change the key frame only when the user presses or releases the button, not every frame in between.
function moveChar(event:Event):void{
if(leftKeyDown){
vector.x -= mainSpeed;
// No frame checks or frame changes here.
}
[...]
function checkKeysDown(event:KeyboardEvent):void{
if(event.keyCode == 37){
leftKeyDown = true;
vector.scaleX=-1;
vector.gotoAndPlay("andando");
// Send the character to the correct frame when the user presses the key.
}
[...]
function checkKeysUp(event:KeyboardEvent):void{
if(event.keyCode == 37){
leftKeyDown = false;
vector.gotoAndPlay("parado");
// Send it back to idle when the user releases the key.
}
[...]
Another option is to store each animation in a movieclip by itself and put them in a container movieclip. So there will be only two frames in the character's symbol, one for the idle animation and the other for the walking animation. In your code you use gotoAndStop instead of gotoAndPlay, so it doesn't matter if it's called every frame.
Edit: Also try to group your conditionals.
} else {
if(rightKeyDown){
if(vector.currentLabel!="andando") {
vector.x += mainSpeed;
vector.scaleX=1;
vector.gotoAndPlay("andando");
}
}
}
can be rewritten as
} else if (rightKeyDown && vector.currentLabel != "andando"){
vector.x += mainSpeed;
vector.scaleX=1;
vector.gotoAndPlay("andando");
}