views:

285

answers:

1

Ok, what im trying to do is make a day to night cycle behind my landscape. There is a sun and a moon, they rotate in a circle on opposite sides. (i.e. the sun is up when the moon is down and vice versa) when the sun is coming up it should fade from the night movieclip to the dawn movieclip, then when the sun is up a little bit more, fade into the day moviclip, this works quite well, but, for some reason, when it gets to the sunset, it just wont work :/ and the same goes for when it goes from the sunset to night :/ any and all healp is greatly appreciated, ive spent 5 hours trying to figure this out and cant! please help!

stage.addEventListener(Event.ENTER_FRAME, daynightcycle)

//setChildIndex(night, getChildIndex(day));

setChildIndex(sunset, 0);
setChildIndex(day, 1);
setChildIndex(dawn, 2);
setChildIndex(night, 3);

function daynightcycle(e:Event):void {

 if(sun.currentLabel == "dawn") {
  setChildIndex(sunset, 0);
  setChildIndex(day, 1);
  setChildIndex(dawn, 2);
  setChildIndex(night, 3);
  stage.addEventListener(Event.ENTER_FRAME, nightTdawn);

 }else if(sun.currentLabel == "sunset") {
  setChildIndex(dawn, 0);
  setChildIndex(night, 1);
  setChildIndex(sunset, 2);
  setChildIndex(day, 3);
  stage.addEventListener(Event.ENTER_FRAME, dayTsunset);

 }else if(sun.currentLabel == "night") {
  setChildIndex(day, 0);
  setChildIndex(dawn, 1);
  setChildIndex(night, 2);
  setChildIndex(sunset, 3);
  stage.addEventListener(Event.ENTER_FRAME, sunsetTnight);

 }else if(sun.currentLabel == "day") {
  setChildIndex(night, 0);
  setChildIndex(sunset, 1);
  setChildIndex(day, 2);
  setChildIndex(dawn, 3);
  stage.addEventListener(Event.ENTER_FRAME, dawnTday);

 }else if(sun.currentLabel == "switch") {
  stage.addEventListener(Event.ENTER_FRAME, switchLayers);
 }



}

function nightTdawn(e:Event):void {


 if(night.alpha != 0) {

  night.alpha -= 0.01;
 }else {
  stage.removeEventListener(Event.ENTER_FRAME, nightTdawn);
  night.alpha = 100;
  //setChildIndex(night, getChildIndex(sunset));
 }


}


function dayTsunset(e:Event):void {


 if(day.alpha != 0) {
  day.alpha -= 0.01;
 }else {
  stage.removeEventListener(Event.ENTER_FRAME, dayTsunset);
  day.alpha = 100;
  //setChildIndex(day, getChildIndex(dawn));
 } 

 //day.visible = false;
 //sunset.visible = true;

}
function sunsetTnight(e:Event):void {


 if(sunset.alpha != 0) {
  sunset.alpha -= 0.01;
 }else{
  stage.removeEventListener(Event.ENTER_FRAME, sunsetTnight);
  sunset.alpha = 100;
  //setChildIndex(sunset, (getChildIndex(day)));
 } 

 //sunset.visible = false;
 //night.visible = true;

}
function dawnTday(e:Event):void {

 sunset.visible = true;
 day.visible = true;

 if(dawn.alpha != 0) {
  dawn.alpha -= 0.01;
 }else{
  stage.removeEventListener(Event.ENTER_FRAME, dawnTday);
  dawn.alpha = 100;
  //setChildIndex(dawn, (getChildIndex(night)));
 } 
}

function switchLayers(e:Event):void {
 setChildIndex(dawn, 0);
 setChildIndex(night, 1);
 setChildIndex(sunset, 2);
 setChildIndex(day, 3);

 night.alpha = 100;
 sunset.alpha = 100;
 day.alpha = 100;
 dawn.alpha = 100;
 stage.removeEventListener(Event.ENTER_FRAME, switchLayers);

}
A: 

The problem likely stems from the fact that daynightcycle() is being called on every frame, and it in turn is adding a new EnterFrame listener every time.

In addition, it is quite expensive to be calling daynightcycle() on every single frame, when you really only need to call it when you change the state of the sun.

I've rewritten it for you in a cleaner style, so it should be pretty clear what is going on.

If you are not familiar with the Switch/Case syntax, then watch this explanation: As3 Switch Statement

var incomingLayer:DisplayObject

//initialize the order of the layers
setChildIndex(sunset, 0);
setChildIndex(day, 1);
setChildIndex(dawn, 2);
setChildIndex(night, 3);


//call this function anytime you change the label of the sun
function onSunLabelChanged():void
{
    switch (sun.currentLabel)
    {
        case "dawn":
            switchToLayer(dawn);
            break;
        case "sunset":
            switchToLayer(sunset);
            break;
        case "night":
            switchToLayer(night);
            break;
        case "day":
            switchToLayer(day);
            break;
    }
}


function switchToLayer(targ:DisplayObject):void
{
    incomingLayer = targ; //save a reference to the incoming layer
    incomingLayer.alpha = 0; //make it transparent
    setChildIndex(incomingLayer, 3); //put it on top
    stage.addEventListener(Event.ENTER_FRAME, onEnterFrame); //set a listener to fade it in
}


function onEnterFrame(e:Event):void
{
    incomingLayer.alpha += 0.01; //increment the alpha of the incoming layer
    if (incomingLayer.alpha >= 1) //if the layer is fully opaque
    {
        stage.removeEventListener(Event.ENTER_FRAME, onEnterFrame); //remove the listener
    }
}
Mark L
WOW! thanx mark! I was not familiar with the switch statements, but one question, how do i call the "onSunLabelChanged()" function when the label of the sun changes to get the whole thing working? :/
Jackson Smith
That depends, are you updating the sun by code? Or is it a MovieClip that just loops?
Mark L
Its a MovieClip that does loops, should i change that?
Jackson Smith
No that's fine, you should be able to just make an "actions" layer, put a keyframe at each of the points where the label changes, and in the actions for each of those keyframes put: onSunLabelChanged();The only potential problem is that onSunLabelChanged() may not be within the variable scope of your sun MovieClip, but that is not something I can help you with without seeing the whole app. Read up on it here:http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f9d.html#WS5b3ccc516d4fbf351e63e3d118a9b90204-7f8c
Mark L