The Tile Engine: The Ins and Outs

squaring it all

The Tank sprites all extend a class called BasicTank which in turn extends the GameSprite class. The BasicTank contains the logic that controls the tank’s state, or frame in the animation. It also contains a reference to the tank’s bullet object. A tank can only shoot if its previously shot bullet is null, so the bullet either is no longer on stage, or no bullets have been fired yet.

The Player tank adds a bit more functionality with the Keyboard input. Again nothing different from the player object in H.E.R.O.

The one method worth reviewing is the one that adds the bullet:

1
2
3
4
5
6
override protected function createBullet ():void {
	if (_gameData.gameMode == GameConstants.PAUSE) return;
	if (_bullet) return;
	//addPlayerBullet may return null if front of tank is too close to a wall
	_bullet = _gameStage.addPlayerBullet(this);
}

So if there is a bullet shot from this tank already on stage, simply return. If not, the _gameStage.addPlayerBullet method will create a bullet object and ask the Maze object to check if the initial position is valid, meaning if the bullet would not overlap a solid cell when placed on stage. If that is the case that method will return NULL to this method, and so _bullet would remain with a null value.

The BasicTank Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package tiletank.tank {
 
	import flash.events.Event;
 
	import tiletank.dynamic.GameSprite;
	import tiletank.bullet.*;
	import tiletank.*;
 
	/**
	* The class Player Tank and Ai Tank will extend
	*/
	public class BasicTank extends GameSprite {
 
		//is this AI or Player?
		protected var _controller:String;
		protected var _bullet:BasicBullet;
 
		function BasicTank () {
			_stageElements.addElement(this);
			_manager.addBody(this);
			//default speed
			_speed = 3;
		}
 
		//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>public function get bullet ():BasicBullet {
			return _bullet;
		}
		public function set bullet (value:BasicBullet):void {
			_bullet = value;
		}
		public function get controller ():String {
			return _controller;
		}
		//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>override public function update ():void {
			_vx = 0;
			_vy = 0;
		}
 
		/**
		* Retrieve the current direction the tank is moving to
		* (based on the tank's sprite current label)
		*/
		public function getDirection ():String {
			if (states.currentLabel.indexOf(GameConstants.UP) != -1) {
				if (scaleY > 0) {
					return GameConstants.UP;
				} else {
					return GameConstants.DOWN;
				}
			} else {
				if (scaleX > 0) {
					return GameConstants.RIGHT;
				} else {
					return GameConstants.LEFT;
				}
			}
			return "";
		}
 
		/**
		* set correct frame label of tank sprite based on direction of movement
		*/
		override public function setState ():void {
			if (_vx > 0) {
				scaleX = 1;
				if (states.currentLabel != GameConstants.SIDE+"_move") states.gotoAndStop(GameConstants.SIDE+"_move");
			} else if (_vx < 0) {
				scaleX = -1;
				if (states.currentLabel != GameConstants.SIDE+"_move") states.gotoAndStop(GameConstants.SIDE+"_move");
			} else if (_vy > 0) {
				scaleY = -1;
				if (states.currentLabel != GameConstants.UP+"_move") states.gotoAndStop(GameConstants.UP+"_move");
			} else if (_vy < 0) {
				scaleY = 1;
				if (states.currentLabel != GameConstants.UP+"_move") states.gotoAndStop(GameConstants.UP+"_move");
			}
		}
 
		protected function createBullet ():void {}
 
		override protected function removeMe (event:Event):void {
			super.removeMe(event);
			_stageElements.removeElement(this);
		}
 
		override protected function onGamePause (event:Event):void {
			if (states.currentLabel == GameConstants.SIDE+"_move") states.gotoAndStop(GameConstants.SIDE);
			if (states.currentLabel == GameConstants.UP+"_move") states.gotoAndStop(GameConstants.UP);
 
		}
 
	}
 
}

The PlayerTank class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package tiletank.tank {
 
	import flash.events.Event;
	import flash.events.KeyboardEvent;
 
	import tiletank.*;
 
	public class PlayerTank extends BasicTank {
 
		private var _moveLeft:Boolean = false;
		private var _moveRight:Boolean = false;
		private var _moveUp:Boolean = false;
		private var _moveDown:Boolean = false;
 
		function PlayerTank () {
			super();
			_controller = GameConstants.PLAYER;
		}
 
 
		override public function update ():void {
			super.update();
			if (_moveLeft) {
				_vx = -_speed;
			} else if (_moveRight) {
				_vx = _speed;
			} else if (_moveUp) {
				_vy = -_speed;
			} else if (_moveDown) {
				_vy = _speed;
			}
 
			_nextX = _nowX + _vx;
			_nextY = _nowY + _vy;
 
		}
 
 
		override protected function createBullet ():void {
			if (_gameData.gameMode == GameConstants.PAUSE) return;
			if (_bullet) return;
			//addPlayerBullet may return null if front of tank is too close to a wall
			_bullet = _gameStage.addPlayerBullet(this);
		}
 
		override public function setState ():void {
			super.setState();
 
			if (_moveDown || _moveLeft || _moveRight || _moveUp) {
				if (states.currentLabel.indexOf("move") == -1) states.gotoAndStop(states.currentLabel + "_move");
			} else {
				if (states.currentLabel.indexOf(GameConstants.UP) != -1 && states.currentLabel != GameConstants.UP)
					states.gotoAndStop(GameConstants.UP);
				if (states.currentLabel.indexOf(GameConstants.SIDE) != -1 && states.currentLabel != GameConstants.SIDE)
					states.gotoAndStop(GameConstants.SIDE);
			}
 
		}
 
		override public function destroy ():void {
			_gameStage.removePlayer(this);
		}
 
		override protected function initMe (event:Event):void {
			super.initMe(event);
		 	stage.addEventListener(KeyboardEvent.KEY_UP, onKey_Up, false, 0, true);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, onKey_Down, false, 0, true);
		}
		override protected function removeMe (event:Event):void {
			super.removeMe(event);
			stage.removeEventListener(KeyboardEvent.KEY_UP, onKey_Up);
			stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKey_Down);
		}
 
		private function onKey_Up (event:KeyboardEvent):void {
			if (event.keyCode == 38) {
				//UP KEY is up
				_moveUp = false;
			} else if (event.keyCode == 39) {
				//RIGHT KEY is up
				_moveRight = false;
			} else if (event.keyCode == 37) {
				//LEFT Key is up
				_moveLeft = false;
			} else if (event.keyCode == 40) {
				//DOWN KEY is up
				_moveDown = false;
			} if (event.keyCode == 32) {
				//SPACE Bar is up
				createBullet();
			}
		}
		private function onKey_Down (event:KeyboardEvent):void {
 
			if (event.keyCode == 38) {
				//UP KEY is down
				_moveUp = true;
			} else if (event.keyCode == 39) {
				//RIGHT KEY is down
				_moveRight = true;
 
			} else if (event.keyCode == 37) {
				//LEFT Key is down
				_moveLeft = true;
 
			} else if (event.keyCode == 40) {
				//DOWN KEY is down
				_moveDown = true;
			}
		}
	}
}

Leave a Comment