Best way to make screens in Flash.

Discussion in 'Game Development (Technical)' started by ErikH2000, Feb 18, 2006.

  1. ErikH2000

    Original Member

    Joined:
    Aug 3, 2004
    Messages:
    681
    Likes Received:
    1
    I made a game in Flash/ActionScript for a contract job recently and had to learn a bunch of stuff in a hurry. I find that there's usually 5 different ways to do any particular programming task, and I usually can't tell which way is best until after I've coded and tried them all. You might agree with me that trial-and-error isn't the most efficient way to figure things out.

    So I have an app with multiple screens, i.e. title screen, instructions screen, game screen. Movie execution tends to stop on one frame (main timeline) and then let ActionScript handle animating everything in that one frame (as opposed to using multiple frames to show what happens on a screen).

    One way to split up the screens is to put one screen on one frame of the main timeline. If I want to go to another screen, then I execute gotoAndStop("ScreenFrameName"). That's fine, but all the state information stored in movieclips, buttons, and text boxes is lost when I leave the frame. I particularly like to add extra properties to movieclips, and that information gets lost too. So with this approach I have to write "save" code for leaving the screen's frame and "restore" code for returning to the screen's frame. That's not a terrible thing, but I'd like to avoid it.

    My second approach is to put all the screens on the same frame of the main timeline. Each screen is contained in one screen-sized movieclip. Instead of changing frames to go to a new screen, I instead make the movieclip for the destination screen visible, while making all the other screen movieclips invisible. In this way, the state of each screen is never lost.

    I know this second approach works, because I completed my first project with it. My next contract project has more screens than the first, and the screens contain more UI elements. I wonder if I should expect the performance of the Flash app to suffer a lot from using the second approach of having all screens loaded into movieclips on one frame. I don't want to find out near the end of my project that I've introduced a lot of slowness that needs to be fixed.

    -Erik
     
  2. kreso

    Original Member

    Joined:
    May 13, 2005
    Messages:
    54
    Likes Received:
    0
    Well, if your invisible screens do not have any functions running or animated frames, flash will ignore them and you should be fine.

    Biggest drawback of flash is it's rendering engine (because it's resource consumption) - so know that flash redraws the screen if you change visual appearance of your movieclip in any way - whether this movieclip is visible or invisible!
     
  3. ErikH2000

    Original Member

    Joined:
    Aug 3, 2004
    Messages:
    681
    Likes Received:
    1
    Thanks for the info, Kreso. I think I will put all my screens in movieclips on one frame, taking care, as you advise, not to leave anything active in a screen when it is invisible. I'd try it that way to begin with. And if I have to, I imagine, I can move those movieclips to separate frames, and write the dumb save/restore code. It seems like I won't have to though.

    -Erik
     
  4. StGabriel

    Original Member

    Joined:
    Jan 27, 2006
    Messages:
    26
    Likes Received:
    0
    I use multiple frames and gotoAndStop(). And I store all of my data in a central "Game" class. I recommend using classes to organize your code and centralizing state as much as possible into one class. Do all of your updates, rendering, etc., from that main class, using other classes that contain your movieclips (or extend movieclip). I highly recommend reading "Essential Actionscript 2.0" by Colin Moock it helped me a lot to transition to programming in Flash in a way that made sense to me.
     
  5. ErikH2000

    Original Member

    Joined:
    Aug 3, 2004
    Messages:
    681
    Likes Received:
    1
    Okay, I understand that I can put a lot of my data in a persistent instance of a class. And actually, I will do that--it's a much better way to organize data than dropping all the vars into global vars.

    But for solving my problem that only goes so far. For example, a player can leave my game screen midway, pausing the game, and go to main menu and option screens, and then come back to the game screen. If I put the game screen on a separate frame, then I will need to store all of the positions, enabled/disabled status, current frame and so on of all movieclips and other objects on the game screen when the player leaves that screen. And then when the player returns, it must all be restored. This is not a technically difficult task. I'm sure it will all fit neatly into data structures of a class, BUT... it is tedious work and introduces more opportunities for me to make errors. If you think there is some way to make this restore/save very simple or automatic, then I will gladly learn from you.

    There is also a downside that if many objects must be restored, the time to restore it can introduce a delay. I have seen this delay in the first version of the game which I'm making a sequel for. The programmer used the save/restore method with screens in multiple frames to recreate state when player returns to game screen frame.

    -Erik
     
  6. StGabriel

    Original Member

    Joined:
    Jan 27, 2006
    Messages:
    26
    Likes Received:
    0
    If all of your MovieClips are stored in your Game class then removing or adding them to a screen is simply a matter of iterating over the MovieClips with a for loop (or whatever makes sense with how you store your MovieClips). It's really no different than rendering a screen as you would in any other environment (with a classical C program you would store items as sprites and upon returning to your game you would have to redraw all of the sprites as they were arrayed across the board). If there is certain state data in those MovieClips then you will want to create a class which contains those MovieClips and additional state. Then you can iterate over objects of that class.

    As an example, for a game ideas I was recently prototyping I made a Tile class. Tiles can be placed on the board and dragged with the mouse and there are many possible tile faces. Each tile object stores an x/y location, the current tile face and other data. An instance of my Game class contains a matrix of tiles that have been placed on the board and a pointer to any tile which is being dragged. Redrawing all tiles that have been placed on the board is simply a matter of iterating over all the tiles stored in the matrix.
     
  7. StGabriel

    Original Member

    Joined:
    Jan 27, 2006
    Messages:
    26
    Likes Received:
    0
    That's not the only way to do it, of course. If you want to just draw a "Game Over" screen on top of your game then that will be fine although in the end I think you'll end up slowing down more just because you have invisible MovieClips still being rendered. This is just the way that makes the most sense to me, it is the most similar to how I program games in Java and C, and seems efficient enough for my purposes.
     
  8. iopred

    Indie Author

    Joined:
    Apr 2, 2005
    Messages:
    42
    Likes Received:
    0
    If you use the _visible = false; property, the movieclip does not get drawn at all, you wont lose performance if you do this. That said holding all the screens in the one frame will keep them all in memory.

    You can get away by having the 'world' objects in seperate frames, and on another layer, have the player MC only on a single keyframe, this way you can change the frame to change the scenery, but the player MC will keep all his variables/states.
     
  9. kreso

    Original Member

    Joined:
    May 13, 2005
    Messages:
    54
    Likes Received:
    0
    You can easely test this if you have flash 8 installed. Create an animated movieclip and use onClipEvent(load){this._visible = false:} on it.
    If you test the scene you can't see that movie because it's invisible but if you right-click and turn on 'Show redraw regions' you will se that the screen is beeing redrawn anyway ;)

    I would suggest taking advantage of flash's ease of use in your matter. With this I mean, if you don't need extra stuff, don't bother with it (classes etc..), or your development time will take longer than it really has to, just my 2c.

    Also, maybe it would be usefull to put all these screens into one movieclip and then attach this movie to the timeline with code (attachMovie) instead of just placing it on the timeline. Attached movies stay on the timeline if you change frames (or scenes) so that way you can go anyway you like in your swf and always bring back the screens via screens_mc._visible = true
     
  10. yanuart

    Original Member

    Joined:
    Sep 16, 2004
    Messages:
    539
    Likes Received:
    0
    AFAIK, making a movieclip visible doesn't make flash player stop rendering the movie. This is something I read in Macromedia forum a long time ago but I never got the chance to prove it.

    Having multiple screens is what I do most of the time. Mostly because it'll be easier to manage/edit. I won't say that having mulitple movieclips is bad, as it does save the movieclip states and it's very useful sometimes.
    All I'm trying to say is.. there's no easy fix, you need to juggle between those two options according to what you need.
     
  11. iopred

    Indie Author

    Joined:
    Apr 2, 2005
    Messages:
    42
    Likes Received:
    0
    If the movieclip is not animated, you can change the _x/_y values as much as you like, the clip will not be drawn (or shown in redraw) if _visible is false, which is as said, a speed reduction (especially compared to _alpha = 0)
     
  12. StGabriel

    Original Member

    Joined:
    Jan 27, 2006
    Messages:
    26
    Likes Received:
    0
    This is a point of style of course but I strongly suggest exactly the opposite. I started learning Flash a month or so ago for my experimental game design blog and since then I've made several game prototypes with it. Even though I am not, by nature, an object-oriented programmer, I am finding that the more comfortable I become with using the type-system and using classes, the shorter my development time is. I created a playable game prototype in just 3 hours last night (after having spent about a few hours a few nights ago to create the graphics). My first prototype, programmed without "the extra stuff", took me over 20 hours to code and a LOT of debugging. I haven't learned much Flash in between the two except for learning how to effectively type everything and use classes.

    The thing is, you can write a good shell of a Game class once and then you can use that for every Flash game you create after that. This is exactly the process you would take for normal game developent and IMO, this is for very good reason. The sloppier you are, the less reusable and debuggable your code will be. The latter is a particularly problematic with Flash where, because of the dynamic typing, one misspelled variable name can silently doom your entire game.

    As far as efficiency, using a central Game class to do all of your rendering and input handling will also reduce your entry points to actionscript which seems to be a lot more efficient.

    I recommend reading this essay. The more I program with Flash the more I find it to be spot on.
     
  13. ErikH2000

    Original Member

    Joined:
    Aug 3, 2004
    Messages:
    681
    Likes Received:
    1
    I did some testing. If a movieclip is set to invisible the region over it won't be redrawn. Unless it's animating, then the region over the movieclip will be redrawn. It doesn't matter if you hide the container of an animating movieclip or hide the animated movieclip itself. Either way, the region over the animated movieclip will be redrawn. As long as I'm careful to stop animations before hiding a screen, I think it should be fine. It seems pretty easy to leave something going on a hidden screen, so I'll have to look at the redraw regions in the player every now and then to make sure I got everything.

    My results are redundant with an explanation given above, but since it sounded like a few different claims were being made, I wanted to test for myself to make sure it worked one way.

    -Erik
     
  14. ErikH2000

    Original Member

    Joined:
    Aug 3, 2004
    Messages:
    681
    Likes Received:
    1
    Post-Mortem

    I ended up putting all my screens (7 of them) on one frame. Each screen was kept in it's own movieclip and I hid screen movieclips for inactive screens. It worked great with no evidence of slowdown. Screens change without any delay and data doesn't need to be restored. Particularly useful, is that the positions of symbols and any information stored in extra members of the symbols are kept without going through save and restore code. Since my screens create many movieclips at runtime and store paths for them to travel in a member of the movieclip, it would have taken a noticable delay to save and restore them. In fact, in an earlier version of the game we used save-and-restore code that created an ugly 10-second delay to return to a game screen.

    For best performance, it is definitely necessary to stop any animation in a screen when it is hidden. The redraw regions will pick up on animations even if they are hidden, and no doubt their is some CPU time lost calculating bounding rects and other animation-related info for the hidden but still-active animations. I wrote code for each screen to stop animations and it wasn't too much trouble. If this code ever became too unruly, I think I'd keep an array of movieclip references for each screen and some general-purpose function to pause/resume animations.

    Off the subject, this was also my first project using classes in ActionScript instead of just functions. Simply having the compiler report problems with undefined functions and variables was worth the switch, but then there's the other OO advantages as well. I'll be sticking with classes from now on, I think.

    Much thanks to everyone who posted their ideas! The advice about redraw regions for hidden animation from Yanuart was especially valuable.

    -Erik
     

Share This Page

  • About Indie Gamer

    When the original Dexterity Forums closed in 2004, Indie Gamer was born and a diverse community has grown out of a passion for creating great games. Here you will find over 10 years of in-depth discussion on game design, the business of game development, and marketing/sales. Indie Gamer also provides a friendly place to meet up with other Developers, Artists, Composers and Writers.
  • Buy us a beer!

    Indie Gamer is delicately held together by a single poor bastard who thankfully gets help from various community volunteers. If you frequent this site or have found value in something you've learned here, help keep the site running by donating a few dollars (for beer of course)!

    Sure, I'll Buy You a Beer