Action Script 3: Adding an gotoAndStop Animation - actionscript-3

So the other day I found a tutorial on how to create a pattern lock screen in action script. To do so I had to create a class, I have a good grasp on how the class is working. But I want to add an animation so when the user goes over the dots in the pattern and animation plays. But I have no idea how to do something like this through the class. Here is the code I used in my class.
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import fl.transitions.Tween;
import fl.transitions.easing.Strong;
public class Main extends Sprite
{
private var dots:Array = []; // Stores the in stage movieclips
private var pattern:Array = []; //The pattern entered by the user
private var pass:Array = [1,4,7,8,5,2,5]; //The correct pattern to proceed
public function Main():void
{
dots = [one,two,three,four,five,six,seven,eight,nine]; //add the clips in stage
addListeners();
}
private function addListeners():void //adds the listeners to each dot
{
var dotsLength:int = dots.length;
for (var i:int = 0; i < dotsLength; i++)
{
dots[i].addEventListener(MouseEvent.MOUSE_DOWN, initiatePattern);
dots[i].addEventListener(MouseEvent.MOUSE_UP, stopPattern);
}
}
/* Adds a mouse over listener and uses it to add the number of the dot to the pattern */
private function initiatePattern(e:MouseEvent):void
{
var dotsLength:int = dots.length;
for (var i:int = 0; i < dotsLength; i++)
{
dots[i].addEventListener(MouseEvent.MOUSE_OVER, addPattern);
}
pattern.push(dots.indexOf(e.target) + 1); //adds the array index number of the clip plus one, because arrays are 0 based
}
private function addPattern(e:MouseEvent):void
{
pattern.push(dots.indexOf(e.target) + 1); //adds the pattern on mouse over
}
private function stopPattern(e:MouseEvent):void //stops storing the pattern on mouse up
{
var dotsLength:int = dots.length;
for (var i:int = 0; i < dotsLength; i++)
{
dots[i].removeEventListener(MouseEvent.MOUSE_OVER, addPattern);
}
checkPattern();
}
private function checkPattern():void //compares the patterns
{
var pLength:int = pass.length;
var correct:int = 0;
for (var i:int = 0; i < pLength; i++) //compares each number entered in the user array to the pass array
{
if (pass[i] == pattern[i])
{
correct++;
}
}
if (correct == pLength) //if the arrays match
{
//Hides Sign In
MovieClip(root).LockScreen.visible = false;
MovieClip(root).RTID.visible = false;
MovieClip(root).SignIn.visible = false;
//Turns On Main Menu
MovieClip(root).gamemenu_mc.visible = true;
MovieClip(root).biggamesmenu_mc.visible = true;
MovieClip(root).totaltextmenu_mc.visible = true;
MovieClip(root).tmenu_mc.visible = true;
MovieClip(root).smenu_mc.visible = true;
MovieClip(root).optionsmenu_mc.visible = true;
}
pattern = []; //clears the user array
}
}
}

Easiest way I can think to do this is:
inside your dot movie clip, put a stop() action on the first frame
create your animation on the dot timeline and on the last frame of the animation put another stop().
In your mouse over function, tell the dot to play.
private function addPattern(e:MouseEvent):void
{
var dot:MovieClip = MovieClip(e.currentTarget);
if(dot.currentFrame < 2) dot.play(); //play only if on the first frame
pattern.push(dots.indexOf(dot) + 1); //adds the pattern on mouse over
}
Reset the dots animation
private function stopPattern(e:MouseEvent):void //stops storing the pattern on mouse up
{
for (var i:int = 0; i < dots.length; i++)
{
dots[i].removeEventListener(MouseEvent.MOUSE_OVER, addPattern);
dots[i].gotoAndStop(1); //go back to the first frame
}
checkPattern();
}
Alternatively, if you're just want something simple like a layer of the dot fading in/out or the size of the dot increasing, you could just use a tweening library and tween the appropriate property on mouse over.
If you wanted to draw lines to connect the dots, you could do this:
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import fl.transitions.Tween;
import fl.transitions.easing.Strong;
import flash.display.Shape;
public class Main extends Sprite
{
private var lineContainer:Shape = new Shape();
private var dots:Array = []; // Stores the in stage movieclips
private var pattern:Array = []; //The pattern entered by the user //don't make life hard, just store the object itself instead of the index
private var pass:Array;
public function Main():void
{
dots = [one,two,three,four,five,six,seven,eight,nine]; //add the clips in stage
pass = [one,four,seven,eight,five,two,five]; //The correct pattern to proceed
addChildAt(lineContainer, this.getChildIndex(one)); //the line container right behind the first dot.
addListeners();
}
private function addListeners():void //adds the listeners to each dot
{
var dotsLength:int = dots.length;
for (var i:int = 0; i < dotsLength; i++)
{
dots[i].addEventListener(MouseEvent.MOUSE_DOWN, initiatePattern);
dots[i].addEventListener(MouseEvent.MOUSE_UP, stopPattern); //you could attach this to `this` instead of each dot, same result
}
}
/* Adds a mouse over listener and uses it to add the number of the dot to the pattern */
private function initiatePattern(e:MouseEvent):void
{
pattern = []; //reset array
lineContainer.graphics.clear(); //clear lines
for (var i:int = 0; i < dots.length; i++)
{
dots[i].addEventListener(MouseEvent.MOUSE_OVER, addPattern);
}
addPattern(e); //trigger the mouse over for this element
}
private function addPattern(e:MouseEvent):void
{
//if (pattern.indexOf(e.currentTarget) == -1) { //wrap in this if statemnt if only wanted a dot to be selected once (like Android)
pattern.push(e.currentTarget); //adds the pattern on mouse over
drawLines();
var dot:MovieClip = MovieClip(e.currentTarget);
if(dot.currentFrame < 2) dot.play(); //play only if on the first frame
//}
}
private function drawLines():void {
lineContainer.graphics.clear(); //clear the current lines
lineContainer.graphics.lineStyle(5, 0xFF0000); //thickness (5px) and color (red) of the lines
if (pattern.length > 1) { //don't draw if there aren't at least two dots in the pattern
lineContainer.graphics.moveTo(pattern[0].x + pattern[0].width * .5, pattern[0].y + pattern[0].height * .5); //move to first
for (var i:int = 1; i < pattern.length; i++) {
lineContainer.graphics.lineTo(pattern[i].x + pattern[i].width * .5, pattern[i].y + pattern[i].height * .5); //draw a line to the current dot
}
}
lineContainer.graphics.endFill();
}
private function stopPattern(e:MouseEvent):void //stops storing the pattern on mouse up
{
for (var i:int = 0; i < dots.length; i++)
{
dots[i].removeEventListener(MouseEvent.MOUSE_OVER, addPattern);
dots[i].gotoAndStop(1); //go back to the first frame
}
checkPattern();
}
private function checkPattern():void //compares the patterns
{
var pLength:int = pass.length;
var correct:int = 0;
for (var i:int = 0; i < pLength; i++) //compares each number entered in the user array to the pass array
{
if (pass[i] == pattern[i])
{
correct++;
}
}
if (correct == pLength) //if the arrays match
{
//Hides Sign In
MovieClip(root).LockScreen.visible = false;
MovieClip(root).RTID.visible = false;
MovieClip(root).SignIn.visible = false;
//Turns On Main Menu
MovieClip(root).gamemenu_mc.visible = true;
MovieClip(root).biggamesmenu_mc.visible = true;
MovieClip(root).totaltextmenu_mc.visible = true;
MovieClip(root).tmenu_mc.visible = true;
MovieClip(root).smenu_mc.visible = true;
MovieClip(root).optionsmenu_mc.visible = true;
}
pattern = []; //clears the user array
lineContainer.graphics.clear(); //clear the lines
}
}
}

Related

AS3: Why is a line created with .graphics appearing in two different places and when removed with parent.visible = false, only one goes?

Nobody seems to have this question already so I asked it because I've spent a few hours trying to debug this and can't find a solution;
Essentially, I have a function called draw, which is declared in my document class:
public function draw(Target: MovieClip,mX: int,mY: int,lX: int,lY: int):void {
Target.graphics.clear();
Target.graphics.lineStyle(1,0x000000,1);
Target.graphics.moveTo(mX,mY);
Target.graphics.lineTo(lX,lY);
}
I call it later to draw two lines, on two different MovieClips:
draw(Line,Line.mX,Line.mY,Mirror.x + (Mirror.width / 2),Line.lY);
draw(nextLine,(Mirror.x + (Mirror.width / 2)),200,(Mirror.x + (Mirror.width / 2)),0);
where
var Line: MovieClip = new MovieClip();
var Mirror: MovieClip = new mirror();
and Mirror is draggable, so Mirror.x changes whenever it is dragged.
Line is a line made using .graphics and Line.mX is equal to the Line.graphics.moveTo X value last time it was modified. Line.mY is the same, but for the Y coordinate. I set these values by doing this:
Line.mX = 0;
Line.mY = 200;
Line.lX = 550;
Line.lY = 200;
But with whatever values I want to draw the line, with lX and lY being equal to the X and Y coordinates of Line.graphics.lineTo. Then I draw Line using my draw function like this:
draw(Line,Line.mX,Line.mY,Line.lX,Line.lY);
Then it gets more complex because, actually, Line is just one line in an array of lines, created like this:
public var lines = [line0,line1,line2,line3,line4,line5,line6,line7,line8];
and each of those lines is created like this (with 0 being replaced by the line's number, respectively):
public var line0: MovieClip = new MovieClip();
then I give each line a number and a name, add them to the stage and hide them like this:
for each(var setupLine:MovieClip in lines) {
setupLine.num = (lines.indexOf(setupLine));
setupLine.name = ('line' + setupLine.num);
addChild(setupLine);
setupLine.visible = false;
}
Then, after making line0 visible, because I need to see it at the start, I loop through each line in a function that runs on ENTER_FRAME, and set the value of nextLine to a different value each time I run the loop like this:
for each(var Line:MovieClip in lines) {
nextLine = this['line' + (Line.num + 1)];
}
Within that loop, I then loop through a few other arrays, then check for a collision with the selected Line and another selected MovieClip from another array, which I wont go into or this question will be longer than the code for node.js.
So essentially, if the collision with the two MovieClips is present, I draw the line that I mentioned at the top of my question. But for some reason, although Line draws correctly, nextLine draws correctly, but a duplicate of it is drawn across the Y axis at 0, and stops where nextLine is on the Y axis (nextLine is vertical, so it has the same Y value at the start as at the end).
Even stranger, when I try to hide nextLine if the collision with the two MovieClips is no longer present, using this code:
nextLine.visible = false;
it only hides the version of nextLine that runs along the top of the stage, which I didn't even intend to create in the start.
EDIT
here is a link to the current source code
Here is a link to the entire project files with the original source code
copy/paste the new source code from the pastebin link to get the new version
Thanks in advance,
-Raph
I figured out how to do this, code is
package {
import flash.events.*;
import flash.utils.*;
import flash.display.*;
[SWF(backgroundColor="0xbdc3c7")]
public class LightStage extends MovieClip {
//import classes
public var globeClass:Globe = new Globe();
public var mirrorClass:Mirror = new Mirror();
public var lineClass:Line = new Line();
//create all stage objects
public var curLine:Line
public var nextLine:Line;
public var curMirror:Mirror;
//create containers
public var mirrors:Vector.<Mirror> = new Vector.<Mirror>(); //a vector is an array, but every member has to be (or subclass) the specified class
public var globes:Vector.<Globe> = new Vector.<Globe>();
public var lines:Vector.<Line> = new Vector.<Line>();
trace('lightstage: working');
//create level object
public var curLevel:int = -1;
//create dependent variables
public var kill: Boolean = true;
//init function
public function LightStage() {
//setup MovieClips
var i:int = 0;
for (i = 0; i < 4; i++) {
mirrors.push(new Mirror());
}
for (i = 0; i < 4;i++ ) {
globes.push(new Globe());
}
var tmpLine:Line;
for (i = 0; i < 10; i++) {
tmpLine = new Line();
lines.push(tmpLine);
addChild(tmpLine);
tmpLine.visible = false;
}
//create ENTER_FRAME listener
stage.addEventListener(Event.ENTER_FRAME,enterFrame);
//start the game
levelUp();
}
//levelUp function
public function levelUp() {
curLevel++;
curLine = lines[curLevel]; //set line to the current level
curLine.curX = 0;
curLine.curY = 200;
curLine.draw(550, 200);
curLine.visible = true;
//show and position mirrors and globes
curMirror = mirrors[curLevel];
addChild(curMirror);
curMirror.x = 250;
curMirror.y = 350;
var curGlobe:Globe = globes[curLevel];
addChild(curGlobe);
curGlobe.x = 100;
curGlobe.y = 50;
//set mirror types
curMirror.gotoAndStop(2);
trace("you are now on level " + (curLevel + 1) + "!");
}
//ENTER_FRAME function
public function enterFrame(event:Event) {
//line1.visible = true;
for (var i:int = 0; i < lines.length;i++){
if (i < lines.length - 1) nextLine = lines[i + 1]; //check for out of bounds before assignment next line
if (lines[i].visible == true) {
kill = true;
for each(var mirror:Mirror in mirrors) {
if (lines[i].visible && mirror.stage && mirror.hitTestObject(lines[i])) { //for efficiency, do the hit test last in the if statement
for each(var globe:Globe in globes) {
//Looped through Mirrors and Lines and checked for collision - if collision is present, we loop through globes here
if (nextLine && nextLine.stage) {
addChild(nextLine);
}
//check for active globes
if (lines[i].visible && lines[i].hitTestObject(globe)) {
//check if the selected line touches the selected globe - if it does then we will start the timer for that globe
if (!globe.running){
globe.start();
//trace('timing');
kill = false;
}
}
else {
globe.reset();
}
switch(mirror.currentFrame) {
case 1:
break;
case 2:
//trace('live a life you will remember' + Math.random());
if(nextLine) nextLine.visible = true;
lines[i].draw(mirror.x + (mirror.width / 2),lines[i].curY);
if (nextLine) {
nextLine.curX = mirror.x + (mirror.width / 2);
nextLine.curY = 200;
nextLine.draw(mirror.x + (mirror.width / 2), 0);
}
kill = false;
break;
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
trace(mirror.currentFrame);
kill = false;
break;
}
}
}
else if (lines[i].visible && mirror.stage && lines[i].stage){
if (kill && nextLine){
nextLine.graphics.clear();
nextLine.visible = false;
}
}
}
}
}
}
}
}
//MIRROR CLASS DECLARATION
import flash.events.MouseEvent;
class Mirror extends MovieClip {
trace('mirror: working');
public function Mirror() {
this.addEventListener(MouseEvent.MOUSE_DOWN,onDown,false,0,true);
}
private function onDown(e:MouseEvent):void {
//add the mouse up listener on the stage, that way it's consistent even if the user drags so fast that the mouse leaves the bounds of the mirror
stage.addEventListener(MouseEvent.MOUSE_UP, onUp, false, 0, true);
this.startDrag();
}
private function onUp(e:MouseEvent):void {
//we need to remove the listener from the stage now
stage.removeEventListener(MouseEvent.MOUSE_UP, onUp, false);
this.stopDrag();
}
}
//LINE CLASS DECLARATION
import flash.display.Graphics;
class Line extends MovieClip {
trace('line: working');
public var curX:int;
public var curY:int;
public function Line():void {
}
public function draw(toX:int,toY:int):void {
graphics.clear();
graphics.lineStyle(1,0x000000,1);
graphics.moveTo(curX,curY);
graphics.lineTo(toX, toY);
curX = toX;
curY = toY;
}
}
//GLOBE CLASS DECLARATION
import flash.display.MovieClip;
import flash.events.TimerEvent;
import flash.utils.Timer;
class Globe extends MovieClip {
trace('globe: working');
private var timer:Timer = new Timer(3 * 100, 5);
public function Globe():void {
timer = new Timer(300, 5);
timer.addEventListener(TimerEvent.TIMER, repeatShine, false, 0, true);
}
public function reset():void {
timer.reset();
}
public function start():void {
timer.start();
}
public function get running():Boolean { return timer.running; };
private function repeatShine(e:TimerEvent):void {
}
}

Added child stays invisible even though its container is visible

I have been struggling for a couple of days with an issue in Flash CS4. I am re-structuring an old game project into a Main class which handles the mainMenu, playGame, etc. functions. I have a ship added from the "game", which is added by Main.
The issue is "myShip" works as expected, except it's never visible. I've checked a lot of times, and both myShip and its containter (game) visible properties are always true. Alpha values are not the problem either, nor layers nor depth. Every other child I've added from "game" works just fine, but "myShip" refuses to be visible.
Any ideas as to why this could happen? I do not know how what to try next to solve the problem. Any help would be very appreciated. The code for the Main, Game and Ship class is below.
Thank you!
Code from the Main class:
public class Main extends Sprite {
public var mainMenuDisplay:MainMenuDisplay;
public var game:Game;
public var gameOverMenu:GameOverMenu;
public function Main() {
showMainMenu();
}
public function showMainMenu() {
mainMenuDisplay = new MainMenuDisplay(this);
gameOverMenu=remove_movie_clip(gameOverMenu);
addChild(mainMenuDisplay);
}
public function showGameOver() {
gameOverMenu = new GameOverMenu(this);
game=remove_movie_clip(game);
addChild(gameOverMenu);
}
public function playTheGame() {
game = new Game(this);
mainMenuDisplay = remove_movie_clip(mainMenuDisplay);
gameOverMenu=remove_movie_clip(gameOverMenu);
stage.addChild(game);
}
private function remove_movie_clip(clip:*) {
if (clip) {
removeChild(clip);
}
return null;
}
}
Code from the Game class:
package {
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
import com.coreyoneil.collision.CollisionList;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.events.MouseEvent;
import com.greensock.*;
import flash.display.Sprite;
import flash.display.SpreadMethod;
import flash.display.GradientType;
import flash.geom.Matrix;
import com.sounds.music.Music_mainMusic;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.display.DisplayObject;
public class Game extends MovieClip {
var mainClass:Main;
//Main menu
//var mainMenuDisplay:MainMenuDisplay = new MainMenuDisplay();
//static var inMenu:Boolean = true;
//
//Ship variables
static var myShip:Ship = new Ship();
var myDirectionBar:Direction_bar = new Direction_bar();
//
//Enemy variables
static var enemyShipTimer_1:Timer;
//
//PowerUp variables
static var powerUpTimer:Timer;
static var nuking:Boolean;
//
//Wall generation variables
static var wall_mov_speed:Number;
var randomize:Number = 1;
var wallArray:Array = new Array();
var index:int = 0;
//
//Wall collision variables (powered by CDK by Corey O'Neil)
var myWallCollisionList:CollisionList; // = new CollisionList(myShip);
var wall_collisions:Array = new Array();
//
//Score variables
static var score:Number;
static var scoreText:TextField = new TextField();
var scoreFormat = new TextFormat("LCD5x8H", 20, 0x0066FF, true);
var distance_score_counter:int;
//
//Health variables
static var healthMeter_1:HealthMeter = new HealthMeter();
//
//Game modes
//var levelSelectDisplay:LevelSelectDisplay = new LevelSelectDisplay();
//**NOTE: These are extremely important, because they are the functions, which in reality are attributes, that allow us to call,
//from an Event Listener, a function in which we have a parameter to pass. This way we call these variables instead of the
//function we are interested in, these will call it for us.
//var functionLevelSelect_1:Function = selectedLevel(1);
//var functionLevelSelect_2:Function = selectedLevel(2);
//var functionLevelSelect_3:Function = selectedLevel(3);
//var functionLevelSelect_4:Function = selectedLevel(4);
//var functionLevelSelect_5:Function = selectedLevel(5);
//The level composition (that's the numbers of the frame in the MC of the Walls, each number is a type. The last one stores all of them.
//var level_1_composition:Array = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];
//var level_2_composition:Array = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];
//var level_3_composition:Array = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];
//var level_4_composition:Array = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];
//var storyModeLevelCompositions:Array = new Array(level_1_composition, level_2_composition, level_3_composition, level_4_composition);
//
var levelPlaying:int = 0;
var wallPieceCount:int = 0;
//
//Pause variables
var pauseScreen:PauseScreen = new PauseScreen();
//This variables states whether we are in pause or not
static var isPause:Boolean = false;
//This other tells us if we can pause at the moment or not
static var isPauseable:Boolean = false;
//
//Game Over, new Game and Game menu variables
//static var gameOverMenu:GameOverMenu = new GameOverMenu();
static var inGameStopping:Boolean = false;
//
//Transition screen variables
var darkening:Boolean;
//NOTE: We do it this way because, when putting an Enter Frame event listener onto the function funcTransition,
//which has a pass variable, the variable changed all the time to true, giving us problems.
//Background graphics variables
var color1:uint = Math.floor(Math.random()*0xFFFFFF + 1);
var color2:uint = Math.floor(Math.random()*0xFFFFFF + 1);
var colors:Object = {left:color1, right:color2};
var newColor1:uint = Math.floor(Math.random()*0xFFFFFF + 1);
var newColor2:uint = Math.floor(Math.random()*0xFFFFFF + 1);
var newColors:Object = {left:newColor1, right:newColor2};
var mySprite:Sprite = new Sprite();
//
//Music variables
var myMainMusic:Music_mainMusic = new Music_mainMusic();
//
//Credits variables
//var myCredits:Credits = new Credits();
//var myVersion:VersionDisplay = new VersionDisplay();
//
//Other variables
//var initThingy:Boolean;
var initTransition:Boolean = true;
var allPurposeCounter:int = 0;
var myTransitionScreen:TransitionScreen = new TransitionScreen();
//
//New necessary variables
//
public function Game(passedClass:Main) {
mainClass = passedClass;
if (stage) {
init(null);
}else{
this.addEventListener(Event.ADDED_TO_STAGE, init);
}
}
public function init(e:Event) {
this.removeEventListener(Event.ADDED_TO_STAGE, init);
this.parent.addChild(this);
//Necessary initial booting:
mySprite.x = 0;
mySprite.y = 0;
stage.addChildAt(mySprite, 1);
drawGradient();
animateBackground();
//////////////////////////////////////////////////////
/*mainMenuDisplay.x = 400 - mainMenuDisplay.width/2;
mainMenuDisplay.y = 240 - mainMenuDisplay.height/2;
stage.addChild(mainMenuDisplay);*/
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
/*levelSelectDisplay.x = 400 - levelSelectDisplay.width/2;
levelSelectDisplay.y = 240 - levelSelectDisplay.height/2;
levelSelectDisplay.visible = false;
stage.addChild(levelSelectDisplay);*/
//////////////////////////////////////////////////////
//Transitions
myTransitionScreen.visible = false;
stage.addChild(myTransitionScreen);
//
//////////////////////////////////////////////////////
//myCredits.x = 20;
//myCredits.y = 438;
//stage.addChild(myCredits);
//myVersion.x = 710;
//myVersion.y = 438;
//stage.addChild(myVersion);
//////////////////////////////////////////////////////
//myMainMusic.play(0,99999);
initGame(null);
//mainMenuIdleState();
//
}
//////////////////////////////////////////////////////
/*function mainMenuIdleState(){
stage.addChild(mainMenuDisplay);
stage.addChild(levelSelectDisplay);
inMenu = true;
mainMenuDisplay.visible = true;
mainMenuDisplay.mainMenuPlayStoryButton_instance.addEventListener(MouseEvent.MOUSE_DOWN, level_select);
mainMenuDisplay.mainMenuPlayEndlessButton_instance.addEventListener(MouseEvent.MOUSE_DOWN, endless_mode_selected);
}*/
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
/*function endless_mode_selected(e:Event){
levelPlaying = 0;
initGame(null);
}*/
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
/*function level_select(e:Event){
mainMenuDisplay.visible = false;
levelSelectDisplay.visible = true;
levelSelectDisplay.levelSelectButton1_instance.addEventListener(MouseEvent.MOUSE_DOWN, functionLevelSelect_1);
levelSelectDisplay.levelSelectButton2_instance.addEventListener(MouseEvent.MOUSE_DOWN, functionLevelSelect_2);
levelSelectDisplay.levelSelectButton3_instance.addEventListener(MouseEvent.MOUSE_DOWN, functionLevelSelect_3);
levelSelectDisplay.levelSelectButton4_instance.addEventListener(MouseEvent.MOUSE_DOWN, functionLevelSelect_4);
levelSelectDisplay.levelSelectButtonBack_instance.addEventListener(MouseEvent.MOUSE_DOWN, functionLevelSelect_5);
}
function selectedLevel(level:int):Function {
switch (level){
case 1:
return function(e:MouseEvent):void {
//trace("1 clicked");
levelPlaying = 1;
levelSelectDisplay.visible = false;
initGame(null);
}
break;
case 2:
return function(e:MouseEvent):void {
//trace("2 clicked");
levelPlaying = 2;
levelSelectDisplay.visible = false;
initGame(null);
}
break;
case 3:
return function(e:MouseEvent):void {
//trace("3 clicked");
levelPlaying = 3;
levelSelectDisplay.visible = false;
initGame(null);
}
break;
case 4:
return function(e:MouseEvent):void {
//trace("4 clicked");
levelPlaying = 4;
levelSelectDisplay.visible = false;
initGame(null);
}
break;
default:
return function(e:MouseEvent):void {
//trace("back clicked");
levelPlaying = 0;
levelSelectDisplay.visible = false;
mainMenuDisplay.visible = true;
levelSelectDisplay.levelSelectButton1_instance.removeEventListener(MouseEvent.MOUSE_DOWN, functionLevelSelect_1);
levelSelectDisplay.levelSelectButton2_instance.removeEventListener(MouseEvent.MOUSE_DOWN, functionLevelSelect_2);
levelSelectDisplay.levelSelectButton3_instance.removeEventListener(MouseEvent.MOUSE_DOWN, functionLevelSelect_3);
levelSelectDisplay.levelSelectButton4_instance.removeEventListener(MouseEvent.MOUSE_DOWN, functionLevelSelect_4);
levelSelectDisplay.levelSelectButtonBack_instance.removeEventListener(MouseEvent.MOUSE_DOWN, functionLevelSelect_5);
}
break;
}
}*/
//////////////////////////////////////////////////////
function initGame(e:Event):void{
//This has so many redundancies, when everything is done, START CLEANING THIS!
//////////////////////////////////////////////////////
//Main menu
//mainMenuDisplay.visible = false;
//inMenu = false; THIS GOES AT THE END TO PREVENT PROBLEMS
//directNewGame tells us if we come from the newGame function (and thus we do not go through the mainMenuIdleState
//function and this instances have not been placed on stage) or not. If we come from the main menu, we DO need to
//remove them.
//
trace(myShip);
//Ship
myShip.x = -10; //Before there were numbers to implement stage.stageWidth/2;
myShip.y = 200; //Before there were numbers to implement stage.stageHeight/2;
myShip.visible = true;
//mainClass.addChild(myShip);
this.addChild(myShip);
//We make sure the ship doesn't enter to stage with 0 health
//(problems of working with only one instance of ship due to the static var references)
Ship.health = 100;
//Check "NOTE" below
myShip.alpha = 0.35;
myShip.visible = true;
//
trace(myShip.visible);
//Direction bar
myDirectionBar.x = stage.stageWidth/2;
myDirectionBar.y = stage.stageHeight/2;
this.addChild(myDirectionBar);
//
//Timers (enemies)
enemyShipTimer_1 = new Timer(1000)
enemyShipTimer_1.addEventListener(TimerEvent.TIMER, spawn_enemies);
enemyShipTimer_1.start();
//
//Timer (powerUps)
powerUpTimer = new Timer(10000);
powerUpTimer.addEventListener(TimerEvent.TIMER, spawn_powerUp);
powerUpTimer.start();
//
//PowerUps (other)
nuking = false;
//
myWallCollisionList = new CollisionList(myShip);
//Initial movement speed of the walls
wall_mov_speed = 8;
//Calling to the generating/adequating wallArray function
adequateArrayOfWalls(true);
wallArray[0].gotoAndStop(1);
wallArray[1].gotoAndStop(1);
myWallCollisionList.addItem(wallArray[0].theActualWall);
myWallCollisionList.addItem(wallArray[1].theActualWall);
//Collision managements
wall_collisions = 0 as Array;
//NOTE: Here we limit the alpha value to consider for collision just to make sure the game doesn't start with you killed, and that you are "invincible"
//for some time
myWallCollisionList.alphaThreshold = 0.95;
//
//Adding score format and text
scoreText.defaultTextFormat = scoreFormat;
scoreText.x = 700;
scoreText.y = 10;
score = 0;
scoreText.text = String(score);
stage.addChild(scoreText);
distance_score_counter = 0;
scoreText.visible = true;
//
//Adding health meter
healthMeter_1 = new HealthMeter();
healthMeter_1.x = 10;
healthMeter_1.y = 10;
stage.addChild(healthMeter_1);
//
//Adding the Pause screen & other pause variables
pauseScreen.x = 400 - pauseScreen.width/2;
pauseScreen.y = 240 - pauseScreen.height/2;
pauseScreen.visible = false;
stage.addChild(pauseScreen);
isPauseable = true;
//Adding a key managing event (for pausing, menu, etc.)
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyManaging);
//
/*//Adding a Game Over Menu
gameOverMenu = new GameOverMenu();
gameOverMenu.x = 400 - gameOverMenu.width/2;
gameOverMenu.y = 240 - gameOverMenu.height/2;
gameOverMenu.visible = false;
stage.addChild(gameOverMenu);
gameOverMenu.playAgainButton_instance.addEventListener(MouseEvent.MOUSE_DOWN, newGame);
gameOverMenu.backToMenuButton_instance.addEventListener(MouseEvent.MOUSE_DOWN, backToTheMenu);
//*/
//Shield
//
//Event listeners
addEventListener(Event.ENTER_FRAME, update_game);
//
//////////////////////////////////////////////////////
/*//Credits
myCredits.visible = false;
myVersion.visible = false;
//
initThingy = true;
inMenu = false;*/
//////////////////////////////////////////////////////
}
function update_game(e:Event){
myShip.visible = true;
//Look the adequate array function for more info. We are just moving the two pieces of the array on stage
wallArray[(index - 1)].x -= wall_mov_speed;
wallArray[index].x -= wall_mov_speed;
if(wallArray[index].x < 0){
spawn_wall_piece();
}
//
if(index == 5){
//We call this function for cleaning
adequateArrayOfWalls(false);
}
if(wall_mov_speed < 20){
wall_mov_speed += 0.003;
}
wall_collisions = myWallCollisionList.checkCollisions();
if(wall_collisions.length > 0){
trace("hit!");
if(myShip.visible == true){
//We only kill the ship if it's visible, if not, it means it is already dead
Ship.receiveDamage(Ship.max_health);
}
wall_collisions = 0 as Array;
}
if(distance_score_counter >= 10){
distance_score_counter = 0;
updateScore(1);
}
distance_score_counter++;
//NOTE2: We use this nuke variable in order not to make the "nuke()" function static, type in which we couldn't handle the stage property
//And we also make this variable false here so as to eliminate not only a single enemy but all on stage
Enemy1.enemies_1Nuked = false;
if(nuking == true){
Enemy1.enemies_1Nuked = true;
nuking = false;
}
//We put these all the time at the front so we can see them and the walls don't overpass them
scoreText.parent.setChildIndex(scoreText, scoreText.parent.numChildren - 1);
healthMeter_1.parent.setChildIndex(healthMeter_1, healthMeter_1.parent.numChildren - 1);
pauseScreen.parent.setChildIndex(pauseScreen, pauseScreen.parent.numChildren -1);
//gameOverMenu.parent.setChildIndex(gameOverMenu, gameOverMenu.parent.numChildren - 1);
var n:uint = stage.numChildren;
for(var i=0; i < n; i++){
if(stage.getChildAt(i) is Enemy1){
var anEnemy1:Enemy1 = Enemy1(stage.getChildAt(i));
anEnemy1.parent.setChildIndex(anEnemy1, anEnemy1.parent.numChildren -1);
}
else if(stage.getChildAt(i) is PowerUp){
var aPowerUp:PowerUp = PowerUp(stage.getChildAt(i));
aPowerUp.parent.setChildIndex(aPowerUp, aPowerUp.parent.numChildren -1);
}
}
//Done like this due to the impossibility of calling a function inside an static one (in this case, gameOver)
if(inGameStopping == true){
funcEasing();
}
//Probably not necessary later
//////////////////////////////////////////////////////
/*if(initThingy == true){
stage.focus = stage;
initThingy = false;
}*/
//////////////////////////////////////////////////////
}
function spawn_enemies(e:Event){
var myEnemy1:Enemy1 = new Enemy1();
stage.addChild(myEnemy1);
}
function spawn_wall_piece(){
index++;
wallArray[index].x = (wallArray[index - 1].x + wallArray[index - 1].width);
wallArray[index].y = 0;
stage.addChild(wallArray[index]);
myWallCollisionList.addItem(wallArray[index].theActualWall);
myWallCollisionList.removeItem(wallArray[index - 2].theActualWall);
stage.removeChild(wallArray[index - 2]);
}
function adequateArrayOfWalls(init:Boolean):void{
//This only executes if we are initialitizing the array
if(init == true){
for(index = 0; index < 10; index++){
var aWall:Walls = new Walls();
//We check if we got special blocks next (e.g. "ramp caves"). Then we only allow a certain type of blocks to come.
//If no special block is detected, then we just randomize the next one, except for those that are not allowed to
//show up unless a previous special one appeared.
if(randomize == 9 || randomize == 15){
randomize = 15 + Math.floor(Math.random()*1 + 1);
}else{
randomize = Math.floor(Math.random()*14 + 1);
}
aWall.gotoAndStop(randomize);
//TheActualWall is the raw shape of the wall, where the ship collides, and it is what we push into collisionList,
//but not into the wallArray which includes the Walls (comprised by graphics and actual walls)
aWall.theActualWall.gotoAndStop(randomize);
wallArray.push(aWall);
}
wallArray[0].gotoAndStop(1);
wallArray[0].theActualWall.gotoAndStop(1);
stage.addChild(wallArray[0]);
wallArray[1].x = 800;
wallArray[1].y = 0;
stage.addChild(wallArray[1]);
//if not, then we are just cleaning it and rearranging it so it doesn't grow bigger and bigger
}else{
for(var a:Number = 0; a < index - 1; a++){
wallArray.splice(0,1);
}
for(a = index - 1; a < (10-2); a++){
var aWall2:Walls = new Walls();
if(randomize == 9 || randomize == 15){
randomize = 15 + Math.floor(Math.random()*1 + 1);
}else{
randomize = Math.floor(Math.random()*14 + 1);
}
aWall2.gotoAndStop(randomize);
aWall2.theActualWall.gotoAndStop(randomize);
wallArray.push(aWall2);
}
}
//Then, either way, we tell index to be 1 since the reference in the function is [index - 1] and [index], so it starts with [0] and [1]
index = 1;
}
static function updateScore(points:Number){
score += points;
scoreText.text = score.toString();
}
static function resetScore(){
score = 0;
scoreText.text = score.toString();
}
function spawn_powerUp(e:Event){
var pU:PowerUp = new PowerUp();
stage.addChild(pU);
}
static function gameOver(){
wall_mov_speed = 8;
//gameOverMenu.end_game_score_display.text = score.toString();
//gameOverMenu.visible = true;
scoreText.visible = false;
enemyShipTimer_1.stop();
powerUpTimer.stop();
inGameStopping = true; //In game stopping only influentiates in the easing speed effect
isPauseable = false;
}
function funcEasing(){
if(wall_mov_speed >= 0.1){
wall_mov_speed /= 1.07;
}else{
wall_mov_speed = 0;
removeEventListener(Event.ENTER_FRAME, update_game);
initTransition = true;
darkening = true; //See notes on variable declaration.
funcTransition(null);
}
}
function funcTransition(e:Event){
if(initTransition == true){
myTransitionScreen.init(darkening);
myTransitionScreen.parent.setChildIndex(myTransitionScreen, stage.numChildren - 1);
myTransitionScreen.parent.addEventListener(Event.ENTER_FRAME, funcTransition);
initTransition = false;
allPurposeCounter = 0;
}
if((darkening == true && myTransitionScreen.alpha == 1) || (darkening == false && myTransitionScreen.alpha == 0)){
trace("fsdfa");
allPurposeCounter++;
trace(allPurposeCounter);
if(allPurposeCounter >= 20){
myTransitionScreen.parent.removeEventListener(Event.ENTER_FRAME, funcTransition);
initTransition = true;
allPurposeCounter = 0;
if(darkening == true){ //This means if we are now with a black screen coming from the game, which is when we will end our game process
endGameProcess();
}
}
}
}
function endGameProcess(){
mainClass.showGameOver();
}
function newGame(e:Event){
darkening = true; //See notes on variable declaration.
initTransition = true;
funcTransition(null);
}
//Check To-Do List below
function funcPause(pMode:String){
if(pMode == "pausing"){
pauseScreen.visible = true;
removeEventListener(Event.ENTER_FRAME, update_game);
myShip.thePause("pausing");
//Check and stop the childs on stage (emitted by stage, so particles don't count)
var n:uint = stage.numChildren;
for(var i=0; i < n; i++){
if(stage.getChildAt(i) is Enemy1){
var anEnemy1:Enemy1 = Enemy1(stage.getChildAt(i));
anEnemy1.thePause("pausing");
}
else if(stage.getChildAt(i) is Trail){
var aTrailUnit:Trail = Trail(stage.getChildAt(i));
aTrailUnit.thePause("pausing");
}
else if(stage.getChildAt(i) is PowerUp){
var aPowerUp:PowerUp = PowerUp(stage.getChildAt(i));
aPowerUp.thePause("pausing");
}
}
enemyShipTimer_1.stop();
powerUpTimer.stop();
isPause = true;
isPauseable = false;
}else if(pMode == "unpausing"){
pauseScreen.visible = false;
addEventListener(Event.ENTER_FRAME, update_game);
myShip.thePause("unpausing");
//Check and re-run the childs on stage (emitted by stage, so particles don't count)
var m:uint = stage.numChildren;
for(var j=0; j < m; j++){
if(stage.getChildAt(j) is Enemy1){
var anotherEnemy1:Enemy1 = Enemy1(stage.getChildAt(j));
anotherEnemy1.thePause("unpausing");
}
else if(stage.getChildAt(j) is Trail){
var anotherTrailUnit:Trail = Trail(stage.getChildAt(j));
anotherTrailUnit.thePause("unpausing");
}
else if(stage.getChildAt(j) is PowerUp){
var anotherPowerUp:PowerUp = PowerUp(stage.getChildAt(j));
anotherPowerUp.thePause("unpausing");
}
}
enemyShipTimer_1.start();
powerUpTimer.start();
isPause = false;
isPauseable = true;
}
}
//Key pressing management
function keyManaging(e:KeyboardEvent){
var key:uint = e.keyCode;
trace("algo");
switch (key){
case Keyboard.P:
if(isPause == false && isPauseable == true){
funcPause("pausing");
}else if (isPause == true){
funcPause("unpausing");
}
break;
case Keyboard.M:
//go back to menu: still to complete
//Has to be only possible to do while in the pause menu
trace("going back to menu");
//
break;
}
}
//
//Background color management
function drawGradient():void {
var m:Matrix = new Matrix();
m.createGradientBox(805, 485, 0, 0, 0);
mySprite.graphics.clear(); // here we clean it
mySprite.graphics.beginGradientFill(GradientType.LINEAR, [colors.left, colors.right], [1, 1], [0x00, 0xFF], m, SpreadMethod.REFLECT);
mySprite.graphics.drawRoundRect(0,0,805,485, 0);
stage.setChildIndex(mySprite, 1);
}
function animateBackground(){
TweenMax.to(colors, 3, {hexColors:{left:newColor1, right:newColor2}, onUpdate:drawGradient, onComplete:reRandomize});
}
function reRandomize(){
color1 = newColor1;
color2 = newColor2;
newColor1 = Math.floor(Math.random()*0xFFFFFF + 1);
newColor2 = Math.floor(Math.random()*0xFFFFFF + 1);
animateBackground();
}
}
}
Code from Ship:
public class Ship extends MovieClip {
public function Ship() {
if (stage) {
init(null);
}else{
this.addEventListener(Event.ADDED_TO_STAGE, init);
}
}
public function init(e:Event) {
this.removeEventListener(Event.ADDED_TO_STAGE, init);
this.addEventListener(Event.ENTER_FRAME, update_ship);
}
public function update_ship(e:Event){
x_vel = Direction_bar.dX*power;
y_vel = Direction_bar.dY*power;
this.x += x_vel;
this.y += y_vel;
if((10 < Math.abs(Direction_bar.dX) || 10 < Math.abs(Direction_bar.dY)) || ((0.9 < Math.abs(x_vel)||(0.9 < Math.abs(y_vel))))){
this.rotation = Direction_bar.point_direction;
}
rotation_now = this.rotation;
if(myShield != null){
if(myShield.visible == true){
myShield.alpha -= 0.0005;
if(myShield.alpha == 0){
myShield.visible = false;
myShield.alpha = 1;
}
}
}
}
Some basics that you have to know in order to understand what's going on.
It's a very common mistake to add things to stage.
Here's what the documentation of addChild says
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObjectContainer.html#addChild%28%29
objects should not be added to the Stage, directly, at all
I guess people add DispalyObjects to stage because they think it is
"the stage" that they see and interact with in the Flash authoring
environment. But it's not. stage.addChild() is not the same
thing as dragging a symbol from the library onto the screen. What by
default represents the main time line is the root property.
However, if you add anything to stage directly, its root property and its stage property both reference the same object,
which is regularly only referenced by stage. stage is some
container that your .swf is added to when running in the flash
player.
The documentation of addChildAt says this about the index:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObjectContainer.html#addChildAt%28%29
The child is added at the index position specified. An index of 0 represents the back (bottom) of the display list for this
DisplayObjectContainer object.
Applying these basics, the following happens:
FlashPlayer creates the stage object, instantiates your main class
and adds that instance to stage, it is the child with the index 0.
Among other things, stage.addChildAt(mySprite, 1); is executed,
adding mySprite as a second child to stage. With index of 1 it is
rendered in front of the object that is at index 0, which happens to
be the instance of your main class AKA your .swf file. I hope that
anything being rendered "outside the .swf file" illustrates well
enough why adding things to stage is not recommended.
Later, this.addChild(myShip); happens. (Which is actually the
proper way to do it; no need to use this here:addChild(myShip);
is all you need.) and adds the ship to the display list. Assuming all
of its parents are added to the display list as well, it will be
displayed.
But you still cannot see it, because you added mySprite in front of
the instance of your main class and filled it with a content in
drawGradient() which covers up everything else.
In all honesty, the best solution would be to start over from scratch.
Working with this code will not help you in any way. Even working yourself through it and making it work somehow will not make you understand anything better (except for how not to do things). It seems like the only motivation to modify this code to use classes was for the sake of doing it. Forcing such old code into the object oriented paradigm will not work very well. The benefits of oop will not be apparent, making this experience even more frustrating.
Last but not least, do not roll your own transition code. There are many libraries that do this (including flash's own Tween class http://www.republicofcode.com/tutorials/flash/as3tweenclass/ or the popular tweenlite http://greensock.com/tweenlite)
You could try adding an ADDED_TO_STAGE event. See this excellent explanation from the master of game programming
Understanding ADDED_TO_STAGE Event

hitTestObject issue // remove stage Error #2025

hey :S I`m trying to make 2 things so far but neither work :(
The 1st is to make an Row of 5 Ships that position them selves from the top to left.Then add an Event to make them move down.
But every time i try to make a new Row of 5 new ships ... they position themselves after the last ship from the previous Row.I did think of a way to fix that by waiting the 1st Row of ships to go beyond the stage and then remove them from the stage and splice from the Array but ... when I increase the speed of spawning (when i have 2 rows with 5 ships on the stage or more)that does't work.
And the second error I think is from that fact .... that I have 2 rows at the same time on the stage.
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at MainClass/doShips()
at MainClass/everyFrame()
I dont know what exactly to paste from the code so i had to push everything in the MainClass of the FLA.fail :D but i did it neatly! so if anyone helped me he would track the code easily
so its a simple FLA.fail with 4 MC and in those 4 MC there is no code
a Bullet
a Ship with colour Yellow
a Ship2 with colour Green so i can see the randomising
and a Player with the class Turret
so the MainClass of the FLA is :
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class MainClass extends MovieClip {
protected var mouseSpeed:Number = 20;
protected var _thePlayer:Turret = new Turret();
protected var shipCount:Number;
protected var shipCount2:Number;
protected var shipArray:Array = new Array();
protected var counter:int = 0;
//variables for bullets
private var shootCooldown:Number = 0; //speed of the fire
private var firing:Boolean = false;//bullets triger
private var numToShoot:int = 1; //bullets
const MAX_COOLDOWN = 10; //bullets timer
protected var _bulletsArray:Array = new Array();
public function MainClass() {
_thePlayer.x = stage.stageWidth/2
_thePlayer.y = stage.stageHeight - _thePlayer.height/2
addChild(_thePlayer)
addEventListener(Event.ENTER_FRAME, everyFrame)
stage.addEventListener(MouseEvent.MOUSE_DOWN, startFire);
stage.addEventListener(MouseEvent.MOUSE_UP, stopFire);
}
private function startFire(ev:MouseEvent) {
firing = true;
}
private function stopFire(ev:MouseEvent) {
firing = false;
}
//every frame do this
protected function everyFrame(ev:Event):void{
//Moving The Turret
moveTheTurret();
//increase the counter every frame
counter++;
if(counter % 70 == 0){
//position the ships on the stage
positionShips();
}
//handle the ships when they are added on the stage
doShips();
//when to fire
updateFire();
//handle the bullets
doBullets();
}
//Moving The Turret
protected function moveTheTurret() {
if (mouseX > _thePlayer.x +15) {
_thePlayer.x += mouseSpeed;
} else if (mouseX < _thePlayer.x - 15) {
_thePlayer.x -= mouseSpeed;
} else {
_thePlayer.x = mouseX;
}
}
//createShips and position them
protected function positionShips() {
shipCount = 3;
shipCount2 = 2;
var gap = 10;
for (var i:int = 0; i < shipCount; i++) {
var s = new Ship();
shipArray.push(s);
}
for (var j:int = 0; j < shipCount2; j++) {
s = new Ship2();
shipArray.push(s);
}
var array:Array=new Array();
while (shipArray.length>0) {
var index:uint = Math.floor(Math.random() * shipArray.length);
array.push(shipArray[index]);
shipArray.splice(index,1);
}
shipArray = array;
//shipsArray has been randomized
for (var k:int = shipArray.length - 1; k >= 0; k--) {
addChild(shipArray[k]);
shipArray[k].x = shipArray[k].width/2 + (shipArray[k].width * k) + (gap*k);
}
}
//move the ships
protected function doShips() {
for (var i:int = shipArray.length - 1; i >= 0; i--) {
shipArray[i].y +=3 //make the Ships fall down
for (var bcount= _bulletsArray.length-1; bcount >= 0; bcount--) {
//if the bullet is touching the ship
if (shipArray[i].hitTestObject(_bulletsArray[bcount])) {
//if we get here it means there`s is a collision
removeChild(_bulletsArray[bcount]);
_bulletsArray.splice(bcount,1);
removeChild(shipArray[i]);
_bulletsArray.splice(i,1);
}
}
//if it gets over 380 remove from stage and splice from the array
if(shipArray[i].y > 380){ // stage.stageHeight)
removeChild(shipArray[i]);
shipArray.splice(i,1);
}
}
}
//when to fire
public function updateFire() {
//if we are currently holding the mouse down
if(firing == true){
fire();
}
//reduce the cooldown by 1 every frame
shootCooldown--;
}
//Shoot bullets
private function fire() {
if (shootCooldown <= 0) {
//reset the cooldown
shootCooldown = MAX_COOLDOWN
for (var i=0; i<numToShoot; i++){
//spown a bullet
var b = new Bullet();
//set the rotation of the bullet
b.rotation = -90
b.x = _thePlayer.x;
b.y = _thePlayer.y;
//add the bullet to the list/Array of _bulletsArray
_bulletsArray.push(b);
//add the bullet to the perent object;
addChild(b);
}
}
}
//handling the bullets
protected function doBullets(){
//make a for loop to iterate all the _bulletsArray on the screen
for (var bcount:int = _bulletsArray.length-1; bcount>=0; bcount--) {
//make the bullets move Up
_bulletsArray[bcount].y -=20;
//if the bullet is beyond the screen remove from the stage and the Array
if(_bulletsArray[bcount].y < 0){
removeChild(_bulletsArray[bcount])
_bulletsArray.splice(bcount,1);
}
}
}
}
}
I dont know how to fix neither of the 2 problems.Would be very thankful for any help!!!
Thanks in advance.

How do I add Child when two instances collide?

I'm trying to create a virtual life simulation, where when a boy fish and a girl fish collide they reproduce. This is my first time using external class files and I'm quite confused.
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Main extends MovieClip
{
var numBalls:Number = 3;
var bFishList:Array = new Array();
var gFishList:Array = new Array();
public static var bFish:BoyFish = new BoyFish ;
public static var gFish:GirlFish = new GirlFish ;
var fishName:Object = bFish.name;
public function Main()
{
addEventListener(Event.ADDED_TO_STAGE, enterFrameNow);
function enterFrameNow(event:Event):void {
// constructor code
for (var i = 0; i < numBalls; i++) {
var bFish:MovieClip = new BoyFish();
bFish.name = "bFish"+i;
addChild(bFish);
//variable ball a movieclip is a new instance of Ball
var gFish:MovieClip = new GirlFish();
// ball x and y value was in the middle of the stage
bFish.x = stage.stageWidth / 2;
bFish.y = stage.stageHeight / 2;
// add ball to stage
bFishList.push(bFish);
// ball x and y value was in the middle of the stage
gFish.x = stage.stageWidth / 2;
gFish.y = stage.stageHeight / 2;
// add ball to stage
addChild(gFish);
gFishList.push(gFish);
addEventListener(Event.ENTER_FRAME, hitTest);
function hitTest(event:Event):void {
for (i = 0; i < bFishList.length; i++) {
if (gFish.hitTestObject(bFishList[i]) == true) {
addChild(gFish);
gFishList.push(gFish);
trace("hit");
}
}
}
}
}
trace(bFishList);
trace(gFishList);
}
}
}
Here's the code from my Main.as file. I've tried for so long with the hitTestObject thing, and it's just not working for me.
Can anyone help me? I want it to add another instance to the stage when a bFish and a gFish collide.
You shouldn't add that many enterFrame events.
Add just one enterFrame handler, in your class, not as a local function, and add a nested loop into it.
//Somewhere in your Main() function :
addEventListener(Event.ENTER_FRAME, this.hitTest);
//In class Main
public function hitTest(event:Event):void
{
for (var i = 0; i < bFishList.length; i++)
{
for (var j = 0; j < gFishList.length; j++)
{
if (gFishList[j].hitTestObject(bFishList[i]))
{
var newFish:MovieClip = new GirlFish(); //Create it.
addChild(newFish);
gFishList.push(newFish);
}
}
}
}
Please note that if you aren't doing any more action, that could result of the creation of many girl fish each frame, which could eventually freeze the flashplayer.

How to make new bubbles stack in my Bubble Shooter game?

I'm making a Bubble Shooter game, and I'm trying to make the bubble I'm fireing to stack and then be at the right place in the column. The bubbles I've placed on the board looks like this:
000000000000000
000000000000000
000000000000000
000000000000000
There's 4 rows with 15 bubbles. This is the code I have written so far:
Main
package {
import flash.display.Sprite;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.display.SpreadMethod;
public class Main extends Sprite {
private const ROT_SPEED:uint=2;
private const R:uint=18;
private const DEG_TO_RAD:Number=0.0174532925;
private const BUBBLE_SPEED:uint=10;
private var bubbleArr:Array=new Array();
private var loadArr:Array=new Array();
private var cannon:cannon_mc;
private var bubble:bubble_mc;
private var row:uint=0;
private var col:uint=0;
private var left:Boolean=false;
private var right:Boolean=false;
public var bubCont:Sprite;
private var loadCont:Sprite;
private var fire:Boolean=false;
private var vx,vy:Number;
public function Main() {
placeContainer();
placeCannon();
loadBubble();
stage.addEventListener(KeyboardEvent.KEY_DOWN,onKDown);
stage.addEventListener(KeyboardEvent.KEY_UP,onKUp);
addEventListener(Event.ENTER_FRAME,onEFrame);
trace("row= "+row+" , col= "+col);
}
private function placeCannon():void {
cannon=new cannon_mc();
addChild(cannon);
cannon.y=385.5;
cannon.x=320;
}
private function onKDown(e:KeyboardEvent):void {
switch(e.keyCode) {
case 37 :
left=true;
break;
case 39 :
right=true;
break;
case 38 :
if (! fire) {
fire=true;
var radians=(cannon.rotation-90)*DEG_TO_RAD;
vx=BUBBLE_SPEED*Math.cos(radians);
vy=BUBBLE_SPEED*Math.sin(radians);
}
break;
}
}
private function onKUp(e:KeyboardEvent):void {
switch(e.keyCode) {
case 37 :
left=false;
break;
case 39 :
right=false;
break;
}
}
private function onEFrame(e:Event):void {
if (left) {
cannon.rotation-=ROT_SPEED;
}
if (right) {
cannon.rotation+=ROT_SPEED;
}
if (fire) {
bubble.x+=vx;
bubble.y+=vy;
if (bubble.x<59) {
bubble.x=59;
vx*=-1;
}
if (bubble.x>(59+R*R)) {
bubble.x=59+R*R;
vx*=-1;
}
if (bubble.y<(40)) {
bubble.y=40;
}
}
}
public function placeContainer():void {
var iRow:Boolean=false;
bubCont=new Sprite();
addChild(bubCont);
for (var i:uint=0; i<4; i++) {
if (! iRow) {
for (var j:uint=0; j<15; j++) {
bubbleArr[i]=new Array();
bubbleArr[i][j]=Math.floor(Math.random()*6);
bubble = new bubble_mc(bubbleArr[i][j],i,j);
bubCont.addChild(bubble);
iRow=true;
row++;
col++;
}
} else {
for (j=0; j<15; j++) {
bubbleArr[i]=new Array();
bubbleArr[i][j]=Math.floor(Math.random()*6);
bubble = new bubble_mc(bubbleArr[i][j],i,j);
bubble.x=77+j*2*R;
bubCont.addChild(bubble);
iRow=false;
row++;
col++;
}
}
}
}
private function loadBubble():void {
addChild(bubble);
bubble.gotoAndStop(Math.floor(Math.random()*6))+1;
bubble.x=320;
bubble.y=410;
}
}
bubble_mc class:
package {
import flash.display.MovieClip;
public class bubble_mc extends MovieClip {
public function bubble_mc(val:uint,row:uint,col:uint) {
gotoAndStop(val+1);
name=row+"_"+col;
x=59+col*36;
y=40+row*32;
}
}
I have absolutley no idea how to make the bubbles stack together.. I have tried using hitTestObject-function and I have tried to write my own function that checks for collision and then calls a function that is supposed to place the bubble in the right place, but it doesn't work and I dont know why. I'm getting a error called TypeError: Error #1010.
Here is the collision function and the parkBubble function- which is supposed to place the bubbles in the right place:
private function parkBubble(bubble:bubble_mc,row:int,col:int):void {
var iRow:Boolean=false;
for (var j:uint=0; j<col; j++) {
trace("first for loop ");
for (var i:uint=row; i>0; i--) {
trace("second for loop ");
if (bubbleArr[i][j]!=null) {
trace("first if loop ");
if (! iRow) {
trace("second if loop ");
bubbleArr[i+1]=new Array();
bubbleArr[i+1][j]=Math.floor(Math.random()*6);
bubble = new bubble_mc(bubbleArr[i+1][j],(i+1),j);
bubCont.addChild(bubble);
iRow=true;
row++;
col++;
} else {
trace("first for loop after else ");
bubbleArr[i+1]=new Array();
bubbleArr[i+1][j]=Math.floor(Math.random()*6);
bubble = new bubble_mc(bubbleArr[i+1][j],(i+1),j);
bubble.x=77+j*2*R;
bubCont.addChild(bubble);
iRow=false;
row++;
col++;
}
}
}
}
removeChild(bubble);
fire=false;
loadBubble();
trace("slutet av parkBubble ");
}
private function collide(bub:bubble_mc):Boolean {
var dist_x:Number=bub.x-bubble.x;
var dist_y:Number=bub.y-bubble.y;
return Math.sqrt(dist_x*dist_x+dist_y*dist_y)<=2*R-4;
}
Was the TypeError on this line?
var placed_bubble:bubble_mc=new bubble_mc([row][col],row,col);
The [row] is an array, and [col] is an array. But the constructor expects an unsigned integer:
public function bubble_mc(val:uint,row:uint,col:uint) {
In order to copy the bubble to the bubble container, pass the frame number:
var placed_bubble:bubble_mc=new bubble_mc(bubble.currentFrame-1, row, col);
This might not be the only problem. TypeError often results from a variable not being defined, which could be from some other code that modifies the variable "bubble". For example, placeContainer assigns the bubbles in the container to the variable "bubble".
The function parkBubble always sets "iRow" to false, but if the bubble collides with a row above it that is odd you want iRow to be true.
var row:uint=Math.floor(bubble.y/(40+R*Math.sqrt(3)));
var iRow:Boolean= row % 2 == 1 ? true : false;
After it is at least compiling, you'll have less problems if you go back and simplify and optimize the math with some constant names. Then you'll more easily see the above code for calculating the row is not quite right. It should subtract the top margin (40). That is obvious with named constants:
private const Y_PER_ROW:int = int(R * Math.sqrt(3));
private const TOP:int = 40;
...
var row:uint = int((bubble.y - TOP) / Y_PER_ROW);
I would double-check your other calculations, too. Puzzle Bobble games usually set the odd rows to horizontally offset at radius, not at 2 radius (2 * R). So they fit together like hexagons.
The placeContainer function could be simplified. Most of the code in even or odd rows is the same, so could be taken out of the if block. And in this code you posted, I don't see why you need "row++" and "col++" in placeContainer. This is equivalent and easier to read:
for (var i:uint=0; i<4; i++) {
var xOffset:int = (i % 2) * 2 * R;
for (var j:uint=0; j<15; j++) {
bubbleArr[i] = new Array();
bubbleArr[i][j] = int(Math.random()*6);
bubble = new bubble_mc(bubbleArr[i][j], i, j);
bubble.x += xOffset;
bubCont.addChild(bubble);
row++;
col++;
}
}
Then, the collision detection code could be simplified and optimized to avoid calculations when the bubble is far away and avoid the expensive square-root calculation:
Circle Collision Detection HTML5 Canvas
http://cgp.wikidot.com/circle-to-circle-collision-detection