|
-
change variable value dynamically
var game:Object = new Object;
game.Tile0.frame = 1;
game.Tile1.frame = 2;
animation.gotoAndStop(game.Tile+i+.frame);
need a way to change from tile0 to tile1 through variable
Real Example::
Code:
var myMap:Array = [
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1]
];
var game:Object = new Object;
game = {tileW:30, tileH:30};
game.Tile0 = function () { };
game.Tile0.walkable = true;
game.Tile0.frame = 1;
game.Tile1 = function () { };
game.Tile1.walkable = false;
game.Tile1.frame = 2;
function buildMap(map) {
var mainMC:empty = new empty();
stage.addChild(mainMC);
var mapWidth = map[0].length;
var mapHeight = map.length;
for (var i = 0; i<mapHeight; ++i) {
for (var j = 0; j<mapWidth; ++j) {
var D_tile:tile = new tile();
D_tile.x = (j*game.tileW);
D_tile.y = (i*game.tileH);
D_tile.gotoAndStop(game.Tile+map[i][j]+.frame);
mainMC.addChild(D_tile);
}
}
}
buildMap(myMap);
Last edited by onenonly; 04-13-2011 at 11:22 PM.
-

Your total flouting of common style conventions is rather annoying.
Classes should start with a capital letter. Nothing else should. When you call a constructor, use the () even if you are passing no arguments. Give every single variable and function a type. Do not add your children directly to the stage. Add them to some container, even if that is the main timeline.
Now, some things that don't make sense:
Code:
var game:Object = new Object;
game = {tileW:30, tileH:30};
This declares and creates a new game variable of type Object, then throws away that just created Object and replaces it with another one. Why bother creating the first one?
Code:
var game:Object = {tileW:30, tileH:30};
You have two properties named Tile<index>, but they are not related in any way except name. You'd be much happier with them in an Array. There is absolutely no reason for these Tile objects to be functions. I have literally no idea why you did that.
Code:
game.tiles = [];
game.tiles.push({walkable:true, frame:1});
game.tiles.push({walkable:false, frame:2});
Code:
D_tile.gotoAndStop(game.tiles[map[i][j]].frame);
Of course, by using plain objects you are forgoing any compile time type checking and property existence checks, as well as editor autocompletion, and you have to manage all the relationships between your vague objects yourself. You should make classes to encapsulate functionality and provide strong types. You could definitely benefit from having a Tile class and a GameBoard class. It looks like you do have a tile class, but it is only providing graphic assets. Why shouldn't it also keep track of whether it's walkable and whatever else you are doing with tiles.
Make a Tile class that contains common functionality to your tiles. It would have a boolean walkable property. Then make subclasses like GrassTile, WaterTile, WallTile, etc with the associated graphics and walkable values. Then you can just associate your map tile values to the classes.
Code:
var myMap:Array = [
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1]
];
var game:GameBoard = new GameBoard(30,30);
game.setTileTypeIndex(0, GrassTile);
game.setTileTypeIndex(1, WaterTile);
game.buildMap(myMap);
addChild(game);
In GameBoard:
Code:
public class GameBoard extends Sprite{
public var tileW:int;
public var tileH:int;
private var tiles:Vector.<Vector.<Tile>>;
private var tileDefinitionMappings:Array;
public function GameBoard(tw:int, th:int){
this.tileW = tw;
this.tileH = th;
this.tiles = new Vector.<Vector.<Tile>>();
this.tileDefinitionMappings = [];
}
public function setTileTypeIndex(index:int, tileClass:Class):void{
tileDefinitionMappings[index] = tileClass;
}
public function buildMap(map:Array):void {
var mapWidth:int = map[0].length;
var mapHeight:int = map.length;
var tileRow:Vector.<Tile>;
for (var i = 0; i<mapHeight; ++i) {
tileRow = new Vector.<Tile>();
tiles.push(tileRow);
for (var j = 0; j<mapWidth; ++j) {
var tile:Tile = Tile(new tileDefinitionMappings[map[i][j]]());
tile.x = tileW * j;
tile.y = tileH * i;
tileRow.push(tile);
addChild(tile);
}
}
}
public function getTile(col:int, row:int):Tile{
if (row < tiles.length){
var tileRow:Vector.<Tile> = tiles[row];
if (col < tileRow.length){
return tileRow[col];
}
}
return null; //or throw error.
}
}
Last edited by 5TonsOfFlax; 04-14-2011 at 10:13 AM.
-
I really do appreciate your help 
even if its harsh criticism lol
I don't understand Action Script too much (I self taught myself) I was reading a tutorial for games build in tile but it was in as1/as2 and I was trying to convert it to as3.
BTW your script looks very very confusing can you please comment it for me because I'm still new to Action Script and the whole OOP concept.
Last edited by onenonly; 04-14-2011 at 06:44 PM.
-
I hope I wasn't too harsh.
First, a disclaimer. I just wrote the code above without attempting to compile or use it. There are probably typos and minor mistakes, but they'll be the kind the compiler will help you fix.
So, commented versions.
Actionscript Code:
var myMap:Array = [ [1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 1], [1, 0, 1, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 1, 0, 1], [1, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1] ];
/*game will be an instance of GameBoard. This differs from your original code because GameBoard is also a display object and will manage the tiles it displays as well. */ var game:GameBoard = new GameBoard(30,30);
//Call a method in your GameBoard instance to associate numbers with Tile classes game.setTileTypeIndex(0, GrassTile); game.setTileTypeIndex(1, WaterTile);
/*call a method in your GameBoard instance to build the map and display based on your myMap array */ game.buildMap(myMap);
/*put your GameBoard on the displayList as a child of the calling instance (which is probably the main timeline) */ addChild(game);
Actionscript Code:
package{ //you will have to add imports here, such as: import flash.display.Sprite;
/** GameBoard is a class that models a grid of Tiles, and holds them as display children */
/*extends Sprite because we need a DisplayObjectContainer, but we do not need a timeline */ public class GameBoard extends Sprite{ /*in the top section of the class, we declare (but do not instantiate) the class level variables. */
//public variables for tile width and height. //these could just as easily be private public var tileW:int; public var tileH:int;
/*private variable to hold our 2d collection of Tiles tiles is a Vector of Vectors, each of which holds Tiles This is very similar to a 2d array, but with typechecking Vectors are a flash 10 feature. If you must publish for versions below 10, you will have to change this to a 2d Array */ private var tiles:Vector.<Vector.<Tile>>;
/*This will hold the associations between numbers and Tile Classes. ideally, it would be something like a Map<int, Class>, but that sort of parameterized type is not available in actionscript. so I used an Array, which already maps ints to arbitrary Objects. */ private var tileDefinitionMappings:Array;
/*The GameBoard constructor. This is called when you call new GameBoard(somewidth, someheight); */ public function GameBoard(tw:int, th:int){ /*by using "this." we explicitly call out the fact that we are setting instance properties. In this case, it's not necessary because we named our parameters to not conflict. But it's a good habit to get into in the constructor */ //set tile width and height from parameters this.tileW = tw; this.tileH = th; /*instantiate our tiles 2d vector and mapping array if we didn't do this, they would remain null. */ this.tiles = new Vector.<Vector.<Tile>>(); this.tileDefinitionMappings = []; }
/*this is a public function, meaning that any other class can call it, as you see in the timeline code. tileClass is a parameter of type Class, so we are not storing actual Tiles in tileDefinitionMappings, but rather the Classes necessary to create them. */ public function setTileTypeIndex(index:int, tileClass:Class):void{ tileDefinitionMappings[index] = tileClass; }
//build our map based on a 2d array public function buildMap(map:Array):void { var mapWidth:int = map[0].length; var mapHeight:int = map.length; //it's convenient to have a variable to hold an entire row of Tiles. var tileRow:Vector.<Tile>; for (var i = 0; i<mapHeight; ++i) { /*since our 2d tiles vector exists, but starts out empty, before we can add a Tile, we must add the row the Tile goes in. */ tileRow = new Vector.<Tile>(); tiles.push(tileRow); for (var j = 0; j<mapWidth; ++j) { //I expanded the tile creation line into three parts //get the int for the tile type from the map var tileTypeIndex:int = map[i][j]; //get the tile class associated with that int from the definition mappings array var tileClass:Class = tileDefinitionMappings[tileTypeIndex]; //create a new Tile from that class /*I cast it to Tile here, because I'm not sure if the compiler will complain otherwise. I'd have to try it. */ var tile:Tile = Tile(new tileClass()); //position your new tile. tile.x = tileW * j; tile.y = tileH * i; //add the tile to the row tileRow.push(tile); //add the tile to the display addChild(tile); } } }
//this method retrieves a Tile from the grid by column and row. public function getTile(col:int, row:int):Tile{ //check whether the row exists if (row < tiles.length){ //get the row var tileRow:Vector.<Tile> = tiles[row]; //check whether the column exists in that row if (col < tileRow.length){ //return the Tile at that index. return tileRow[col]; } } //if we get here, either the row or column didn't exist. return null; //or throw error. } }
}
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|