添加的子项保持不可见,即使它的容器是可见的
Added child stays invisible even though its container is visible
我已经为 Flash CS4 中的一个问题苦苦挣扎了几天。我正在将一个旧游戏项目重组为 Main class,它处理 mainMenu、playGame 等功能。我从 "game" 添加了一艘船,它是由 Main 添加的。
问题是 "myShip" 按预期工作,只是它永远不可见。我检查了很多次,myShip 及其容器(游戏)可见属性始终为真。 Alpha 值也不是问题,层数和深度也不是问题。我从 "game" 添加的所有其他子项都工作正常,但 "myShip" 拒绝显示。
关于为什么会发生这种情况有什么想法吗?我不知道下一步该怎么做才能解决问题。任何帮助将不胜感激。 Main、Game 和 Ship class 的代码如下。
谢谢!
主要代码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;
}
}
游戏代码class:
包裹{
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();
}
}
}
发货代码:
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;
}
}
}
}
您可以尝试添加一个 ADDED_TO_STAGE 事件。看这个游戏编程大师的精彩讲解
Understanding ADDED_TO_STAGE Event
为了理解正在发生的事情,您必须了解一些基础知识。
在舞台上添加东西是一个很常见的错误。
这是 addChild 的文档所说的
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
我猜人们将 DispalyObjects 添加到舞台是因为他们认为它是
"the stage" 他们在 Flash 创作中看到并与之互动
环境。 但是不一样stage.addChild()
不一样
将符号从库中拖到屏幕上。什么通过
默认代表主时间线是root
属性。
但是,如果你直接向stage
添加任何东西,它的root
属性和它的stage
属性都会引用同样 object,
通常只被 stage
引用。 stage
是一些
在闪存中 运行 时,您的 .swf 添加到的容器
玩家.
addChildAt 的文档是这样描述索引的:
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.
应用这些基础知识,会发生以下情况:
- FlashPlayer 创建
stage
object,实例化您的主 class
并将该实例添加到 stage
,它是索引为 0. 的 child
- 除其他外,
stage.addChildAt(mySprite, 1);
被执行,
添加 mySprite
作为第二个 child 到 stage
。索引为 1 是
呈现在索引 0 处的 object 前面,这恰好
成为您的主要 class 又名您的 .swf 文件的实例。 我希望
正在渲染的任何东西 "outside the .swf file" 说明得很好
够了为什么不推荐在舞台上添加东西。
- 稍后,
this.addChild(myShip);
发生了。 (这实际上是
正确的方法;此处无需使用 this
:addChild(myShip);
就是你所需要的。)并将船舶添加到显示列表中。假设所有
它的 parents 也被添加到显示列表中,它将是
显示。
- 但是你还是看不到,因为你在前面加了
mySprite
您的 main class 的实例并用内容填充它
drawGradient()
这掩盖了其他一切。
老实说,最好的解决办法是从头开始。
使用此代码对您没有任何帮助。即使自己努力完成它并以某种方式让它发挥作用也不会让你更好地理解任何事情(除了如何不做事)。似乎修改此代码以使用 classes 的唯一动机是为了这样做。将这样的旧代码强行纳入面向 object 的范例将不会很好地工作。 oop 的好处不会很明显,使这种体验更加令人沮丧。
最后但同样重要的是,不要推出自己的转换代码。有很多库可以做到这一点(包括flash自带的Tween class http://www.republicofcode.com/tutorials/flash/as3tweenclass/ or the popular tweenlite http://greensock.com/tweenlite)
我已经为 Flash CS4 中的一个问题苦苦挣扎了几天。我正在将一个旧游戏项目重组为 Main class,它处理 mainMenu、playGame 等功能。我从 "game" 添加了一艘船,它是由 Main 添加的。
问题是 "myShip" 按预期工作,只是它永远不可见。我检查了很多次,myShip 及其容器(游戏)可见属性始终为真。 Alpha 值也不是问题,层数和深度也不是问题。我从 "game" 添加的所有其他子项都工作正常,但 "myShip" 拒绝显示。
关于为什么会发生这种情况有什么想法吗?我不知道下一步该怎么做才能解决问题。任何帮助将不胜感激。 Main、Game 和 Ship class 的代码如下。
谢谢!
主要代码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;
}
}
游戏代码class: 包裹{
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();
}
}
}
发货代码:
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;
}
}
}
}
您可以尝试添加一个 ADDED_TO_STAGE 事件。看这个游戏编程大师的精彩讲解 Understanding ADDED_TO_STAGE Event
为了理解正在发生的事情,您必须了解一些基础知识。
在舞台上添加东西是一个很常见的错误。
这是 addChild 的文档所说的 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
我猜人们将 DispalyObjects 添加到舞台是因为他们认为它是 "the stage" 他们在 Flash 创作中看到并与之互动 环境。 但是不一样
stage.addChild()
不一样 将符号从库中拖到屏幕上。什么通过 默认代表主时间线是root
属性。 但是,如果你直接向stage
添加任何东西,它的root
属性和它的stage
属性都会引用同样 object, 通常只被stage
引用。stage
是一些 在闪存中 运行 时,您的 .swf 添加到的容器 玩家.addChildAt 的文档是这样描述索引的: 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.
应用这些基础知识,会发生以下情况:
- FlashPlayer 创建
stage
object,实例化您的主 class 并将该实例添加到stage
,它是索引为 0. 的 child
- 除其他外,
stage.addChildAt(mySprite, 1);
被执行, 添加mySprite
作为第二个 child 到stage
。索引为 1 是 呈现在索引 0 处的 object 前面,这恰好 成为您的主要 class 又名您的 .swf 文件的实例。 我希望 正在渲染的任何东西 "outside the .swf file" 说明得很好 够了为什么不推荐在舞台上添加东西。 - 稍后,
this.addChild(myShip);
发生了。 (这实际上是 正确的方法;此处无需使用this
:addChild(myShip);
就是你所需要的。)并将船舶添加到显示列表中。假设所有 它的 parents 也被添加到显示列表中,它将是 显示。 - 但是你还是看不到,因为你在前面加了
mySprite
您的 main class 的实例并用内容填充它drawGradient()
这掩盖了其他一切。
老实说,最好的解决办法是从头开始。 使用此代码对您没有任何帮助。即使自己努力完成它并以某种方式让它发挥作用也不会让你更好地理解任何事情(除了如何不做事)。似乎修改此代码以使用 classes 的唯一动机是为了这样做。将这样的旧代码强行纳入面向 object 的范例将不会很好地工作。 oop 的好处不会很明显,使这种体验更加令人沮丧。
最后但同样重要的是,不要推出自己的转换代码。有很多库可以做到这一点(包括flash自带的Tween class http://www.republicofcode.com/tutorials/flash/as3tweenclass/ or the popular tweenlite http://greensock.com/tweenlite)