AS3.0 tutorial – Platform creation tutorial 2

17
Jun/08
4

Here’s part 2 of Bart de Boer’s translation of Emanuele Feronato’s platform game creation tutorial into AS3. For part one, see here.

Click here to see what you will have by the end of this tutorial.

It's all commented, and there's a source to download at the end.

Here's Script.as:

  1. /*____________________________________________________
  2. |______________    register of functions _______________|
  3. |____________________________________________________|
  4.  
  5. - main()            only calling to update_hero() (every frame)
  6.  
  7. - create_hero()        creates hero as the var "Hero"
  8.  
  9. - update_hero()        check collision an move
  10.  
  11. - BuildMap()        load and create the level
  12.  
  13. extern
  14.  
  15. Data.as
  16. - Setup()            create levels
  17.  
  18. collision_manager.as
  19. - Setup(size,map,hero)        setup the map
  20.  
  21. - Solve_all(forecastx,forecasty)        solves the collsions and checks for a jump
  22. */
  23.  
  24. package{                                                //The begin of an .as file
  25. import flash.display.MovieClip;                        //import some libraries
  26. import flash.events.Event;
  27. import flash.events.KeyboardEvent;
  28.  
  29. public class Script extends MovieClip{                // start the script
  30.  
  31. private const gravity:int = 1;
  32. private const max_speed:int = 8;
  33.  
  34. private const walkspeed:int = 4;
  35. private const jumpspeed:int = 10;
  36.  
  37. private var forecast_x:int;
  38. private var forecast_y:int;
  39.  
  40. private const start_x:int = 50;
  41. private const start_y:int = 50;
  42.  
  43. private var left:Boolean;
  44. private var up:Boolean;
  45. private var right:Boolean;
  46. private var space:Boolean;
  47.  
  48. private var level:Array = new Array();
  49. private var tiles:Array = new Array();
  50.  
  51. private var Map_data:Data = new Data;                // create a version of the Data.as
  52. private var Hero_col:collision_manager = new collision_manager;
  53.  
  54. private var Hero:hero = new hero;
  55.  
  56. public function Script(){                        // the init (will only be runned once)
  57. BuildMap();
  58. create_hero();
  59. addEventListener(Event.ENTER_FRAME, main);
  60. stage.addEventListener(KeyboardEvent.KEY_DOWN, key_down);
  61. stage.addEventListener(KeyboardEvent.KEY_UP, key_up);
  62.  
  63. Hero_col.Setup(25,level,Hero);
  64. }
  65.  
  66. private function main(event:Event){
  67. update_hero();
  68. }
  69.  
  70. private function key_down(event:KeyboardEvent){
  71. if(event.keyCode == 37){
  72. left = true;
  73. }
  74. if(event.keyCode == 38){
  75. up = true;
  76. }
  77. if(event.keyCode == 39){
  78. right = true;
  79. }
  80. }
  81.  
  82. private function key_up(event:KeyboardEvent){
  83. if(event.keyCode == 37){
  84. left = false;
  85. }
  86. if(event.keyCode == 38){
  87. up = false;
  88. }
  89. if(event.keyCode == 39){
  90. right = false;
  91. }
  92. }
  93.  
  94. /*
  95. ///    ///        /////////    ///////////        ///////////
  96. ///    ///        ///            ////    ///        ///        ///
  97. ///    ///        ///            ////    ///        ///        ///
  98. //////////        /////////    //////////        ///        ///
  99. //////////        /////////    ////    ///        ///        ///
  100. ///    ///        ///            ////    ///        ///        ///
  101. ///    ///        ///            ////    ///        ///        ///
  102. ///    ///        /////////    ////    ///        ///////////
  103. */
  104. private function create_hero(){
  105. addChild(Hero);
  106. Hero.x = start_x;
  107. Hero.y = start_y;
  108. Hero.x_speed = 0;
  109. Hero.y_speed = 0;
  110. }
  111.  
  112. private function update_hero(){
  113. Hero.y_speed += gravity;
  114. if(left){
  115. Hero.x_speed = -walkspeed;
  116. }
  117. if(right){
  118. Hero.x_speed = walkspeed;
  119. }
  120. if(up && Hero_col.can_jump){
  121. Hero.y_speed = -jumpspeed;
  122. }
  123.  
  124. if(Hero.y_speed > max_speed){
  125. Hero.y_speed = max_speed;
  126. }
  127.  
  128. forecast_y = Hero.y + Hero.y_speed;
  129. forecast_x = Hero.x + Hero.x_speed;
  130.  
  131. Hero_col.solve_all(forecast_x, forecast_y);
  132.  
  133. Hero.x_speed = 0;
  134. }
  135.  
  136. /*
  137. |||||||||||         |||||||||||      ||||||||||    ||||||||||
  138. ||||||||||||    ||||||||||||     ||||     ||||    ||||    |||
  139. ||||    ||||| |||||        ||||     ||||||||||||    ||||||||||
  140. ||||      |||||||        ||||     ||||     ||||    ||||
  141. ||||        |||            ||||    ||||      ||||    ||||
  142. ||||                    ||||    ||||      ||||    ||||
  143. */
  144.  
  145. private function BuildMap(){
  146. Map_data.Setup();                                                // setup data from extern file
  147.  
  148. level = Map_data.level1;                                        // get data from extern file
  149.  
  150. for(var t = 0; t < level.length; t++){
  151. for(var u = 0; u < level[t].length; u++){
  152. if(level[t][u] != 0){                                    //if the data is not null
  153. var new_tile:platform_tile = new platform_tile;        //than build a tile
  154.  
  155. addChild(new_tile);                                    //put it on the screen
  156.  
  157. new_tile.gotoAndStop(1);
  158. new_tile.x = u * 25;
  159. new_tile.y = t * 25;
  160.  
  161. tiles.push(new_tile);                                //put it in an array
  162. }
  163. }
  164. }
  165. }
  166. }
  167. }
  168.  
  169. // You may not post this on any other site than: http://www.emanueleferonato.com or http://www.frozenhaddock.com. You may not claim that you wrote this code. I'm not responsible for any nuclear activity that may be caused by this script.

Here's Data.as:

  1. package{
  2.  
  3. public class Data{
  4.  
  5. public var level1:Array = new Array();
  6. public function Setup(){
  7. level1 = [
  8. [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  9. [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  10. [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  11. [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  12. [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  13. [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1],
  14. [1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  15. [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  16. [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  17. [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  18. [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  19. [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  20. [1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  21. [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  22. [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
  23. ]
  24. }
  25. }
  26. }
  27.  
  28. // You may not post this on any other site than: http://www.emanueleferonato.com or http://www.frozenhaddock.com. You may not claim that you wrote this code. I'm not responsible for any nuclear activity that may be caused by this script.

And here's collision_manager.as:

  1. package{
  2.  
  3. public class collision_manager{
  4. private var Tile_size:int;            //containing the size of the tiles
  5. private var level;                    //level data container
  6. private var forecast_x:int;            //where the player will be at the end of the frame
  7. private var forecast_y:int;            //"                                                  "
  8. public var can_jump:Boolean;        //same as in Emanuele's tutorial
  9. private var hero;                    //to store the Hero object in
  10.  
  11. public function Setup(size,map,heroj){        //my standard setup function(init)
  12. Tile_size = size;                        //initializing al vars
  13. level = map;
  14. hero = heroj;
  15. }
  16.  
  17. public function get_corners(point_x,point_y){
  18. //get the position of the four corners of the hero
  19.  
  20. hero.downy = Math.round((point_y + 10 - Tile_size/2) / Tile_size);
  21. hero.upy = Math.round((point_y - 10 - Tile_size/2) / Tile_size);
  22. hero.rightx = Math.round((point_x + 5 - Tile_size/2) / Tile_size)
  23. hero.leftx = Math.round((point_x - 5 - Tile_size/2) / Tile_size);
  24. /*
  25. Looks in wich tiles these four point are.
  26. *Attention* TILES and not pixel!
  27.  
  28. Will be used to get the position of the corners
  29. and to get the end position of the hero.
  30. */
  31.  
  32. hero.downleft = level[hero.downy][hero.leftx];
  33. hero.downright = level[hero.downy][hero.rightx];
  34. hero.upright = level[hero.upy][hero.rightx];
  35. hero.upleft = level[hero.upy][hero.leftx];
  36.  
  37. /*
  38. Gets the sort tile the position of the corners has.
  39.  
  40. One means there can be collision, zero is air.
  41. */
  42. }
  43.  
  44. public function check_ground(){
  45. hero.downy = Math.round((hero.y + 11 - Tile_size/2) / Tile_size);
  46. hero.rightx = Math.round((hero.x + 5 - Tile_size/2) / Tile_size)
  47. hero.leftx = Math.round((hero.x - 5 - Tile_size/2) / Tile_size);
  48. // Makes three points in tile-coordinates
  49.  
  50. hero.downleft = level[hero.downy][hero.leftx];
  51. hero.downright = level[hero.downy][hero.rightx];
  52. //Checks the sort
  53.  
  54. if(hero.downleft == 1 || hero.downright ==1){        //if there is any collision by the hero's feet
  55. can_jump = true;                                //than can jump
  56. }
  57. else{
  58. can_jump = false;                                //else not
  59. }
  60. }
  61.  
  62. public function solve_all(forecastx, forecasty){
  63. /*
  64. This function looks hard... an it is...
  65. I've been working on it for loads of hours, and this is the result.
  66.  
  67. This is the best collision-test I've ever made, for sqaures.
  68.  
  69. It's still readable, because I made it simple.
  70.  
  71. It's four times almost the same. It checks for collision between the spots,
  72. the four spots if there only were x_speeds, the four spots if there only was y_speed,
  73. the four spots if there were both y- and x_speed.
  74. That are 3*4 = 12 spots.
  75.  
  76. //////////////////////////////////
  77. Why's:
  78.  
  79. question:
  80. Why did I used forecast_x and forecast_y and not just hero.x and hero.y?
  81.  
  82. answer:
  83. Changing the hero over the screen will cost loads of CPU because an hero
  84. exist out of loads of pixels. The forecast's are just simple variables
  85.  
  86. question:
  87. Is such a huge function not requiring a lot of CPU?
  88.  
  89. answer:
  90. It doesn't uses any while- or for loops, Math. functions and the most important of
  91. all: no hitTestPoint()/hitTestObject(). So it's a lot faster.
  92.  
  93. question:
  94. Is there a better or faster collision test?
  95.  
  96. answer:
  97. Probaly, yes.
  98. //////////////////////////////////
  99.  
  100. var-explanation:
  101.  
  102. downC     ->     is collision under the spot
  103. upC        ->    is collision above the spot
  104. rightC    ->    is collision right from the spot
  105. leftC    ->    You probaly wouldn't expect this, but this is collision left from the spot
  106.  
  107. */
  108. forecast_x = forecastx;
  109. forecast_y = forecasty;
  110.  
  111. get_corners(forecast_x,forecast_y);
  112.  
  113. if(hero.downleft == 1){
  114. get_corners(hero.x,forecast_y);
  115. if(hero.downleft == 1){
  116. hero.downC = true;
  117. }
  118. else{
  119. hero.downC = false;
  120. }
  121. get_corners(forecast_x,hero.y);
  122. if(hero.downleft == 1){
  123. hero.leftC = true;
  124. }
  125. else{
  126. hero.leftC = false;
  127. }
  128. if(hero.leftC &amp;&amp; hero.downC){
  129. forecast_x = (hero.leftx+1) * 25 + 5;
  130. forecast_y = (hero.downy+1) * 25 - 11;
  131. hero.y_speed = 0;
  132. }
  133. else if(hero.leftC){
  134. forecast_x = (hero.leftx+1) * 25 + 5;
  135. }
  136. else if(hero.downC){
  137. forecast_y = (hero.downy+1) * 25 - 11;
  138. hero.y_speed = 0;
  139. }
  140. }
  141.  
  142. get_corners(forecast_x,forecast_y);
  143.  
  144. if(hero.downright == 1){
  145. get_corners(hero.x,forecast_y);
  146. if(hero.downright == 1){
  147. hero.downC = true;
  148. }
  149. else{
  150. hero.downC = false;
  151. }
  152. get_corners(forecast_x,hero.y);
  153. if(hero.downright == 1){
  154. hero.rightC = true;
  155. }
  156. else{
  157. hero.rightC = false;
  158. }
  159. if(hero.rightC &amp;&amp; hero.downC){
  160. forecast_x = hero.rightx * 25 - 6;
  161. forecast_y = (hero.downy+1) * 25 - 11;
  162. hero.y_speed = 0;
  163. }
  164. else if(hero.rightC){
  165. forecast_x = hero.rightx * 25 - 6;
  166. }
  167. else if(hero.downC){
  168. forecast_y = (hero.downy+1) * 25 - 11;
  169. hero.y_speed = 0;
  170. }
  171. }
  172.  
  173. get_corners(forecast_x,forecast_y);
  174.  
  175. if(hero.upleft == 1){
  176. get_corners(hero.x,forecast_y);
  177. if(hero.upleft == 1){
  178. hero.upC = true;
  179. }
  180. else{
  181. hero.upC = false;
  182. }
  183. get_corners(forecast_x,hero.y);
  184. if(hero.upleft == 1){
  185. hero.leftC = true;
  186. }
  187. else{
  188. hero.leftC = false;
  189. }
  190. if(hero.leftC &amp;&amp; hero.upC){
  191. forecast_x = (hero.leftx+1) * 25 + 5;
  192. forecast_y = (hero.upy) * 25 + 10;
  193. hero.y_speed = 0;
  194. }
  195. else if(hero.leftC){
  196. forecast_x = (hero.leftx+1) * 25 + 5;
  197. }
  198. else if(hero.upC){
  199. forecast_y = (hero.upy) * 25 + 10;
  200. hero.y_speed  = 0;
  201. }
  202. }
  203.  
  204. get_corners(forecast_x,forecast_y);
  205.  
  206. if(hero.upright == 1){
  207. get_corners(hero.x,forecast_y);
  208. if(hero.upright == 1){
  209. hero.upC = true;
  210. }
  211. else{
  212. hero.upC = false;
  213. }
  214. get_corners(forecast_x,hero.y);
  215. if(hero.upright == 1){
  216. hero.leftC = true;
  217. }
  218. else{
  219. hero.leftC = false;
  220. }
  221. if(hero.leftC &amp;&amp; hero.upC){
  222. forecast_x = hero.rightx * 25 - 6;
  223. forecast_y = (hero.upy) * 25 + 10;
  224. hero.y_speed = 0;
  225. }
  226. else if(hero.leftC){
  227. forecast_x = hero.rightx * 25 - 6;
  228. }
  229. else if(hero.upC){
  230. forecast_y = (hero.upy) * 25 + 10;
  231. hero.y_speed  = 0;
  232. }
  233. }
  234.  
  235. hero.x = forecast_x;        //place the hero
  236. hero.y = forecast_y;
  237.  
  238. check_ground()        //runs the function to check for ground
  239. }
  240. }
  241. }
  242.  
  243. // You may not post this on any other site than: http://www.emanueleferonato.com or http://www.frozenhaddock.com. You may not claim that you wrote this code. I'm not responsible for any nuclear activity that may be caused by this script.

Thanks again to Bart! You can download the source here.

Comments (4) Trackbacks (0)
  1. jay
    5:13 am on July 17th, 2008

    Looks fun :p thanks!

  2. hey
    10:16 pm on July 27th, 2008

    What? no goal? make a part three :(

  3. pedro
    5:09 am on August 17th, 2008

    Hello , I’ve followed this tutorial and I got the game up and running and I have added “coins” for the player to collect but when I try to make a text on the frame for it to show the score it gives me an error .. so Id like to know if im not putting on the right place and i have to somewhere else so it will work so yeah help? D=

  4. Gatzä02
    8:16 pm on December 2nd, 2008

    hi,
    i have a question. I made a try of a platfrom game but i still have two problems. The first one: I can not find out how to make the hero collecting coins. Problem 2: I’d like to have some opponents. But i don’t know how this works. Problem 2 is less important but i tryed to find out something about the coins one week. Maybe I could send someone my try of the platform game.
    greetings,
    Gatzä02

Leave a comment

No trackbacks yet.