A Flash Developer Resource Site

Results 1 to 17 of 17

Thread: [F8] [AS2/OOP] Loading individual levels and items

  1. #1
    bibuti. nolen's Avatar
    Join Date
    Sep 2002
    Location
    az.
    Posts
    191

    [F8] [AS2/OOP] Loading individual levels and items

    Alright.

    This is my first foray into Object-Oriented design with Flash and also one of the biggest games I've worked on, personally. Essentially, I am in the process of creating an adventure game along the likes of King's Quest, Sam and Max, Hugo's Whodunnit, etc, where the character wanders around and attempts to solve puzzles to complete the game.

    I have each room in the game loaded at runtime as a bitmap so that I may perform per-pixel calculations to detect collisions. Currently it is written so that any pure black lines are not able to be walked through, though any other color is fair game. This allows me to draw out the levels in Photoshop and merely import them into Flash, thus saving me numerous hours in the programming department.

    My "problem" is this: Organization and placement of code. At the moment, I have four files -
    1. the .fla
    2. Game.as, where I declared the Game class
    3. Level. as, where I declare the Level class
    4. Item.as, where I declare the Item class

    Most code resides in the Game class file, so that all I need to do in the .fla is create a new Game object and call the run() method. I am confused on what I should do for loading each level and all the items associated with it as the character moves from room to room. An array filled with the names of the levels would make sense, but where do I create each individual instance of the level object for each room? And on top of that, where do I assign the list of item objects AND their specific properties (x,y, description, etc) to each respective level?

    Example:

    I have an instance of a level named "hotel" which would have a few items like "key", "blanket", "window", and maybe "ear plugs". When I load the hotel level, I would want it to load the specific bitmap for the hotel, and then the items listed above, making sure to place them in the proper position, each with their unique properties. If the character were to walk out the door or off screen, a new level (room) would be loaded, along with whatever items may be in that level (room).

    Does any of that make sense?

    I'll post my three class files if that might help as well. Keep in mind that most of my code is in the Game class and the other two haven't had much added to them at this point. I guess I'm a "start big, work small" kind of guy?



    Code:
    import flash.display.BitmapData
    import mx.utils.Delegate
    
    class Game
    {
    	
    	public var walkSpeed:Number;
    	public var walking:Boolean;
    	private var xdir:Number;	  // holds the horizontal direction (-1 or 1)
    	private var ydir:Number;	 // holds the vertical direction (-1 or 1)
    	// variables to hold level information
    	private var levelBmp:BitmapData;
    	private var level_mc:MovieClip;
    	// keyListener object to let us interface with the keyboard
    	private var keyListener:Object = new Object();  
    	
    	// constructor
    	public function Game(walkSpeed:Number, walking:Boolean)
    	{
    		this.walkSpeed = walkSpeed;
    		this.walking = walking;
    		this.xdir = 0;
    		this.ydir = 0;
    		listenForKeys();
    		loadLevel();
    		loadHero();
    			
    	}
    	
    	private function initLevels():Void
    	{
    		// code to initialize new Level objects and the items that are attached to them
    	}
    	private function loadLevel():Void
    	{
    		levelBmp = BitmapData.loadBitmap("playground");
    
    		level_mc = _root.createEmptyMovieClip("level_mc", 1);
    
    		level_mc.attachBitmap(levelBmp, level_mc.getNextHighestDepth());
    	}	
    	
    	private function loadHero():Void
    	{
    		_root.attachMovie("dave", "dave", _root.getNextHighestDepth(), {_x: 250, _y:400});
    	}
    	
    	// listen for key presses
    	private function listenForKeys():Void
    	{
    
    		// tells us what to do when a key is pressed
    		keyListener.onKeyDown = Delegate.create(this, keyDownFunction);
    		
    		function keyDownFunction():Void
    		{ 
    			
    			if(Key.getCode() == Key.LEFT)
    			{
    				
    				if(xdir == -1)
    				{
    					xdir = 0;
    					walking = false;
    				}
    				else
    				{
    					_root.dave._xscale = -100;
    					ydir = 0;
    					xdir = -1;
    					walking = true;
    				}
    			}
    
    			if(Key.getCode() == Key.RIGHT)
    			{
    				if(xdir == 1)
    				{
    					xdir = 0;
    					walking = false;
    				}
    				else
    				{
    					_root.dave._xscale = 100;
    					ydir = 0;
    					xdir = 1;
    					walking = true;
    				}
    			}
    
    			if(Key.getCode() == Key.UP)
    			{
    				if(ydir == -1)
    				{
    					ydir = 0;
    					walking = false;
    				}
    
    				else
    				{
    					xdir = 0;
    					ydir = -1;
    					walking = true;
    				}	
    			}
    
    			if(Key.getCode() == Key.DOWN)
    			{
    
    				if(ydir == 1)
    				{
    					ydir = 0;
    					walking = false;
    				}
    				else
    				{
    					xdir = 0;
    					ydir = 1;
    					walking = true;
    				}
    			}
    		}	
    		Key.addListener(keyListener);
    	}
    	
    	// checks for collisions between dave and black pixels inside the level clip
    	private function checkForWalls():Void
    	{
    		
    		for(var i:Number = 1; i<=walkSpeed; i++)
    		{
    			if(levelBmp.getPixel(_root.dave._x, _root.dave._y+(i*ydir)) == 0x000000)
    			{
    				_root.dave._y+= (i-1)*ydir;
    				ydir = 0;
    				walking = false;
    				break;
    			}
    		}
    
    		for(var i:Number = 1; i<=walkSpeed; i++)
    		{
    			if(levelBmp.getPixel(_root.dave._x+(i*xdir), _root.dave._y) == 0x000000)
    			{
    				_root.dave._x+= (i-1)*xdir;
    				xdir = 0;
    				walking = false;
    				break;
    			}
    		}
    		
    	}
    	
    	
    	public function run():Void
    	{
    		checkForWalls();
    	
    		_root.dave._x += walkSpeed*xdir;
    		_root.dave._y += walkSpeed*ydir;
    		
    		if(walking==true)
    		{
    			_root.dave.gotoAndStop(2);
    		}
    		else
    		{
    			_root.dave.gotoAndStop(1);
    		}
    	}
    }

    Code:
    class Level
    {
    	// variables that hold the name of the rooms to the left and right of it
    	public var levelLeft:String;
    	public var levelRight:String;
    	// this level's name
    	public var levelName:String;
    	
    	public function Level()
    	{
    		// constructor
    	}
    	
    	
    	
    	public function loadItems()
    	{
    		_root.attachMovie("blob", "blob", 501, {_x: 270, _y:350});
    	}
    	
    	
    }
    Code:
    class Item extends MovieClip
    {	
    	// setup a variable to hold who the hero is currently
    	//static private var hero:MovieClip;
    	
    	public function Item()
    	{
    		//Constructor
    	}
    	
    	// check the distance between the object and a movieclip
    	private function checkForClipDistance():Void
    	{
    		var X:Number;
    		var Y:Number;
    		var distance:Number;
    		
    		X = _root.dave._x - this._x;
    		Y = _root.dave._y - this._y;
    		distance = Math.sqrt(Y*Y+X*X);
    		
    		if(distance<this._width/2)
    		{
    			trace("ITEM CLOSE");
    		}
    	}
    
    }
    i'm obsessed with video games.

  2. #2
    Senior Member tonypa's Avatar
    Join Date
    Jul 2001
    Location
    Estonia
    Posts
    8,223
    Have you thought about setting up xml files for each level? Having external xml files has the advantage of you being able to edit them later when needed without compling main swf again.

  3. #3
    bibuti. nolen's Avatar
    Join Date
    Sep 2002
    Location
    az.
    Posts
    191
    Quote Originally Posted by tonypa
    Have you thought about setting up xml files for each level? Having external xml files has the advantage of you being able to edit them later when needed without compling main swf again.
    I've considered it, but wouldn't that mean that I would have a small loading time between rooms? I want it all to run smoothly from room to room.
    i'm obsessed with video games.

  4. #4
    Feeling adventurous? T1ger's Avatar
    Join Date
    Mar 2004
    Posts
    850
    Quote Originally Posted by nolen
    I've considered it, but wouldn't that mean that I would have a small loading time between rooms? I want it all to run smoothly from room to room.
    Ehm, I didnt read every single character of your first post.. but didn't you ask how to load the rooms individually? (Actually you just have to read the title to get that)

    If you load the rooms induvidually whenever you enter it, youre bound to get a small loading-time..
    I don't have a photograph, but you can have my footprints. They're upstairs in my socks.

  5. #5
    bibuti. nolen's Avatar
    Join Date
    Sep 2002
    Location
    az.
    Posts
    191
    Quote Originally Posted by T1ger
    Ehm, I didnt read every single character of your first post.. but didn't you ask how to load the rooms individually? (Actually you just have to read the title to get that)

    If you load the rooms induvidually whenever you enter it, youre bound to get a small loading-time..
    Yeah perhaps my wording is incorrect. Maybe when I say 'loading' I mean declaring? I am just curious how other people would go about creating a game like the one I am trying to achieve. How would you setup your world with different 'rooms', each with their own items?

    Does that help?
    i'm obsessed with video games.

  6. #6
    Senior Member
    Join Date
    Jan 2006
    Location
    USA
    Posts
    383
    It seems as if you're just trying to accomplish how to represent a room with different items?

    If that's correct, then you can just create a room class with an array of items.

    You can use XML to set up your room objects and items for each room.

    Call or load the corresponding room object depending on where the player moved.

  7. #7
    Pumpkin Carving 2008 ImprisonedPride's Avatar
    Join Date
    Apr 2006
    Location
    Grand Rapids MI
    Posts
    2,377
    As far as loading the rooms goes, the initial pause should only be during the first room loading. Then, once the player starts going keep loading the levels (if they are static levels hardcoded in the fla, even better) using frame loading .
    The 'Boose':
    ASUS Sabertooth P67 TUF
    Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
    8GB G.Skill Ripjaws 1600 DDR3
    ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
    New addition: OCZ Vertex 240GB SATA III SSD
    WEI Score: 7.6

  8. #8
    bibuti. nolen's Avatar
    Join Date
    Sep 2002
    Location
    az.
    Posts
    191
    Alright so it's possible to use a separate xml file for each level and not have loading times for each one?


    Here is something I put together really quick. Would this be sufficient?

    Code:
    <levels>
    	
    	
    	
    	<level name="sidewalk">
    	
    		<items>
    		
    			<item x="50" y="200" name="blob" description="looks like some sort of blob i guess..."/>
    		
    		</items>
    	
    	</level>
    	
    	
    	
    	
    	<level name="hotel">
    		
    		<items>
    			
    			<item x="75" y="26" name="window" description="you can see a fire escape next to the balcony"/>
    		
    		</items>
    		
    	</level>
    	
    </levels>
    i'm obsessed with video games.

  9. #9
    Senior Member tonypa's Avatar
    Join Date
    Jul 2001
    Location
    Estonia
    Posts
    8,223
    You could also include the xml object into swf if you worry about the loading time. Or preload all the level xml files at the start.

    Then again, I have used completely different way in several games. You could use frames in movie clip to draw each level in the Flash itself. When each fame represents different level, to change level you simply show another frame. You drag all the items where they have to go in the Flash so its all visible when creating the game. Once the level loads you need some script to register position and type of every item by looping through the childs.

  10. #10
    bibuti. nolen's Avatar
    Join Date
    Sep 2002
    Location
    az.
    Posts
    191
    Quote Originally Posted by tonypa
    You could also include the xml object into swf if you worry about the loading time. Or preload all the level xml files at the start.

    Then again, I have used completely different way in several games. You could use frames in movie clip to draw each level in the Flash itself. When each fame represents different level, to change level you simply show another frame. You drag all the items where they have to go in the Flash so its all visible when creating the game. Once the level loads you need some script to register position and type of every item by looping through the childs.

    Yeah it looks like XML is going to be my best bet if I want to keep this organized. I'm going to whip out ye olde Flash 8 ActionScript book and read up on the XML object.

    If anyone else has any suggestions though, I'm all ears.
    i'm obsessed with video games.

  11. #11
    bibuti. nolen's Avatar
    Join Date
    Sep 2002
    Location
    az.
    Posts
    191
    So far, XML has been perfect for this situation. Thanks for the suggestions everyone.


    I do have a question though: XML is fine for a web game, but what if I wanted to package this game (or future games) and distribute it as a PC/Mac application? I don't want the XML to be accessible by the end user, since they could just edit those files to do whatever they please.
    i'm obsessed with video games.

  12. #12
    Senior Member webgeek's Avatar
    Join Date
    Sep 2000
    Posts
    1,352
    I do have a question though: XML is fine for a web game, but what if I wanted to package this game (or future games) and distribute it as a PC/Mac application? I don't want the XML to be accessible by the end user, since they could just edit those files to do whatever they please.
    I personally don't see an issue if the user edits your XML. It's up to you if you are concerned about it.

    One easy option is to create a hash of the XML data as a string and then hard code that hash in the SWF (a hash is quite small). When you load the XML, you hash it again and compare the hard-coded SWF hash with the newly generated hash. If they don't match, you know the user tampered with the XML. This sounds harder then it is. Probably less then 20 lines of code at the most. It also works even if the game is being run locally or from the web as it's deployment agnostic. I can provide more details if you are interested.

    Also, many of the SWF to EXE wrappers provide the ability to embed data into the EXE itself and then provide an API to load that data back. I've not used it myself but I'm pretty sure Zinc does that. It's similiar to embeding resource files (like icons) into an EXE when you build it from Visual Studio - if you've done that in school or some such you will know what I mean. Have fun!

  13. #13
    Pumpkin Carving 2008 ImprisonedPride's Avatar
    Join Date
    Apr 2006
    Location
    Grand Rapids MI
    Posts
    2,377
    [offtopic]
    Web are you from the 70's? Lately I've noticed you're a bit too obsessed with hash.
    [/offtopic]
    The 'Boose':
    ASUS Sabertooth P67 TUF
    Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
    8GB G.Skill Ripjaws 1600 DDR3
    ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
    New addition: OCZ Vertex 240GB SATA III SSD
    WEI Score: 7.6

  14. #14
    Senior Member webgeek's Avatar
    Join Date
    Sep 2000
    Posts
    1,352
    All joking aside, it's always been a good technique and effective tool. In AS1 and 2, it was slow and a hassle to implement so it didn't get much use. In AS3 multiple libraries exist to create a hash of any data you want and it's too useful to pass up. When it comes to ensuring data integrity, it's one of the best ways around.

  15. #15
    Who needs pants? hooligan2001's Avatar
    Join Date
    Apr 2001
    Location
    Somewhere
    Posts
    1,976
    One easy option is to create a hash of the XML data as a string and then hard code that hash in the SWF (a hash is quite small). When you load the XML, you hash it again and compare the hard-coded SWF hash with the newly generated hash. If they don't match, you know the user tampered with the XML. This sounds harder then it is. Probably less then 20 lines of code at the most. It also works even if the game is being run locally or from the web as it's deployment agnostic. I can provide more details if you are interested.
    Does that mean you would have to edit each levels hash every time you edit a level. I guess you could add the hash at release time. Do you have an example of the hash being used in this such case?

  16. #16
    Senior Member webgeek's Avatar
    Join Date
    Sep 2000
    Posts
    1,352
    Does that mean you would have to edit each levels hash every time you edit a level.
    Yes, which is why I often add a "development" or "debug" flag into the game that turns that type of code off until I get close to release. When I implement things like this, I also make a utility that helps reduce overhead. In this case, the level editor could simply provide a hash at the same time it creates the XML.

    Do you have an example of the hash being used in this such case?
    In which case specifically? As a way to ensure data integrity? Yup. I blog about it in detail here:
    http://mikegrundvig.blogspot.com/200...en-client.html
    It's a slightly different case (ensuring valid data between client and server) but it's an identical approach. Basically using a hash to create a fingerprint of the data and then comparing the fingerprint later on to confirm that nothing changed. Works great.

    The same approach is often used in enterprise systems that transfer files around. They will send the file, then they will send a hash so the recipient can check the hash to ensure transmission succeeded.

    Also, the same technique is used by more tech-savy developers all the time. That's why many sites have a MD5 link next to the download. For instance:
    http://httpd.apache.org/download.cgi

    Have fun!

  17. #17
    Who needs pants? hooligan2001's Avatar
    Join Date
    Apr 2001
    Location
    Somewhere
    Posts
    1,976
    Wow great read webgeek. Thanks for the heads up on the technique.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center