Swipe Gesture, As3 - actionscript-3

hello im trying to make my gotoAndStop button as swipe instead of onpress. but it only work once, the second frame i make is not working anymore and i dont know the error please help me , thanks
Multitouch.inputMode = MultitouchInputMode.GESTURE;
story1chapter3.addEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipe);
function onSwipe (e:TransformGestureEvent):void{
if (e.offsetX == 1) {
//User swiped towards right(back button)
story1chapter3.x += 100;
gotoAndStop(31);
}
if (e.offsetX == -1) {
//User swiped towards left(next)
story1chapter3.x -= 100;
gotoAndStop(159);
}
}
this code is working but when i try to make another code same as this in different frame its not working anymore, i also change the instance name so it wont dupplicate
Multitouch.inputMode = MultitouchInputMode.GESTURE;
story1chapter2.addEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipe);
function onSwipe2 (e:TransformGestureEvent):void{
if (e.offsetX == 1) {
//User swiped towards right(back button)
story1chapter2.x += 100;
gotoAndStop(30);
}
if (e.offsetX == -1) {
//User swiped towards left(next)
story1chapter1.x -= 100;
gotoAndStop(27);
}
}
PS i also try to change onSwipe2 to onSwipe , but error comes saying its duplicate

Well this is not the clean way of doing this by having two similar functions but that's another topic :) I assume the problem is that when you do the swipe the second time BOTH event listeners are getting the swipe event and both try to gotoAndPlay. Try to remove the event listener on swipe:
story1chapter3.addEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipe);
function onSwipe (e:TransformGestureEvent):void{
if (e.offsetX == 1) {
//User swiped towards right(back button)
story1chapter3.x += 100;
story1chapter3.removeEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipe);
gotoAndStop(31);
}
if (e.offsetX == -1) {
//User swiped towards left(next)
story1chapter3.x -= 100;
story1chapter3.removeEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipe);
gotoAndStop(159);
}
}
A better approach would be to have just ONE event listener on the stage and have one function that would bring the player to the right chapter depending on where you currently are, then you would not need to mess around with several functions but have everything in one place

Related

Need help fixing player jumping diagonally Flash CS4

I can't figure out why when I try and get my player to jump diagonally by pressing the right and up arrow key it does nothing, I've used trace to see if anything was happening and nothing was when they were used together.
Up won't work by itself or with right but when right is by itself it works.
player is named hero, platforms are named platform, platform2, platform3 etc
platforms are in the platform layer
stop();
var gravity:Number=5; //Very important, allows player to fall
var movex:Number=0; // Moving players X
// Moving player
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveHero);
var speed=10;
function moveHero(event:KeyboardEvent) {
if (event.keyCode==Keyboard.LEFT) {
hero.x-=speed;
hero.play();
}
if (event.keyCode==Keyboard.RIGHT) {
hero.x+=speed;
hero.play();
}
}
hero.addEventListener(Event.ENTER_FRAME, testCollision2);
// Allowing player to jump when on platform
function testCollision2(e: Event) {
//Allowing player to jump when on platform continued
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveHeroUP);
function moveHeroUP(event:KeyboardEvent) {
if (hero.hitTestObject(platform) && event.keyCode==Keyboard.UP) {
gravity=-50;
hero.y=hero.y+gravity;
} else if (hero.hitTestObject(platform2) && event.keyCode==Keyboard.UP) {
gravity=-50;
hero.y=hero.y+gravity;
} else if (hero.hitTestObject(platform4) && event.keyCode==Keyboard.UP) {
gravity=-50;
hero.y=hero.y+gravity;
}
if(hero.hitTestObject(platform) && event.keyCode==Keyboard.UP && event.keyCode==Keyboard.RIGHT){
movex = 20;
hero.x = hero.x + movex;
gravity =-50;
hero.y = hero.y + gravity;
}
}
I'm trying to get the player to jump in the code chunk at the very end
Flash CS4
AS3
To start, let's go through how you've set up this code and explain what's happening.
You have this line:
hero.addEventListener(Event.ENTER_FRAME, testCollision2);
Which is saying, every frame tick that hero exists, run the function testCollision2. Frame tick here doesn't relate to timeline frames, it relates to the frame rate of your application. So if that is set to 12, that function will run 12 times every second.
Inside testCollision2, you add another listener:
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveHeroUP);
and create an inline function called moveHeroUP. So every frame tick, you create a new function, and attach it to a key down event. So (assuming 12 frames per second) 5 seconds into your application, you'll have 60 keyboard listeners all doing the same thing. This is also a memory leak (as you keep creating a new function every frame), so eventually your program will crash.
To get to the actual question, a keyboard event is tied to one specific key. This means the event's keyCode is only ever one key (the key that triggered the event). So doing something like (event.keyCode==Keyboard.UP && event.keyCode==Keyboard.RIGHT) will always be false because event.keyCode only ever holds one value.
A common approach to your situation, is to have one global key down and key up listener. Then use a dictionary to store which keys are currently down:
//create just one key down listener
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
//create a dictionary to store key presses
var keyboardDown:Dictionary = new Dictionary();
function keyDownHandler(e:KeyboardEvent):void {
keyboardDown[e.keyCode] = true;
}
function keyUpHandler(e:KeyboardEvent):void {
keyboardDown[e.keyCode] = false;
}
What you're doing here, is when a key down event fires, you set the value in the dictionary to true (with the keycode as the dictionary key), then on the key up event you set it to false.
Now, in your ENTER_FRAME handler, you use the dictionary values to check for key combinations:
hero.addEventListener(Event.ENTER_FRAME, moveHero);
function moveHero(event:Event) {
//DO ALL YOUR MOVEMENTS IN ONE ENTER FRAME FUNCTION
if (keyboardDown[Keyboard.LEFT]) {
hero.x-=speed;
hero.play();
}
if (keyboardDown[Keyboard.RIGHT]) {
hero.x+=speed;
hero.play();
}
if (hero.hitTestObject(platform) && keyboardDown[Keyboard.UP]) {
gravity=-50;
hero.y=hero.y+gravity;
} else if (hero.hitTestObject(platform2) && keyboardDown[Keyboard.UP]) {
gravity=-50;
hero.y=hero.y+gravity;
} else if (hero.hitTestObject(platform4) && keyboardDown[Keyboard.UP]) {
gravity=-50;
hero.y=hero.y+gravity;
}
if(hero.hitTestObject(platform) && keyboardDown[Keyboard.UP] && keyboardDown[Keyboard.RIGHT]){
movex = 20;
hero.x = hero.x + movex;
gravity =-50;
hero.y = hero.y + gravity;
}
}

AS3 flash keyboard events spacebar issue

hi guys thank you so much for trying to help
Ok so the question is this. I am trying to move a movieclip automatically with
movieClip.x += xspeed ;
ofcourse this works but the point is i want this to be triggered with keyboard press ..problem is i couldn't a keyboard event which works as a mouse click..it works as long as space bar is pressed but if i release it ..it stops working..i want it to be like onclick it should start moving automatically.
Any ideas? thanks
hi thanks so much for your reply and sorry for the delay. Your code gave me an idea but I tried to write it without classes . It doesnt throw up any errors however it doesnt work either . I must be doing something stupid , please have a look and let me know . //rope coding
var ropey = MovieClip(this.root).boat_mc.rope_mc.fishyrope_mc.hitbox_mc.y ;
trace(ropey);
var ropemove:Boolean;
stage.addEventListener(Event.ENTER_FRAME,ropeCode);
function ropeCode(e:Event):void
{
//detect keyboard spacebar click
stage.addEventListener(KeyboardEvent.KEY_UP,onSpacebarUp);
function onSpacebarUp(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.SPACE)
{
ropemove = true;
} else if(ropey > 600 ) {
ropemove = false;
}
}
//drop rope if variable = true
function dropRope(e:Event):void
{
if(ropemove = true) {
MovieClip(this.root).boat_mc.rope_mc.y += xSpeed;
} else if (ropemove = false) {
MovieClip(this.root).boat_mc.rope_mc.y -= xSpeed;
}
}
}
MyObj extends MovieClip (or Sprite). Basically alls that's happening is you should just toggle a variable when you get the KEY_UP (not KEY_DOWN, as that will repeat if the key is held down). Then, every frame, check this variable, and if's it's good, move
Something like:
private var m_shouldMove:Boolean = false;
// constructor
public function MyObj()
{
// add our listener for when we're added to the stage as we'll be adding events on it
this.addEventListener( Event.ADDED_TO_STAGE, this._onAddedToStage );
}
private function _onAddedToStage( e:Event ):void
{
// NOTE: the keyboard listener goes onto the stage
// you'll also need to remove the events when your object is removed (e.g. REMOVED_FROM_STAGE)
this.removeEventListener( Event.ADDED_TO_STAGE, this._onAddedToStage );
this.addEventListener( Event.ENTER_FRAME, this._onEnterFrame );
this.stage.addEventListener( KeyboardEvent.KEY_UP, this._onKeyUp );
}
private function _onEnterFrame( e:Event ):void
{
// every frame, if we should move, do so
if( this.m_shouldMove )
this.x += this.speed;
}
private function _onKeyUp( e:KeyboardEvent ):void
{
if( e.keyCode == Keyboard.SPACE )
this.m_shouldMove = !this.m_shouldMove; // toggle our var
}
Update
I've reworked your code sample, so it should work now:
var rope = MovieClip(this.root).boat_mc.rope_mc.fishyrope_mc.hitbox_mc;
var ropeMove:Boolean = false;
stage.addEventListener(Event.ENTER_FRAME, ropeCode);
stage.addEventListener(KeyboardEvent.KEY_UP, onSpacebarUp);
function onSpacebarUp(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.SPACE)
ropeMove = !ropeMove; // toggles ropeMove (i.e. if it's true, sets it to false, and vice versa)
}
function ropeCode(e:Event):void
{
// move the rope
if( ropeMove )
{
rope.y += xSpeed;
// stop moving if we've gone too far
if( rope.y > 600.0 )
{
rope.y = 600.0;
ropeMove = false;
}
}
}
What I changed:
Held your rope as a variable to make it easier to access
Removed ropey as it's not needed (for your > 600.0 check, you need to recalculate it anyway
The keyboard event is now added with the enter frame event (you were adding a new keyboard event every frame
The keyboard event listener just toggles the ropeMove var (there's no point checking for > 600.0 here as it means you only check when any other key is pressed)
The enter frame event simply moves the rope y
In the enter frame event, if our y is too big, we stop moving
What the code is doing:
We set up our vars - rope and ropeMove - ropeMove is used to know if we can move the rope or not
We add our event listeners - one for the keybard event, to catch the spacebar key, and one enter frame event, so we can move our rope if necessary
In the keyboard event, if our key is the spacebar, we toggle our ropeMove variable
In the enter frame event, if ropeMove is true, we move our rope
If our rope.y is greater than 600, we clamp it to 600, and set ropeMove to false so we stop moving
Update 2
With the addition of a variable ropeDir, the rope will now continuously move up and down (assuming ropeMove is true)
var rope = MovieClip(this.root).boat_mc.rope_mc.fishyrope_mc.hitbox_mc;
var ropeMove:Boolean = false;
var ropeDir:int = 1;
stage.addEventListener(Event.ENTER_FRAME, ropeCode);
stage.addEventListener(KeyboardEvent.KEY_UP, onSpacebarUp);
function onSpacebarUp(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.SPACE)
ropeMove = !ropeMove; // toggles ropeMove (i.e. if it's true, sets it to false, and vice versa)
}
function ropeCode(e:Event):void
{
// move the rope
if( ropeMove )
{
rope.y += xSpeed * ropeDir;
// stop moving if we've gone too far
if( rope.y > 600.0 && ropeDir == 1 )
ropeDir = -1;
else if( rope.y < 0.0 && ropeDir == -1 )
ropeDir = 1;
}
}
addEventListener(KeyboardEvent.KEY_DOWN, moveStarter);
function moveStarter():void
{
addEventListener(Event.ENTER_FRAME, startMove);
}

as3 continuous movement of object with touch event

i am attempting to make an interactive scene fot my nexus 7 using actionscript. i am attempting to make a nape body to move continuously while a button is being pressed. the trace(event.target.name); in the tap handler is returning the instance name of the button being pressed as i expected it to but the same trace statement in the enter_frame pressed function is returning the buttons parent name and thus the movement is not happening below is my code..
resetBtn.addEventListener(TouchEvent.TOUCH_BEGIN , tapHandler);
ballBtn.addEventListener(TouchEvent.TOUCH_BEGIN , tapHandler );
leftArrow.addEventListener(TouchEvent.TOUCH_BEGIN , tapHandler );
rightArrow.addEventListener(TouchEvent.TOUCH_BEGIN , tapHandler );
private function tapHandler(event:TouchEvent):void
{
//listen for mouse up on the stage, in case the finger moved off of the button accidentally when they release.
rightArrow.addEventListener(TouchEvent.TOUCH_END, endTouch);
//while the mouse is down, run the tick function once every frame as per the project frame rate
addEventListener(Event.ENTER_FRAME, pressed);
trace(event.target.name);
//ball.applyImpulse(new Vec2(25,0));
}
function endTouch(e:Event):void
{
removeEventListener(Event.ENTER_FRAME, pressed);
//stop running the tick function every frame now that the mouse is up
this.removeEventListener(TouchEvent.TOUCH_END,endTouch);
//remove the listener for endTouch
}
function pressed(e:Event):void
{
space.step(1 / stage.frameRate);
trace(e.target.name);
if(e.target.name == "leftArrow")
{
trace("going left");
crane.position.x -= 5;
boom.position.x -= 5;
c.position.x -= 5;
}
if(e.target.name == "rightArrow")
{
trace("going Right");
crane.position.x += 5;
boom.position.x += 5;
c.position.x += 5;
}
}
if you can help me fix this or suggest a better way of achieving this wour help would be greatly appreciated.
Your issue is basically that you're adding the listener to the parent for the Enter_frame events so the target when that event dispatches isn't your buttons as you desire. I think instead of moving the listener though you're better off using a variable to hold a reference to your buttons like this:
private var curButton:Sprite;
resetBtn.addEventListener(TouchEvent.TOUCH_BEGIN , tapHandler);
ballBtn.addEventListener(TouchEvent.TOUCH_BEGIN , tapHandler );
leftArrow.addEventListener(TouchEvent.TOUCH_BEGIN , tapHandler );
rightArrow.addEventListener(TouchEvent.TOUCH_BEGIN , tapHandler );
private function tapHandler(event:TouchEvent):void
{
curButton = event.target;
curButton.addEventListener(TouchEvent.TOUCH_END, endTouch);
addEventListener(Event.ENTER_FRAME, pressed);
}
function endTouch(e:Event):void
{
trace("touch end received");
removeEventListener(Event.ENTER_FRAME, pressed);
curButton.removeEventListener(TouchEvent.TOUCH_END, endTouch);
curButton = null;
}
function pressed(e:Event):void
{
trace("currently pressed");
space.step(1 / stage.frameRate);
if(curButton == leftArrow)
{
trace("going left");
crane.position.x -= 5;
boom.position.x -= 5;
c.position.x -= 5;
}
if(curButton == rightArrow)
{
trace("going Right");
crane.position.x += 5;
boom.position.x += 5;
c.position.x += 5;
}
}
Okay see my edits above, hopefully should help resolve. Also as it seems you've probably already figured out the instance name that you give a variable when you define it, isn't the same as the .name property or the .id property, the instance name is no longer available at run time (if you really want to you can use the name property but you have to populate it yourself, and generally it's best to just use the instance names in the code instead, as this is checked at compile time, and incurs no extra run-time overhead).

AS3 : How to remove movieclip properly without Error 1009 overflow?

I have a class Catcher which lets you control a movieclip in a game. I'm trying to program the game so it finishes and you can restart. So I need to remove everything and go back to the menu. Should be a simple thing to solve but I can't seem to find out how.
So far I just have ourCatcher.parent.removeChild(ourCatcher); to remove my movieclip from the stage. And an if statement to stop one of the functions which drops things onto the stage. SoundMixer.stopAll(); to stop the music.Then I just have it going to frame 3 which is the gameover screen.
It looks fine but I get constant 1009 errors overflowing in the error console and when I restart the game, it's super slow. It seems the function for movement within Catcher is still running and creating an error because the Catcher was removed from stage and is null now.
I know I need to un-reference everything to do with the Catcher but I can't find out any documentation online to do it in my situation. Everyone seems to have different methods which I've tried and don't work.
The two functions in the Catcher class I'm using to move the character :
public function Catcher(stageRef:Stage)
{
stop();
this.stageRef = stageRef;
key = new KeyObject(stageRef);
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
//movement
public function loop(e:Event):void
{
if (key.isDown(Keyboard.A))
vx -= walkSpeed;
else if (key.isDown(Keyboard.D))
vx += walkSpeed;
else
vx *= friction;
//update position
x += vx;
//speed adjustment
if (vx > maxspeed)
vx = maxspeed;
else if (vx < -maxspeed)
vx = -maxspeed;
//stay inside screen
if (x > stageRef.stageWidth)
{
x = stageRef.stageWidth;
vx = -vx
}
else if (x < 0)
{
x = 0;
vx = -vx;
}
if (key.isDown(Keyboard.A))
{
scaleX = -1;
}
else if (key.isDown(Keyboard.D))
{
scaleX = 1;
}
movement();
// Jumping
jump += gravity;
if (y > stage.stageHeight /1.5)
{
jump = 0;
canJump = true;
}
if (key.isDown(Keyboard.SPACE) && canJump)
{
jump = -10;
canJump = false;
}
y += jump;
}
The other class where I'm removing the things from the stage is called CatchingGame and it has a function which drops objects, I put the game over code there for when playerlives == 0 .
if (playerLives == 0 )
{
stop();
ourCatcher.parent.removeChild(ourCatcher);
SoundMixer.stopAll();
gotoAndStop(3);
}
I've probably made an elementary mistake since this is my first flash game. Any help is greatly appreciated as this is pretty much the last step in finishing my game.
Instead of just removing the child by referencing its parent to remove itself (I had to test to make sure this actually worked). Create a function in same place that you create/instantiate the Catcher that removes first the eventListener ENTER_FRAME, then removes the Catcher.
if (playerLives == 0 ) {
stop();
removeCatcher();
SoundMixer.stopAll();
gotoAndStop(3);
}
// new location in the main code where the catcher is created
function removeCatcher():void {
ourCatcher.cleanUp();
removeChild(ourCatcher);
}
// in the Catcher class
function cleanUp():void {
removeEventListener(Event.ENTER_FRAME, loop);
}
if (ourCatcher.parent) ourCatcher.parent.removeChild(ourCatcher);
else trace("Catcher without a parent still plays! DEBUG THIS!");
Basically, you are most likely losing control flow of your catcher, that is, it seemingly tries to remove itself from the stage twice. After it removes itself first time, its parent becomes null, hence the 1009. And, seeing as you've hit a 2028, the same reason applies, your catcher is no longer a child of anywhere.

Creating collision detection on more than one variable in a for loop?

Essentially I am trying to create a game, where the player has to dodge certain items, so far I have a piece of code that randomly adds 3 sharks to the stage.
The idea is that once the player has hit a shark he/she returns to the start location, I have an Action Script file that contains the speed,velocity etc of the shark, the every time the program is run the sharks will appear in a different location.
However, when I attempt to do a collision test of the sharks only one of the sharks respond, I cannot figure out how to make it that all 3 sharks effect the player (square_mc). Any help would be greatly appreciated.
//Pirate game, where you have to avoid particular object and get to the finish line to move onto the final level.
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveMode );
function moveMode(e:KeyboardEvent):void {
//movements for the pirate ship, this will allow the ship to move up,down,left and right.
if (e.keyCode == Keyboard.RIGHT) {
trace("right");
square_mc.x = square_mc.x + 25;
}
else if (e.keyCode == Keyboard.LEFT) {
trace("left");
square_mc.x = square_mc.x - 25;
}
else if (e.keyCode == Keyboard.UP) {
trace("up");
square_mc.y = square_mc.y - 25;
}
else if (e.keyCode == Keyboard.DOWN) {
trace("down");
square_mc.y = square_mc.y + 25;
}
}
//for.fla
//this program uses a for loop to create my Sharks
//a second for loop displays the property values of the sharks
function DisplayShark():void{
for (var i:Number=0;i<3;i++)
{
var shark:Shark = new Shark(500);
addChild(shark);
shark.name=("shark"+i);
shark.x=450*Math.random();
shark.y=350*Math.random();
}
}
DisplayShark();
for(var i=0; i<3;i++){
var currentShark:DisplayObject=getChildByName("shark"+i);
trace(currentShark.name+"has an x position of"+currentShark.x+"and a y position of"+currentShark.y);
}
//here we will look for colliosion detection between the two move clips.
addEventListener(Event.ENTER_FRAME, checkForCollision);
function checkForCollision(e:Event):void {
if (square_mc.hitTestObject(currentShark))
{
trace("The Square has hit the circle");
square_mc.x=50
square_mc.y=50 //these lines of code return the square back to it's original location
}
}
Just move your for loop into the ENTER_FRAME:
addEventListener(Event.ENTER_FRAME, checkForCollision);
function checkForCollision(e:Event):void {
for(var i=0; i<3;i++){
var currentShark:DisplayObject=getChildByName("shark"+i);
if (square_mc.hitTestObject(currentShark))
{
trace("The Square has hit the circle");
square_mc.x=50;
square_mc.y=50;
}
}
}
You can't just go through the for loop once and set the currentShark variable - you'll just end up testing against one shark every time you perform the collision test. Rather, every time you want to check collisions you must loop through all the sharks and do the collision testing.