SilentSorrow

Flappy Aya

Feb 5th, 2015
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 8.43 KB | None | 0 0
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
  6.  
  7.     <!--<meta name="apple-mobile-web-app-capable" content="yes">-->
  8.     <!--<meta name="mobile-web-app-capable" content="yes">-->
  9.  
  10.     <title>FlappyJS</title>
  11.  
  12.     <script src="sprite.js"></script>
  13.  
  14.     <style>
  15.     canvas {
  16.         display: block;
  17.         position: absolute;
  18.         margin: auto;
  19.         top: 0;
  20.         bottom: 0;
  21.         left: 0;
  22.         right: 0;
  23.     }
  24.     </style>
  25. </head>
  26. <body>
  27. <script>
  28.  
  29. var
  30.  
  31. // Game vars //
  32.  
  33. canvas,
  34. ctx,
  35. width,
  36. height,
  37.  
  38. fgpos = 0,
  39. frames = 0,
  40. score = 0,
  41. best = 0,
  42.  
  43. // State vars //
  44.  
  45. currentstate,
  46. states = {
  47.     Splash: 0, Game: 1, Score: 2
  48. },
  49.  
  50. // Game objects //
  51.  
  52. /**
  53.  * Ok button initiated in main()
  54.  */
  55. okbtn,
  56.  
  57. /**
  58.  * The bird
  59.  */
  60. bird = {
  61.  
  62.     x: 60,
  63.     y: 0,
  64.  
  65.     frame: 0,
  66.     velocity: 0,
  67.     animation: [0, 1, 2, 1], // animation sequence
  68.  
  69.     rotation: 0,
  70.     radius: 12,
  71.  
  72.     gravity: 0.25,
  73.     _jump: 4.6,
  74.  
  75.     /**
  76.      * Makes the bird "flap" and jump
  77.      */
  78.     jump: function() {
  79.         this.velocity = -this._jump;
  80.     },
  81.  
  82.     /**
  83.      * Update sprite animation and position of bird
  84.      */
  85.     update: function() {
  86.         // make sure animation updates and plays faster in gamestate
  87.         var n = currentstate === states.Splash ? 10 : 5;
  88.         this.frame += frames % n === 0 ? 1 : 0;
  89.         this.frame %= this.animation.length;
  90.  
  91.         // in splash state make bird hover up and down and set
  92.         // rotation to zero
  93.         if (currentstate === states.Splash) {
  94.  
  95.             this.y = height - 280 + 5*Math.cos(frames/10);
  96.             this.rotation = 0;
  97.  
  98.         } else { // game and score state //
  99.  
  100.             this.velocity += this.gravity;
  101.             this.y += this.velocity;
  102.  
  103.             // change to the score state when bird touches the ground
  104.             if (this.y >= height - s_fg.height-10) {
  105.                 this.y = height - s_fg.height-10;
  106.                 if (currentstate === states.Game) {
  107.                     currentstate = states.Score;
  108.                 }
  109.                 // sets velocity to jump speed for correct rotation
  110.                 this.velocity = this._jump;
  111.             }
  112.  
  113.             // when bird lack upward momentum increment the rotation
  114.             // angle
  115.             if (this.velocity >= this._jump) {
  116.  
  117.                 this.frame = 1;
  118.                 this.rotation = Math.min(Math.PI/2, this.rotation + 0.3);
  119.  
  120.             } else {
  121.  
  122.                 this.rotation = -0.3;
  123.  
  124.             }
  125.         }
  126.     },
  127.  
  128.     /**
  129.      * Draws bird with rotation to canvas ctx
  130.      *
  131.      * @param  {CanvasRenderingContext2D} ctx the context used for
  132.      *                                        drawing
  133.      */
  134.     draw: function(ctx) {
  135.         ctx.save();
  136.         // translate and rotate ctx coordinatesystem
  137.         ctx.translate(this.x, this.y);
  138.         ctx.rotate(this.rotation);
  139.        
  140.         var n = this.animation[this.frame];
  141.         // draws the bird with center in origo
  142.         s_bird[n].draw(ctx, -s_bird[n].width/2, -s_bird[n].height/2);
  143.  
  144.         ctx.restore();
  145.     }
  146. },
  147.  
  148. /**
  149.  * The pipes
  150.  */
  151. pipes = {
  152.  
  153.     _pipes: [],
  154.     // padding: 80, // TODO: Implement paddle variable
  155.  
  156.     /**
  157.      * Empty pipes array
  158.      */
  159.     reset: function() {
  160.         this._pipes = [];
  161.     },
  162.  
  163.     /**
  164.      * Create, push and update all pipes in pipe array
  165.      */
  166.     update: function() {
  167.         // add new pipe each 100 frames
  168.         if (frames % 100 === 0) {
  169.             // calculate y position
  170.             var _y = height - (s_pipeSouth.height+s_fg.height+120+200*Math.random());
  171.             // create and push pipe to array
  172.             this._pipes.push({
  173.                 x: 500,
  174.                 y: _y,
  175.                 width: s_pipeSouth.width,
  176.                 height: s_pipeSouth.height
  177.             });
  178.         }
  179.         for (var i = 0, len = this._pipes.length; i < len; i++) {
  180.             var p = this._pipes[i];
  181.  
  182.             if (i === 0) {
  183.  
  184.                 score += p.x === bird.x ? 1 : 0;
  185.  
  186.                 // collision check, calculates x/y difference and
  187.                 // use normal vector length calculation to determine
  188.                 // intersection
  189.                 var cx  = Math.min(Math.max(bird.x, p.x), p.x+p.width);
  190.                 var cy1 = Math.min(Math.max(bird.y, p.y), p.y+p.height);
  191.                 var cy2 = Math.min(Math.max(bird.y, p.y+p.height+80), p.y+2*p.height+80);
  192.                 // closest difference
  193.                 var dx  = bird.x - cx;
  194.                 var dy1 = bird.y - cy1;
  195.                 var dy2 = bird.y - cy2;
  196.                 // vector length
  197.                 var d1 = dx*dx + dy1*dy1;
  198.                 var d2 = dx*dx + dy2*dy2;
  199.                 var r = bird.radius*bird.radius;
  200.                 // determine intersection
  201.                 if (r > d1 || r > d2) {
  202.                     currentstate = states.Score;
  203.                 }
  204.             }
  205.             // move pipe and remove if outside of canvas
  206.             p.x -= 2;
  207.             if (p.x < -p.width) {
  208.                 this._pipes.splice(i, 1);
  209.                 i--;
  210.                 len--;
  211.             }
  212.         }
  213.     },
  214.  
  215.     /**
  216.      * Draw all pipes to canvas context.
  217.      *
  218.      * @param  {CanvasRenderingContext2D} ctx the context used for
  219.      *                                        drawing
  220.      */
  221.     draw: function(ctx) {
  222.         for (var i = 0, len = this._pipes.length; i < len; i++) {
  223.             var p = this._pipes[i];
  224.             s_pipeSouth.draw(ctx, p.x, p.y);
  225.             s_pipeNorth.draw(ctx, p.x, p.y+80+p.height);
  226.         }
  227.     }
  228. };
  229.  
  230. /**
  231. * Called on mouse or touch press. Update and change state
  232. * depending on current game state.
  233. *
  234. * @param  {MouseEvent/TouchEvent} evt tho on press event
  235. */
  236. function onpress(evt) {
  237.  
  238.     switch (currentstate) {
  239.  
  240.         // change state and update bird velocity
  241.         case states.Splash:
  242.             currentstate = states.Game;
  243.             bird.jump();
  244.             break;
  245.  
  246.         // update bird velocity
  247.         case states.Game:
  248.             bird.jump();
  249.             break;
  250.  
  251.         // change state if event within okbtn bounding box
  252.         case states.Score:
  253.             // get event position
  254.             var mx = evt.offsetX, my = evt.offsetY;
  255.  
  256.             if (mx == null || my == null) {
  257.                 mx = evt.touches[0].clientX;
  258.                 my = evt.touches[0].clientY;
  259.             }
  260.  
  261.             // check if within
  262.             if (okbtn.x < mx && mx < okbtn.x + okbtn.width &&
  263.                 okbtn.y < my && my < okbtn.y + okbtn.height
  264.             ) {
  265.                 pipes.reset();
  266.                 currentstate = states.Splash;
  267.                 score = 0;
  268.             }
  269.             break;
  270.  
  271.     }
  272. }
  273.  
  274. /**
  275. * Starts and initiate the game
  276. */
  277. function main() {
  278.     // create canvas and set width/height
  279.     canvas = document.createElement("canvas");
  280.  
  281.     width = window.innerWidth;
  282.     height = window.innerHeight;
  283.  
  284.     var evt = "touchstart";
  285.     //if (width >= 500) {
  286.         width  = 420;
  287.         height = 600;
  288.         canvas.style.border = "1px solid #000";
  289.         evt = "mousedown";
  290.     //}
  291.  
  292.     // listen for input event
  293.     document.addEventListener(evt, onpress);
  294.  
  295.     canvas.width = width;
  296.     canvas.height = height;
  297.     ctx = canvas.getContext("2d");
  298.  
  299.     currentstate = states.Splash;
  300.     // append canvas to document
  301.     document.body.appendChild(canvas);
  302.  
  303.     // initate graphics and okbtn
  304.     var img = new Image();
  305.     img.onload = function() {
  306.         initSprites(this);
  307.         ctx.fillStyle = s_bg.color;
  308.  
  309.         okbtn = {
  310.             x: (width - s_buttons.Ok.width)/2,
  311.             y: height - 200,
  312.             width: s_buttons.Ok.width,
  313.             height: s_buttons.Ok.height
  314.         }
  315.  
  316.         run();
  317.     }
  318.     img.src = "res/sheet.png";
  319. }
  320.  
  321. /**
  322.  * Starts and update gameloop
  323.  */
  324. function run() {
  325.     var loop = function() {
  326.         update();
  327.         render();
  328.         window.requestAnimationFrame(loop, canvas);
  329.     }
  330.     window.requestAnimationFrame(loop, canvas);
  331. }
  332.  
  333. /**
  334.  * Update forground, bird and pipes position
  335.  */
  336. function update() {
  337.     frames++;
  338.  
  339.     if (currentstate !== states.Score) {
  340.         fgpos = (fgpos - 2) % 14;
  341.     } else {
  342.         // set best score to maximum score
  343.         best = Math.max(best, score);
  344.     }
  345.     if (currentstate === states.Game) {
  346.         pipes.update();
  347.     }
  348.  
  349.     bird.update();
  350. }
  351.  
  352. /**
  353.  * Draws bird and all pipes and assets to the canvas
  354.  */
  355. function render() {
  356.     // draw background color
  357.     ctx.fillRect(0, 0, width, height);
  358.     // draw background sprites
  359.     s_bg.draw(ctx, 0, height - s_bg.height);
  360.     s_bg.draw(ctx, s_bg.width, height - s_bg.height);
  361.     s_bg.draw(ctx, s_bg.width, height - s_bg.height);
  362.  
  363.     pipes.draw(ctx);
  364.     bird.draw(ctx);
  365.  
  366.     // draw forground sprites
  367.     s_fg.draw(ctx, fgpos, height - s_fg.height);
  368.     s_fg.draw(ctx, fgpos+s_fg.width, height - s_fg.height);
  369.  
  370.     var width2 = width/2; // center of canvas
  371.  
  372.     if (currentstate === states.Splash) {
  373.         // draw splash text and sprite to canvas
  374.         s_splash.draw(ctx, width2 - s_splash.width/2, height - 300);
  375.         s_text.GetReady.draw(ctx, width2 - s_text.GetReady.width/2, height-380);
  376.  
  377.     }
  378.     if (currentstate === states.Score) {
  379.         // draw gameover text and score board
  380.         s_text.GameOver.draw(ctx, width2 - s_text.GameOver.width/2, height-400);
  381.         s_score.draw(ctx, width2 - s_score.width/2, height-340);
  382.         s_buttons.Ok.draw(ctx, okbtn.x, okbtn.y);
  383.         // draw score and best inside the score board
  384.         s_numberS.draw(ctx, width2-47, height-304, score, null, 10);
  385.         s_numberS.draw(ctx, width2-47, height-262, best, null, 10);
  386.  
  387.     } else {
  388.         // draw score to top of canvas
  389.         s_numberB.draw(ctx, null, 20, score, width2);
  390.  
  391.     }
  392. }
  393.  
  394. // start and run the game
  395. main();
  396. </script>
  397. </body>
  398. </html>
Advertisement
Add Comment
Please, Sign In to add comment