New tile based platform engine - part 9 - coins n’ spikes

You asked for coins and spikes, and here they are...

As usual I had to define some rules... in this case spikes are deadly only when the player has both feet on it... later I will make a lava (or electric) tile that will kill the player even if he only has one foot on it.

At the moment the player just restarts when he dies, later I will manage real deaths.

Coins are... well... coins... just collect them.

Fix for the fix for infamous Ladder Bug in the Platform Tutorials

In New tile based platform engine - more theory I said superdean fixed the ladder bug... that's not completely true because with his code the player cannot climb down a ladder when he's walking over it.

So the correct if statement to perform when the player presses DOWN is neither mine

if (over == "ladder") {

nor superdean's one

if (top_right == 6 or bottom_right == 6 or top_left == 6 or bottom_left == 6){

but

if ((over == "ladder") or (top_right == 6 or bottom_right == 6 or top_left == 6 or bottom_left == 6)) {

Now grab the source code:

ACTIONSCRIPT:
  1. tile_size = 20;
  2. ground_acceleration = 1;
  3. ground_friction = 0.8;
  4. air_acceleration = 0.5;
  5. air_friction = 0.7;
  6. ice_acceleration = 0.15;
  7. ice_friction = 0.95;
  8. treadmill_speed = 2;
  9. max_speed = 3;
  10. xspeed = 0;
  11. yspeed = 0;
  12. falling = false;
  13. gravity = 0.5;
  14. jump_speed = 6;
  15. climbing = false;
  16. climb_speed = 0.8;
  17. level = new Array();
  18. enemy = new Array();
  19. coin = new Array();
  20. level[0] = [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];
  21. level[1] = [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. level[2] = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 1, 0, 0, 0, 0, 1];
  23. level[3] = [1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1];
  24. level[4] = [1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1];
  25. level[5] = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1];
  26. level[6] = [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 1, 0, 0, 0, 0, 0, 1];
  27. level[7] = [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 1];
  28. level[8] = [1, 1, 1, 1, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 7, 0, 0, 6, 0, 0, 0, 0, 7, 0, 1];
  29. level[9] = [1, 1, 1, 1, 1, 1, 1, 2, 2, 8, 8, 8, 8, 1, 1, 3, 3, 1, 4, 4, 1, 8, 1, 8, 1];
  30. player = [5, 8];
  31. enemy[0] = [10, 3, -2];
  32. enemy[1] = [3, 3, -2];
  33. coin[0] = [2, 2];
  34. coin[1] = [23, 4];
  35. coin;
  36. function create_level(l) {
  37.     _root.createEmptyMovieClip("level_container", 1);
  38.     level_height = l.length;
  39.     level_width = l[0].length;
  40.     for (y=0; y<level_height; y++) {
  41.         for (x=0; x<level_width; x++) {
  42.             if (l[y][x] != 0) {
  43.                 t = level_container.attachMovie("tile", "t"+y+"_"+x, _root.level_container.getNextHighestDepth(), {_x:x*tile_size, _y:y*tile_size});
  44.                 t.gotoAndStop(l[y][x]);
  45.             }
  46.         }
  47.     }
  48.     place_player();
  49.     for (x=0; x<coin.length; x++) {
  50.         coin_mc = level_container.attachMovie("coin", "coin_"+_root.level_container.getNextHighestDepth(), _root.level_container.getNextHighestDepth(), {_x:coin[x][0]*tile_size+tile_size/2, _y:coin[x][1]*tile_size+tile_size/2+1});
  51.         coin_mc.onEnterFrame = function() {
  52.             if (this.hitTest(level_container.hero._x, level_container.hero._y, true)) {
  53.                 this.removeMovieClip();
  54.             }
  55.         };
  56.     }
  57.     for (x=0; x<enemy.length; x++) {
  58.         foe = level_container.attachMovie("patrol", "patrol_"+_root.level_container.getNextHighestDepth(), _root.level_container.getNextHighestDepth(), {_x:enemy[x][0]*tile_size+tile_size/2, _y:enemy[x][1]*tile_size+tile_size/2+1});
  59.         foe.speed = enemy[x][2];
  60.         foe.onEnterFrame = function() {
  61.             this.x_pos = this._x;
  62.             this.y_pos = this._y;
  63.             this.x_pos += this.speed;
  64.             this.left_foot_x = Math.floor((this.x_pos-6)/tile_size);
  65.             this.right_foot_x = Math.floor((this.x_pos+5)/tile_size);
  66.             this.foot_y = Math.floor((this.y_pos+9)/tile_size);
  67.             this.bottom = Math.floor((this.y_pos+8)/tile_size);
  68.             this.left_foot = level[this.foot_y][this.left_foot_x];
  69.             this.right_foot = level[this.foot_y][this.right_foot_x];
  70.             this.left = level[this.bottom][this.left_foot_x];
  71.             this.right = level[this.bottom][this.right_foot_x];
  72.             if (this.left_foot != 0 and this.right_foot != 0 and this.left == 0 and this.right == 0) {
  73.                 this._x = this.x_pos;
  74.             } else {
  75.                 this.speed *= -1;
  76.             }
  77.         };
  78.     }
  79. }
  80. create_level(level);
  81. _root.onEnterFrame = function() {
  82.     ground_under_feet();
  83.     walking = false;
  84.     climbing = false;
  85.     if (Key.isDown(Key.LEFT)) {
  86.         xspeed -= speed;
  87.         walking = true;
  88.     }
  89.     if (Key.isDown(Key.RIGHT)) {
  90.         xspeed += speed;
  91.         walking = true;
  92.     }
  93.     if (Key.isDown(Key.UP)) {
  94.         get_edges();
  95.         if (top_right == 6 or bottom_right == 6 or top_left == 6 or bottom_left == 6) {
  96.             jumping = false;
  97.             falling = false;
  98.             climbing = true;
  99.             climbdir = -1;
  100.         }
  101.     }
  102.     if (Key.isDown(Key.DOWN)) {
  103.         get_edges();
  104.         if ((over == "ladder") or (top_right == 6 or bottom_right == 6 or top_left == 6 or bottom_left == 6)) {
  105.             jumping = false;
  106.             falling = false;
  107.             climbing = true;
  108.             climbdir = 1;
  109.         }
  110.     }
  111.     if (Key.isDown(Key.SPACE)) {
  112.         get_edges();
  113.         if (!falling and !jumping) {
  114.             jumping = true;
  115.             yspeed = -jump_speed;
  116.         }
  117.     }
  118.     if (!walking) {
  119.         xspeed *= friction;
  120.         if (Math.abs(xspeed)<0.5) {
  121.             xspeed = 0;
  122.         }
  123.     }
  124.     if (xspeed>max_speed) {
  125.         xspeed = max_speed;
  126.     }
  127.     if (xspeed<max_speed*-1) {
  128.         xspeed = max_speed*-1;
  129.     }
  130.     if (falling or jumping) {
  131.         yspeed += gravity;
  132.     }
  133.     if (climbing) {
  134.         yspeed = climb_speed*climbdir;
  135.     }
  136.     if (!falling and !jumping and !climbing) {
  137.         yspeed = 0;
  138.     }
  139.     xspeed += bonus_speed;
  140.     check_collisions();
  141.     level_container.hero._x = x_pos;
  142.     level_container.hero._y = y_pos;
  143.     xspeed -= bonus_speed;
  144. };
  145. function ground_under_feet() {
  146.     bonus_speed = 0;
  147.     left_foot_x = Math.floor((x_pos-6)/tile_size);
  148.     right_foot_x = Math.floor((x_pos+5)/tile_size);
  149.     foot_y = Math.floor((y_pos+9)/tile_size);
  150.     left_foot = level[foot_y][left_foot_x];
  151.     right_foot = level[foot_y][right_foot_x];
  152.     if (left_foot != 0) {
  153.         current_tile = left_foot;
  154.     } else {
  155.         current_tile = right_foot;
  156.     }
  157.     switch (current_tile) {
  158.     case 0 :
  159.         over = "air";
  160.         speed = air_acceleration;
  161.         friction = air_friction;
  162.         falling = true;
  163.         break;
  164.     case 1 :
  165.         over = "ground";
  166.         speed = ground_acceleration;
  167.         friction = ground_friction;
  168.         break;
  169.     case 2 :
  170.         over = "ice";
  171.         speed = ice_acceleration;
  172.         friction = ice_friction;
  173.         break;
  174.     case 3 :
  175.         over = "treadmill";
  176.         speed = ground_acceleration;
  177.         friction = ground_friction;
  178.         bonus_speed = -treadmill_speed;
  179.         break;
  180.     case 4 :
  181.         over = "treadmill";
  182.         speed = ground_acceleration;
  183.         friction = ground_friction;
  184.         bonus_speed = treadmill_speed;
  185.         break;
  186.     case 5 :
  187.         over = "cloud";
  188.         speed = ground_acceleration;
  189.         friction = ground_friction;
  190.         break;
  191.     case 6 :
  192.         over = "ladder";
  193.         speed = ground_acceleration;
  194.         friction = ground_friction;
  195.         break;
  196.     case 7 :
  197.         over = "trampoline";
  198.         speed = ground_acceleration;
  199.         friction = ground_friction;
  200.         break;
  201.     case 8 :
  202.         over = "spikes";
  203.         if (left_foot == 8 and right_foot == 8) {
  204.             place_player();
  205.         }
  206.     }
  207. }
  208. function check_collisions() {
  209.     y_pos += yspeed;
  210.     get_edges();
  211.     // collision to the bottom
  212.     if (yspeed>0) {
  213.         if ((bottom_right != 0 and bottom_right != 6) or (bottom_left != 0 and bottom_left != 6)) {
  214.             // not a cloud...
  215.             if (bottom_right != 5 and bottom_left != 5) {
  216.                 // a trampoline
  217.                 if ((bottom_right == 7 or bottom_left == 7) and (Math.abs(yspeed)>1)) {
  218.                     yspeed = yspeed*-1;
  219.                     jumping = true;
  220.                     falling = true;
  221.                 } else {
  222.                     y_pos = bottom*tile_size-9;
  223.                     yspeed = 0;
  224.                     falling = false;
  225.                     jumping = false;
  226.                 }
  227.             } else {
  228.                 //cloud
  229.                 if (prev_bottom<bottom) {
  230.                     y_pos = bottom*tile_size-9;
  231.                     yspeed = 0;
  232.                     falling = false;
  233.                     jumping = false;
  234.                 }
  235.             }
  236.         }
  237.     }
  238.     // collision to the top                                                         
  239.     if (yspeed<0) {
  240.         if ((top_right != 0 and top_right != 5 and top_right != 6) or (top_left != 0 and top_left != 5 and top_left != 6)) {
  241.             y_pos = bottom*tile_size+1+8;
  242.             yspeed = 0;
  243.             falling = false;
  244.             jumping = false;
  245.         }
  246.     }
  247.     x_pos += xspeed;
  248.     get_edges();
  249.     // collision to the left           
  250.     if (xspeed<0) {
  251.         if ((top_left != 0 and top_left != 5 and top_left != 6 and top_left != 7) or (bottom_left != 0 and bottom_left != 5 and bottom_left != 6 and bottom_left != 7)) {
  252.             x_pos = (left+1)*tile_size+6;
  253.             xspeed = 0;
  254.         }
  255.     }
  256.     // collision to the right                                                                               
  257.     if (xspeed>0) {
  258.         if ((top_right != 0 and top_right != 5 and top_right != 6 and top_right != 7) or (bottom_right != 0 and bottom_right != 5 and bottom_right != 6 and bottom_right != 7)) {
  259.             x_pos = right*tile_size-6;
  260.             xspeed = 0;
  261.         }
  262.     }
  263.     prev_bottom = bottom;
  264. }
  265. function get_edges() {
  266.     // right edge
  267.     right = Math.floor((x_pos+5)/tile_size);
  268.     // left edge   
  269.     left = Math.floor((x_pos-6)/tile_size);
  270.     // bottom edge
  271.     bottom = Math.floor((y_pos+8)/tile_size);
  272.     // top edge
  273.     top = Math.floor((y_pos-9)/tile_size);
  274.     // adjacent tiles
  275.     top_right = level[top][right];
  276.     top_left = level[top][left];
  277.     bottom_left = level[bottom][left];
  278.     bottom_right = level[bottom][right];
  279. }
  280. function place_player() {
  281.     level_container.hero.removeMovieClip();
  282.     x_pos = player[0]*tile_size+tile_size/2;
  283.     y_pos = player[1]*tile_size+tile_size/2+1;
  284.     level_container.attachMovie("hero", "hero", _root.level_container.getNextHighestDepth(), {_x:x_pos, _y:y_pos});
  285. }

and play the game.

<