Added child stays invisible even though its container is visible - actionscript-3
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
Related
Actionscript 3 drag and drop multiple objects to target with well done
The drag and drop works, however, I have no idea how to create an if statement that goes to the next scene when all movieclips have been placed on the target. I've tried placing the instance names in an if statement with the hittestobject however, no luck. import flash.events.TouchEvent; import flash.ui.Multitouch; import flash.ui.MultitouchInputMode; import flash.display.MovieClip; /* Touch and Drag Event Allows the object to be moved by holding and dragging the object. */ var objectoriginalX:Number; var objectoriginalY:Number; Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT; var lemons:Array = [lemon1_mc, lemon2_mc, lemon3_mc, lemon4_mc, lemon5_mc]; for each(var lemonMC:MovieClip in lemons) { lemonMC.buttonMode = true; lemonMC.addEventListener(TouchEvent.TOUCH_BEGIN, pickobject); lemonMC.addEventListener(TouchEvent.TOUCH_END, dropobject); lemonMC.startX = lemonMC.x; lemonMC.startY = lemonMC.y; } var fl_DragBounds:Rectangle = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight); function pickobject(event:TouchEvent):void { event.target.startTouchDrag(event.touchPointID, false, fl_DragBounds); event.target.parent.addChild(event.target); objectoriginalX = event.target.x; objectoriginalY = event.target.y; } function dropobject(event:TouchEvent):void { if(event.target.hitTestObject(target_mc)){ event.target.buttonMode = false; event.target.x = target_mc.x; event.target.y = target_mc.y; event.target.visible = false; } else { event.target.x = event.target.startX; event.target.y = event.target.startY; event.target.buttonMode = true; } } var melons:Array = [melon1_mc, melon2_mc, melon3_mc, melon4_mc, melon5_mc, melon6_mc, melon7_mc]; for each(var melonMC:MovieClip in melons) { melonMC.buttonMode = true; melonMC.addEventListener(TouchEvent.TOUCH_BEGIN, pickobject2); melonMC.addEventListener(TouchEvent.TOUCH_END, dropobject2); melonMC.startX = melonMC.x; melonMC.startY = melonMC.y; } var fl_DragBounds2:Rectangle = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight); function pickobject2(event:TouchEvent):void { event.target.startTouchDrag(event.touchPointID, false, fl_DragBounds2); event.target.parent.addChild(event.target); objectoriginalX = event.target.x; objectoriginalY = event.target.y; } function dropobject2(event:TouchEvent):void { if(event.target.hitTestObject(target_null)){ event.target.buttonMode = false; event.target.x = target_mc.x; event.target.y = target_mc.y; event.target.visible = false; } else { event.target.x = event.target.startX; event.target.y = event.target.startY; event.target.buttonMode = true; } }
How about adding a counter that is equal to number of objects to drag, then every time you drop object (and detect if it was on target) you decrements the counter and at the end of the function you check if it's 0?
An easy way to do this would be to remove your lemons/melons from their arrays when they pass the hit test. Then check if each array is empty and continue to the next scene should that be the case. You can actually reduce redundant code and use the same function (dropobject) for both lemons and melons. function dropobject(event:TouchEvent):void { //Figure out which array this belongs to (is it a lemon or a melon) var array:Array; //the array the dropped item belongs to var hitMC:MovieClip; //the hit object for the lemon or melon if(lemons.indexOf(event.currentTarget) > -1){ //if the lemon array contains the currentTarget array = lemons; hitMC = target_mc; }else{ array = melons; hitMC = target_null; } if(event.currentTarget.hitTestObject(hitMC)){ event.currentTarget.buttonMode = false; event.currentTarget.x = hitMC.x; event.currentTarget.y = hitMC.y; event.currentTarget.visible = false; //remove the item from it's array array.removeAt(array.indexOf(event.currentTarget)); //check if there are any items left if(lemons.length < 1 && melons.length < 1){ //both arrays are empty, so move on play(); //or however you want to move on } } } Getting more advanced, a better way to do this would be to make a base class for your lemons, melons and anything else you want to drag in the future. Then you can add the dragging functionality into that base class and add properties for the hit target and an event for when it's hit it's target. This would give you one code base that can be easily applied to any library object.
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 { } }
how to call actionscript functions from flash timeline
I am using AS3, and i want to call function 'startMatchThree' which is in a MatchThree.as (external actionscript file) into the flahs main timeline actions. here is my code: package { import flash.display.; import flash.events.; import flash.text.*; import flash.utils.Timer; public class MatchThree extends MovieClip { // constants static const numPieces:uint = 4; static const spacing:Number = 45; static const offsetX:Number = 30; static const offsetY:Number = 50; // game grid and mode private var grid:Array; private var gameSprite:Sprite; private var firstPiece:Piece; private var isDropping,isSwapping:Boolean; private var gameScore:int; // set up grid and start game public function startMatchThree() { // create grid array grid = new Array(); for(var gridrows:int=0;gridrows<8;gridrows++) { grid.push(new Array()); } setUpGrid(); isDropping = false; isSwapping = false; gameScore = 0; addEventListener(Event.ENTER_FRAME,movePieces); } public function setUpGrid() { // loop until valid starting grid while (true) { // create sprite gameSprite = new Sprite(); // add 64 random pieces for(var col:int=0;col<8;col++) { for(var row:int=0;row<8;row++) { addPiece(col,row); } } // try again if matches are present if (lookForMatches().length != 0) continue; // try again if no possible moves if (lookForPossibles() == false) continue; // no matches, but possibles exist: good board found break; } // add sprite addChild(gameSprite); } // create a random piece, add to sprite and grid public function addPiece(col,row:int):Piece { var newPiece:Piece = new Piece(); newPiece.x = col*spacing+offsetX; newPiece.y = row*spacing+offsetY; newPiece.col = col; newPiece.row = row; newPiece.type = Math.ceil(Math.random()*4); newPiece.gotoAndStop(newPiece.type); newPiece.select.visible = false; gameSprite.addChild(newPiece); grid[col][row] = newPiece; newPiece.addEventListener(MouseEvent.CLICK,clickPiece); return newPiece; } // player clicks on a piece public function clickPiece(event:MouseEvent) { var piece:Piece = Piece(event.currentTarget); // first one selected if (firstPiece == null) { piece.select.visible = true; firstPiece = piece; // clicked on first piece again } else if (firstPiece == piece) { piece.select.visible = false; firstPiece = null; // clicked on second piece } else { firstPiece.select.visible = false; // same row, one column over if ((firstPiece.row == piece.row) && (Math.abs(firstPiece.col-piece.col) == 1)) { makeSwap(firstPiece,piece); firstPiece = null; // same column, one row over } else if ((firstPiece.col == piece.col) && (Math.abs(firstPiece.row-piece.row) == 1)) { makeSwap(firstPiece,piece); firstPiece = null; // bad move, reassign first piece } else { firstPiece = piece; firstPiece.select.visible = true; } } } // start animated swap of two pieces public function makeSwap(piece1,piece2:Piece) { swapPieces(piece1,piece2); // check to see if move was fruitful if (lookForMatches().length == 0) { swapPieces(piece1,piece2); } else { isSwapping = true; } } // swap two pieces public function swapPieces(piece1,piece2:Piece) { // swap row and col values var tempCol:uint = piece1.col; var tempRow:uint = piece1.row; piece1.col = piece2.col; piece1.row = piece2.row; piece2.col = tempCol; piece2.row = tempRow; // swap grid positions grid[piece1.col][piece1.row] = piece1; grid[piece2.col][piece2.row] = piece2; } // if any pieces are out of place, move them a step closer to being in place // happens when pieces are swapped, or they are dropping public function movePieces(event:Event) { var madeMove:Boolean = false; for(var row:int=0;row<8;row++) { for(var col:int=0;col<8;col++) { if (grid[col][row] != null) { // needs to move down if (grid[col][row].y < grid[col][row].row*spacing+offsetY) { grid[col][row].y += 5; madeMove = true; // needs to move up } else if (grid[col][row].y > grid[col][row].row*spacing+offsetY) { grid[col][row].y -= 5; madeMove = true; // needs to move right } else if (grid[col][row].x < grid[col][row].col*spacing+offsetX) { grid[col][row].x += 5; madeMove = true; // needs to move left } else if (grid[col][row].x > grid[col][row].col*spacing+offsetX) { grid[col][row].x -= 5; madeMove = true; } } } } // if all dropping is done if (isDropping && !madeMove) { isDropping = false; findAndRemoveMatches(); // if all swapping is done } else if (isSwapping && !madeMove) { isSwapping = false; findAndRemoveMatches(); } } // gets matches and removes them, applies points public function findAndRemoveMatches() { // get list of matches var matches:Array = lookForMatches(); for(var i:int=0;i<matches.length;i++) { var numPoints:Number = (matches[i].length-1)*50; for(var j:int=0;j<matches[i].length;j++) { if (gameSprite.contains(matches[i][j])) { var pb = new PointBurst(this,numPoints,matches[i][j].x,matches[i][j].y); addScore(numPoints); gameSprite.removeChild(matches[i][j]); grid[matches[i][j].col][matches[i][j].row] = null; affectAbove(matches[i][j]); } } } // add any new piece to top of board addNewPieces(); // no matches found, maybe the game is over? if (matches.length == 0) { if (!lookForPossibles()) { endGame(); } } } when I put 'startMatchThree' in the actions tab in timeline, it is showing this error message: 1180: Call to a possibly undefined method startMatchThree. SO how to solve this error!! Thank you for the help!! :)
startMatchThree() is a method of the MatchThree class, so you need a reference to an instance of MatchThree. Is there a symbol on the timeline somewhere which is linked to the MatchThree class? Then you can do something like this, where "matchThree" is the instance name of the symbol: matchThree.startMatchThree(); Are you instantiating the MatchThree class in code? Then you just need to use that code reference, something like this,: var matchThree:MatchThree = new MatchThree(); matchThree.startMatchThree();
I am creating an auto solve function for a sliding puzzle
I am new to actionscript and I am trying to make a "cheat" way of completing a sliding puzzle where when I click the [s] key it calls a solve puzzle function which makes a for loop put all the puzzle pieces in the correct location. This function must call a for loop, those were the instructions I was given. Could anyone help me understand the code that I need to make this happen. I have already made the function and it does properly call when I hit the s key but everything past that doesn't seem to make the code actually move the pieces. Thank you for any help I can get. package { import flash.display.*; import flash.events.*; import flash.net.URLRequest; import flash.geom.*; import flash.utils.Timer; public class SlidingPuzzle extends MovieClip { // space between pieces and offset static const pieceSpace:Number = 2; static const horizOffset:Number = 50; static const vertOffset:Number = 50; // number of pieces static const numPiecesHoriz:int = 5; static const numPiecesVert:int = 5; // random shuffle steps static const numShuffle:int = 200; // animation steps and time static const slideSteps:int = 10; static const slideTime:int = 250; // size of pieces private var pieceWidth:Number; private var pieceHeight:Number; // game pieces private var puzzleObjects:Array; // tracking moves private var blankPoint:Point; private var slidingPiece:Object; private var slideDirection:Point; private var slideAnimation:Timer; public function startSlidingPuzzle() { // blank spot is the bottom right blankPoint = new Point(numPiecesHoriz-1,numPiecesVert-1); // load the bitmap loadBitmap("oceanshore.jpg"); // event to complete the puzzle for you. stage.addEventListener(KeyboardEvent.KEY_UP, solvePuzzle); } // get the bitmap from an external source public function loadBitmap(bitmapFile:String) { var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadingDone); var request:URLRequest = new URLRequest(bitmapFile); loader.load(request); } // bitmap done loading, cut into pieces public function loadingDone(event:Event):void { // create new image to hold loaded bitmap var image:Bitmap = Bitmap(event.target.loader.content); pieceWidth = image.width/numPiecesHoriz; pieceHeight = image.height/numPiecesVert; // cut into puzzle pieces makePuzzlePieces(image.bitmapData); // shuffle them shufflePuzzlePieces(); } // cut bitmap into pieces public function makePuzzlePieces(bitmapData:BitmapData) { puzzleObjects = new Array(); for(var x:uint=0;x<numPiecesHoriz;x++) { for (var y:uint=0;y<numPiecesVert;y++) { // skip blank spot if (blankPoint.equals(new Point(x,y))) continue; // create new puzzle piece bitmap and sprite var newPuzzlePieceBitmap:Bitmap = new Bitmap(new BitmapData(pieceWidth,pieceHeight)); newPuzzlePieceBitmap.bitmapData.copyPixels(bitmapData,new Rectangle(x*pieceWidth,y*pieceHeight,pieceWidth,pieceHeight),new Point(0,0)); var newPuzzlePiece:Sprite = new Sprite(); newPuzzlePiece.addChild(newPuzzlePieceBitmap); addChild(newPuzzlePiece); // set location newPuzzlePiece.x = x*(pieceWidth+pieceSpace) + horizOffset; newPuzzlePiece.y = y*(pieceHeight+pieceSpace) + vertOffset; // create object to store in array var newPuzzleObject:Object = new Object(); newPuzzleObject.currentLoc = new Point(x,y); newPuzzleObject.homeLoc = new Point(newPuzzlePiece.x,newPuzzlePiece.y); newPuzzleObject.piece = newPuzzlePiece; newPuzzlePiece.addEventListener(MouseEvent.CLICK,clickPuzzlePiece); puzzleObjects.push(newPuzzleObject); } } } //make the puzzle solve itself public function solvePuzzle(evt:KeyboardEvent) { if (evt.keyCode == 83) { for(var i:int = 0; i<puzzleObjects.length; i++) { } } } // make a number of random moves public function shufflePuzzlePieces() { for(var i:int=0;i<numShuffle;i++) { shuffleRandom(); } } // random move public function shuffleRandom() { // loop to find valid moves var validPuzzleObjects:Array = new Array(); for(var i:uint=0;i<puzzleObjects.length;i++) { if (validMove(puzzleObjects[i]) != "none") { validPuzzleObjects.push(puzzleObjects[i]); } } // pick a random move var pick:uint = Math.floor(Math.random()*validPuzzleObjects.length); movePiece(validPuzzleObjects[pick],false); } public function validMove(puzzleObject:Object): String { // is the blank spot above if ((puzzleObject.currentLoc.x == blankPoint.x) && (puzzleObject.currentLoc.y == blankPoint.y+1)) { return "up"; } // is the blank spot below if ((puzzleObject.currentLoc.x == blankPoint.x) && (puzzleObject.currentLoc.y == blankPoint.y-1)) { return "down"; } // is the blank to the left if ((puzzleObject.currentLoc.y == blankPoint.y) && (puzzleObject.currentLoc.x == blankPoint.x+1)) { return "left"; } // is the blank to the right if ((puzzleObject.currentLoc.y == blankPoint.y) && (puzzleObject.currentLoc.x == blankPoint.x-1)) { return "right"; } // no valid moves return "none"; } // puzzle piece clicked public function clickPuzzlePiece(event:MouseEvent) { // find piece clicked and move it for(var i:int=0;i<puzzleObjects.length;i++) { if (puzzleObjects[i].piece == event.currentTarget) { movePiece(puzzleObjects[i],true); break; } } } // move a piece into the blank space public function movePiece(puzzleObject:Object, slideEffect:Boolean) { // get direction of blank space switch (validMove(puzzleObject)) { case "up": movePieceInDirection(puzzleObject,0,-1,slideEffect); break; case "down": movePieceInDirection(puzzleObject,0,1,slideEffect); break; case "left": movePieceInDirection(puzzleObject,-1,0,slideEffect); break; case "right": movePieceInDirection(puzzleObject,1,0,slideEffect); break; } } // move the piece into the blank spot public function movePieceInDirection(puzzleObject:Object, dx,dy:int, slideEffect:Boolean) { puzzleObject.currentLoc.x += dx; puzzleObject.currentLoc.y += dy; blankPoint.x -= dx; blankPoint.y -= dy; // animate or not if (slideEffect) { // start animation startSlide(puzzleObject,dx*(pieceWidth+pieceSpace),dy*(pieceHeight+pieceSpace)); } else { // no animation, just move puzzleObject.piece.x = puzzleObject.currentLoc.x*(pieceWidth+pieceSpace) + horizOffset; puzzleObject.piece.y = puzzleObject.currentLoc.y*(pieceHeight+pieceSpace) + vertOffset; } } // set up a slide public function startSlide(puzzleObject:Object, dx, dy:Number) { if (slideAnimation != null) slideDone(null); slidingPiece = puzzleObject; slideDirection = new Point(dx,dy); slideAnimation = new Timer(slideTime/slideSteps,slideSteps); slideAnimation.addEventListener(TimerEvent.TIMER,slidePiece); slideAnimation.addEventListener(TimerEvent.TIMER_COMPLETE,slideDone); slideAnimation.start(); } // move one step in slide public function slidePiece(event:Event) { slidingPiece.piece.x += slideDirection.x/slideSteps; slidingPiece.piece.y += slideDirection.y/slideSteps; } // complete slide public function slideDone(event:Event) { slidingPiece.piece.x = slidingPiece.currentLoc.x*(pieceWidth+pieceSpace) + horizOffset; slidingPiece.piece.y = slidingPiece.currentLoc.y*(pieceHeight+pieceSpace) + vertOffset; slideAnimation.stop(); slideAnimation = null; // check to see if puzzle is complete now if (puzzleComplete()) { clearPuzzle(); gotoAndStop("gameover"); } } // check to see if all pieces are in place public function puzzleComplete():Boolean { for(var i:int=0;i<puzzleObjects.length;i++) { if (!puzzleObjects[i].currentLoc.equals(puzzleObjects[i].homeLoc)) { return false; } } return true; } // remove all puzzle pieces public function clearPuzzle() { for (var i in puzzleObjects) { puzzleObjects[i].piece.removeEventListener(MouseEvent.CLICK,clickPuzzlePiece); removeChild(puzzleObjects[i].piece); } puzzleObjects = null; } }
First, program must know where to place the objects, for them to placed correctly. And best way to do it, is to record piece's initial positions. Before you set piece's new location, create the Object and take it's initial location. newPuzzleObject.initialLoc = new Point(newPuzzlePiece.x,newPuzzlePiece.y); Object creation must come before this part, before piece's initial position changed; // set location newPuzzlePiece.x = x*(pieceWidth+pieceSpace) + horizOffset; newPuzzlePiece.y = y*(pieceHeight+pieceSpace) + vertOffset; And at the solvePuzzle, place them all back to their initial location. for(i:uint; i < puzzleObjects.length; i++) { puzzleObjects[i].x = puzzleObjects[i].initialLoc.x; puzzleObjects[i].y = puzzleObjects[i].initialLoc.y; }
AS3 not recognising MovieClips - 1046: Type was not found or was not a compile-time constant: MP_00
So Im new to AS3, trying to make a simple videogame for smartphones. And it was all going smooth until I hit this problem. I was using and manipulating objects from timeline without a problem and than all the sudden whatever I try I get the 1046. Here is some code that gets an error: mp = new MP_00(); And at the top I have this: import flash.display.MovieClip; var mp:Movieclip; And at the end this: function mapMove(){ mp.y = mp.y - playerSpeed; } Im searching for a solution all the time, but nobody seems to have the same problem. I do have AS linkage set to MP_00 and witch ever object I try to put in, it dosent work. While objects put in on the same way before, they work. For example I have this var player:MovieClip; player = new Player(); with AS Linkage set to Player, and that works. This is all done in Flash Professional cs6 EDIT 1 full code Keep in mind that a lot of stuff is placeholder or just not finished code. On this code Im getting the error twice for the same object Scene 1 1046: Type was not found or was not a compile-time constant: MP_00. Scene 1, Layer 'Actions', Frame 1, Line 165 1046: Type was not found or was not a compile-time constant: MP_00. Thats the errors. import flash.display.MovieClip; import flash.events.MouseEvent; import flash.text.engine.SpaceJustifier; import flashx.textLayout.operations.MoveChildrenOperation; /*----------------------------Main VARs-----------------------------*/ var STATE_START:String="STATE_START"; var STATE_START_PLAYER:String="STATE_START_PLAYER"; var STATE_PLAY:String="STATE_PLAY"; var STATE_END:String="STATE_END"; var gameState:String; var player:MovieClip; var playerSpeed:Number; var map:Array; var bullets:Array; //holds civil vehicles var civil:Array; //holds enemy vehicles var enemy:Array; var explosions:Array; var BBullet:MovieClip; //maps var mp:MovieClip; /* var MP_01:MovieClip; var MP_02:MovieClip; var MP_03:MovieClip; */ //sets the bullet type and properties var BType = "BBasic"; var BProp:Array; //bullet preperties by type var BBasic:Array = new Array(1, 1, 100, 50, 0, new BBasicA()); /** ARRAY SETTING 0 = bullet position (middle , back, sides etc...) 1-middle front 2-left side front 3-right side front 4-left and right side middle 5-back 7-left and right side wheels 1 = bullet direction 1-forward 2-back 3-sides 2 = fire speed (in millisecounds so 1000 = 1sec) 3 = speed of movement 4 = damage 10-100 5 = name of the firing animation in library 6 = name of launch animation in library 7 = name of impact animation in library **/ var level:Number; //BCivil speed and randomness var BCSpeed:Number = 3; var BCRand:Number = 120; /*------------------------------Setup-------------------------------*/ introScreen.visible = false; loadingScreen.visible = false; gameScreen.visible = false; endScreen.visible = false; //map visibility //MpRSimple.visible = false; /*---------------------------Intro screen--------------------------*/ /*-----------------------------mainScreen---------------------------*/ mainScreen.play_btn.addEventListener(MouseEvent.CLICK, clickAway); function clickAway(event:MouseEvent):void { gameStart(); } function gameStart():void { //Move main screen from stage mainScreen.visible = false; //Begin loading the game loadingScreen.visible = true; gameState = STATE_START; trace (gameState); addEventListener(Event.ENTER_FRAME, gameLoop); } /*----------------------------gameLoop-----------------------------*/ function gameLoop(e:Event):void { switch(gameState) { case STATE_START: startGame(); break; case STATE_START_PLAYER: startPlayer(); break; case STATE_PLAY: playGame(); break; case STATE_END: endGame(); break; } } /*-_________________________-Game STATES-_________________________-*/ /*---------------------------STATE_START---------------------------*/ function startGame():void { level = 1; //setting level for enemies //Graphics //player icon player = new Player(); //add bullet holder bullets = new Array(); //basicCivil icon civil = new Array(); //basicEnemy icon enemy = new Array(); //holds explosions explosions = new Array(); //map //mp = new MP_00(); //var mp:MP_00 = new MP_00(); //Load map parts //End startGame gameState = STATE_START_PLAYER; trace(gameState); } /*------------------------STATE_START_PLAYER-----------------------*/ function startPlayer():void { //start the player //set possition of player player.y = stage.stageHeight - player.height; addChild(player); addEventListener(Event.ENTER_FRAME, movePlayer); //changing screens gameScreen.visible = true; //start game gameState = STATE_PLAY; trace(gameState); } //player controll function movePlayer(e:Event):void { //gameScreen.visible = true; //mouse\touch recognition player.x = stage.mouseX; player.y = stage.mouseY; //player does not move out of the stage if (player.x < 0) { player.x = 0; } else if (player.x > (stage.stageWidth - player.width)) { player.x = stage.stageWidth + player.width; } } //setting bullet type if (BType == "BBasic") { BProp = BBasic; /*case BMissile; BProp = BMissile; break; */ } //creating bullets //gameScreen.fire_btn.addEventListener(MouseEvent.CLICK, fireHandler()); /* function fireHandler():void { var bulletTimer:Timer = new Timer (500); bulletTimer.addEventListener(TimerEvent.TIMER, timerListener); bulletTimer.start(); trace("nja"); } function timerListener(e:TimerEvent):void { //need and if statement to determine the bullet speed and travel depended on type of bullet var tempBullet:MovieClip = /*BProp[5] new BBasicA(); //shoots bullets in the middle tempBullet.x = player.x +(player.width/2); tempBullet.y = player.y; //shooting speed tempBullet.speed = 10; bullets.push(tempBullet); addChild(tempBullet); //bullets movement forward for(var i=bullets.length-1; i>=0; i--) { tempBullet = bullets[i]; tempBullet.y -= tempBullet.speed; } } */ /*----------------------------STATE_PLAY---------------------------*/ function playGame():void { //gameplay //speedUp(); mapMove(); //fire(); makeBCivil(); makeBEnemy(); moveBCivil(); moveBEnemy(); vhDrops(); testCollision(); testForEnd(); removeExEplosions(); } function mapMove(){ mp.y = mp.y - playerSpeed; } /* function speedUp():void { var f:Number; for (f<10; f++;) { var playerSpeed = playerSpeed + 1; f = 0; //mapMove(); MpRSimple = new MP_RS(); MpRSimple.y = MpRSimple.y - playerSpeed; trace ("speed reset"); } trace (f); } */ function makeBCivil():void { //random chance var chance:Number = Math.floor(Math.random()*BCRand); if (chance <= 1 + level) { var tempBCivil:MovieClip; //generate enemies tempBCivil = new BCivil(); tempBCivil.speed = BCSpeed; tempBCivil.x = Math.round(Math.random()*800); addChild(tempBCivil); civil.push(tempBCivil); } } function moveBCivil():void { //move enemies var tempBCivil:MovieClip; for(var i:int = civil.length-1; i>=0; i--) { tempBCivil = civil[i]; tempBCivil.y += tempBCivil.speed } //testion colision with the player and screen out if (tempBCivil.y > stage.stageHeight /* || tempBCivil.hitTestObject(player) */) { trace("ds hit"); //makeExplosion (player.x, player.y); removeCivil(i); //gameState = STATE_END; } } //Test bullet colision function testCollision():void { var tempBCivil:MovieClip; var tempBEnemy:MovieClip; var tempBullet:MovieClip; //civil/bullet colision civils:for(var i:int=civil.length-1; i>=0; i--) { tempBCivil = civil[i]; for (var j:int=bullets.length-1; j>=0; j--) { tempBullet = bullets[j]; if (tempBCivil.hitTestObject(tempBullet)) { trace("laser hit the civil"); makeExplosion (tempBCivil.x, tempBCivil.y); removeCivil(i); removeBullet(j); break civils; } } } //enemy/bullet colision enemy:for(var k:int=enemy.length-1; k>=0; k--) { tempBEnemy = enemy[k]; for (var l:int=bullets.length-1; l>=0; l--) { tempBullet = bullets[l]; if (tempBEnemy.hitTestObject(tempBullet)) { trace("bullet hit the Enemy"); makeExplosion (tempBEnemy.x, tempBEnemy.y); removeEnemy(k); removeBullet(l); break enemy; } } } } function makeExplosion(ex:Number, ey:Number):void { var tempExplosion:MovieClip; tempExplosion = new boom(); tempExplosion.x = ex; tempExplosion.y = ey; addChild(tempExplosion) explosions.push(tempExplosion); } function makeBEnemy():void { //random chance var chance:Number = Math.floor(Math.random()*BCRand); if (chance <= 1 + level) { var tempBEnemy:MovieClip; //generate enemies tempBEnemy = new BEnemy(); tempBEnemy.speed = BCSpeed; tempBEnemy.x = Math.round(Math.random()*800); addChild(tempBEnemy); enemy.push(tempBEnemy); } } function moveBEnemy():void { //move enemies var tempBEnemy:MovieClip; for(var i:int = enemy.length-1; i>=0; i--) { tempBEnemy = enemy[i]; tempBEnemy.y += tempBEnemy.speed } //testion colision with the player and screen out if (tempBEnemy.y > stage.stageHeight /* || tempBCivil.hitTestObject(player) */) { trace("enemy"); //makeExplosion (player.x, player.y); removeEnemy(i); //gameState = STATE_END; } } function vhDrops():void {} function testForEnd():void { //check damage //end game //gameState = STATE_END; trace(gameState); } /*--------------------REMOVING BS FROM STAGE-----------------------*/ //removing civils function removeCivil(idx:int):void { if(idx >= 0) { removeChild(civil[idx]); civil.splice(idx, 1); } } //removing enemies function removeEnemy(idx:int):void { if(idx >= 0) { removeChild(enemy[idx]); enemy.splice(idx, 1); } } //removing civils function removeBullet(idx:int):void { if(idx >= 0) { removeChild(bullets[idx]); bullets.splice(idx, 1); } } //removing expired explosions function removeExEplosions():void { var tempExplosion:MovieClip; for(var i=explosions.length-1; i>=0; i--) { tempExplosion = explosions[i]; if (tempExplosion.currentFrame >= tempExplosion.totalFrames) { removeExplosion(i); } } } //removing civils function removeExplosion(idx:int):void { if(idx >= 0) { removeChild(explosions[idx]); explosions.splice(idx, 1); } } /*--------------------------STATE_END------------------------------*/ function endGame():void { } /*gameScreen*/ /*endScreen*/ And Im sure theres some other bad code here but that doesent matter now. Export for AS and AS Linkage is set: http://i.stack.imgur.com/UvMAt.png EDIT: removed the 2nd var declaration, still get the same error.
It would be great if you give more code and explanations, but here what I found about 1046 : "One reason you will get this error is if you have an object on the stage with the same name as an object in your library." Look at : http://curtismorley.com/2007/06/20/flash-cs3-flex-2-as3-error-1046/ Did you search any explanation on the Web for code 1046 ? Have you checked this one ? I see that you have two var mp declaration. Try to remove the first one, var mp:MovieClip;. If it doesn't work, check your Flash Library carefully, be sure that MP_00 is a name available. If it's a MovieClip, check that it is exported for ActionScript. If it's an instance name, check that it's not used twice. EDIT. My suggestion is : 1- Change all references of mp to mp1. Maybe there is a conflict with an instance "...an object on the stage with the same name as an object in your library." 2- var mp1:MP_00; instead of var mp:MovieClip; in the declaration section. 3- Put the mp1 = new MP_00(); back in the startGame() function 4- Be sure that your new mp1 variable is everywhere you need and you have no more ref. to mp variable. If... it's still doesn't work. I suggest : Change the name of your MovieClip linkage, like TestA, or whatever. Yes I know, a doubt on everything, but there is no magic, testing everything will show the problem for sure. EDIT. For mapMove() function... First : be sure the speedUp() function is available, not in comments, and call it in your playGame() function. Your playerSpeed variable must have a value, so change : var playerSpeed = playerSpeed + 1; for playerSpeed = playerSpeed + 1;. Do not use var declaration twice for the same variable. (See var playerSpeed:Number; in header file.) Beside... you have to know if the MP_00 clip on stage is YOUR mp1 clip. (I assumed you published all the code you have.) Case A : MP_00 is on stage when you start your Clip. If you actually see your MP_00 on screen, that mean you don't have to do mp1 = new MP_00(); and addchild(mp1);. It's already done for you (dragging a clip from library and giving a name instance, is the same as doing new and addchild). Find the instance name (or give one). You should get your instance name and move your object (here the instance name is mp1): mp1.y = mp1.y - playerSpeed; Case B : MP_00 is NOT on stage when you start your Clip. Do : 1- your declaration : var mp1:MP_00; 2- allocation memory : mp1 = new MP_00(); 3- add to the display list : addchild(mp1); 4- "Shake it bb" : mp1.y = mp1.y - playerSpeed; or mp1.y -= playerSpeed; I don't know what is your knowledge level exactly, so I tried to put everything. Sorry if it's too much.