Ajax Loader
×
HTML
  <div class="container">
1
  <div class="container">
2
 
3
    <!-- Start Screen -->
4
    <div id="start_screen">
5
      <h1 id="title">pappu pakia</h1>
6
      <h3 id="credits">
7
        by
8
        <a href="http://twitter.com/SolitaryDesigns">Kushagra</a>
9
        and
10
        <a href="http://twitter.com/_rishabhp">Rishabh</a>
11
      </h3>
12
      <h3 id="last_score"></h3>
13
      <h3 id="high_score"></h3>
14
 
15
      <div class="controls"></div>
16
 
17
      <div class="options">
18
        <ul>
19
          <li><a href="javascript:void(0);" id="start_game">start</a></li>
20
          <li><a href="javascript:void(0);" target="_blank" id="tweet">tweet</a></li>
21
          <li><a href="javascript:void(0);" target="_blank" id="fb">fb like</a></li>
22
        </ul>
23
      </div>
24
    </div>
25
    <!-- /Start Screen -->
26
  
27
    <!-- Loading sounds -->
28
    <audio id="start" loop>
29
      <source src="https://dl.dropbox.com/u/26141789/pappu-pakia/pappu-pakia2.3.ogg"  type="audio/ogg">
30
      <source src="https://dl.dropbox.com/u/26141789/pappu-pakia/pappu-pakia2.3.mp3"  type="audio/mp3">
31
    </audio>
32
    
33
    <audio id="angry_jump">
34
      <source src="https://dl.dropbox.com/u/26141789/pappu-pakia/jump1.ogg" type="audio/ogg">
35
      <source src="https://dl.dropbox.com/u/26141789/pappu-pakia/jump1.mp3">
36
    </audio>
37
    
38
    <audio id="sad_jump">
39
      <source src="https://dl.dropbox.com/u/26141789/pappu-pakia/jump2.ogg" type="audio/ogg">
40
      <source src="https://dl.dropbox.com/u/26141789/pappu-pakia/jump2.mp3" type="audio/mp3">
41
    </audio>
42
    
43
    <audio id="happy_jump">
44
      <source src="https://dl.dropbox.com/u/26141789/pappu-pakia/jump3.ogg" type="audio/ogg">
45
      <source src="https://dl.dropbox.com/u/26141789/pappu-pakia/jump3.mp3" type="audio/mp3">
46
    </audio>
47
    
48
    <audio id="flap">
49
      <source src="https://dl.dropbox.com/u/26141789/pappu-pakia/flap.ogg">
50
      <source src="https://dl.dropbox.com/u/26141789/pappu-pakia/flap.mp3" type="audio/mp3">
51
    </audio>
52
    
53
    <audio id="ting">
54
      <source src="https://dl.dropbox.com/u/26141789/pappu-pakia/ting.ogg" type="audio/ogg">
55
      <source src="https://dl.dropbox.com/u/26141789/pappu-pakia/ting.mp3" type="audio/mp3">
56
    </audio>
57
 
58
    <canvas id="game_bg"></canvas>
59
    <canvas id="game_main"></canvas>
60
 
61
    <div id="score_board">0</div>
62
 
63
    <div id="invincible_timer">
64
      <div id="invincible_loader"></div>
65
    </div>
66
 
67
    <a href="javascript:void(0)" id="mute"></a>
68
    
69
    <!-- Loading Screen -->
70
    <div id="loading">
71
      <p id="loadText">Loading...</p>
72
      <div id="barCont">
73
        <div id="bar"></div>
74
      </div>
75
    </div>
76
 
77
  </div>
78
 
79
  <div id="fps_count"></div>
80
 
81
  <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
82
  <script>window.mit = window.mit || {};</script>
 
CSS
@import url(http://fonts.googleapis.com/css?family=Open+Sans);
1
@import url(http://fonts.googleapis.com/css?family=Open+Sans);
2
 
3
* {
4
  margin: 0; padding: 0;
5
  -moz-box-sizing: border-box;
6
  box-sizing: border-box;
7
}
8
 
9
/* Loading */
10
#loading {
11
  width: 100%;
12
  height: 100%;
13
  position: absolute;
14
  top: 0;
15
  left: 0;
16
  background: #FF6767;
17
  z-index: 10;
18
}
19
 
20
#loading #barCont {
21
  width: 400px;
22
  height: 20px;
23
  position: absolute;
24
  top: 50%;
25
  left: 50%;
26
  margin: -10px 0 0 -200px;
27
  background: black;
28
}
29
 
30
#loading #bar {
31
  width: 0;
32
  height: 20px;
33
  position: absolute;
34
  left: 0;
35
  background: #F3FF67;
36
}
37
 
38
html, body {
39
  width: 100%; height: 100%;
40
  min-width: 1050px;
41
  min-height: 600px;
42
}
43
 
44
body {
45
  background: #000 url(http://i.imgur.com/XgUk6.jpg) top center no-repeat fixed;
46
  font-family: 'Open Sans', Verdana;
47
}
48
 
49
h1, #loadText {
50
  text-align: center;
51
  color: #fff;
52
  margin-top: 20px;
53
  font-family: 'Happy Sans', cursive;
54
}
55
 
56
#loadText {
57
  line-height: 380px;
58
  font-size: 30px;
59
}
60
 
61
#fps_count {
62
  position: absolute;
63
  top: 10px;
64
  right: 10px;
65
  font-size: 20px;
66
  color: white;
67
  font-family: 'Happy Sans', cursive;
68
}
69
 
70
.gads {
71
  text-align: center;
72
  max-width: 1000px;
73
  margin: 20px auto;
74
}
75
 
76
#mute {
77
  width: 49px;
78
  height: 40px;
79
  background: url(http://i.imgur.com/uO2ST.png) no-repeat;
80
  display: block;
81
  text-decoration: none;
82
  outline: none;
83
  position: absolute;
84
  top: 15px;
85
  right: 15px;
86
  z-index: 15;
87
  background-position: 0 0;
88
}
89
 
90
.container {
91
  position: relative;
92
  margin: 20px auto 50px;
93
  width: auto;
94
  max-width: 1000px;
95
  height: 500px;
96
}
97
 
98
footer {
99
  margin: 20px auto;
100
  padding: 0 0 20px;
101
  max-width: 1000px;
102
}
103
footer h3 {
104
  color: #E7E7E7;
105
  margin-top: 30px;
106
  font-size: 18px;
107
  margin-bottom: 10px;
108
}
109
footer p {
110
  margin-bottom: 10px;
111
  font-size: 13px;
112
  font-weight: normal;
113
  color: #D1D1D1;
114
}
115
footer a {
116
  text-decoration: none;
117
  color: #FF6767;
118
}
119
footer a:visited {
120
  color: #7FFF67;
121
}
122
footer a:hover {
123
  color: #67DBFF;
124
}
125
footer a:active {
126
  color: #F3FF67;
127
}
128
footer a:focus {
129
  color: #FF67ED;
130
}
131
 
132
 
133
canvas#game_main {
134
  display: block;
135
  margin: 0 auto;
136
  position: absolute;
137
}
138
canvas#game_bg {
139
  display: block;
140
  margin: 0 auto;
141
  position: absolute;
142
}
143
 
144
 
145
/* Score Board */
146
#score_board {
147
  position: absolute;
148
  top: 0; left: 0; right: 0;
149
  padding: 10px;
150
  height: 10%;
151
  text-align: left;
152
  font-size: 30px;
153
  font-weight: normal;
154
  font-family: 'Happy Sans', cursive;
155
 
156
  -webkit-user-select: none;
157
  -moz-user-select: none;
158
  -o-user-select: none;
159
  user-select: none;
160
}
161
 
162
#invincible_timer {
163
  width: 150px;
164
  height: 10px;
165
  position: absolute;
166
  top: 20px;
167
  left: 50%;
168
  border: 1px solid #fff;
169
  margin-left: -75px;
170
  display: none;
171
}
172
#invincible_loader {
173
  width: 100%; height: 100%;
174
  background: #FDCF7D;
175
}
176
 
177
 
178
/* Start Screen */
179
#start_screen {
180
  position: absolute;
181
  top: 0;
182
  left: 0;
183
  height: 100%;
184
  z-index: 1;
185
  width: 100%;
186
 
187
  -webkit-user-select: none;
188
  -moz-user-select: none;
189
  -o-user-select: none;
190
  user-select: none;
191
}
192
 
193
#title {
194
  font-size: 67px;
195
  line-height: 100px;
196
  font-weight: normal;
197
  color: #945430;
198
  text-align: center;
199
  margin: 0;
200
  padding: 0;
201
  text-shadow: 3px 3px 0px white;
202
}
203
 
204
#credits, #high_score, #last_score {
205
  font: 36px 'Happy Sans', cursive;
206
  color: white;
207
  padding: 0;
208
  text-align: center;
209
  margin: -10px 0 10px;
210
}
211
 
212
#credits a {
213
  color: #FFEEAA;
214
  text-decoration: none;
215
}
216
 
217
.options {
218
  height: 400px;
219
  background-image: url(http://i.imgur.com/UpZJE.png);
220
  background-position: bottom center;
221
  width: 225px;
222
  background-repeat: no-repeat;
223
  position: absolute;
224
  bottom: 0;
225
  right: 50px;
226
}
227
 
228
.options:before {
229
  content: '';
230
  background-image: url(http://i.imgur.com/vcF0r.png);
231
  background-repeat: no-repeat;
232
  position: absolute;
233
  width: 47px;
234
  height: 49px;
235
  bottom: -1px;
236
  left: 50%;
237
  margin-left: -27px;
238
  z-index: -1;
239
}
240
 
241
.options ul {
242
  margin: 0;
243
  padding: 50px 0 0;
244
  list-style: none;
245
}
246
 
247
.options ul li {
248
  display: block;
249
  font: 40px 'Happy Sans', cursive;
250
  text-align: center;
251
  margin: 0 0 20px;
252
}
253
 
254
.options ul li a {
255
  color: #FFEEAA;
256
  text-decoration: none;
257
}
258
 
259
.options ul li:first-child {
260
  background: url(http://i.imgur.com/ou5JQ.png) no-repeat top center;
261
  height: 70px;
262
  line-height: 70px;
263
}
264
 
265
.options ul li:nth-child(2) {
266
  background: url(http://i.imgur.com/uq5EF.png) no-repeat top center;
267
  height: 63px;
268
  line-height: 63px;
269
}
270
 
271
.options ul li:last-child {
272
  background: url(http://i.imgur.com/hRoDZ.png) no-repeat top center;
273
  height: 75px;
274
  line-height: 75px;
275
}
276
 
277
.controls {
278
  width: 200px;
279
  height: 48px;
280
  background: url(http://i.imgur.com/Vmq49.png) no-repeat top center;
281
  margin: 10px auto;
282
  position: absolute;
283
  top: 60%; left: 50%;
284
  margin-top: -24px; margin-left: -100px;
285
}
286
 
287
/* Share Buttons */
288
#share_btns {
289
  max-width: 440px;
290
  overflow: hidden;
291
  margin: 0 auto;
292
}
293
 
294
.share-button {
295
  float: left;
296
  margin-right: 10px;
297
}
298
 
299
#disqus_thread {
300
  max-width: 1000px;
301
  margin: 0 auto;
302
}
303
 
304
#disqus_thread a {
305
  color: red;
306
}
307
 
308
div.comments-button a, div.chrome-button  a{
309
  background-color: #52a8e8;
310
  background-image: -webkit-linear-gradient(top, #52a8e8, #377ad0);
311
  background-image: -moz-linear-gradient(top, #52a8e8, #377ad0);
312
  background-image: -ms-linear-gradient(top, #52a8e8, #377ad0);
313
  background-image: -o-linear-gradient(top, #52a8e8, #377ad0);
314
  background-image: linear-gradient(top, #52a8e8, #377ad0);
315
  color: #fff;
316
  font: normal 11px "open sans", sans-serif;
317
  line-height: 1;
318
  padding: 3px 5px;
319
  text-align: center;
320
  text-decoration: none;
321
  width: 112px;
322
  border-radius: 3px;
323
}
324
 
325
div.comments-button a:hover {
326
    background-color: #3e9ee5;
327
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #3e9ee5), color-stop(100%, #206bcb));
328
    background-image: -webkit-linear-gradient(top, #3e9ee5 0%, #206bcb 100%);
329
    background-image: -moz-linear-gradient(top, #3e9ee5 0%, #206bcb 100%);
330
    background-image: -ms-linear-gradient(top, #3e9ee5 0%, #206bcb 100%);
331
    background-image: -o-linear-gradient(top, #3e9ee5 0%, #206bcb 100%);
332
    background-image: linear-gradient(top, #3e9ee5 0%, #206bcb 100%);
333
}
334
 
335
div.chrome-button {
336
  float: none;
337
  display: block;
338
  margin: 0 auto;
339
  width: 200px;
340
}
341
 
342
div.chrome-button a {
343
  width: 200px;
344
  display: block;
345
  margin: 20px auto;
346
  font-size: 13px;
347
  padding: 10px;
348
  background-image: -webkit-linear-gradient(top, #5587da, #4d7cd6);
349
  background-image: -moz-linear-gradient(top, #5587da, #4d7cd6);
350
  background-image: -ms-linear-gradient(top, #5587da, #4d7cd6);
351
  background-image: -o-linear-gradient(top, #5587da, #4d7cd6);
352
  background-image: linear-gradient(top, #5587da, #4d7cd6);
353
  box-shadow: inset 0px 2px 0px rgba(255, 255, 255, 0.4);
354
}
 
JavaScript
(function() {
1
(function() {
2
 
3
  window.utils = window.utils || {};
4
 
5
  /*
6
  Random Number Generator.
7
  
8
  Pretty awesome explanation here:
9
  http://stackoverflow.com/a/1527820
10
  */
11
  utils.randomNumber = function(min, max) {
12
    return Math.floor(Math.random() * (max - min + 1)) + min;
13
  };
14
 
15
  utils.isInt = function(number) {
16
    return parseFloat(number) === parseInt(number);
17
  };
18
 
19
  utils.toRadian = function(degree) {
20
    return (degree * Math.PI/180);
21
  };
22
 
23
  utils.toDegree = function(radian) {
24
    return (radian * 180/Math.PI);
25
  };
26
 
27
  utils.intersect = function(bounds1, bounds2) {
28
 
29
    return !(
30
      bounds1.end_x < bounds2.start_x ||
31
      bounds2.end_x < bounds1.start_x ||
32
      bounds1.end_y < bounds2.start_y ||
33
      bounds2.end_y < bounds1.start_y
34
    );
35
    
36
  };
37
 
38
}());(function() {
39
 
40
  mit.Backgrounds = {
41
 
42
    // Speeds and Velocities of Backgrounds
43
    common_bg_speed: 1,
44
 
45
    cloud_bg_move_speed: 0,
46
    cloud_bg_vx: 0,
47
 
48
    backtree_bg_move_speed: 0,
49
    backtree_bg_vx: 0,
50
 
51
    fronttree_bg_move_speed: 0,
52
    fronttree_bg_vx: 0,
53
 
54
    ground_bg_move_speed: 0,
55
    ground_bg_vx: 0,
56
 
57
    combined_bg_move_speed: 0,
58
    combined_bg_vx: 0,
59
 
60
    log_x: 40,
61
    log_y: 0,
62
 
63
    sky_gradient: {},
64
 
65
    first_speed_inc: 0,
66
    second_speed_inc: 0,
67
    third_speed_inc: 0,
68
 
69
    init: function(ctx) {
70
      // Sky Gradient
71
      this.sky_gradient = ctx.createLinearGradient(0, 0, 0, mit.H);  
72
      this.sky_gradient.addColorStop(0, '#06c4f4');
73
      this.sky_gradient.addColorStop(1, '#7bd4f6');
74
 
75
 
76
      // Clouds
77
      // this.cloud_img = new Image();
78
      // this.cloud_img.src = 'img/clouds.png';
79
      this.cloud_img = mit.image.clouds;
80
 
81
      this.cloud_img.width = mit.W;
82
      this.cloud_img.height = mit.H;
83
 
84
 
85
      // Back Trees
86
      // this.backtree_img = new Image();
87
      // this.backtree_img.src = 'img/back_trees.png';
88
      this.backtree_img = mit.image.backtrees;
89
 
90
      this.backtree_img.width = mit.W;
91
      this.backtree_img.height = mit.H;
92
 
93
 
94
      // Front Trees
95
      // this.fronttree_img = new Image();
96
      // this.fronttree_img.src = 'img/front_trees.png';
97
      this.fronttree_img = mit.image.fronttrees;
98
 
99
      this.fronttree_img.width = mit.W;
100
      this.fronttree_img.height = mit.H;
101
 
102
 
103
      // Ground
104
      // this.ground_img = new Image();
105
      // this.ground_img.src = 'img/ground.png';
106
      this.ground_img = mit.image.ground;
107
 
108
      this.ground_img.width = mit.W;
109
      this.ground_img.height = mit.H;
110
 
111
 
112
      // Grass
113
      // this.grass_img = new Image();
114
      // this.grass_img.src = 'img/grass.png';
115
      this.grass_img = mit.image.grass;
116
 
117
      this.grass_img.width = mit.W;
118
      this.grass_img.height = mit.H;
119
 
120
 
121
      // Log on which pappu sits
122
      // this.log_img = new Image();
123
      // this.log_img.src = 'img/log.png';
124
      this.log_img = mit.image.log;
125
 
126
 
127
      // Combined BG Image
128
      // this.combined_bg_img = new Image();
129
      // this.combined_bg_img.src = 'img/bg_combined.png';
130
      this.combined_bg_img = mit.image.bg_combined;
131
 
132
      // Reset all speed
133
      this.resetAllSpeed();
134
    },
135
 
136
    resetAllSpeed: function() {
137
        this.cloud_bg_move_speed = 2;
138
        this.backtree_bg_move_speed = 3;
139
        this.fronttree_bg_move_speed = 5;
140
        this.ground_bg_move_speed = 7;
141
        
142
        this.combined_bg_move_speed = 3;
143
    },
144
 
145
    drawClouds: function(ctx) {
146
      var cloud_bg_vx_abs = Math.abs(this.cloud_bg_vx);
147
 
148
      // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE
149
      try {
150
        ctx.drawImage(
151
          this.cloud_img,
152
 
153
          cloud_bg_vx_abs,
154
          0,
155
          mit.W + this.cloud_bg_vx,
156
          mit.H,
157
 
158
          0, 0,
159
          mit.W + this.cloud_bg_vx,
160
          mit.H
161
        );
162
 
163
        ctx.drawImage(
164
          this.cloud_img,
165
 
166
          0, 0,
167
          cloud_bg_vx_abs,
168
          mit.H,
169
 
170
          mit.W + this.cloud_bg_vx,
171
          0,
172
          cloud_bg_vx_abs,
173
          mit.H
174
        );
175
      }
176
      catch(e) {}
177
      this.cloud_bg_vx -= this.cloud_bg_move_speed;
178
 
179
      if (-this.cloud_bg_vx >= mit.W) {
180
        this.cloud_bg_vx = 0;
181
      }
182
 
183
      return;
184
    },
185
 
186
    drawBackTrees: function(ctx) {
187
      var backtree_bg_vx_abs = Math.abs(this.backtree_bg_vx);
188
 
189
      // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE
190
      try {
191
        ctx.drawImage(
192
          this.backtree_img,
193
 
194
          backtree_bg_vx_abs,
195
          0,
196
          mit.W + this.backtree_bg_vx,
197
          mit.H,
198
 
199
          0, 0,
200
          mit.W + this.backtree_bg_vx,
201
          mit.H
202
        );
203
 
204
        ctx.drawImage(
205
          this.backtree_img,
206
 
207
          0, 0,
208
          backtree_bg_vx_abs,
209
          mit.H,
210
 
211
          mit.W + this.backtree_bg_vx,
212
          0,
213
          backtree_bg_vx_abs,
214
          mit.H
215
        );
216
      }
217
      catch(e) {}
218
 
219
      if (mit.game_started)
220
        this.backtree_bg_vx -= this.backtree_bg_move_speed * this.common_bg_speed;
221
 
222
      if (-this.backtree_bg_vx >= mit.W) {
223
        this.backtree_bg_vx = 0;
224
      }
225
 
226
      return;
227
    },
228
 
229
    drawFrontTrees: function(ctx) {
230
      var fronttree_bg_vx_abs = Math.abs(this.fronttree_bg_vx);
231
 
232
      // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE
233
      try {
234
        ctx.drawImage(
235
          this.fronttree_img,
236
 
237
          fronttree_bg_vx_abs,
238
          0,
239
          mit.W + this.fronttree_bg_vx,
240
          mit.H,
241
 
242
          0, 0,
243
          mit.W + this.fronttree_bg_vx,
244
          mit.H
245
        );
246
 
247
        ctx.drawImage(
248
          this.fronttree_img,
249
 
250
          0, 0,
251
          fronttree_bg_vx_abs,
252
          mit.H,
253
 
254
          mit.W + this.fronttree_bg_vx,
255
          0,
256
          fronttree_bg_vx_abs,
257
          mit.H
258
        );
259
      }
260
      catch(e) {}
261
      if (mit.game_started)
262
        this.fronttree_bg_vx -= this.fronttree_bg_move_speed * this.common_bg_speed;
263
 
264
      if (-this.fronttree_bg_vx >= mit.W) {
265
        this.fronttree_bg_vx = 0;
266
      }
267
 
268
      return;
269
    },
270
 
271
    drawGround: function(ctx) {
272
      var ground_bg_vx_abs = Math.abs(this.ground_bg_vx);
273
      // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE
274
      try {
275
        ctx.drawImage(
276
          this.ground_img,
277
 
278
          ground_bg_vx_abs,
279
          0,
280
          mit.W + this.ground_bg_vx,
281
          mit.H,
282
 
283
          0, 0,
284
          mit.W + this.ground_bg_vx,
285
          mit.H
286
        );
287
 
288
        ctx.drawImage(
289
          this.ground_img,
290
 
291
          0, 0,
292
          ground_bg_vx_abs,
293
          mit.H,
294
 
295
          mit.W + this.ground_bg_vx,
296
          0,
297
          ground_bg_vx_abs,
298
          mit.H
299
        );
300
      }
301
      catch(e) {}
302
 
303
      if (mit.game_started)
304
        this.ground_bg_vx -= this.ground_bg_move_speed * this.common_bg_speed;
305
 
306
      if (-this.ground_bg_vx >= mit.W) {
307
        this.ground_bg_vx = 0;
308
      }
309
 
310
      // console.log(-this.ground_bg_vx);
311
 
312
      return;
313
    },
314
 
315
    drawGrass: function(ctx) {
316
      var grass_bg_vx_abs = Math.abs(this.grass_bg_vx);
317
      // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE
318
      try {
319
        ctx.drawImage(
320
          this.grass_img,
321
 
322
          grass_bg_vx_abs,
323
          0,
324
          mit.W + this.grass_bg_vx,
325
          mit.H,
326
 
327
          0, 0,
328
          mit.W + this.grass_bg_vx,
329
          mit.H
330
        );
331
 
332
        ctx.drawImage(
333
          this.grass_img,
334
 
335
          0, 0,
336
          grass_bg_vx_abs,
337
          mit.H,
338
 
339
          mit.W + this.grass_bg_vx,
340
          0,
341
          grass_bg_vx_abs,
342
          mit.H
343
        );
344
      }
345
      catch(e) {}
346
 
347
      if (mit.game_started)
348
        this.grass_bg_vx -= this.grass_bg_move_speed * this.common_bg_speed;
349
 
350
      if (-this.grass_bg_vx >= mit.W) {
351
        this.grass_bg_vx = 0;
352
      }
353
 
354
      return;
355
    },
356
 
357
    drawInitLog: function(ctx) {
358
 
359
      this.log_y = mit.H-(this.log_img.height+45);
360
 
361
      ctx.drawImage(this.log_img, this.log_x, this.log_y);
362
 
363
      if (mit.game_started) {
364
        this.log_x -= this.ground_bg_move_speed * this.common_bg_speed;
365
      }
366
    },
367
 
368
    drawCombinedBG: function(ctx) {
369
      var combined_bg_vx_abs = Math.abs(this.combined_bg_vx);
370
      // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE
371
      try {
372
        ctx.drawImage(
373
          this.combined_bg_img,
374
 
375
          combined_bg_vx_abs,
376
          0,
377
          mit.W + this.combined_bg_vx,
378
          mit.H,
379
 
380
          0, 0,
381
          mit.W + this.combined_bg_vx,
382
          mit.H
383
        );
384
 
385
        ctx.drawImage(
386
          this.combined_bg_img,
387
 
388
          0, 0,
389
          combined_bg_vx_abs,
390
          mit.H,
391
 
392
          mit.W + this.combined_bg_vx,
393
          0,
394
          combined_bg_vx_abs,
395
          mit.H
396
        );
397
      }
398
      catch(e) {}
399
 
400
      if (mit.game_started)
401
        this.combined_bg_vx -= this.combined_bg_move_speed * this.common_bg_speed;
402
 
403
      if (-this.combined_bg_vx >= mit.W) {
404
        this.combined_bg_vx = 0;
405
      }
406
    },
407
 
408
    // Draw Awesome Backgrounds
409
    // Backgrounds have been made for 1000x500 dimensions
410
    draw: function(ctx) {
411
 
412
      if (mit.start_btn_clicked) {
413
        if (!this.fps || this.fps === 5000)
414
          this.fps = mit.fps;
415
      }
416
      else {
417
        this.fps = 5000;
418
      }
419
 
420
 
421
      if (this.fps > 56) {
422
 
423
        // Draw Linear Gradient for real/pure BG (sky/water)
424
        ctx.save();
425
        ctx.fillStyle = this.sky_gradient;
426
        ctx.fillRect(0, 0, mit.W, mit.H);
427
        ctx.restore();
428
 
429
        // Clouds
430
        this.drawClouds(ctx);
431
        
432
        // Back Small Trees
433
        this.drawBackTrees(ctx);
434
 
435
        // Front Big Trees
436
        this.drawFrontTrees(ctx);
437
      }
438
      else {
439
        this.drawCombinedBG(ctx);
440
      }
441
 
442
      // Drawing the initial wood log on which
443
      // Pappu gonna sit and bask in the cool and cozy
444
      // environment.
445
      if (this.log_x+100 > 0) {
446
        this.drawInitLog(ctx);
447
      }
448
      else if (!mit.game_started) {
449
        this.log_x = 40;
450
      }
451
 
452
      // Draw Ground now!
453
      this.drawGround(ctx);
454
 
455
 
456
      // Increasing speed based on points
457
      if (mit.score > 200 && !this.first_speed_inc) {
458
        this.cloud_bg_move_speed++;
459
        this.backtree_bg_move_speed++;
460
        this.fronttree_bg_move_speed++;
461
        this.ground_bg_move_speed++;
462
        this.combined_bg_move_speed++;
463
 
464
        this.first_speed_inc = 1;
465
      }
466
 
467
      if (mit.score > 1000 && !this.second_speed_inc) {
468
        this.cloud_bg_move_speed++;
469
        this.backtree_bg_move_speed++;
470
        this.fronttree_bg_move_speed++;
471
        this.ground_bg_move_speed++;
472
        this.combined_bg_move_speed++;
473
 
474
        this.second_speed_inc = 1;
475
      }
476
 
477
      if (mit.score > 3000 && !this.third_speed_inc) {
478
        this.cloud_bg_move_speed++;
479
        this.backtree_bg_move_speed++;
480
        this.fronttree_bg_move_speed++;
481
        this.ground_bg_move_speed++;
482
        this.combined_bg_move_speed++;
483
 
484
        this.third_speed_inc = 1;
485
      }
486
 
487
    }
488
 
489
  };
490
 
491
}());(function() {
492
 
493
  // The Fork Class
494
  // We'll have lots of forks.
495
  // Each fork will be on object of this
496
  // constructor.
497
 
498
  mit.Fork = function() {
499
    // Handle x/y
500
    this.x = 0;
501
    this.y = 0;
502
 
503
    // W/H
504
    this.w = 0;
505
    this.h = 0;
506
 
507
 
508
    // Head x/y
509
    this.head_x = 0;
510
    this.head_y = 0;
511
 
512
    // Head W/H
513
    this.head_w = 0;
514
    this.head_h = 0;
515
 
516
    // Edge on which the fork will stand on
517
    this.edge = 'btm';
518
 
519
    // Get Handle Bounds
520
    this.getHandleBounds =  function() {
521
      var b = {};
522
 
523
      b.start_x = this.x;
524
      b.start_y = this.y;
525
      b.end_x   = this.x + this.w;
526
      b.end_y   = this.y + this.h;
527
 
528
      //console.log(bounds);
529
      return b;
530
    };
531
 
532
    // Get Head Bounds
533
    this.getHeadBounds = function() {
534
      var b = {};
535
 
536
      b.start_x = this.head_x;
537
      b.start_y = this.head_y;
538
      b.end_x   = this.head_x + this.head_w;
539
      b.end_y   = this.head_y + this.head_h;
540
 
541
      return b;
542
    };
543
  };
544
 
545
  
546
  // A ForkUtils class to help save the world
547
 
548
  mit.ForkUtils = {
549
 
550
    // Master array of all existing forks in memory
551
    forks: [],
552
    // Forks can be placed on top/bottom edges
553
    edges: ['top', 'btm'],
554
 
555
    // Images for fork handle, fork head and the digged part
556
    fork_img: {},
557
    fork_head_img: {},
558
    dig_img: {},
559
 
560
    // How many forks to have in memory ?
561
    count: 6,
562
 
563
    init: function() {
564
      // Loading Images
565
 
566
      // Fork handle
567
      // this.fork_img = new Image();
568
      // this.fork_img.src = 'img/fork_handle.png';
569
      this.fork_img = mit.image.fork_handle;
570
 
571
      // Fork Head
572
      // this.fork_head_img = new Image();
573
      // this.fork_head_img.src = 'img/fork_head.png';
574
      this.fork_head_img = mit.image.fork_head;
575
 
576
      // Dig Image
577
      // this.dig_img = new Image();
578
      // this.dig_img.src = 'img/dig.png';
579
    },
580
 
581
    /*
582
      How do we go about positioning forks exactly ?
583
 
584
      - Forks can appear on top or bottom edge.
585
      - Forks should vary in sizes, but should be
586
        mostly long to produce a harder gameplay.
587
      - Forks should appear at random distance.
588
        But there needs to be a range (or capping).
589
      - Every fork object should know what edge it
590
        is put on. This will help us calculate the
591
        exact height based on entire canvas
592
        height/width.
593
        This means, we only need the x/y position
594
        along with the edge, to put on the fork.
595
    */
596
 
597
    /*
598
      This method will generate a random x/y
599
      position for the forks to start at.
600
 
601
      Based on the `fork.edge` we can draw
602
      the fork easily on the canvas edges.
603
    */
604
 
605
    getRandomForkPos: function() {
606
      // We have access to `forks` here
607
      var pos = {};
608
 
609
      if (this.forks[this.forks.length-1]) {
610
        pos.x = this.forks[this.forks.length-1].x;
611
 
612
        if (mit.score > 2500)
613
          pos.x += utils.randomNumber(300,600);
614
        else
615
          pos.x += utils.randomNumber(500,800);
616
      }
617
      else {
618
        pos.x = mit.W/1000 * 1050;
619
      }
620
 
621
      var branches = mit.BranchUtils.branches;
622
      /*var last_branch = [branches.length-1];
623
 
624
      if (last_branch) {
625
        if (Math.abs(pos.x - last_branch.x) < 300)
626
          pos.x = last_branch.x + 300;
627
      }*/
628
 
629
      if (branches.length) {
630
        branches.forEach(function(branch) {
631
          if (Math.abs(pos.x - branch.x) < 500)
632
            pos.x = branch.x + 500;
633
        });
634
      }
635
 
636
      return pos;
637
    },
638
 
639
    create: function() {
640
      var fork_img = this.fork_img,
641
          dig_img = this.dig_img,
642
          fork_head_img = this.fork_head_img,
643
          forks = this.forks,
644
          count = this.count;
645
 
646
      if (forks.length < count) {
647
        
648
        for (var i = 0; i < count - forks.length; i++) {
649
          var fork = new mit.Fork();
650
 
651
          // Setting a Random Edge
652
          fork.edge = this.edges[utils.randomNumber(0,1)];
653
 
654
          // Setting the Dig Position
655
          if (fork.edge === 'btm') {
656
            var dig_rand = utils.randomNumber(3,5);
657
 
658
            fork.dig_x = dig_img.width / dig_rand;
659
            fork.dig_y = mit.H - dig_img.height;
660
            // console.log(this.dig_img.width);
661
 
662
            fork.y = 200 + utils.randomNumber(0,100);
663
            fork.y += fork_head_img.height;
664
          }
665
 
666
          if (fork.edge === 'top') {
667
            fork.y = 0 - utils.randomNumber(0,100);
668
            fork.y -= fork_head_img.height;
669
          }
670
 
671
          var pos = this.getRandomForkPos();
672
          fork.x = pos.x;
673
 
674
          // Height and Width
675
          fork.w = fork_img.width;
676
          fork.h = fork_img.height;
677
 
678
          forks.push(fork);
679
        }
680
        
681
      }
682
    },
683
 
684
    draw: function(ctx) {
685
      var fork_img = this.fork_img,
686
          dig_img = this.dig_img,
687
          fork_head_img = this.fork_head_img,
688
          forks = this.forks,
689
          dead_forks = 0;
690
 
691
      this.create();
692
      
693
      // Loop over forks and draw each of them
694
      forks.forEach(function(fork, index) {
695
 
696
        fork.x -= mit.Backgrounds.ground_bg_move_speed;
697
 
698
        if (fork.x + fork.w < 0) {
699
          ++dead_forks;
700
          return;
701
        }
702
 
703
        // Out of view port, no need to draw
704
        if (fork.x > mit.W) {
705
          // console.log('out of view port');
706
          return;
707
        }
708
 
709
        if (fork.edge === 'top') {
710
          // ctx.lineTo(fork.x, 0);
711
 
712
          // Top forks need flippin
713
          ctx.save();
714
          ctx.translate(fork.x, fork.y);
715
          ctx.translate(~~(fork_img.width/2), ~~(fork_img.height/2));
716
          ctx.rotate( utils.toRadian(180) );
717
          ctx.drawImage(fork_img, -~~(fork_img.width/2), -~~(fork_img.height/2));
718
          ctx.restore();
719
 
720
 
721
          fork.head_x = fork.x-~~(fork_head_img.width/8);
722
          fork.head_y = fork.y+fork_img.height;
723
 
724
          fork.head_w = fork_head_img.width;
725
          fork.head_h = fork_head_img.height;
726
 
727
          // Draw Fork Head
728
          ctx.save();
729
          ctx.translate(fork.head_x, fork.head_y);
730
          ctx.translate(~~(fork_head_img.width/2), ~~(fork_head_img.height/2));
731
          ctx.rotate( utils.toRadian(180) );
732
          ctx.drawImage(fork_head_img, -~~(fork_head_img.width/2), -~~(fork_head_img.height/2));
733
          ctx.restore();
734
        }
735
        else if (fork.edge === 'btm') {
736
 
737
          ctx.drawImage(fork_img, fork.x, fork.y);
738
 
739
          fork.head_x = fork.x-~~(fork_head_img.width/5);
740
          fork.head_y = fork.y-fork_head_img.height;
741
 
742
          fork.head_w = fork_head_img.width;
743
          fork.head_h = fork_head_img.height;
744
 
745
          // Draw Fork Head
746
          ctx.save();
747
          ctx.translate(fork.head_x, fork.head_y);
748
          ctx.translate(1* ~~(fork_head_img.width/2), 1* ~~(fork_head_img.height/2));
749
          ctx.scale(-1,1);
750
          ctx.drawImage(
751
            fork_head_img,
752
            1* -~~(fork_head_img.width/2),
753
            1* -~~(fork_head_img.height/2)
754
          );
755
          ctx.restore();
756
        }
757
 
758
      });
759
 
760
      if (dead_forks) {
761
        forks.splice(0, dead_forks);
762
      }
763
 
764
      return;
765
    },
766
 
767
    // Forks have black digs in grounds
768
    // This function will draw those
769
    drawDigs: function(ctx) {
770
      // Loop over forks and draw digs for each of them
771
      var dig_img = this.dig_img;
772
 
773
      this.forks.forEach(function(fork, index) {
774
 
775
        if (fork.edge === 'btm') {
776
          ctx.drawImage(dig_img, fork.x - fork.dig_x, fork.dig_y);
777
        }
778
 
779
      });
780
    },
781
 
782
    // Check Fork Collision
783
    checkCollision: function() {
784
      var first_fork = this.forks[0];
785
 
786
      // Useless optimization
787
      if (first_fork.x > mit.W/2)
788
        return;
789
 
790
      // Get Pappu Bounds
791
      var pappu_bounds = mit.Pappu.getBounds(),
792
          // Get Nearest Fork's Handle's Bounds
793
          fork_bounds = first_fork.getHandleBounds();
794
      
795
      // Check whether pappu collided with the
796
      // fork handle or not.
797
      if (utils.intersect(pappu_bounds, fork_bounds)) {
798
        // console.log(pappu_bounds, fork_bounds);
799
        mit.gameOver();
800
      }
801
 
802
      // We'll have to check for collision with fork heads.
803
      // If there's a collision pappu will be pushed!
804
      var fork_head_bounds = first_fork.getHeadBounds();
805
 
806
      // Check whether pappu collided with the
807
      // fork head or not. With fork heads
808
      // collision detection checks would be
809
      // a little casual than super stern.
810
 
811
      // if (utils.intersect(pappu_bounds, fork_head_bounds)) {
812
 
813
      if (
814
        pappu_bounds.end_x      >  fork_head_bounds.start_x+20 &&
815
        fork_head_bounds.end_x-20  >  pappu_bounds.start_x &&
816
        pappu_bounds.end_y      >  fork_head_bounds.start_y+20 &&
817
        fork_head_bounds.end_y-20  >  pappu_bounds.start_y
818
      ) {
819
        mit.gameOver();
820
      }
821
    }
822
 
823
  };
824
 
825
}());(function() {
826
 
827
  // We're having lots of forks to
828
  // make gameplay a little harder
829
  // and incorporate ggo's required concepts.
830
 
831
  // But we'll also try to incorporate
832
  // 'branching' by adding some branches
833
  // at random spots. So let the forks
834
  // come, but sometimes there wont be forks,
835
  // but a single branch (from top to bottom).
836
  // 
837
  // The branches are gonna have a little hole
838
  // in between or some other random position
839
  // through which pappu will need to pass.
840
  // 
841
  // If it collides at some part other than
842
  // the hole, he'll decease.
843
 
844
  mit.Branch = function() {
845
    this.x = 0;
846
    this.y = 0;
847
 
848
    // Width
849
    this.w;
850
    // Height
851
    this.h;
852
 
853
    this.escape_x;
854
    this.escape_y;
855
    this.escape_w;
856
    this.escape_h;
857
 
858
    this.getBounds = function() {
859
      var b = {};
860
 
861
      b.start_x = this.x;
862
      b.start_y = this.y;
863
      b.end_x   = this.x + this.w;
864
      b.end_y   = this.y + this.h;
865
 
866
      return b;
867
    };
868
 
869
    this.getEscapeBounds = function() {
870
      var b = {};
871
 
872
      b.start_x = this.escape_x;
873
      b.start_y = this.escape_y;
874
      b.end_x   = this.escape_x + this.escape_w;
875
      b.end_y   = this.escape_y + this.escape_h;
876
 
877
      return b;
878
    };
879
  };
880
 
881
 
882
  mit.BranchUtils = {
883
 
884
    branch_img: {},
885
 
886
    branches: [],
887
    count: 4,
888
 
889
    init: function() {
890
      // Load Images
891
      // this.branch_img = new Image();
892
      // this.branch_img.src = 'img/branch.png';
893
 
894
      this.branch_img = mit.image.branch;
895
    },
896
 
897
    /*
898
      This method will generate a random x/y
899
      position for the forks to start at.
900
 
901
      Based on the `fork.edge` we can draw
902
      the fork easily on the canvas edges.
903
    */
904
    getRandomBranchPos: function() {
905
      // We have access to `branches` here
906
      var pos = {};
907
 
908
      if (this.branches[this.branches.length-1]) {
909
        pos.x = this.branches[this.branches.length-1].x;
910
        pos.x += utils.randomNumber(500, 2000);
911
      }
912
      else {
913
        // First
914
        pos.x = utils.randomNumber(2000, 2500);
915
      }
916
 
917
      var forks = mit.ForkUtils.forks;
918
      /*var last_fork = forks[forks.length-1];
919
      
920
      if (last_fork) {
921
 
922
        if (Math.abs(pos.x - last_fork.x) < 300) {
923
          pos.x = last_fork.x + 300;
924
        }
925
      }*/
926
 
927
      if (forks.length) {
928
        forks.forEach(function(fork) {
929
          if (Math.abs(pos.x - fork.x) < 500)
930
            pos.x = fork.x + 500;
931
        });
932
      }
933
 
934
      return pos;
935
    },
936
 
937
    create: function() {
938
      var branches = this.branches,
939
          count = this.count;
940
 
941
      if (branches.length < count) {
942
      
943
        for (var i = 0; i < count - branches.length; i++) {
944
          var branch = new mit.Branch();
945
 
946
          var pos = this.getRandomBranchPos();
947
          branch.x = pos.x;
948
          branch.y = 0;
949
 
950
          branch.w = this.branch_img.width;
951
          branch.h = this.branch_img.height;
952
 
953
          // Escape Positions
954
          branch.escape_x = branch.x;
955
          branch.escape_y = branch.y + utils.randomNumber(0, branch.h-150);
956
 
957
          // Escape Area's Width/Height
958
          branch.escape_w = this.branch_img.width;
959
          branch.escape_h = 150;
960
 
961
          branches.push(branch);
962
        }
963
    }
964
    },
965
 
966
    draw: function(ctx) {
967
      var branches = this.branches,
968
          branch_img = this.branch_img,
969
          dead_branch = 0;
970
 
971
      this.create();
972
 
973
      // console.log(branches);
974
 
975
      // Loop over branches and draw each of them
976
      branches.forEach(function(branch, index) {
977
 
978
        branch.x -= mit.Backgrounds.ground_bg_move_speed;
979
 
980
        if (branch.x + branch.w < 0) {
981
          dead_branch++;
982
          return;
983
        }
984
 
985
        // Out of view port, no need to draw
986
        if (branch.x > mit.W)
987
          return;
988
 
989
        // Escape Positions
990
        branch.escape_x = branch.x;
991
 
992
        ctx.drawImage(branch_img, branch.x, branch.y);
993
 
994
        // Draw Escapes
995
        ctx.save();
996
        ctx.globalCompositeOperation = 'destination-out';
997
        ctx.fillStyle = 'white';
998
        ctx.fillRect(
999
          branch.escape_x,
1000
          branch.escape_y,
1001
          branch.escape_w,
1002
          branch.escape_h
1003
        );
1004
        ctx.restore();
1005
      });
1006
 
1007
      if (dead_branch) {
1008
        branches.splice(0, dead_branch);
1009
      }
1010
 
1011
      return;
1012
    },
1013
 
1014
    // Check collisions with branches
1015
    checkCollision: function() {
1016
      var first_branch = this.branches[0];
1017
 
1018
      // Useless optimization
1019
      if (first_branch.x > mit.W/2)
1020
        return;
1021
 
1022
      // Get Pappu Bounds
1023
      var pappu_bounds = mit.Pappu.getBounds(),
1024
          // Get Nearest Branch's Top Part's Bounds
1025
          branch_bounds = first_branch.getBounds();
1026
 
1027
      if (utils.intersect(pappu_bounds, branch_bounds)) {
1028
        // console.log(pappu_bounds, branch_bounds);
1029
 
1030
        // If the Escape Area intersects then pappu
1031
        // can escape, else game over matey!
1032
        var escape_bounds = first_branch.getEscapeBounds();
1033
 
1034
        if (!utils.intersect(pappu_bounds, escape_bounds)) {
1035
          mit.gameOver();
1036
        }
1037
 
1038
      }
1039
 
1040
      return;
1041
    }
1042
 
1043
  };
1044
 
1045
}());(function() {
1046
 
1047
  /*
1048
  We'll have some collectibles:
1049
 
1050
  - Ones that give 50, 100, 500, 1000 points.
1051
 
1052
  - One to clone pappu that'll kill all
1053
    forks, branches, pakias.
1054
 
1055
  - One for pappu's invincibility
1056
  */
1057
  
1058
  mit.Collectible = function() {
1059
 
1060
    // x/y pos
1061
    this.x;
1062
    this.y;
1063
 
1064
    // width/height
1065
    this.w;
1066
    this.h;
1067
 
1068
    // Collectible Type - read above
1069
    this.type;
1070
 
1071
    // Sound
1072
    this.sound = document.getElementById("ting");
1073
    this.sound.volume = 0.35;
1074
 
1075
    // Some collectible types may have subtypes
1076
    // like coins of 50, 100, 500, 1000 and so on ...
1077
    this.sub_type;
1078
 
1079
    this.getBounds = function() {
1080
      var b = {};
1081
 
1082
      b.start_x = this.x;
1083
      b.start_y = this.y;
1084
      b.end_x   = this.x + this.w;
1085
      b.end_y   = this.y + this.h;
1086
 
1087
      return b;
1088
    };
1089
 
1090
 
1091
    this.draw = function(ctx) {
1092
      switch (this.type) {
1093
 
1094
        case 'coin':
1095
          this.drawCoin(ctx);
1096
          break;
1097
 
1098
        case 'clone':
1099
          this.drawClone(ctx);
1100
          break;
1101
 
1102
        case 'invincible':
1103
          this.drawInvincible(ctx);
1104
          break;
1105
 
1106
      }
1107
 
1108
      return;
1109
    };
1110
 
1111
    this.drawCoin = function(ctx) {
1112
      // Get coin color based on sub type
1113
      var pos = mit.CollectibleUtils.getCoinSpritePos(this.sub_type);
1114
 
1115
      ctx.drawImage(
1116
        mit.CollectibleUtils.coin_img,
1117
        pos.x, pos.y,
1118
        30, 30,
1119
        this.x, this.y,
1120
        30, 30
1121
      );
1122
    };
1123
 
1124
    this.drawClone = function(ctx) {
1125
      ctx.drawImage(
1126
        mit.CollectibleUtils.clone_img,
1127
        this.x,
1128
        this.y
1129
      );
1130
    };
1131
 
1132
    this.drawInvincible = function(ctx) {
1133
      ctx.drawImage(
1134
        mit.CollectibleUtils.invincible_img,
1135
        this.x,
1136
        this.y
1137
      );
1138
    };
1139
  };
1140
 
1141
 
1142
  mit.CollectibleUtils = {
1143
 
1144
    collecs: [],
1145
 
1146
    count: 2,
1147
 
1148
    types: ['coin', 'clone', 'invincible'],
1149
    //types: ['invincible'],
1150
 
1151
    sub_types: {
1152
      coin: [50, 100, 500]
1153
    },
1154
 
1155
    init: function() {
1156
      // this.coin_img = new Image();
1157
      // this.coin_img.src = 'img/coins.png';
1158
      this.coin_img = mit.image.coins;
1159
 
1160
      // this.clone_img = new Image();
1161
      // this.clone_img.src = 'img/berries.png';
1162
      this.clone_img = mit.image.berries;
1163
 
1164
      // this.invincible_img = new Image();
1165
      // this.invincible_img.src = 'img/star.png';
1166
      this.invincible_img = mit.image.star;
1167
    },
1168
 
1169
    getCoinSpritePos: function(sub_type) {
1170
 
1171
      switch (sub_type) {
1172
        case 50:
1173
          // Yellow (first)
1174
          return {x: 0, y: 0};
1175
 
1176
        case 100:
1177
          // Pink (second)
1178
          return {x: 30, y: 0};
1179
 
1180
        case 500:
1181
          // Red (third)
1182
          // Pink (second)
1183
          return {x: 60, y: 0};
1184
 
1185
        case 1000:
1186
          // Blue (last)
1187
          return {x: 90, y: 0};
1188
      }
1189
 
1190
    },
1191
 
1192
    getRandomPos: function() {
1193
      var pos = {};
1194
 
1195
      var last = this.collecs[this.collecs.length - 1];
1196
 
1197
      if (last) {
1198
        pos.x = last.x + utils.randomNumber(1000, 1500);
1199
      }
1200
      else {
1201
        pos.x = utils.randomNumber(2000, 3000);
1202
        pos.x = utils.randomNumber(500, 1000);
1203
      }
1204
 
1205
      pos.y = utils.randomNumber(100, mit.H-100);
1206
 
1207
      // Check Positioning with forks
1208
      var forks = mit.ForkUtils.forks;
1209
 
1210
      if (forks.length) {
1211
        forks.forEach(function(fork) {
1212
          if (Math.abs(pos.x - fork.x) < 300)
1213
            pos.x = fork.x + 300;
1214
        });
1215
      }
1216
 
1217
      // Check Positioning with branches
1218
      var branches = mit.BranchUtils.branches;
1219
 
1220
      if (branches.length) {
1221
        branches.forEach(function(branch) {
1222
          if (Math.abs(pos.x - branch.x) < 300)
1223
            pos.x = branch.x + 300;
1224
        });
1225
      }
1226
 
1227
      return pos;
1228
    },
1229
 
1230
    create: function() {
1231
      var count = this.count - this.collecs.length;
1232
      var collec,
1233
          sub_types,
1234
          pos;
1235
 
1236
      for (var i = 0; i < count; i++) {
1237
        collec = new mit.Collectible();
1238
 
1239
        pos = this.getRandomPos();
1240
 
1241
        collec.x = pos.x;
1242
        collec.y = pos.y;
1243
 
1244
        collec.w = 30;
1245
        collec.h = 30;
1246
 
1247
        // Type
1248
        collec.type = this.types[utils.randomNumber(0, this.types.length-1)];
1249
 
1250
        // Choosing Sub types if any
1251
        sub_types = this.sub_types[collec.type];
1252
        if (sub_types)
1253
          collec.sub_type = sub_types[utils.randomNumber(0, sub_types.length-1)];
1254
 
1255
        this.collecs.push(collec);
1256
      }
1257
    },
1258
 
1259
    draw: function(ctx) {
1260
 
1261
      var self = this;
1262
 
1263
      self.create();
1264
 
1265
      self.collecs.forEach(function(collec, i) {
1266
        if (collec.x < 0) {
1267
          // Moved off the left edge
1268
          /*var pos = self.getRandomPos();
1269
 
1270
          collec.x = pos.x;
1271
          collec.y = pos.y;*/
1272
          self.collecs.splice(i,1);
1273
        }
1274
 
1275
        collec.x -= mit.Backgrounds.ground_bg_move_speed;
1276
 
1277
        collec.draw(ctx);
1278
      });
1279
 
1280
      return;
1281
    },
1282
 
1283
    checkCollision: function() {
1284
      // First collec
1285
      var collec = this.collecs[0],
1286
          // Get Pappu Bounds
1287
          pappu_bounds = mit.Pappu.getBounds(),
1288
          // Get Nearest Collectible Bounds
1289
          collec_bounds = collec.getBounds();
1290
 
1291
      if (utils.intersect(pappu_bounds, collec_bounds)) {
1292
        // Pappu haz collected!
1293
        collec.sound.play();
1294
        // Determine type and perform action accordingly
1295
        switch (collec.type) {
1296
 
1297
          case 'coin':
1298
            mit.score += collec.sub_type;
1299
            break;
1300
 
1301
          case 'clone':
1302
            mit.Pappu.createClones(3);
1303
            break;
1304
 
1305
          case 'invincible':
1306
            mit.Pappu.invincible = 1;
1307
 
1308
            // Kush says we shouldnt add up
1309
            /*if (!mit.Pappu.invincibility_start) {
1310
              mit.Pappu.invincibility_time = 5000;
1311
            }
1312
            else {
1313
              var cur_time = new Date().getTime();
1314
              var prev_remaining_time = cur_time - mit.Pappu.invincibility_start;
1315
 
1316
              mit.Pappu.invincibility_time = 5000 + prev_remaining_time;
1317
            }*/
1318
 
1319
            mit.Pappu.invincibility_start = new Date().getTime();
1320
            mit.Pappu.invincibility_time = 5000;
1321
 
1322
            // Show timer
1323
            mit.ui.invincible_timer.show();
1324
 
1325
            break;
1326
        }
1327
 
1328
        // Nuke the collectible
1329
        this.collecs.shift();
1330
      }
1331
 
1332
      return;
1333
    }
1334
 
1335
  };
1336
 
1337
}());(function() {
1338
 
1339
  // There will be only 1 Pappu
1340
 
1341
  mit.Pappu = {
1342
    x: 50,
1343
    y: 10,
1344
    w: 50,
1345
    h: 50,
1346
 
1347
    invincible: 0,
1348
    invincibility_start: 0,
1349
    invincibility_time: 0,
1350
    clones: [],
1351
 
1352
    rotate_angle: 0,
1353
 
1354
    sprite: {},
1355
    sound: '',
1356
 
1357
    // Rate of sprite frame change
1358
    // per animation frame.
1359
    change_per_frame: 10,
1360
 
1361
    fly_frame_count: 0,
1362
    max_fly_frame_count: 10,
1363
 
1364
    init: function() {
1365
      this.sound = document.getElementById("flap");
1366
 
1367
      // Initializing Pappu Sprite, lolzzz..!
1368
      // this.sprite = new Image();
1369
      // this.sprite.src = 'img/pappu.png';
1370
      this.sprite = mit.image.pappu;
1371
 
1372
      //pappu.w = pappu.sprite.width;
1373
      mit.Pappu.w = mit.Pappu.sprite.width;
1374
      mit.Pappu.h = 60;
1375
 
1376
      // Sprite Frame Count
1377
      mit.Pappu.max_fly_frame_count = 8;
1378
      mit.Pappu.max_fly_frame_count--;
1379
 
1380
      // Sprite Frame Change Speed.
1381
      // This will affect the flap speed.
1382
      // 1.6 is the perfect value!
1383
      mit.Pappu.change_per_frame = 1.6;
1384
 
1385
      // X Pos
1386
      mit.Pappu.x = 33;
1387
    },
1388
 
1389
    undoInvincible: function() {
1390
      this.invincible = 0;
1391
      this.invincibility_start = 0;
1392
      this.invincible_timer = 0;
1393
 
1394
      mit.ui.invincible_timer.hide();
1395
    },
1396
 
1397
    draw: function(ctx) {
1398
      var cur_sprite_frame = this.fly_frame_count / this.change_per_frame;
1399
      
1400
      if (utils.isInt(cur_sprite_frame)) {
1401
        var source_y = cur_sprite_frame * 60;
1402
      }
1403
 
1404
      else {
1405
        //var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)%this.change_per_frame;
1406
 
1407
        // Ultra smooth animations
1408
        var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)
1409
        var source_y = old_sprite_frame * 60;
1410
      }
1411
      
1412
      // console.log(cur_sprite_frame, source_x);
1413
 
1414
      // Rotation on Flying
1415
      if (mit.flying_up) {
1416
        this.sound.play();
1417
 
1418
        if (this.rotate_angle > -15) {
1419
          this.rotate_angle -= 2;
1420
        }
1421
      }
1422
      else if (mit.game_over) {
1423
        // draw() is called as long as
1424
        // pappu hasnt hit boundaries and over'ed the game :P
1425
 
1426
        // Game Over Gugglu!
1427
        this.rotate_angle += 4;
1428
      }
1429
      else {
1430
        if (this.rotate_angle < 30) {
1431
          this.rotate_angle += 2;
1432
        }
1433
      }
1434
 
1435
      ctx.save();
1436
 
1437
      ctx.translate(this.x, this.y);
1438
      ctx.translate(this.w/2, this.h/2);
1439
      ctx.rotate(utils.toRadian(this.rotate_angle));
1440
 
1441
      if (this.invincible) {
1442
        ctx.globalAlpha = 0.4;
1443
 
1444
        // Current time
1445
        var cur_time = new Date().getTime();
1446
        var time_diff = cur_time - this.invincibility_start;
1447
 
1448
        var timer_progress = (time_diff/this.invincibility_time) * 100;
1449
 
1450
        if (timer_progress > 100)
1451
          this.undoInvincible();
1452
        else
1453
          mit.ui.invincible_loader.css('width', timer_progress + '%');
1454
 
1455
        // console.log(timer_progress)
1456
      }
1457
 
1458
      ctx.drawImage(
1459
          this.sprite,
1460
          0,
1461
          source_y,
1462
          this.w,
1463
          60,
1464
          -this.w/2,
1465
          -this.h/2,
1466
          this.w,
1467
          60
1468
        );
1469
 
1470
      ctx.restore();
1471
    },
1472
 
1473
    drawStatic: function(ctx) {
1474
      var cur_sprite_frame = this.fly_frame_count / this.change_per_frame;
1475
      
1476
      if (utils.isInt(cur_sprite_frame)) {
1477
        var source_y = cur_sprite_frame * 60;
1478
      }
1479
 
1480
      else {
1481
        //var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)%this.change_per_frame;
1482
 
1483
        // Ultra smooth animations
1484
        var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)
1485
        var source_y = old_sprite_frame * 60;
1486
      }
1487
 
1488
 
1489
      this.y = mit.Backgrounds.log_y-42;
1490
 
1491
      /*ctx.drawImage(
1492
        this.sprite,
1493
        0,
1494
        0,
1495
        this.w,
1496
        60,
1497
        this.x,
1498
        this.y,
1499
        this.w,
1500
        60
1501
      );*/
1502
      
1503
      ctx.drawImage(
1504
        this.sprite,
1505
        0,
1506
        source_y,
1507
        this.w,
1508
        60,
1509
        this.x,
1510
        this.y,
1511
        this.w,
1512
        60
1513
      );
1514
    },
1515
 
1516
    updateFlyFrameCount: function(count) {
1517
      if (typeof count !== 'number') {
1518
        this.fly_frame_count++;
1519
 
1520
        if (parseInt(this.fly_frame_count/this.change_per_frame) > this.max_fly_frame_count) {
1521
          this.fly_frame_count = 0;
1522
        }
1523
 
1524
        return;
1525
      }
1526
 
1527
      this.fly_frame_count = count;
1528
    },
1529
 
1530
    hasReachedBoundary: function(canvas_width, canvas_height) {
1531
      // Crossed Sides ?
1532
      // `c` stands for crossed
1533
 
1534
      var ctop = (this.y < 0 - this.h);
1535
      var cbtm = (this.y > mit.H);
1536
      var cleft = (this.x < 0);
1537
      var crgt = (this.x > mit.W);
1538
 
1539
      // return true if crossed any sides
1540
      if (ctop || cbtm || cleft || crgt) {
1541
        return true;
1542
      }
1543
 
1544
      return false;
1545
    },
1546
 
1547
    getBounds: function() {
1548
      var b = {};
1549
 
1550
      b.start_x = this.x;
1551
      b.start_y = this.y;
1552
      b.end_x   = this.x + this.w;
1553
      b.end_y   = this.y + this.h;
1554
 
1555
      return b;
1556
    },
1557
 
1558
    createClones: function(count) {
1559
      // This method will be usually called
1560
      // when pappu gathers a 'clone' collectible.
1561
 
1562
      var pappu_clone;
1563
 
1564
      for (var i = 0; i < count; i++) {
1565
        pappu_clone = Object.create(mit.Pappu);
1566
 
1567
        pappu_clone.invincible = 0;
1568
 
1569
        this.clones.push(pappu_clone);
1570
      }
1571
 
1572
      return;
1573
    },
1574
 
1575
    drawClones: function(ctx) {
1576
 
1577
      var self = this;
1578
 
1579
      self.clones.forEach(function(clone, index) {
1580
        if (clone.x > mit.W || clone.y < 0 || clone.y > mit.H)
1581
          self.clones.splice(index, 1);
1582
 
1583
        clone.x += utils.randomNumber(5, 10);
1584
        clone.y += utils.randomNumber(-20, 20);
1585
 
1586
        clone.draw(ctx);
1587
      });
1588
 
1589
      return;
1590
    },
1591
 
1592
    checkCloneCollision: function() {
1593
 
1594
      var self = this;
1595
 
1596
      // super optimization :P
1597
      if (!self.clones.length)
1598
        return;
1599
      
1600
      var branches = mit.BranchUtils.branches;
1601
      var forks = mit.ForkUtils.forks;
1602
      var pakias = mit.PakiaUtils.pakias;
1603
 
1604
      // Check collisions with branches
1605
      branches.forEach(function(branch, branch_index) {
1606
        var branch_bound = branch.getBounds();
1607
 
1608
        var branch_broke = 0;
1609
 
1610
        self.clones.forEach(function(clone) {
1611
 
1612
          if (branch_broke)
1613
            return;
1614
 
1615
          var clone_bound = clone.getBounds();
1616
 
1617
          if (utils.intersect(branch_bound, clone_bound)) {
1618
            branches.splice(branch_index, 1);
1619
 
1620
            branch_broke = 1;
1621
          }
1622
        });
1623
 
1624
        return;
1625
      });
1626
 
1627
      // Check collisions with forks
1628
      forks.forEach(function(fork, fork_index) {
1629
        var fork_head_bound = fork.getHeadBounds();
1630
        var fork_handle_bound = fork.getHandleBounds();
1631
 
1632
        var fork_broke = 0;
1633
 
1634
        self.clones.forEach(function(clone) {
1635
 
1636
          if (fork_broke)
1637
            return;
1638
 
1639
          var clone_bound = clone.getBounds();
1640
 
1641
          if (
1642
            utils.intersect(fork_head_bound, clone_bound) ||
1643
            utils.intersect(fork_handle_bound, clone_bound)
1644
          ) {
1645
 
1646
            // 2 pakias could kill same fork
1647
            // hence just check whether it exists or not
1648
            forks.splice(fork_index, 1);
1649
 
1650
            fork_broke = 1;
1651
          }
1652
 
1653
          return;
1654
        });
1655
 
1656
        return;
1657
      });
1658
 
1659
      // Check collisions with pakias
1660
      pakias.forEach(function(pakia, pakia_index) {
1661
        var pakia_bound = pakia.getBounds();
1662
 
1663
        var pakia_dead = 0;
1664
 
1665
        self.clones.forEach(function(clone) {
1666
 
1667
          if (pakia_dead)
1668
            return;
1669
 
1670
          var clone_bound = clone.getBounds();
1671
 
1672
          if (utils.intersect(pakia_bound, clone_bound)) {
1673
            mit.PakiaUtils.cur_pakia = false;
1674
 
1675
            pakia_dead = 1;
1676
          }
1677
 
1678
          return;
1679
        });
1680
 
1681
        return;
1682
      });
1683
 
1684
      return;
1685
    }
1686
  };
1687
 
1688
}());(function() {
1689
 
1690
  mit.Pakia = function() {
1691
 
1692
    // Default type will be angry
1693
    this.type = 'angry';
1694
    this.sound = document.getElementById("jump1");
1695
 
1696
    // Cheating on a bit with the physics
1697
    // cant have same gravity for pappu and pakias :(
1698
    this.gravity = 0.3;
1699
 
1700
    this.x;
1701
    this.y;
1702
    this.w;
1703
    this.h;
1704
 
1705
    this.draw = function(ctx) {
1706
      ctx.drawImage(mit.PakiaUtils.pakia_img[this.type], this.x, this.y);
1707
    };
1708
 
1709
    this.generateRandomPos = function() {
1710
      this.x = mit.config.canvas_width/2 + 200;
1711
      this.y = mit.config.canvas_height;
1712
    };
1713
 
1714
    this.generateRandomVelocity = function() {
1715
      this.vx = -12;
1716
      this.vy = utils.randomNumber(-18,-10);
1717
    };
1718
 
1719
    this.getBounds = function() {
1720
      var bounds = {};
1721
 
1722
      bounds.start_x = this.x;
1723
      bounds.start_y = this.y;
1724
      bounds.end_x = this.x + this.w;
1725
      bounds.end_y = this.y + this.h;
1726
 
1727
      return bounds;
1728
    };
1729
  };
1730
 
1731
 
1732
  mit.PakiaUtils = {
1733
 
1734
    pakias: [],
1735
 
1736
    // Only 1 pakia at once, to make sure
1737
    // gameplay is not terribly hard
1738
    // as forks and branches have already
1739
    // made it quite hard.
1740
    cur_pakia: false,
1741
 
1742
    types: [
1743
      'sad', // pulls
1744
      'happy', // pushes
1745
      'angry' // kills
1746
    ],
1747
 
1748
    // Sounds
1749
    sounds: [
1750
      document.getElementById("angry_jump"),
1751
      document.getElementById("sad_jump"),
1752
      document.getElementById("happy_jump")
1753
    ],      
1754
 
1755
    pakia_img: {
1756
      sad: {},
1757
      happy: {},
1758
      angry: {}
1759
    },
1760
 
1761
    init: function() {
1762
 
1763
      // Loading All Pakia Images
1764
 
1765
      // this.pakia_img.sad = new Image();
1766
      // this.pakia_img.sad.src = 'img/sad_pakia.png';
1767
      this.pakia_img.sad = mit.image.sad_pakia;
1768
 
1769
      // this.pakia_img.happy = new Image();
1770
      // this.pakia_img.happy.src = 'img/happy_pakia.png';
1771
      this.pakia_img.happy = mit.image.happy_pakia;
1772
 
1773
      // this.pakia_img.angry = new Image();
1774
      // this.pakia_img.angry.src = 'img/angry_pakia.png';
1775
      this.pakia_img.angry = mit.image.angry_pakia;
1776
    },
1777
 
1778
    createPakias: function() {
1779
 
1780
      for (var i = 0; i < 3; i++) {
1781
        var pakia = new mit.Pakia();
1782
        pakia.w = this.pakia_img.sad.width;
1783
        pakia.h = this.pakia_img.sad.height;
1784
 
1785
        pakia.generateRandomPos();
1786
 
1787
        pakia.generateRandomVelocity();
1788
 
1789
        pakia.type = this.types[i];
1790
        // pakia.type = this.types[0];
1791
 
1792
        if (pakia.type == 'angry')
1793
          pakia.sound = this.sounds[0];
1794
        else if (pakia.type == 'sad')
1795
          pakia.sound = this.sounds[1];
1796
        else if (pakia.type == 'happy')
1797
          pakia.sound = this.sounds[2];
1798
 
1799
        this.pakias.push(pakia);
1800
      }
1801
 
1802
      //console.log(this.pakias);
1803
    },
1804
 
1805
    reflow: function(ctx) {
1806
 
1807
      if (!this.cur_pakia) {
1808
        // cur_pakia is one thats currently visible
1809
        // that is, in the air!
1810
 
1811
        // Object by Reference!
1812
        this.cur_pakia = this.pakias[utils.randomNumber(0,2)];
1813
 
1814
        this.cur_pakia.generateRandomPos();
1815
        this.cur_pakia.generateRandomVelocity();
1816
      }
1817
 
1818
      this.cur_pakia.vy += this.cur_pakia.gravity;
1819
 
1820
      this.cur_pakia.x += this.cur_pakia.vx;
1821
      this.cur_pakia.y += this.cur_pakia.vy;
1822
      // console.log(this.cur_pakia.x)
1823
 
1824
      // Reset positions
1825
      if (
1826
        this.cur_pakia.x + this.cur_pakia.w < 0 ||
1827
        this.cur_pakia.y > mit.H
1828
        ) {
1829
        this.cur_pakia.generateRandomPos();
1830
 
1831
        this.cur_pakia.generateRandomVelocity();
1832
 
1833
        // Important! since JS's game's all about
1834
        // objects by reference.
1835
        if (this.cur_pakia.has_stuck)
1836
          delete this.cur_pakia.has_stuck;
1837
 
1838
        // wont set the referenced pointer to
1839
        // false, so we're safe :D
1840
        this.cur_pakia = false;
1841
      }
1842
    },
1843
 
1844
    repaint: function(ctx) {
1845
      if (this.cur_pakia)
1846
        this.cur_pakia.draw(ctx);
1847
    },
1848
 
1849
    render: function(ctx) {
1850
      if (!this.pakias.length) {
1851
        this.createPakias();
1852
      }
1853
 
1854
      if (mit.score.toFixed(2) % 20 === 0 || this.cur_pakia) {
1855
        this.reflow(ctx);
1856
        this.repaint(ctx);
1857
      }
1858
 
1859
      if (mit.score.toFixed(2) % 20 === 0 && this.cur_pakia) {
1860
        this.cur_pakia.sound.play();
1861
      }
1862
    },
1863
 
1864
    checkCollision: function() {
1865
      if (!this.cur_pakia)
1866
        return;
1867
 
1868
      var pappu_bounds = mit.Pappu.getBounds();
1869
      var pakia_bounds = this.cur_pakia.getBounds();
1870
 
1871
      if (
1872
        pappu_bounds.end_x     >  pakia_bounds.start_x+20 &&
1873
        pakia_bounds.end_x-20  >  pappu_bounds.start_x    &&
1874
        pappu_bounds.end_y     >  pakia_bounds.start_y+20 &&
1875
        pakia_bounds.end_y-20  >  pappu_bounds.start_y
1876
      ) {
1877
 
1878
        // Depending upon the type of the pakia
1879
        switch (this.cur_pakia.type) {
1880
          case 'angry':
1881
            mit.gameOver();
1882
            break;
1883
 
1884
          case 'sad':
1885
            // Pull
1886
 
1887
            if (!this.cur_pakia.has_stuck) {
1888
              mit.vy += 20;
1889
              this.cur_pakia.y += 20;
1890
              this.cur_pakia.vx = 0;
1891
            }
1892
 
1893
            this.cur_pakia.has_stuck = 1;
1894
 
1895
            break;
1896
 
1897
          case 'happy':
1898
            // Push
1899
 
1900
            if (this.cur_pakia.vy < 0)
1901
              mit.vy -= 10;
1902
            else
1903
              mit.vy += 10;
1904
 
1905
            break;
1906
        }
1907
 
1908
      }
1909
 
1910
      return;
1911
    }
1912
 
1913
  };
1914
 
1915
}());
1916
mit.main = function() {
1917
 
1918
  // rAF
1919
  window.requestAnimationFrame = function() {
1920
    return window.requestAnimationFrame ||
1921
      window.webkitRequestAnimationFrame ||
1922
      window.mozRequestAnimationFrame ||
1923
      window.msRequestAnimationFrame ||
1924
      window.oRequestAnimationFrame ||
1925
      function(f) {
1926
        window.setTimeout(f,1e3/60);
1927
      }
1928
  }();
1929
 
1930
  // cAF
1931
  window.cancelAnimationFrame = function() {
1932
    return window.cancelAnimationFrame ||
1933
      window.webkitCancelAnimationFrame ||
1934
      window.mozCancelAnimationFrame ||
1935
      window.msCancelAnimationFrame ||
1936
      window.oCancelAnimationFrame ||
1937
      function(f) {
1938
        window.setTimeout(f,1e3/60);
1939
      }
1940
  }();
1941
 
1942
  var config = mit.config = {
1943
 
1944
  };
1945
 
1946
  var ui = mit.ui = {
1947
    body: $('body'),
1948
    score_board: $('#score_board'),
1949
    last_score: $('#last_score'),
1950
    high_score: $('#high_score'),
1951
    start_screen: $('#start_screen'),
1952
    start_game: $('#start_game'),
1953
    tweet: $('#tweet'),
1954
    fb: $('#fb'),
1955
    fps_count: $('#fps_count'),
1956
    invincible_timer: $('#invincible_timer'),
1957
    invincible_loader: $('#invincible_loader')
1958
  };
1959
 
1960
  /*
1961
  Basic Canvas Inits
1962
  */
1963
 
1964
  // Main Canvas
1965
 
1966
  var canvas = document.querySelector('#game_main');
1967
  var ctx = canvas.getContext('2d');
1968
 
1969
  var W = canvas.width = ui.body.width();
1970
  var H = canvas.height = ui.body.height();
1971
 
1972
  // Width x Height capped to 1000 x 500
1973
  if (canvas.width > 1000) {
1974
    W = canvas.width = 1000;
1975
  }
1976
  if (canvas.height > 500) {
1977
    H = canvas.height = 500;
1978
  }
1979
 
1980
  // Resizing Width/Height
1981
  if (canvas.height < 500) {
1982
    canvas.width = canvas.height * 1000/500;
1983
  }
1984
  if (canvas.width < 1000) {
1985
    canvas.height = canvas.width * 500/1000;
1986
  }
1987
 
1988
  // BG Canvas
1989
  var bg_canvas = document.querySelector('#game_bg');
1990
  var bg_ctx = bg_canvas.getContext('2d');
1991
 
1992
  bg_canvas.width = canvas.width;
1993
  bg_canvas.height = canvas.height;
1994
 
1995
  var music = document.getElementById("start");
1996
  music.volume = 0.2;
1997
  
1998
  var isMute = false;
1999
 
2000
  // Mute the game if button is clicked
2001
  $("#mute").click(function() {
2002
    if(isMute == false) {
2003
      $(this).css("backgroundPosition", "0px -40px");
2004
      music.volume = 0;
2005
      isMute = true;
2006
    }
2007
 
2008
    else {
2009
      $(this).css("backgroundPosition", "0px 0px");
2010
      music.volume = 0.2;
2011
      isMute = false;
2012
    }
2013
 
2014
    return false;
2015
  });
2016
 
2017
  /*
2018
    Game Start Screen and Lolz
2019
  */
2020
  mit.game_started = 0;
2021
  mit.game_over = 0;
2022
  mit.start_btn_clicked = 0;
2023
 
2024
  ui.start_screen.css('width', canvas.width + 'px');
2025
  ui.start_screen.css('height', canvas.height + 'px');
2026
 
2027
  // Start Button
2028
  var startGame = function() {
2029
    // Play the awesome music! Really awesome
2030
    music.play();
2031
    flap.pause();
2032
 
2033
    // Hide the Start Screen
2034
    ui.start_screen.fadeOut();
2035
 
2036
    // Start btn has been clicked
2037
    // Game hasnt started. Game will
2038
    // start on flight.
2039
    mit.start_btn_clicked = 1;
2040
    mit.game_started = 0;
2041
 
2042
    mit.Backgrounds.common_bg_speed = 1;
2043
    mit.Backgrounds.resetAllSpeed();
2044
 
2045
    // Reset all accelerations and make
2046
    // pappu stationary
2047
    mit.Pappu.drawStatic(ctx);
2048
    mit.ax = 0; mit.ay = 0;
2049
    mit.vx = 0; mit.vy = 0;
2050
 
2051
    // if game over due to hitting someone
2052
    // he'll rotate a lot. so need ta reset
2053
    // on restart
2054
    mit.Pappu.rotate_angle = 0;
2055
 
2056
    // reset score
2057
    mit.score = 0;
2058
 
2059
    // Nuke all forks
2060
    mit.ForkUtils.forks = [];
2061
    // Nuke all branches
2062
    mit.BranchUtils.branches = [];
2063
    // Nuke all collectibles
2064
    mit.CollectibleUtils.collecs = [];
2065
    // Nuke all pakias and cur_pakia
2066
    mit.PakiaUtils.pakias = [];
2067
    mit.PakiaUtils.cur_pakia = false;
2068
  };
2069
 
2070
  ui.start_game.on('mousedown', function() {
2071
    startGame();
2072
 
2073
    return false;
2074
  });
2075
 
2076
 
2077
 
2078
  // startGame();
2079
 
2080
  // Share links
2081
  var tweet = document.getElementById("tweet");
2082
  tweet.href='http://twitter.com/share?url=http://khele.in/pappu-pakia/&text=I am playing Pappu Pakia, a cute HTML5 game on khele.in!&count=horiztonal&via=_rishabhp&related=solitarydesigns';
2083
 
2084
  var facebook = document.getElementById("fb");
2085
  facebook.href='http://facebook.com/sharer.php?s=100&p[url]=http://khele.in/pappu-pakia/&p[title]=I am playing Pappu Pakia, a cute HTML5 game on khele.in!';
2086
 
2087
 
2088
  // Score Board
2089
  mit.score = 0;
2090
  try {
2091
 
2092
    mit.highScore = JSON.parse(localStorage.getItem("highScore"));
2093
    if (mit.highScore)
2094
      ui.high_score.text("High Score: "+ mit.highScore);
2095
 
2096
  } catch (e) {}
2097
 
2098
  ui.score_board.css('width', canvas.width + 'px');
2099
  ui.score_board.css('height', canvas.height + 'px');
2100
 
2101
 
2102
  // Set Canvas Width/Height in Config
2103
  mit.config.canvas_width = mit.W = W;
2104
  mit.config.canvas_height = mit.H = H;
2105
 
2106
  // Gravity
2107
  mit.gravity = 0.7;
2108
 
2109
  // Velocity x,y
2110
  mit.vx = 0;
2111
  mit.vy = 0;
2112
 
2113
  // Velocity cap on either sides of the
2114
  // number system.
2115
  // 
2116
  // You can console.log velocities in drawing methods
2117
  // and from there decide what to set as the cap.
2118
  mit.v_cap = 6.5;
2119
 
2120
  // Accelaration x,y
2121
  mit.ax = 0;
2122
  mit.ay = 0;
2123
 
2124
  // Flying up ?
2125
  mit.flying_up = 0;
2126
 
2127
  mit.ascend = function() {
2128
    if (!mit.start_btn_clicked)
2129
      return;
2130
 
2131
    if (!mit.game_started) {
2132
      mit.game_started = 1;
2133
      mit.game_over = 0;
2134
    }
2135
 
2136
    mit.ay = -1.5;
2137
    mit.flying_up = 1;
2138
  };
2139
 
2140
  mit.descend = function() {
2141
    if (!mit.start_btn_clicked)
2142
      return;
2143
 
2144
    mit.ay = 0;
2145
    mit.flying_up = 0;
2146
  };
2147
 
2148
  // Game play on mouse clicks too!
2149
  window.addEventListener('mousedown', function(e) {
2150
    mit.ascend();
2151
  }, false);
2152
 
2153
  window.addEventListener('mouseup', function(e) {
2154
    mit.descend();
2155
  }, false);
2156
 
2157
 
2158
  // Game play on touch too!
2159
  window.addEventListener('touchstart', function(e) {
2160
    mit.ascend();
2161
  }, false);
2162
 
2163
  window.addEventListener('touchend', function(e) {
2164
    mit.descend();
2165
  }, false);
2166
 
2167
 
2168
  // ... and keyzz...
2169
  window.addEventListener('keydown', function(e) {
2170
 
2171
    if (e.keyCode === 38) {
2172
      mit.ascend();
2173
 
2174
      e.preventDefault();
2175
    }
2176
 
2177
    if (e.keyCode === 32 || e.keyCode === 13) {
2178
      startGame();
2179
      
2180
      e.preventDefault();
2181
    }
2182
 
2183
  }, false);
2184
 
2185
  window.addEventListener('keyup', function(e) {
2186
 
2187
    if (e.keyCode === 38) {
2188
      mit.descend();
2189
 
2190
      e.preventDefault();
2191
    }
2192
  }, false);
2193
 
2194
 
2195
  /*
2196
    Performing some game over tasks
2197
  */
2198
  mit.gameOver = function() {
2199
    ui.start_screen.fadeIn();
2200
 
2201
    // High Score
2202
    if (mit.score > mit.highScore) {
2203
      mit.highScore = parseInt(mit.score);
2204
      localStorage.setItem("highScore", JSON.stringify(parseInt(mit.score)));
2205
 
2206
      ui.high_score.text("High Score: "+ mit.highScore);
2207
    }
2208
 
2209
    // Show last_score
2210
    ui.last_score.text("Last Score: " + parseInt(mit.score));
2211
 
2212
 
2213
    ui.start_game.html('re-start');
2214
    ui.tweet.html('tweet score');
2215
    ui.fb.html('post on fb');
2216
 
2217
    mit.descend();
2218
 
2219
    // Stop background
2220
    mit.Backgrounds.common_bg_speed = 0;
2221
    mit.Backgrounds.ground_bg_move_speed = 0;
2222
    mit.Backgrounds.fps = 0;
2223
 
2224
    mit.game_over = 1;
2225
    mit.start_btn_clicked = 0;
2226
 
2227
    // Pappu if invincible will be no morez
2228
    mit.Pappu.undoInvincible();
2229
 
2230
    // Nuke all clones
2231
    mit.Pappu.clones.length = 0;
2232
 
2233
    // Share
2234
    var tweet = document.getElementById("tweet");
2235
    tweet.href='http://twitter.com/share?url=http://khele.in/pappu-pakia/&text=I just scored ' +Math.floor(mit.score)+ ' points in Pappu Pakia!&count=horiztonal&via=_rishabhp&related=solitarydesigns';
2236
  
2237
    var facebook = document.getElementById("fb");
2238
    facebook.href='http://facebook.com/sharer.php?s=100&p[url]=http://khele.in/pappu-pakia/&p[title]=I just scored ' +Math.floor(mit.score)+ ' points in the Pappu Pakia!';
2239
 
2240
  };
2241
 
2242
  mit.last_time = new Date();
2243
  setInterval(function() {
2244
    mit.ui.fps_count.html(mit.fps.toFixed(0) + ' FPS');
2245
  }, 1000);
2246
 
2247
 
2248
  // Initializations
2249
  mit.Backgrounds.init(ctx);
2250
  mit.ForkUtils.init();
2251
  mit.BranchUtils.init();
2252
  mit.CollectibleUtils.init();
2253
  mit.Pappu.init();
2254
  mit.PakiaUtils.init();
2255
 
2256
 
2257
  (function renderGame() {
2258
    window.requestAnimationFrame(renderGame);
2259
 
2260
    // Draw Backgrounds on BG Canvas
2261
    mit.Backgrounds.draw(bg_ctx);
2262
 
2263
    ctx.clearRect(0, 0, W, H);
2264
 
2265
    // Draw Digs (holds forks)
2266
    // I am fine without Digs, but Kushagra
2267
    // just WANTS me to do this extra work :/
2268
    // mit.ForkUtils.drawDigs(ctx);
2269
 
2270
    // Draw Grass on Main Canvas
2271
    // mit.Backgrounds.drawGrass(ctx);
2272
 
2273
    if (mit.flying_up || !mit.game_started)
2274
      mit.Pappu.updateFlyFrameCount();
2275
    else
2276
      mit.Pappu.updateFlyFrameCount(0);
2277
 
2278
 
2279
    // Game over on reaching any boundary
2280
    if (mit.Pappu.hasReachedBoundary(W, H)) {
2281
      if (mit.game_over)
2282
        return;
2283
 
2284
      // Performing some game over tasks
2285
      mit.gameOver();
2286
      return;
2287
    }
2288
 
2289
    //mit.ForkUtils.draw(ctx);
2290
    //mit.BranchUtils.draw(ctx);
2291
 
2292
    //mit.ForkUtils.checkCollision();
2293
 
2294
    // Send over Pakias (Enemies)
2295
    // mit.PakiaUtils.render(ctx);
2296
 
2297
    // Collectibles
2298
    // mit.CollectibleUtils.draw(ctx);
2299
 
2300
    // mit.Pappu.createClones(3);
2301
 
2302
    if (mit.game_started) {
2303
 
2304
      // Drawin stuff
2305
      mit.ForkUtils.draw(ctx);
2306
      mit.BranchUtils.draw(ctx);
2307
      mit.CollectibleUtils.draw(ctx);
2308
      mit.Pappu.drawClones(ctx);
2309
 
2310
      // Check Collisions with pappu
2311
      if (!mit.Pappu.invincible) {
2312
        mit.ForkUtils.checkCollision();
2313
        mit.BranchUtils.checkCollision();
2314
        mit.PakiaUtils.checkCollision();
2315
      }
2316
      mit.CollectibleUtils.checkCollision();
2317
      mit.Pappu.checkCloneCollision();
2318
 
2319
      // Send over Pakias (Enemies)
2320
      if (mit.score > 199)
2321
        mit.PakiaUtils.render(ctx);
2322
 
2323
      // Update score
2324
      if (!mit.game_over) {
2325
        mit.score = mit.score += 0.1;
2326
        ui.score_board.text(parseInt(mit.score));
2327
      }
2328
 
2329
      // Acceleration + Gravity
2330
      // mit.ay = mit.ay + mit.gravity;
2331
      
2332
      // Velocity
2333
      if (!mit.game_over) {
2334
        if (
2335
          (mit.vy < mit.v_cap && mit.ay+mit.gravity > 0) ||
2336
          (mit.vy > -mit.v_cap && mit.ay+mit.gravity < 0)
2337
          ) {
2338
 
2339
          // console.log(mit.ay);
2340
          mit.vy += mit.ay;
2341
          mit.vy += mit.gravity;
2342
        }
2343
 
2344
        // console.log(vy, ay)
2345
 
2346
        mit.Pappu.x += mit.vx;
2347
        mit.Pappu.y += mit.vy;
2348
 
2349
        if (mit.vy > mit.v_cap) {
2350
          mit.vy = mit.v_cap;
2351
        }
2352
      }
2353
      else {
2354
        // on game over, he's gravity is unstoppable
2355
        mit.vy += mit.gravity;
2356
        mit.Pappu.y += mit.vy;
2357
      }
2358
    
2359
      mit.Pappu.draw(ctx);
2360
    }
2361
    else {
2362
      mit.Pappu.drawStatic(ctx);
2363
    }
2364
 
2365
    // Calculate FPS
2366
    mit.cur_time = new Date;
2367
    mit.fps = 1e3 / (mit.cur_time - mit.last_time);
2368
    mit.last_time = mit.cur_time;
2369
 
2370
    return;
2371
  }());
2372
 
2373
};(function () {
2374
 
2375
  var Obj = {};
2376
  Obj.size = function(obj) {
2377
      var size = 0, key;
2378
      for (key in obj) {
2379
          if (obj.hasOwnProperty(key)) size++;
2380
      }
2381
      return size;
2382
  };
2383
 
2384
  // Preloading audio stuff
2385
  var loadMusic = document.getElementById("start"),
2386
      loadAngry = document.getElementById("angry_jump"), 
2387
      loadSad = document.getElementById("sad_jump"),
2388
      loadHappy = document.getElementById("happy_jump"),
2389
      loadFlap = document.getElementById("flap"),
2390
      loadTing = document.getElementById("ting");
2391
 
2392
  // Preloading image stuff
2393
 
2394
  mit.audio = [
2395
    loadMusic, 
2396
    loadAngry, 
2397
    loadSad, 
2398
    loadHappy,
2399
    loadFlap, 
2400
    loadTing,
2401
  ];
2402
 
2403
  var images = {
2404
    angry_pakia : "http://i.imgur.com/2IJWS.png",
2405
    backtrees : "http://i.imgur.com/HQ99N.png",
2406
    berries : "http://i.imgur.com/2Clro.png",
2407
    bg_combined: "http://i.imgur.com/jRLJT.png",
2408
    branch : "http://i.imgur.com/tG1ew.png",
2409
    clouds : "http://i.imgur.com/h4ZxP.png",
2410
    coins : "http://i.imgur.com/EpvRf.png",
2411
    controls : "http://i.imgur.com/Vmq49.png",
2412
    //dig : "img/dig.png",
2413
    fork_handle : "http://i.imgur.com/MsGPd.png",
2414
    fork_head : "http://i.imgur.com/EdNlh.png",
2415
    fronttrees : "http://i.imgur.com/gDtzS.png",
2416
    grass : "http://i.imgur.com/o6Zvm.png",
2417
    ground : "http://i.imgur.com/IJX6w.png",
2418
    happy_pakia : "http://i.imgur.com/cTzlN.png",
2419
    log : "http://i.imgur.com/3NhvB.png",
2420
    pappu : "http://i.imgur.com/Vcenh.png",
2421
    plank_bot : "http://i.imgur.com/hRoDZ.png",
2422
    plank_mid : "http://i.imgur.com/uq5EF.png",
2423
    plank_top : "http://i.imgur.com/ou5JQ.png",
2424
    sad_pakia : "http://i.imgur.com/FUms1.png",
2425
    stand : "http://i.imgur.com/UpZJE.png",
2426
    star : "http://i.imgur.com/bOQ8T.png"
2427
  };
2428
 
2429
  mit.image = {};
2430
 
2431
  // Get the size of an Obj
2432
  var size = Obj.size(images);
2433
  size += mit.audio.length;
2434
 
2435
  var counter = 0,
2436
      percent = 0;
2437
 
2438
  var loading = document.getElementById("bar");
2439
  var loader = document.getElementById("loading");
2440
  var loadText = document.getElementById("loadText");
2441
 
2442
  if(!($.browser.webkit && !$.browser.chrome)) {
2443
    for(var i = 0; i < mit.audio.length; i++) {
2444
      var file = mit.audio[i];
2445
 
2446
      if (isNaN(file.duration)) { 
2447
        file.addEventListener("loadeddata", function() {
2448
          counter++;
2449
          percent = Math.floor((counter/size*100));
2450
          loading.style.width = percent + "%";
2451
          loadText.innerHTML = "Loading... " + percent + "%";
2452
 
2453
          if(percent >= 100) {
2454
            $("#loading").fadeOut();
2455
            mit.main();
2456
          }
2457
        });
2458
      }
2459
 
2460
      else {
2461
        counter++;
2462
        percent = Math.floor((counter/size*100));
2463
        loading.style.width = percent + "%";
2464
        loadText.innerHTML = "Loading... " + percent + "%";
2465
 
2466
        if(percent >= 100) {
2467
          $("#loading").fadeOut();
2468
          mit.main();
2469
        }
2470
 
2471
      }
2472
    }
2473
  }
2474
 
2475
  else {counter += mit.audio.length}
2476
 
2477
  for(var src in images) {
2478
    mit.image[src] = new Image();
2479
    mit.image[src].onload = function() {
2480
      counter++;
2481
 
2482
      percent = Math.floor(((counter)/size*100));
2483
      loading.style.width = percent + "%";
2484
      loadText.innerHTML = "Loading... " + percent + "%";
2485
      
2486
      if(percent >= 100) {
2487
        $("#loading").fadeOut();
2488
        mit.main();
2489
      }
2490
 
2491
    };
2492
 
2493
    mit.image[src].src = images[src];
2494
  }
2495
 
2496
}());
 

Untitled

CSSDeck G+