PDA

View Full Version : [AS3] Tile-based game abstraction


hdshngout
04-14-2009, 02:28 PM
Hello again. Now that I have the recursive functioning figured out, I am looking to cut down extra coding I have in my game. I know this is going to sound stupid (and I tried looking, but I wasn't exactly sure what to search for..), but is there a way to cut this down:

private function placeTiles(layout):void {

var whichLevel:int = layout[1];
layout = layout[0];

for(var i:int=0; i<=rows - 1; i++) {

for(var j:int=0; j<=cols - 1; j++) {

if(layout[i][j] == 2) {
var tc1:Wall = new Wall();
tc1.width = tile_w;
tc1.height = tile_h;
tc1.x = j * tile_w;
tc1.y = i * tile_h;
board.addChild(tc1);
tc1.gotoAndStop(whichLevel);
obs.push(tc1);
obs2.push(new Array(tc1, tc1.x, tc1.y));
} else if(layout[i][j] == 3) {
var tc2:Breakable = new Breakable();
tc2.width = tile_w;
tc2.height = tile_h;
tc2.x = j * tile_w;
tc2.y = i * tile_h;
board.addChild(tc2);
tc2.gotoAndStop(whichLevel);
obs.push(tc2);
obs2.push(new Array(tc2, tc2.x, tc2.y));
} else if(layout[i][j] == 8) {
var tc3:Treasure = new Treasure();
tc3.width = tile_w;
tc3.height = tile_h;
tc3.x = j * tile_w;
tc3.y = i * tile_h;
board.addChild(tc3);
obs.push(tc3);
obs2.push(new Array(tc3, tc3.x, tc3.y));
} else if(layout[i][j] == 11) {
var tc4:Treasure_Key = new Treasure_Key();
tc4.width = tile_w;
tc4.height = tile_h;
tc4.x = j * tile_w;
tc4.y = i * tile_h;
obs.push(tc4);
board.addChild(tc4);
obs2.push(new Array(tc4, tc4.x, tc4.y));
} else if(layout[i][j] == 7) {
var tc5:Door = new Door();
tc5.width = tile_w;
tc5.height = tile_h;
tc5.x = j * tile_w;
tc5.y = i * tile_h;
board.addChild(tc5);
tc5.gotoAndStop(whichLevel);
obs.push(tc5);
obs2.push(new Array(tc5, tc5.x, tc5.y));
} else if(layout[i][j] == 12) {
var tc6:Door_Key = new Door_Key();
tc6.width = tile_w;
tc6.height = tile_h;
tc6.x = j * tile_w;
tc6.y = i * tile_h;
board.addChild(tc6);
obs.push(tc6);
obs2.push(new Array(tc6, tc6.x, tc6.y));
} else if(layout[i][j] == 15) {
var tc7:Gate_Open = new Gate_Open();
tc7.width = tile_w;
tc7.height = tile_h;
tc7.x = j * tile_w;
tc7.y = i * tile_h;
board.addChild(tc7);
obs.push(tc7);
obs2.push(new Array(tc7, tc7.x, tc7.y));
} else if(layout[i][j] == 16) {
var tc8:Gate_Closed = new Gate_Closed();
tc8.width = tile_w;
tc8.height = tile_h;
tc8.x = j * tile_w;
tc8.y = i * tile_h;
board.addChild(tc8);
obs.push(tc8);
obs2.push(new Array(tc8, tc8.x, tc8.y));
} else if(layout[i][j] == 18) {
var tc9:H_Spikes = new H_Spikes();
tc9.width = Math.round(tile_w);

tc9.x = j * tile_w;
tc9.y = i * tile_h;
tc9.tripped = 0;
tc9.gotoAndStop(1);
board.addChild(tc9);



obs.push(tc9);
obs2.push(new Array(tc9, tc9.x, tc9.y));
} else if(layout[i][j] == 17) {
var tc10:V_Spikes = new V_Spikes();
tc10.scaleX = .8;
tc10.scaleY = .8;
tc10.x = j * tile_w;
tc10.y = i * tile_h;
tc10.tripped = 0;
board.addChild(tc10);
tc10.gotoAndStop(1);
obs.push(tc10);
obs2.push(new Array(tc10, tc10.x, tc10.y));
} else if(layout[i][j] == 4) {
var tc11:Boulder = new Boulder();
tc11.width = tile_w;
tc11.height = tile_h;
tc11.x = j * tile_w;
tc11.y = i * tile_h;
board.addChild(tc11);
tc11.gotoAndStop(whichLevel);
obs.push(tc11);
obs2.push(new Array(tc11, tc11.x, tc11.y));
} else if(layout[i][j] == 5) {
var tc12:Balloon = new Balloon();
tc12.width = tile_w;
tc12.height = tile_h;
tc12.x = j * tile_w;
tc12.y = i * tile_h;
board.addChild(tc12);
obs.push(tc12);
tc12.gotoAndStop(whichLevel);
obs2.push(new Array(tc12, tc12.x, tc12.y));
} else if(layout[i][j] == 9) {
var tc13:R_Dynamite = new R_Dynamite();
tc13.width = tile_w;
tc13.height = tile_h;
tc13.x = j * tile_w;
tc13.y = i * tile_h;
tc13.lit = 0;
board.addChild(tc13);
obs.push(tc13);
obs2.push(new Array(tc13, tc13.x, tc13.y));
} else if(layout[i][j] == 10) {
var tc14:G_Dynamite = new G_Dynamite();
tc14.width = tile_w;
tc14.height = tile_h;
tc14.x = j * tile_w;
tc14.y = i * tile_h;
board.addChild(tc14);
obs.push(tc14);
obs2.push(new Array(tc14, tc14.x, tc14.y));

That code repeats 18 times for each tile type. Normally, I would take the "one-movie-clip with each tile as a frame" approach, but because each tile tile has multiple colors for different levels, I cannot take that approach.

Basically, I am curious as to whether I can cut down the repetitive nature of

tc__.width = tile_w;
tc__.height = tile_h;
tc__.x = j * tile_w;
tc__.y = i * tile_h;
tc__.lit = 0;
board.addChild(tc__);
obs.push(tc__);
obs2.push(new Array(tc__, tc__.x, tc__.y));


which appears in every iteration of the loop. If someone could point me in the right direction, or even just tell me what the idea is (abstraction, possibly?), I would appreciate it.

Thanks!
-Nick

apiccion
04-16-2009, 01:02 AM
1. Use a switch statement instead of a chain of elseif statements.
2. All your classes inherit from DisplayObject. One feature of Object Oriented Programming is called polymorphism. Basically, it's when you can do this:
var a:DisplayObject = new Dynamite();

This works because Dynamite inherits from DisplayObject.

You can access all properties of Dynamite which inherit from DisplayObject AND ONLY those properties which inherit from DisplayObject.

For example,
a.x = 50; // THIS WORKS
a.lit = 0; // THIS WILL NOT WORK

private function placeTiles(layout):void {
var dp:DisplayObject;

var whichLevel:int = layout[1];
layout = layout[0];

for(var i:int=0; i<=rows - 1; i++) {

for(var j:int=0; j<=cols - 1; j++) {

switch (layout[i][j]) {
case (2):
dp = new Wall();
break;
case (3):
dp = new Breakable();
break;
case(8):
dp = new Treasure();
break;
case(11):
dp = new Treasure_Key();
break;
case(7):
dp = new Door();
break;
case(12):
dp = new Door_Key();
break;
case(15):
dp = new Gate_Open();
break;
case(16):
dp = new Gate_Closed();
break;
case(18):
dp = new H_Spikes();
break;
case(17):
dp = new V_Spikes();
break;
case(4):
dp = new Boulder();
break;
case(5):
dp = new Balloon();
break;
case(9):
dp = new R_Dynamite();
break;
case(10) :
dp = new G_Dynamite();
break;
}
dp.width = tile_w;
dp.height = tile_h;
dp.x = j * tile_w;
dp.y = i * tile_h;
dp.lit = 0;
board.addChild(dp);
obs.push(dp);
obs2.push(new Array(dp, dp.x, dp.y));
}
}

apiccion
04-16-2009, 01:05 AM
There is a mistake in my code at the bottom.

dp.lit = 0;

This will not work. You have to find another way to initialize the lit variable. There are several solutions.