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

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.

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;
}
}

Action script 3 walking animation

i need some help. im trying to make my character walk both direction(left and right) and an idle animation when standing still. i manage to make the character walk to the right and make the idle animation work. now if I copy the code from the right button to the left button, the walking animation gets stuck in the first frame on both direction. I tried to experiment with it but with no luck. im sorry if i sounded noob. i just started with studying programming.
here are the code that i used
RightBtn.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
function mouseDown(e:MouseEvent): void {
if(RightBtn){
isRight = true;
}
}
RightBtn.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
function mouseUp(e:MouseEvent): void {
if(RightBtn){
isRight = false;
}
}
stage.addEventListener(Event.ENTER_FRAME, loop);
function loop(Event){
if(isRight==true && mcPlayer.x < 750){
mcPlayer.x += 7;
mcPlayer.gotoAndStop (2);
mcPlayer.walkR.play ();
}
else{
mcPlayer.gotoAndStop (1)
mcPlayer.Idle.play ();
}
}
LeftBtn.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown2);
function mouseDown2(e:MouseEvent): void {
if(LeftBtn){
isLeft = true;
}
}
LeftBtn.addEventListener(MouseEvent.MOUSE_UP, mouseUp2);
function mouseUp2(e:MouseEvent): void {
if(LeftBtn){
isLeft = false;
}
}
stage.addEventListener(Event.ENTER_FRAME, loop2);
function loop2(Event){
if(isLeft==true && mcPlayer.x > 65){
mcPlayer.x -= 7;
mcPlayer.gotoAndStop (3);
mcPlayer.walkL.play ();
}
else{
mcPlayer.gotoAndStop (1)
mcPlayer.Idle.play ();
}
}
That's what you get from blatant copy&paste without learning the mechanics of how does it internally work. You set two listeners to stage, both altering mcPlayer regardless of whether it was already altered by the other one. So, you need to write both sets of code in one listener, and walk the code with your pen and paper to ensure that both isRight==true and isLeft==true branches work separately and don't interfere with each other. The proper condition statement should be like this:
if (isRight==true && mcPlayer.x < 750) {
// do a step right
} else if (isLeft==true && mcPlayer.x > 65){
// do a step left
} else {
// do idle animation
}
Your codes of initiating animation are correct themselves, they just get overridden by the listeners that are unaware of some other code altering mcPlayer.

Undefined Property Error 1120 moving functions?

I'm very, VERY new at flash, and I've tried really hard to figure this out but it's not working. I keep getting the same error: "1120 Access of undefined property goGame" on line 96 and "1136 Incorrect number of arguments expected 1" on line 82.
I know both of these errors has something to do with the ordering of my functions, but I find that when I move the functions to be in front of the listener, more errors pop up demanding the same thing, and the only way I can fix those is moving them in front of each other etc. etc. So I'm kind of stuck. Help would be great appreciated!
package
{
import flash.display.*;
import flash.events.*;
import flash.ui.*;
import fl.motion.MotionEvent;
import flash.utils.Timer;
import flash.utils.*;
public class StartGame extends MovieClip
{
var questions: Array=new Array();
var correctAnswers: Array=new Array("blue","Russia","10","stone","true","hydrogen and oxygen","Rapunzel","magician","The Mona Lisa","string","12","mammal","lightning bolt","lacrosse","do");
//Creates am array used for the Quiz Time function
var i = 0;
//used to track player's movements on board
var lives = 3;
//the # of lives given at the beginning of the game
var collide: Boolean;
var myTimer: Timer = new Timer(1000, 60);
//used for timer in Storming the Castle Game
var count = 0;
//used to manage chibiKing movements
//stage.addEventListener(Event.ENTER_FRAME,onFrameLoop);
//loops frames card so animation plays
//function to get to the master instructions page
//function to get the the main board
function randomNumber(){
var number=Math.round(Math.random()*5)+1;
return number;
}//end randomNumber function
function StartGame()
{
instructionsButton.addEventListener(MouseEvent.CLICK, masterInstructions);
//listener on instructions button to open the instructions page
goButton.addEventListener(MouseEvent.CLICK, playGame);
//listener on the first play button to go to the game board
}//end StartGame function
function masterInstructions (event:MouseEvent) {
gotoAndPlay(2);
//takes you to the master instructions page
goButton2.addEventListener(MouseEvent.CLICK, playGame);
//listener on the first play button to go to the game board
}// end masterInstructions function
function rollDie (event:MouseEvent) {
goRollButton.removeEventListener (MouseEvent.CLICK, rollDie);
//makes player unable to click roll button after pressing once
goRollButton.visible = false;
//removes visiblity of the roll button one clicked
goButtonGame.visible = true;
//makes game button appear so player can proceed to game
var currentRoll=randomNumber();
//randomly rolls a number between 1 and 6
outputNumber.text=String(currentRoll);
//displays the number rolled
var newMoves = i + currentRoll*10;
//moves player forward, i being the number already moved
//roll multipled by ten for frame movements of tween
gameboy.gotoAndStop(newMoves);
//player stops at the new position
i = newMoves;
//i now changed to rolled number
if (i<=300) {
bossGame();
}//if player gets to end of board, automatically start boss game
}//end rollDie function
function playGame (event: MouseEvent) {
gotoAndPlay(3);
//goes to main board game
livesOutput.text=String(lives);
//displays the 3 of lives the player has in the output box
gameBoard.addEventListener(MouseEvent.CLICK, girlJumps);
//event listener for a pop up
goRollButton.addEventListener(MouseEvent.CLICK, rollDie);
//when pressed, button calls die roll function
goButtonGame.addEventListener(MouseEvent.CLICK, goGame);
//when pressed, chooses a random mini game
ball.addEventListener(MouseEvent.MOUSE_DOWN,ballStartDrag);
ball.addEventListener(MouseEvent.MOUSE_UP, ballEndDrag);
bear.addEventListener(MouseEvent.MOUSE_DOWN, bearStartDrag);
bear.addEventListener(MouseEvent.MOUSE_UP, bearEndDrag);
//functions to create drag and drops for objects on stage game board
goButtonGame.visible=false;
//does not display go button so player must roll dice before playing game
}//end playGame function
function ballStartDrag (evt:MouseEvent) {
ball.startDrag();
}//end ballStartDrag function
function bearStartDrag (evt:MouseEvent) {
bear.startDrag();
}//end bearStartDrag function
function ballEndDrag (evt:MouseEvent) {
ball.stopDrag();
}//end ballEndDrag function
function bearEndDrag (evt:MouseEvent) {
bear.stopDrag();
}//end bearEndDrag function
function girlJumps (evt:MouseEvent) {
girlJump.gotoAndPlay(2);
//has character on board to appear by playing tween
}//end girlJumps function
function bossGame (event:KeyboardEvent) {
stage.addEventListener( KeyboardEvent.KEY_DOWN, finalBoss);
//listener to player movement when keyboard is pressed
addEventListener(Event.ENTER_FRAME,movefireball);
//listener to move the fireball
stage.addEventListener(Event.ENTER_FRAME, collision);
//listener to collisions between symbols on stage
livesBoss.text=String(lives);
//displays number of lives in text box
fireball.height = 100;
fireball.width = 100;
fireball.x=40
fireball.y=40
fireball.xVelocity=8;
fireball.yVelocity=8;
//sets fireball parameters
}//end bossGame function
function movefireball (evt: Event) {
fireball.x +=fireball.xVelocity;
fireball.y +=fireball.yVelocity;
//creates speeds of fireball
checkfireballtoWall();
//calls function
var move1:Number=Math.ceil(Math.random()*stage.stageWidth) + 1;
var move2:Number=Math.ceil(Math.random()*stage.stageWidth) + 1;
//movements randomly created for king's movements
if (count%100 == 0) {
chibiKing.x= move1;
chibiKing.y= move2;
//reassigns chibiKing's movements
}
count++;
//adds to count after so many seconds
}//end movefireball function
function checkfireballtoWall(){
const TOP: Number= 50;
const BOTTOM: Number= stage.stageHeight;
const LEFT: Number= 50;
const RIGHT: Number= stage.stageWidth - 50;
const REVERSE: int = -1;
//limits to fireball's movements
if (fireball.y<TOP) {
fireball.y=TOP;
fireball.yVelocity*=REVERSE;
}
else if (fireball.y>BOTTOM) {
fireball.y=BOTTOM;
fireball.yVelocity*=REVERSE;
}
if (fireball.x<LEFT) {
fireball.x=LEFT;
fireball.xVelocity*=REVERSE;
}
else if (fireball.x>RIGHT) {
fireball.x=RIGHT;
fireball.xVelocity*=REVERSE;
}
//reassignes fireball's direction if fireball hits a certain area
}//end checkfireballtoWall function
function finalBoss (evt: KeyboardEvent) {
if( evt.keyCode == Keyboard.LEFT )
{player.x = player.x - 6;
}
else if( evt.keyCode == Keyboard.UP )
{player.y = player.y - 6;
}
else if( evt.keyCode == Keyboard.RIGHT )
{player.x = player.x + 6;
}
else if( evt.keyCode == Keyboard.DOWN )
{player.y = player.y + 6;
}//allows player to move via keyboard control
}//end finalBoss function
function collision (evt: Event) {
if (player.hitTestObject(chibiKing)) {
gotoAndPlay(14);
//if player hits the king, automatically go to win game screen
if (player.hitTestObject(fireball)) {
lives = lives - 1;
//if player hits fireball, lose a life
if (lives == 0) {
gotoAndPlay(11);}
//if lives equal to zero, go automatically to lose game screen
livesBoss.text=String(lives);
//display the lives remaining the text box
}
}//end collision function
function dragonBattle (event:KeyboardEvent) {
//inset Dragon Battle code
}//end dragonBattle function
function goGame (event:MouseEvent) {
var gameChoose=randomNumber();
//randomly chooses a game to play from the existing mini games
if (gameChoose==1 || gameChoose == 2) {
gotoAndPlay(4);
//game 1 start screen
goButton3.addEventListener (MouseEvent.CLICK, stormingTheCastle);
//listener to go to Storming the Castle Game
}//end goGame function
else if (gameChoose==3 && correctAnswers.length>0) {
gotoAndPlay(7)
//quiz time start screen
quizTimeButton.addEventListener (MouseEvent.CLICK, quizTime);
//quiz time start
}
else {gotoAndPlay(6);
//game 2 start screen
goButton5.addEventListener (MouseEvent.CLICK, dragonBattle);
//listener to start game 2
//wizardess.addEventListener (MouseEvent.CLICK, wizardessMagic);}
}
}//end goGame function
function quizTime (event:MouseEvent) {
questions [0]= "What colour is the sky?";
questions [1]= "What is the world's biggest country in land mass?";
questions [2]= "Do Re Mi Fa So La Ti...";
questions [3]= "How many tentacles does a squid have?";
questions [4]= "In Greek Mythology, looking into Medusa's eyes would turn you to...?";
questions [5]= "True or False: Winnipeg has a hockey team.";
questions [6]= "Water is made out of...?";
questions [7]= "Which princess is the star of Disney's movie 'Tangled'?";
questions [8]= "Harry Houdini was famous for being a(n)...?";
questions [9]= "Leonardo Da Vinci famously painted what?";
questions [10]= "What type of instrument is a sitar?";
questions [11]= "How many are in a dozen?";
questions [12]= "Humans are...?";
questions [13]= "Harry Potter is famous for having a scar shaped as what on his forehead?";
questions [14]= "What is the national sport of Canada?";
//creates questions to go with answers created in startGame function
questionBox.text=questions[questions.length];
//displays the question at the end of the array
answerQuizTime.addEventListener(MouseEvent.CLICK, quiz);
//button to proceed to get quiz marker
}//end quizTime function
function quiz (evt:MouseEvent){
var userAnswer=String(answerInput.text);
//saves the user's answer in userAnswer variable
if (userAnswer==correctAnswers[questions.length]) {
questions.pop();
//removes question from end of array
lives = lives + 1;
//adds life to player's total lives
gotoAndPlay(9);
//goes to minigame win screen
}
else {
questions.pop();
//removes question from end of array
lives = lives - 1;
//removes life from player's total lives
gotoAndPlay(10);
//goes to minigame lose screen
}
}//end quiz function
// handler function for the Arrow Keys to move Player across the stage
function movePlayer(evt: KeyboardEvent) {
// if key is right arrow, move Player to the right
if (evt.keyCode == Keyboard.RIGHT) {
Player.x += 20;
// if key is left arrow, move Player to the left
} else if (evt.keyCode == Keyboard.LEFT) {
Player.x -= 20;
}
}//end movePlayer function
function stormingTheCastle (event:MouseEvent) {
// add a listener for a Frame Event
stage.addEventListener(Event.ENTER_FRAME, onFrameLoop);
// add the listener for Keyboard events to the stage
stage.addEventListener(KeyboardEvent.KEY_DOWN, movePlayer);
// create a custom speed property for each knight
//start timer
knight1.velocity = 4;
knight2.velocity = 6;
knight3.velocity = 3;
knight4.velocity = 5;
collide = false;
myTimer.start();
}//end stormingTheCastle function
// each time frame 1 plays, move each knight
//continues if no collision and count less than 60
//return each night to top if it reaches the bottom
function onFrameLoop(evt: Event) {
if (collide == false && myTimer.currentCount < 60) {
if (knight1.y > 292.2)
{knight1.y = 42.45;}
if (knight2.y > 292.2)
{knight2.y = 42.45;}
if (knight3.y > 292.2)
{knight3.y = 42.45;}
if (knight4.y > 292.2)
{knight4.y = 42.45;}
//move knights down by its speed property amount
knight1.y = knight1.y + knight1.velocity;
knight2.y = knight2.y + knight2.velocity;
knight3.y = knight3.y + knight3.velocity;
knight4.y = knight4.y + knight4.velocity;
//trace timer count
trace(myTimer.currentCount);
//if Player is hit by a knight collision is true
if (knight1.hitTestObject(Player) == true) {
collide = true;
trace("test");
}
if (knight2.hitTestObject(Player) == true) {
collide = true;
}
if (knight3.hitTestObject(Player) == true) {
collide = true;
}
if (knight4.hitTestObject(Player) == true) {
collide = true;
}
else {
if (lives == 0) {
gotoAndPlay(11);}
//trace Game Over when collision is true
trace("GAME OVER");
gotoAndPlay(10);
}
} //end onFrameLoop function
}
}//end startGame function
}//end class function
}//end package
In a class file, the order of functions and var definitions is not an issue (aside from anonymous and nested functions which you should probably steer clear of anyway).
Let's start with line 82. You call bossGame(), but when you look at the function, you've defined it so it requires a parameter:
function bossGame (event:KeyboardEvent)
It's expecting you to pass a KeyboardEvent to the function. Though I'm not sure why because looking at that function it seems to have nothing to do with Keyboard input nor does it use that event in any way.
So, take out the parameter:
function bossGame()
Or, make it optional by giving it a default value:
function bossGame(event:KeyboardEvent = null)
For the second error. Your goGame function is actually nested inside another function collision() , so it has no scope except inside the collision function. If you want to be able to access it outside of that function, then you should break it out.
As an aside, you comments beside your closing function brackets are often incorrect making it difficult to read your code.

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.

AS3 Stop character from moving through walls

I want to stop the movieclips movement when it hits a wall (another movieclip).
The example below works, but after the collision the movieclip 'blocks' all movement to the left...
My question to you is, is this a good way and why isn't it working well?
There will be something wrong in this code, but i'm learning.
For now the example with the leftArrow key;
variables to check the key, if it's hitting the walls and if it's moving or not:
var leftArrow:Boolean;
var speed:int = 10;
var hitting:Boolean;
var ismoving:Boolean;
event listeners for the keys/movement and detecting collision:
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
stage.addEventListener(Event.ENTER_FRAME, walking);
stage.addEventListener(Event.ENTER_FRAME, detectHit);
detecting collision function:
function detectHit(e:Event) :void
{
if(char.hitTestObject(bounds))
{
hitting = true;
}
}
function to the left arrow key:
function keyPressed(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT)
{
leftArrow = true;
}
}
function keyReleased(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT)
{
leftArrow = false;
}
}
And the reason it's not working is probably here, but I don't understand why not:
function walking(event:Event):void {
if (rightArrow) {
char.x += speed;
}
if (leftArrow && ! hitting) {
char.x -= speed;
}
else
{
ismoving = false
}
if (leftArrow && ! hitting)
char will move if hitting is false. When char.hitTestObject(bounds) is true you are setting hitting to true. You are not setting hitting again to false anywhere. That's why once left wall is hit it stops left movement permanently. You need to figure out suitable condition to set hitting to false again.
Adding an else branch in detectHit should solve the problem.
function detectHit(e:Event):void {
if(char.hitTestObject(bounds))
{
hitting = true;
} else {
hitting = false; // add this
}
}
Allthough Taskinoor's method should work, I would suggest another way to do your hittests.
Since you probably are creating a game (character and bounds), you will have more than one bound. In that case, I would strongly suggest bitmap-hittesting. This way, you can create all your bounds in one movieclip and test for a hit.
I will explain this by using the example of a maze. The maze would then be some lines in a movieclip, randomly put together. If you use HitTestObject and you aren't hitting one of the lines, but your character is over the movieclip, hitTestObject will return true, even though you are not hitting a wall. By using bitmapHitTesting, you can overcome this problem (BitmapHitTest takes transparant pixels into account, whereas hitTestObject does not).
Below you can find an example of how to do bitmapHitTesting. Creating the bitmaps in this function is not necesarry if they do not change shape. In that case, I would suggest placing the code for the bitmapdata in a added_to_stage-method.
private var _previousX:int;
private var _previousY:int;
private var _bmpd:BitmapData ;
private var _physicalBitmapData:BitmapData;
private function walkAround(e:Event):void
{
var _xTo:int = //Calculate x-to-position;
var _yTo:int = //Calculate y-to-position;
//If your character doesn't change shape, you don't have to recalculate this bitmapData over and over.
//I suggest placing it in a ADDED_TO_STAGE-Event in that case.
_bmpd = new BitmapData(char.width, char.height, true, 0);
_bmpd.draw(char);
//If your bounds are static, you don't have to recalculate this bitmapData over and over.
//I suggest placing it in a ADDED_TO_STAGE-Event in that case.
_physicalBitmapData = new BitmapData(bounds.width, bounds.height, true, 0);
_bmpd.draw(bounds);
//The below line is the actual hittest
if(_physicalBitmapData.hitTest(new Point(0, 0), 255, _bmpd, new Point(char.x, char.y), 255))
{
char.x = _previousX;
char.y = _previousY;
}
else
{
char.x = _xTo;
char.y = _yTo;
}
_previousX = char.x;
_previousY = char.y;
}
Look at my hint,
function loop(Event)
{
if(isHit==false)
{
if(isRight==true){head_mc.x+=1}
if(isLeft==true){head_mc.x-=1}
if(isUp==true){head_mc.y-=1}
if(isDown==true){head_mc.y+=1}
}
if(head_mc.hitTestObject(build_mc))
{
isHit=true;
if(isRight==true){head_mc.x-=1}
if(isLeft==true){head_mc.x+=1}
if(isUp==true){head_mc.y+=1}
if(isDown==true){head_mc.y-=1}
}
else
{
isHit=false;
}
}
I use step back to opposite direction instead.