├── README.md ├── css └── main.css ├── fonts ├── happy_sans-webfont.eot ├── happy_sans-webfont.svg ├── happy_sans-webfont.ttf └── happy_sans-webfont.woff ├── img ├── Thumbs.db ├── angry_pakia.png ├── apple.png ├── back_trees.png ├── berries.png ├── bg_combined.png ├── branch.png ├── clouds.png ├── coins.png ├── coins_old.png ├── controls.png ├── dig.png ├── fork_handle.png ├── fork_head.png ├── front_trees.png ├── grass.png ├── ground.png ├── happy_pakia.png ├── log.png ├── mute.png ├── pappu.png ├── plank_bot.png ├── plank_mid.png ├── plank_top.png ├── sad_pakia.png ├── stand.png └── star.png ├── index.htm ├── js ├── backgrounds.js ├── branches.js ├── collectibles.js ├── forks.js ├── jquery-1.8.2.min.js ├── loader.js ├── main.js ├── pakia.js ├── pappu.js └── utils.js ├── kong.htm └── sound ├── flap.mp3 ├── flap.ogg ├── jump1.mp3 ├── jump1.ogg ├── jump2.mp3 ├── jump2.ogg ├── jump3.mp3 ├── jump3.ogg ├── pappu-pakia2.3.mp3 ├── pappu-pakia2.3.ogg ├── ting.mp3 └── ting.ogg /README.md: -------------------------------------------------------------------------------- 1 | # Pappu Pakia 2 | 3 | ## Note about this modification 4 | 5 | The original game was created by [Rishabh](http://twitter.com/_rishabhp) and 6 | [Kushagra](http://twitter.com/solitarydesigns). The code for the original version can be found [here](https://github.com/mindd-it/pappu-pakia). 7 | 8 | Caroline Buckey and Sarah Spikes modified the repository to create exercises for 9 | the Udacity course [Version Control Using Git and Github](https://www.udacity.com/course/ud775). These 10 | modifications included introducing bugs and other changes that the original authors did not create! The bugs are intended to give learners experience using 11 | Git to find the commit where a bug was introduced. To play the modified version 12 | of the game, simply open the index.html file in your web browser. 13 | 14 | Many thanks to Rishabh and Kushagrai for creating this awesome game. 15 | 16 | ## Original README 17 | 18 | ![Pappu Pakia](http://i.imgur.com/zYD37.png) 19 | 20 | This HTML5 Game (Pappu Pakia) has been happily made for the 21 | [Github Game Off 2012](https://github.com/blog/1303-github-game-off). 22 | 23 | **[PLAY THE GAME HERE](http://khele.in/pappu-pakia/)** 24 | 25 | ### Credits 26 | 27 | Handsomely coded by [Rishabh](http://twitter.com/_rishabhp). 28 | Beautiful graphics by [Kushagra](http://twitter.com/solitarydesigns). 29 | 30 | ### Sharing is Caring <3 31 | 32 | Some tricks and tips that we learnt while making this game has been 33 | shared on [CodeTheory](http://codetheory.in) and 34 | [CSSDeck](http://cssdeck.com/codecasts). 35 | 36 | ### Game Libraries Used 37 | 38 | No Gaming/Physics Libraries/Frameworks used. All Custom Code and Custom Physics. 39 | Only jQuery used for quick and few DOM manipulations. 40 | 41 | ### About 42 | 43 | Based on the compo's rules, the concepts 44 | that we tried to incorporate are fork, branch, push, pull, clone. 45 | 46 | You are pappu in the game, a little character. You need to 47 | click the mouse or tap (touch screen) to levitate else 48 | pappu will descend. If he hits the top or bottom boundaries 49 | that'll end the game. 50 | 51 | There will be some obstacles along the way like forks, branches 52 | and some enemies who are also known as "pakias". Hitting them 53 | will end the game. 3 types of pakias - sad (pull you), 54 | happy (push you), angry (kill you). Keep safe distance from 55 | them! 56 | 57 | There are some collectibles too! Coins for points (yellow for 50, 58 | pink for 100, red for 500, blue for 1000). Stars for invincibility 59 | for a short period. Berries spawning clones that'll destroy 60 | anything that comes in their way! 61 | 62 | Collisions are not super strict to make the gameplay a little less harder. 63 | 64 | No Libraries/Frameworks used. All Custom Code and Custom Physics. 65 | 66 | Hit Enter or Spacebar keys to (re)start the game. 67 | 68 | # Archival Note 69 | This repository is deprecated; therefore, we are going to archive it. However, learners will be able to fork it to their personal Github account but cannot submit PRs to this repository. If you have any issues or suggestions to make, feel free to: 70 | - Utilize the https://knowledge.udacity.com/ forum to seek help on content-specific issues. 71 | - Submit a support ticket along with the link to your forked repository if (learners are) blocked for other reasons. Here are the links for the [retail consumers](https://udacity.zendesk.com/hc/en-us/requests/new) and [enterprise learners](https://udacityenterprise.zendesk.com/hc/en-us/requests/new?ticket_form_id=360000279131). -------------------------------------------------------------------------------- /css/main.css: -------------------------------------------------------------------------------- 1 | @font-face{ 2 | font-family: 'Happy Sans'; 3 | src: url('../fonts/happy_sans-webfont.eot'); 4 | src: url('../fonts/happy_sans-webfont.eot?#iefix') format('embedded-opentype'), 5 | url('../fonts/happy_sans-webfont.woff') format('woff'), 6 | url('../fonts/happy_sans-webfont.ttf') format('truetype'), 7 | url('../fonts/happy_sans-webfont.svg#webfont') format('svg'); 8 | } 9 | 10 | @import url(http://fonts.googleapis.com/css?family=Open+Sans); 11 | 12 | * { 13 | margin: 0; padding: 0; 14 | -moz-box-sizing: border-box; 15 | box-sizing: border-box; 16 | } 17 | 18 | /* Loading */ 19 | #loading { 20 | width: 100%; 21 | height: 100%; 22 | position: absolute; 23 | top: 0; 24 | left: 0; 25 | background: #FF6767; 26 | z-index: 10; 27 | } 28 | 29 | #loading #barCont { 30 | width: 400px; 31 | height: 20px; 32 | position: absolute; 33 | top: 50%; 34 | left: 50%; 35 | margin: -10px 0 0 -200px; 36 | background: black; 37 | } 38 | 39 | #loading #bar { 40 | width: 0; 41 | height: 20px; 42 | position: absolute; 43 | left: 0; 44 | background: #F3FF67; 45 | } 46 | 47 | html, body { 48 | width: 100%; height: 100%; 49 | } 50 | 51 | body { 52 | background: #000 url(http://i.imgur.com/XgUk6.jpg) top center no-repeat fixed; 53 | font-family: 'Open Sans', Verdana; 54 | } 55 | 56 | h1, #loadText { 57 | text-align: center; 58 | color: #fff; 59 | margin-top: 20px; 60 | font-family: 'Happy Sans', cursive; 61 | } 62 | 63 | #loadText { 64 | line-height: 380px; 65 | font-size: 30px; 66 | } 67 | 68 | #fps_count { 69 | position: absolute; 70 | top: 10px; 71 | right: 10px; 72 | font-size: 20px; 73 | color: white; 74 | font-family: 'Happy Sans', cursive; 75 | } 76 | 77 | .gads { 78 | text-align: center; 79 | max-width: 1000px; 80 | margin: 20px auto; 81 | } 82 | 83 | #mute { 84 | width: 49px; 85 | height: 40px; 86 | background: url(../img/mute.png) no-repeat; 87 | display: block; 88 | text-decoration: none; 89 | outline: none; 90 | position: absolute; 91 | top: 15px; 92 | right: 15px; 93 | z-index: 15; 94 | background-position: 0 0; 95 | } 96 | 97 | .container { 98 | position: relative; 99 | margin: 20px auto 50px; 100 | width: auto; 101 | max-width: 1000px; 102 | height: 500px; 103 | } 104 | 105 | footer { 106 | margin: 20px auto; 107 | padding: 0 0 20px; 108 | max-width: 1000px; 109 | } 110 | footer h3 { 111 | color: #E7E7E7; 112 | margin-top: 30px; 113 | font-size: 18px; 114 | margin-bottom: 10px; 115 | } 116 | footer p { 117 | margin-bottom: 10px; 118 | font-size: 13px; 119 | font-weight: normal; 120 | color: #D1D1D1; 121 | } 122 | footer a { 123 | text-decoration: none; 124 | color: #FF6767; 125 | } 126 | footer a:visited { 127 | color: #7FFF67; 128 | } 129 | footer a:hover { 130 | color: #67DBFF; 131 | } 132 | footer a:active { 133 | color: #F3FF67; 134 | } 135 | footer a:focus { 136 | color: #FF67ED; 137 | } 138 | 139 | 140 | canvas#game_main { 141 | display: block; 142 | margin: 0 auto; 143 | position: absolute; 144 | } 145 | canvas#game_bg { 146 | display: block; 147 | margin: 0 auto; 148 | position: absolute; 149 | } 150 | 151 | 152 | /* Score Board */ 153 | #score_board { 154 | position: absolute; 155 | top: 0; left: 0; right: 0; 156 | padding: 10px; 157 | height: 10%; 158 | text-align: left; 159 | font-size: 30px; 160 | font-weight: normal; 161 | font-family: 'Happy Sans', cursive; 162 | 163 | -webkit-user-select: none; 164 | -moz-user-select: none; 165 | -o-user-select: none; 166 | user-select: none; 167 | } 168 | 169 | #invincible_timer { 170 | width: 150px; 171 | height: 10px; 172 | position: absolute; 173 | top: 20px; 174 | left: 50%; 175 | border: 1px solid #fff; 176 | margin-left: -75px; 177 | display: none; 178 | } 179 | #invincible_loader { 180 | width: 100%; height: 100%; 181 | background: #FDCF7D; 182 | } 183 | 184 | 185 | /* Start Screen */ 186 | #start_screen { 187 | position: absolute; 188 | top: 0; 189 | left: 0; 190 | height: 100%; 191 | z-index: 1; 192 | width: 100%; 193 | 194 | -webkit-user-select: none; 195 | -moz-user-select: none; 196 | -o-user-select: none; 197 | user-select: none; 198 | } 199 | 200 | #title { 201 | font-size: 67px; 202 | line-height: 100px; 203 | font-weight: normal; 204 | color: #945430; 205 | text-align: center; 206 | margin: 0; 207 | padding: 0; 208 | text-shadow: 3px 3px 0px white; 209 | } 210 | 211 | #credits, #high_score, #last_score { 212 | font: 36px 'Happy Sans', cursive; 213 | color: white; 214 | padding: 0; 215 | text-align: center; 216 | margin: -10px 0 10px; 217 | } 218 | 219 | #credits a { 220 | color: #FFEEAA; 221 | text-decoration: none; 222 | } 223 | 224 | .options { 225 | height: 400px; 226 | background-image: url(../img/stand.png); 227 | background-position: bottom center; 228 | width: 225px; 229 | background-repeat: no-repeat; 230 | position: absolute; 231 | bottom: 0; 232 | right: 50px; 233 | } 234 | 235 | .options:before { 236 | content: ''; 237 | background-image: url(../img/dig.png); 238 | background-repeat: no-repeat; 239 | position: absolute; 240 | width: 47px; 241 | height: 49px; 242 | bottom: -1px; 243 | left: 50%; 244 | margin-left: -27px; 245 | z-index: -1; 246 | } 247 | 248 | .options ul { 249 | margin: 0; 250 | padding: 50px 0 0; 251 | list-style: none; 252 | } 253 | 254 | .options ul li { 255 | display: block; 256 | font: 40px 'Happy Sans', cursive; 257 | text-align: center; 258 | margin: 0 0 20px; 259 | } 260 | 261 | .options ul li a { 262 | color: #FFEEAA; 263 | text-decoration: none; 264 | } 265 | 266 | .options ul li:first-child { 267 | background: url(../img/plank_top.png) no-repeat top center; 268 | height: 70px; 269 | line-height: 70px; 270 | } 271 | 272 | .options ul li:nth-child(2) { 273 | background: url(../img/plank_mid.png) no-repeat top center; 274 | height: 63px; 275 | line-height: 63px; 276 | } 277 | 278 | .options ul li:last-child { 279 | background: url(../img/plank_bot.png) no-repeat top center; 280 | height: 75px; 281 | line-height: 75px; 282 | } 283 | 284 | .controls { 285 | width: 200px; 286 | height: 48px; 287 | background: url(../img/controls.png) no-repeat top center; 288 | margin: 10px auto; 289 | position: absolute; 290 | top: 60%; left: 50%; 291 | margin-top: -24px; margin-left: -100px; 292 | } 293 | 294 | /* Share Buttons */ 295 | #share_btns { 296 | max-width: 420px; 297 | overflow: hidden; 298 | margin: 0 auto; 299 | } 300 | 301 | .share-button { 302 | float: left; 303 | margin-right: 10px; 304 | } 305 | 306 | #disqus_thread { 307 | max-width: 1000px; 308 | margin: 0 auto; 309 | } 310 | 311 | #disqus_thread a { 312 | color: red; 313 | } 314 | 315 | div.comments-button a, div.chrome-button a{ 316 | background-color: #52a8e8; 317 | background-image: -webkit-linear-gradient(top, #52a8e8, #377ad0); 318 | background-image: -moz-linear-gradient(top, #52a8e8, #377ad0); 319 | background-image: -ms-linear-gradient(top, #52a8e8, #377ad0); 320 | background-image: -o-linear-gradient(top, #52a8e8, #377ad0); 321 | background-image: linear-gradient(top, #52a8e8, #377ad0); 322 | color: #fff; 323 | font: normal 11px "open sans", sans-serif; 324 | line-height: 1; 325 | padding: 3px 5px; 326 | text-align: center; 327 | text-decoration: none; 328 | width: 112px; 329 | border-radius: 3px; 330 | } 331 | 332 | div.comments-button a:hover { 333 | background-color: #3e9ee5; 334 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #3e9ee5), color-stop(100%, #206bcb)); 335 | background-image: -webkit-linear-gradient(top, #3e9ee5 0%, #206bcb 100%); 336 | background-image: -moz-linear-gradient(top, #3e9ee5 0%, #206bcb 100%); 337 | background-image: -ms-linear-gradient(top, #3e9ee5 0%, #206bcb 100%); 338 | background-image: -o-linear-gradient(top, #3e9ee5 0%, #206bcb 100%); 339 | background-image: linear-gradient(top, #3e9ee5 0%, #206bcb 100%); 340 | } 341 | 342 | div.chrome-button { 343 | float: none; 344 | display: block; 345 | margin: 0 auto; 346 | width: 200px; 347 | } 348 | 349 | div.chrome-button a { 350 | width: 200px; 351 | display: block; 352 | margin: 20px auto; 353 | font-size: 13px; 354 | padding: 10px; 355 | background-image: -webkit-linear-gradient(top, #5587da, #4d7cd6); 356 | background-image: -moz-linear-gradient(top, #5587da, #4d7cd6); 357 | background-image: -ms-linear-gradient(top, #5587da, #4d7cd6); 358 | background-image: -o-linear-gradient(top, #5587da, #4d7cd6); 359 | background-image: linear-gradient(top, #5587da, #4d7cd6); 360 | box-shadow: inset 0px 2px 0px rgba(255, 255, 255, 0.4); 361 | } 362 | -------------------------------------------------------------------------------- /fonts/happy_sans-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/fonts/happy_sans-webfont.eot -------------------------------------------------------------------------------- /fonts/happy_sans-webfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /fonts/happy_sans-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/fonts/happy_sans-webfont.ttf -------------------------------------------------------------------------------- /fonts/happy_sans-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/fonts/happy_sans-webfont.woff -------------------------------------------------------------------------------- /img/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/Thumbs.db -------------------------------------------------------------------------------- /img/angry_pakia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/angry_pakia.png -------------------------------------------------------------------------------- /img/apple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/apple.png -------------------------------------------------------------------------------- /img/back_trees.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/back_trees.png -------------------------------------------------------------------------------- /img/berries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/berries.png -------------------------------------------------------------------------------- /img/bg_combined.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/bg_combined.png -------------------------------------------------------------------------------- /img/branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/branch.png -------------------------------------------------------------------------------- /img/clouds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/clouds.png -------------------------------------------------------------------------------- /img/coins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/coins.png -------------------------------------------------------------------------------- /img/coins_old.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/coins_old.png -------------------------------------------------------------------------------- /img/controls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/controls.png -------------------------------------------------------------------------------- /img/dig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/dig.png -------------------------------------------------------------------------------- /img/fork_handle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/fork_handle.png -------------------------------------------------------------------------------- /img/fork_head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/fork_head.png -------------------------------------------------------------------------------- /img/front_trees.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/front_trees.png -------------------------------------------------------------------------------- /img/grass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/grass.png -------------------------------------------------------------------------------- /img/ground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/ground.png -------------------------------------------------------------------------------- /img/happy_pakia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/happy_pakia.png -------------------------------------------------------------------------------- /img/log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/log.png -------------------------------------------------------------------------------- /img/mute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/mute.png -------------------------------------------------------------------------------- /img/pappu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/pappu.png -------------------------------------------------------------------------------- /img/plank_bot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/plank_bot.png -------------------------------------------------------------------------------- /img/plank_mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/plank_mid.png -------------------------------------------------------------------------------- /img/plank_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/plank_top.png -------------------------------------------------------------------------------- /img/sad_pakia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/sad_pakia.png -------------------------------------------------------------------------------- /img/stand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/stand.png -------------------------------------------------------------------------------- /img/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/img/star.png -------------------------------------------------------------------------------- /index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Pappu Pakia | Khelein 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 22 | 25 |
26 | 27 |
28 | 29 | 30 |
31 |

pappu pakia

32 |

33 | by 34 | Kushagra 35 | and 36 | Rishabh 37 |

38 |

39 |

40 | 41 |
42 | 43 |
44 | 49 |
50 |
51 | 52 | 53 | 54 | 58 | 59 | 63 | 64 | 68 | 69 | 73 | 74 | 78 | 79 | 83 | 84 | 85 | 86 | 87 |
0
88 | 89 |
90 |
91 |
92 | 93 | 94 | 95 | 96 |
97 |

Loading...

98 |
99 |
100 |
101 |
102 | 103 |
104 | 105 |
106 | 107 |
108 | 109 | 110 | 111 |
112 | 113 | Flattr this 114 |
115 | 116 | 117 |
118 | 119 |
120 | 121 | 122 | 129 |
130 | 131 | 132 | 133 |
134 | 135 | 142 |
143 | 144 | 145 |
146 | 147 | 148 |
149 | 150 | 151 | 152 | 153 |
154 |
155 | Add to chrome 156 |
157 | 158 | 159 | 232 | 233 | 234 |
235 | 246 | 247 | comments powered by Disqus 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 276 | 277 | 290 | 291 | 292 | 293 | -------------------------------------------------------------------------------- /js/backgrounds.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | mit.Backgrounds = { 4 | 5 | // Speeds and Velocities of Backgrounds 6 | common_bg_speed: 1, 7 | 8 | cloud_bg_move_speed: 0, 9 | cloud_bg_vx: 0, 10 | 11 | backtree_bg_move_speed: 0, 12 | backtree_bg_vx: 0, 13 | 14 | fronttree_bg_move_speed: 0, 15 | fronttree_bg_vx: 0, 16 | 17 | ground_bg_move_speed: 0, 18 | ground_bg_vx: 0, 19 | 20 | combined_bg_move_speed: 0, 21 | combined_bg_vx: 0, 22 | 23 | log_x: 40, 24 | log_y: 0, 25 | 26 | sky_gradient: {}, 27 | 28 | first_speed_inc: 0, 29 | second_speed_inc: 0, 30 | third_speed_inc: 0, 31 | 32 | init: function(ctx) { 33 | // Sky Gradient 34 | this.sky_gradient = ctx.createLinearGradient(0, 0, 0, mit.H); 35 | this.sky_gradient.addColorStop(0, '#06c4f4'); 36 | this.sky_gradient.addColorStop(1, '#7bd4f6'); 37 | 38 | 39 | // Clouds 40 | // this.cloud_img = new Image(); 41 | // this.cloud_img.src = 'img/clouds.png'; 42 | this.cloud_img = mit.image.clouds; 43 | 44 | this.cloud_img.width = mit.W; 45 | this.cloud_img.height = mit.H; 46 | 47 | 48 | // Back Trees 49 | // this.backtree_img = new Image(); 50 | // this.backtree_img.src = 'img/back_trees.png'; 51 | this.backtree_img = mit.image.backtrees; 52 | 53 | this.backtree_img.width = mit.W; 54 | this.backtree_img.height = mit.H; 55 | 56 | 57 | // Front Trees 58 | // this.fronttree_img = new Image(); 59 | // this.fronttree_img.src = 'img/front_trees.png'; 60 | this.fronttree_img = mit.image.fronttrees; 61 | 62 | this.fronttree_img.width = mit.W; 63 | this.fronttree_img.height = mit.H; 64 | 65 | 66 | // Ground 67 | // this.ground_img = new Image(); 68 | // this.ground_img.src = 'img/ground.png'; 69 | this.ground_img = mit.image.ground; 70 | 71 | this.ground_img.width = mit.W; 72 | this.ground_img.height = mit.H; 73 | 74 | 75 | // Grass 76 | // this.grass_img = new Image(); 77 | // this.grass_img.src = 'img/grass.png'; 78 | this.grass_img = mit.image.grass; 79 | 80 | this.grass_img.width = mit.W; 81 | this.grass_img.height = mit.H; 82 | 83 | 84 | // Log on which pappu sits 85 | // this.log_img = new Image(); 86 | // this.log_img.src = 'img/log.png'; 87 | this.log_img = mit.image.log; 88 | 89 | 90 | // Combined BG Image 91 | // this.combined_bg_img = new Image(); 92 | // this.combined_bg_img.src = 'img/bg_combined.png'; 93 | this.combined_bg_img = mit.image.bg_combined; 94 | 95 | // Reset all speed 96 | this.resetAllSpeed(); 97 | }, 98 | 99 | resetAllSpeed: function() { 100 | this.cloud_bg_move_speed = 2; 101 | this.backtree_bg_move_speed = 3; 102 | this.fronttree_bg_move_speed = 5; 103 | this.ground_bg_move_speed = 7; 104 | 105 | this.combined_bg_move_speed = 3; 106 | }, 107 | 108 | drawClouds: function(ctx) { 109 | var cloud_bg_vx_abs = Math.abs(this.cloud_bg_vx); 110 | 111 | // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE 112 | try { 113 | ctx.drawImage( 114 | this.cloud_img, 115 | 116 | cloud_bg_vx_abs, 117 | 0, 118 | mit.W + this.cloud_bg_vx, 119 | mit.H, 120 | 121 | 0, 0, 122 | mit.W + this.cloud_bg_vx, 123 | mit.H 124 | ); 125 | 126 | ctx.drawImage( 127 | this.cloud_img, 128 | 129 | 0, 0, 130 | cloud_bg_vx_abs, 131 | mit.H, 132 | 133 | mit.W + this.cloud_bg_vx, 134 | 0, 135 | cloud_bg_vx_abs, 136 | mit.H 137 | ); 138 | } 139 | catch(e) {} 140 | this.cloud_bg_vx -= this.cloud_bg_move_speed; 141 | 142 | if (-this.cloud_bg_vx >= mit.W) { 143 | this.cloud_bg_vx = 0; 144 | } 145 | 146 | return; 147 | }, 148 | 149 | drawBackTrees: function(ctx) { 150 | var backtree_bg_vx_abs = Math.abs(this.backtree_bg_vx); 151 | 152 | // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE 153 | try { 154 | ctx.drawImage( 155 | this.backtree_img, 156 | 157 | backtree_bg_vx_abs, 158 | 0, 159 | mit.W + this.backtree_bg_vx, 160 | mit.H, 161 | 162 | 0, 0, 163 | mit.W + this.backtree_bg_vx, 164 | mit.H 165 | ); 166 | 167 | ctx.drawImage( 168 | this.backtree_img, 169 | 170 | 0, 0, 171 | backtree_bg_vx_abs, 172 | mit.H, 173 | 174 | mit.W + this.backtree_bg_vx, 175 | 0, 176 | backtree_bg_vx_abs, 177 | mit.H 178 | ); 179 | } 180 | catch(e) {} 181 | 182 | if (mit.game_started) 183 | this.backtree_bg_vx -= this.backtree_bg_move_speed * this.common_bg_speed; 184 | 185 | if (-this.backtree_bg_vx >= mit.W) { 186 | this.backtree_bg_vx = 0; 187 | } 188 | 189 | return; 190 | }, 191 | 192 | drawFrontTrees: function(ctx) { 193 | var fronttree_bg_vx_abs = Math.abs(this.fronttree_bg_vx); 194 | 195 | // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE 196 | try { 197 | ctx.drawImage( 198 | this.fronttree_img, 199 | 200 | fronttree_bg_vx_abs, 201 | 0, 202 | mit.W + this.fronttree_bg_vx, 203 | mit.H, 204 | 205 | 0, 0, 206 | mit.W + this.fronttree_bg_vx, 207 | mit.H 208 | ); 209 | 210 | ctx.drawImage( 211 | this.fronttree_img, 212 | 213 | 0, 0, 214 | fronttree_bg_vx_abs, 215 | mit.H, 216 | 217 | mit.W + this.fronttree_bg_vx, 218 | 0, 219 | fronttree_bg_vx_abs, 220 | mit.H 221 | ); 222 | } 223 | catch(e) {} 224 | if (mit.game_started) 225 | this.fronttree_bg_vx -= this.fronttree_bg_move_speed * this.common_bg_speed; 226 | 227 | if (-this.fronttree_bg_vx >= mit.W) { 228 | this.fronttree_bg_vx = 0; 229 | } 230 | 231 | return; 232 | }, 233 | 234 | drawGround: function(ctx) { 235 | var ground_bg_vx_abs = Math.abs(this.ground_bg_vx); 236 | // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE 237 | try { 238 | ctx.drawImage( 239 | this.ground_img, 240 | 241 | ground_bg_vx_abs, 242 | 0, 243 | mit.W + this.ground_bg_vx, 244 | mit.H, 245 | 246 | 0, 0, 247 | mit.W + this.ground_bg_vx, 248 | mit.H 249 | ); 250 | 251 | ctx.drawImage( 252 | this.ground_img, 253 | 254 | 0, 0, 255 | ground_bg_vx_abs, 256 | mit.H, 257 | 258 | mit.W + this.ground_bg_vx, 259 | 0, 260 | ground_bg_vx_abs, 261 | mit.H 262 | ); 263 | } 264 | catch(e) {} 265 | 266 | if (mit.game_started) 267 | this.ground_bg_vx -= this.ground_bg_move_speed * this.common_bg_speed; 268 | 269 | if (-this.ground_bg_vx >= mit.W) { 270 | this.ground_bg_vx = 0; 271 | } 272 | 273 | // console.log(-this.ground_bg_vx); 274 | 275 | return; 276 | }, 277 | 278 | drawGrass: function(ctx) { 279 | var grass_bg_vx_abs = Math.abs(this.grass_bg_vx); 280 | // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE 281 | try { 282 | ctx.drawImage( 283 | this.grass_img, 284 | 285 | grass_bg_vx_abs, 286 | 0, 287 | mit.W + this.grass_bg_vx, 288 | mit.H, 289 | 290 | 0, 0, 291 | mit.W + this.grass_bg_vx, 292 | mit.H 293 | ); 294 | 295 | ctx.drawImage( 296 | this.grass_img, 297 | 298 | 0, 0, 299 | grass_bg_vx_abs, 300 | mit.H, 301 | 302 | mit.W + this.grass_bg_vx, 303 | 0, 304 | grass_bg_vx_abs, 305 | mit.H 306 | ); 307 | } 308 | catch(e) {} 309 | 310 | if (mit.game_started) 311 | this.grass_bg_vx -= this.grass_bg_move_speed * this.common_bg_speed; 312 | 313 | if (-this.grass_bg_vx >= mit.W) { 314 | this.grass_bg_vx = 0; 315 | } 316 | 317 | return; 318 | }, 319 | 320 | drawInitLog: function(ctx) { 321 | 322 | this.log_y = mit.H-(this.log_img.height+45); 323 | 324 | ctx.drawImage(this.log_img, this.log_x, this.log_y); 325 | 326 | if (mit.game_started) { 327 | this.log_x -= this.ground_bg_move_speed * this.common_bg_speed; 328 | } 329 | }, 330 | 331 | drawCombinedBG: function(ctx) { 332 | var combined_bg_vx_abs = Math.abs(this.combined_bg_vx); 333 | // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE 334 | try { 335 | ctx.drawImage( 336 | this.combined_bg_img, 337 | 338 | combined_bg_vx_abs, 339 | 0, 340 | mit.W + this.combined_bg_vx, 341 | mit.H, 342 | 343 | 0, 0, 344 | mit.W + this.combined_bg_vx, 345 | mit.H 346 | ); 347 | 348 | ctx.drawImage( 349 | this.combined_bg_img, 350 | 351 | 0, 0, 352 | combined_bg_vx_abs, 353 | mit.H, 354 | 355 | mit.W + this.combined_bg_vx, 356 | 0, 357 | combined_bg_vx_abs, 358 | mit.H 359 | ); 360 | } 361 | catch(e) {} 362 | 363 | if (mit.game_started) 364 | this.combined_bg_vx -= this.combined_bg_move_speed * this.common_bg_speed; 365 | 366 | if (-this.combined_bg_vx >= mit.W) { 367 | this.combined_bg_vx = 0; 368 | } 369 | }, 370 | 371 | // Draw Awesome Backgrounds 372 | // Backgrounds have been made for 1000x500 dimensions 373 | draw: function(ctx) { 374 | 375 | if (mit.start_btn_clicked) { 376 | if (!this.fps || this.fps === 5000) 377 | this.fps = mit.fps; 378 | } 379 | else { 380 | this.fps = 5000; 381 | } 382 | 383 | 384 | if (this.fps > 56) { 385 | 386 | // Draw Linear Gradient for real/pure BG (sky/water) 387 | ctx.save(); 388 | ctx.fillStyle = this.sky_gradient; 389 | ctx.fillRect(0, 0, mit.W, mit.H); 390 | ctx.restore(); 391 | 392 | // Clouds 393 | this.drawClouds(ctx); 394 | 395 | // Back Small Trees 396 | this.drawBackTrees(ctx); 397 | 398 | // Front Big Trees 399 | this.drawFrontTrees(ctx); 400 | } 401 | else { 402 | this.drawCombinedBG(ctx); 403 | } 404 | 405 | // Drawing the initial wood log on which 406 | // Pappu gonna sit and bask in the cool and cozy 407 | // environment. 408 | if (this.log_x+100 > 0) { 409 | this.drawInitLog(ctx); 410 | } 411 | else if (!mit.game_started) { 412 | this.log_x = 40; 413 | } 414 | 415 | // Draw Ground now! 416 | this.drawGround(ctx); 417 | 418 | 419 | // Increasing speed based on points 420 | if (mit.score > 200 && !this.first_speed_inc) { 421 | this.cloud_bg_move_speed++; 422 | this.backtree_bg_move_speed++; 423 | this.fronttree_bg_move_speed++; 424 | this.ground_bg_move_speed++; 425 | this.combined_bg_move_speed++; 426 | 427 | this.first_speed_inc = 1; 428 | } 429 | 430 | if (mit.score > 1000 && !this.second_speed_inc) { 431 | this.cloud_bg_move_speed++; 432 | this.backtree_bg_move_speed++; 433 | this.fronttree_bg_move_speed++; 434 | this.ground_bg_move_speed++; 435 | this.combined_bg_move_speed++; 436 | 437 | this.second_speed_inc = 1; 438 | } 439 | 440 | if (mit.score > 3000 && !this.third_speed_inc) { 441 | this.cloud_bg_move_speed++; 442 | this.backtree_bg_move_speed++; 443 | this.fronttree_bg_move_speed++; 444 | this.ground_bg_move_speed++; 445 | this.combined_bg_move_speed++; 446 | 447 | this.third_speed_inc = 1; 448 | } 449 | 450 | } 451 | 452 | }; 453 | 454 | }()); 455 | -------------------------------------------------------------------------------- /js/branches.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | // We're having lots of forks to 4 | // make gameplay a little harder 5 | // and incorporate ggo's required concepts. 6 | 7 | // But we'll also try to incorporate 8 | // 'branching' by adding some branches 9 | // at random spots. So let the forks 10 | // come, but sometimes there wont be forks, 11 | // but a single branch (from top to bottom). 12 | // 13 | // The branches are gonna have a little hole 14 | // in between or some other random position 15 | // through which pappu will need to pass. 16 | // 17 | // If it collides at some part other than 18 | // the hole, he'll decease. 19 | 20 | mit.Branch = function() { 21 | this.x = 0; 22 | this.y = 0; 23 | 24 | // Width 25 | this.w; 26 | // Height 27 | this.h; 28 | 29 | this.escape_x; 30 | this.escape_y; 31 | this.escape_w; 32 | this.escape_h; 33 | 34 | this.getBounds = function() { 35 | var b = {}; 36 | 37 | b.start_x = this.x; 38 | b.start_y = this.y; 39 | b.end_x = this.x + this.w; 40 | b.end_y = this.y + this.h; 41 | 42 | return b; 43 | }; 44 | 45 | this.getEscapeBounds = function() { 46 | var b = {}; 47 | 48 | b.start_x = this.escape_x; 49 | b.start_y = this.escape_y; 50 | b.end_x = this.escape_x + this.escape_w; 51 | b.end_y = this.escape_y + this.escape_h; 52 | 53 | return b; 54 | }; 55 | }; 56 | 57 | 58 | mit.BranchUtils = { 59 | 60 | branch_img: {}, 61 | 62 | branches: [], 63 | count: 4, 64 | 65 | init: function() { 66 | // Load Images 67 | // this.branch_img = new Image(); 68 | // this.branch_img.src = 'img/branch.png'; 69 | 70 | this.branch_img = mit.image.branch; 71 | }, 72 | 73 | /* 74 | This method will generate a random x/y 75 | position for the forks to start at. 76 | 77 | Based on the `fork.edge` we can draw 78 | the fork easily on the canvas edges. 79 | */ 80 | getRandomBranchPos: function() { 81 | // We have access to `branches` here 82 | var pos = {}; 83 | 84 | if (this.branches[this.branches.length-1]) { 85 | pos.x = this.branches[this.branches.length-1].x; 86 | pos.x += utils.randomNumber(500, 2000); 87 | } 88 | else { 89 | // First 90 | pos.x = utils.randomNumber(2000, 2500); 91 | } 92 | 93 | var forks = mit.ForkUtils.forks; 94 | /*var last_fork = forks[forks.length-1]; 95 | 96 | if (last_fork) { 97 | 98 | if (Math.abs(pos.x - last_fork.x) < 300) { 99 | pos.x = last_fork.x + 300; 100 | } 101 | }*/ 102 | 103 | if (forks.length) { 104 | forks.forEach(function(fork) { 105 | if (Math.abs(pos.x - fork.x) < 500) 106 | pos.x = fork.x + 500; 107 | }); 108 | } 109 | 110 | return pos; 111 | }, 112 | 113 | create: function() { 114 | var branches = this.branches, 115 | count = this.count; 116 | 117 | if (branches.length < count) { 118 | 119 | for (var i = 0; i < count - branches.length; i++) { 120 | var branch = new mit.Branch(); 121 | 122 | var pos = this.getRandomBranchPos(); 123 | branch.x = pos.x; 124 | branch.y = 0; 125 | 126 | branch.w = this.branch_img.width; 127 | branch.h = this.branch_img.height; 128 | 129 | // Escape Positions 130 | branch.escape_x = branch.x; 131 | branch.escape_y = branch.y + utils.randomNumber(0, branch.h-150); 132 | 133 | // Escape Area's Width/Height 134 | branch.escape_w = this.branch_img.width; 135 | branch.escape_h = 150; 136 | 137 | branches.push(branch); 138 | } 139 | } 140 | }, 141 | 142 | draw: function(ctx) { 143 | var branches = this.branches, 144 | branch_img = this.branch_img, 145 | dead_branch = 0; 146 | 147 | this.create(); 148 | 149 | // console.log(branches); 150 | 151 | // Loop over branches and draw each of them 152 | branches.forEach(function(branch, index) { 153 | 154 | branch.x -= mit.Backgrounds.ground_bg_move_speed; 155 | 156 | if (branch.x + branch.w < 0) { 157 | dead_branch++; 158 | return; 159 | } 160 | 161 | // Out of view port, no need to draw 162 | if (branch.x > mit.W) 163 | return; 164 | 165 | // Escape Positions 166 | branch.escape_x = branch.x; 167 | 168 | ctx.drawImage(branch_img, branch.x, branch.y); 169 | 170 | // Draw Escapes 171 | ctx.save(); 172 | ctx.globalCompositeOperation = 'destination-out'; 173 | ctx.fillStyle = 'white'; 174 | ctx.fillRect( 175 | branch.escape_x, 176 | branch.escape_y, 177 | branch.escape_w, 178 | branch.escape_h 179 | ); 180 | ctx.restore(); 181 | }); 182 | 183 | if (dead_branch) { 184 | branches.splice(0, dead_branch); 185 | } 186 | 187 | return; 188 | }, 189 | 190 | // Check collisions with branches 191 | checkCollision: function() { 192 | var first_branch = this.branches[0]; 193 | 194 | // Useless optimization 195 | if (first_branch.x > mit.W/2) 196 | return; 197 | 198 | // Get Pappu Bounds 199 | var pappu_bounds = mit.Pappu.getBounds(), 200 | // Get Nearest Branch's Top Part's Bounds 201 | branch_bounds = first_branch.getBounds(); 202 | 203 | if (utils.intersect(pappu_bounds, branch_bounds)) { 204 | // console.log(pappu_bounds, branch_bounds); 205 | 206 | // If the Escape Area intersects then pappu 207 | // can escape, else game over matey! 208 | var escape_bounds = first_branch.getEscapeBounds(); 209 | 210 | if (!utils.intersect(pappu_bounds, escape_bounds)) { 211 | mit.gameOver(); 212 | } 213 | 214 | } 215 | 216 | return; 217 | } 218 | 219 | }; 220 | 221 | }()); 222 | -------------------------------------------------------------------------------- /js/collectibles.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | /* 4 | We'll have some collectibles: 5 | 6 | - Ones that give 50, 100, 500, 1000 points. 7 | 8 | - One to clone pappu that'll kill all 9 | forks, branches, pakias. 10 | 11 | - One for pappu's invincibility 12 | */ 13 | 14 | mit.Collectible = function() { 15 | 16 | // x/y pos 17 | this.x; 18 | this.y; 19 | 20 | // width/height 21 | this.w; 22 | this.h; 23 | 24 | // Collectible Type - read above 25 | this.type; 26 | 27 | // Sound 28 | this.sound = document.getElementById("ting"); 29 | this.sound.volume = 0.35; 30 | 31 | // Some collectible types may have subtypes 32 | // like coins of 50, 100, 500, 1000 and so on ... 33 | this.sub_type; 34 | 35 | this.getBounds = function() { 36 | var b = {}; 37 | 38 | b.start_x = this.x; 39 | b.start_y = this.y; 40 | b.end_x = this.x + this.w; 41 | b.end_y = this.y + this.h; 42 | 43 | return b; 44 | }; 45 | 46 | 47 | this.draw = function(ctx) { 48 | switch (this.type) { 49 | 50 | case 'coin': 51 | this.drawCoin(ctx); 52 | break; 53 | 54 | case 'clone': 55 | this.drawClone(ctx); 56 | break; 57 | 58 | case 'invincible': 59 | this.drawInvincible(ctx); 60 | break; 61 | 62 | } 63 | 64 | return; 65 | }; 66 | 67 | this.drawCoin = function(ctx) { 68 | // Get coin color based on sub type 69 | var pos = mit.CollectibleUtils.getCoinSpritePos(this.sub_type); 70 | 71 | ctx.drawImage( 72 | mit.CollectibleUtils.coin_img, 73 | pos.x, pos.y, 74 | 30, 30, 75 | this.x, this.y, 76 | 30, 30 77 | ); 78 | }; 79 | 80 | this.drawClone = function(ctx) { 81 | ctx.drawImage( 82 | mit.CollectibleUtils.clone_img, 83 | this.x, 84 | this.y 85 | ); 86 | }; 87 | 88 | this.drawInvincible = function(ctx) { 89 | ctx.drawImage( 90 | mit.CollectibleUtils.invincible_img, 91 | this.x, 92 | this.y 93 | ); 94 | }; 95 | }; 96 | 97 | 98 | mit.CollectibleUtils = { 99 | 100 | collecs: [], 101 | 102 | count: 2, 103 | 104 | types: ['coin', 'clone', 'invincible'], 105 | //types: ['invincible'], 106 | 107 | sub_types: { 108 | coin: [50, 100, 500] 109 | }, 110 | 111 | init: function() { 112 | // this.coin_img = new Image(); 113 | // this.coin_img.src = 'img/coins.png'; 114 | this.coin_img = mit.image.coins; 115 | 116 | // this.clone_img = new Image(); 117 | // this.clone_img.src = 'img/berries.png'; 118 | this.clone_img = mit.image.berries; 119 | 120 | // this.invincible_img = new Image(); 121 | // this.invincible_img.src = 'img/star.png'; 122 | this.invincible_img = mit.image.star; 123 | }, 124 | 125 | getCoinSpritePos: function(sub_type) { 126 | 127 | switch (sub_type) { 128 | case 50: 129 | // Yellow (first) 130 | return {x: 0, y: 0}; 131 | 132 | case 100: 133 | // Pink (second) 134 | return {x: 30, y: 0}; 135 | 136 | case 500: 137 | // Red (third) 138 | // Pink (second) 139 | return {x: 60, y: 0}; 140 | 141 | case 1000: 142 | // Blue (last) 143 | return {x: 90, y: 0}; 144 | } 145 | 146 | }, 147 | 148 | getRandomPos: function() { 149 | var pos = {}; 150 | 151 | var last = this.collecs[this.collecs.length - 1]; 152 | 153 | if (last) { 154 | pos.x = last.x + utils.randomNumber(200, 500); 155 | } 156 | else { 157 | pos.x = utils.randomNumber(100, 200); 158 | } 159 | 160 | pos.y = utils.randomNumber(100, mit.H-100); 161 | 162 | // Check Positioning with forks 163 | var forks = mit.ForkUtils.forks; 164 | 165 | if (forks.length) { 166 | forks.forEach(function(fork) { 167 | if (Math.abs(pos.x - fork.x) < 300) 168 | pos.x = fork.x + 300; 169 | }); 170 | } 171 | 172 | // Check Positioning with branches 173 | var branches = mit.BranchUtils.branches; 174 | 175 | if (branches.length) { 176 | branches.forEach(function(branch) { 177 | if (Math.abs(pos.x - branch.x) < 300) 178 | pos.x = branch.x + 300; 179 | }); 180 | } 181 | 182 | return pos; 183 | }, 184 | 185 | create: function() { 186 | var count = this.count - this.collecs.length; 187 | var collec, 188 | sub_types, 189 | pos; 190 | 191 | for (var i = 0; i < count; i++) { 192 | collec = new mit.Collectible(); 193 | 194 | pos = this.getRandomPos(); 195 | 196 | collec.x = pos.x; 197 | collec.y = pos.y; 198 | 199 | collec.w = 30; 200 | collec.h = 30; 201 | 202 | // Type 203 | collec.type = this.types[utils.randomNumber(0, this.types.length-1)]; 204 | 205 | // Choosing Sub types if any 206 | sub_types = this.sub_types[collec.type]; 207 | if (sub_types) 208 | collec.sub_type = sub_types[utils.randomNumber(0, sub_types.length-1)]; 209 | 210 | this.collecs.push(collec); 211 | } 212 | }, 213 | 214 | draw: function(ctx) { 215 | 216 | var self = this; 217 | 218 | self.create(); 219 | 220 | self.collecs.forEach(function(collec, i) { 221 | if (collec.x < 0) { 222 | // Moved off the left edge 223 | /*var pos = self.getRandomPos(); 224 | 225 | collec.x = pos.x; 226 | collec.y = pos.y;*/ 227 | self.collecs.splice(i,1); 228 | } 229 | 230 | collec.x -= mit.Backgrounds.ground_bg_move_speed; 231 | 232 | collec.draw(ctx); 233 | }); 234 | 235 | return; 236 | }, 237 | 238 | checkCollision: function() { 239 | // First collec 240 | var collec = this.collecs[0], 241 | // Get Pappu Bounds 242 | pappu_bounds = mit.Pappu.getBounds(), 243 | // Get Nearest Collectible Bounds 244 | collec_bounds = collec.getBounds(); 245 | 246 | if (utils.intersect(pappu_bounds, collec_bounds)) { 247 | // Pappu haz collected! 248 | collec.sound.play(); 249 | // Determine type and perform action accordingly 250 | switch (collec.type) { 251 | 252 | case 'coin': 253 | mit.score += collec.sub_type; 254 | break; 255 | 256 | case 'clone': 257 | mit.Pappu.createClones(3); 258 | break; 259 | 260 | case 'invincible': 261 | mit.Pappu.invincible = 1; 262 | 263 | // Kush says we shouldnt add up 264 | /*if (!mit.Pappu.invincibility_start) { 265 | mit.Pappu.invincibility_time = 5000; 266 | } 267 | else { 268 | var cur_time = new Date().getTime(); 269 | var prev_remaining_time = cur_time - mit.Pappu.invincibility_start; 270 | 271 | mit.Pappu.invincibility_time = 5000 + prev_remaining_time; 272 | }*/ 273 | 274 | mit.Pappu.invincibility_start = new Date().getTime(); 275 | mit.Pappu.invincibility_time = 5000; 276 | 277 | // Show timer 278 | mit.ui.invincible_timer.show(); 279 | 280 | break; 281 | } 282 | 283 | // Nuke the collectible 284 | this.collecs.shift(); 285 | } 286 | 287 | return; 288 | } 289 | 290 | }; 291 | 292 | }()); 293 | -------------------------------------------------------------------------------- /js/forks.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | // The Fork Class 4 | // We'll have lots of forks. 5 | // Each fork will be on object of this 6 | // constructor. 7 | 8 | mit.Fork = function() { 9 | // Handle x/y 10 | this.x = 0; 11 | this.y = 0; 12 | 13 | // W/H 14 | this.w = 0; 15 | this.h = 0; 16 | 17 | 18 | // Head x/y 19 | this.head_x = 0; 20 | this.head_y = 0; 21 | 22 | // Head W/H 23 | this.head_w = 0; 24 | this.head_h = 0; 25 | 26 | // Edge on which the fork will stand on 27 | this.edge = 'btm'; 28 | 29 | // Get Handle Bounds 30 | this.getHandleBounds = function() { 31 | var b = {}; 32 | 33 | b.start_x = this.x; 34 | b.start_y = this.y; 35 | b.end_x = this.x + this.w; 36 | b.end_y = this.y + this.h; 37 | 38 | //console.log(bounds); 39 | return b; 40 | }; 41 | 42 | // Get Head Bounds 43 | this.getHeadBounds = function() { 44 | var b = {}; 45 | 46 | b.start_x = this.head_x; 47 | b.start_y = this.head_y; 48 | b.end_x = this.head_x + this.head_w; 49 | b.end_y = this.head_y + this.head_h; 50 | 51 | return b; 52 | }; 53 | }; 54 | 55 | 56 | // A ForkUtils class to help save the world 57 | 58 | mit.ForkUtils = { 59 | 60 | // Master array of all existing forks in memory 61 | forks: [], 62 | // Forks can be placed on top/bottom edges 63 | edges: ['top', 'btm'], 64 | 65 | // Images for fork handle, fork head and the digged part 66 | fork_img: {}, 67 | fork_head_img: {}, 68 | dig_img: {}, 69 | 70 | // How many forks to have in memory ? 71 | count: 6, 72 | 73 | init: function() { 74 | // Loading Images 75 | 76 | // Fork handle 77 | // this.fork_img = new Image(); 78 | // this.fork_img.src = 'img/fork_handle.png'; 79 | this.fork_img = mit.image.fork_handle; 80 | 81 | // Fork Head 82 | // this.fork_head_img = new Image(); 83 | // this.fork_head_img.src = 'img/fork_head.png'; 84 | this.fork_head_img = mit.image.fork_head; 85 | 86 | // Dig Image 87 | // this.dig_img = new Image(); 88 | // this.dig_img.src = 'img/dig.png'; 89 | }, 90 | 91 | /* 92 | How do we go about positioning forks exactly ? 93 | 94 | - Forks can appear on top or bottom edge. 95 | - Forks should vary in sizes, but should be 96 | mostly long to produce a harder gameplay. 97 | - Forks should appear at random distance. 98 | But there needs to be a range (or capping). 99 | - Every fork object should know what edge it 100 | is put on. This will help us calculate the 101 | exact height based on entire canvas 102 | height/width. 103 | This means, we only need the x/y position 104 | along with the edge, to put on the fork. 105 | */ 106 | 107 | /* 108 | This method will generate a random x/y 109 | position for the forks to start at. 110 | 111 | Based on the `fork.edge` we can draw 112 | the fork easily on the canvas edges. 113 | */ 114 | 115 | getRandomForkPos: function() { 116 | // We have access to `forks` here 117 | var pos = {}; 118 | 119 | if (this.forks[this.forks.length-1]) { 120 | pos.x = this.forks[this.forks.length-1].x; 121 | 122 | if (mit.score > 2500) 123 | pos.x += utils.randomNumber(300,600); 124 | else 125 | pos.x += utils.randomNumber(500,800); 126 | } 127 | else { 128 | pos.x = mit.W/1000 * 1050; 129 | } 130 | 131 | var branches = mit.BranchUtils.branches; 132 | /*var last_branch = [branches.length-1]; 133 | 134 | if (last_branch) { 135 | if (Math.abs(pos.x - last_branch.x) < 300) 136 | pos.x = last_branch.x + 300; 137 | }*/ 138 | 139 | if (branches.length) { 140 | branches.forEach(function(branch) { 141 | if (Math.abs(pos.x - branch.x) < 500) 142 | pos.x = branch.x + 500; 143 | }); 144 | } 145 | 146 | return pos; 147 | }, 148 | 149 | create: function() { 150 | var fork_img = this.fork_img, 151 | dig_img = this.dig_img, 152 | fork_head_img = this.fork_head_img, 153 | forks = this.forks, 154 | count = this.count; 155 | 156 | if (forks.length < count) { 157 | 158 | for (var i = 0; i < count - forks.length; i++) { 159 | var fork = new mit.Fork(); 160 | 161 | // Setting a Random Edge 162 | fork.edge = this.edges[utils.randomNumber(0,1)]; 163 | 164 | // Setting the Dig Position 165 | if (fork.edge === 'btm') { 166 | var dig_rand = utils.randomNumber(3,5); 167 | 168 | fork.dig_x = dig_img.width / dig_rand; 169 | fork.dig_y = mit.H - dig_img.height; 170 | // console.log(this.dig_img.width); 171 | 172 | fork.y = 200 + utils.randomNumber(0,100); 173 | fork.y += fork_head_img.height; 174 | } 175 | 176 | if (fork.edge === 'top') { 177 | fork.y = 0 - utils.randomNumber(0,100); 178 | fork.y -= fork_head_img.height; 179 | } 180 | 181 | var pos = this.getRandomForkPos(); 182 | fork.x = pos.x; 183 | 184 | // Height and Width 185 | fork.w = fork_img.width; 186 | fork.h = fork_img.height; 187 | 188 | forks.push(fork); 189 | } 190 | 191 | } 192 | }, 193 | 194 | draw: function(ctx) { 195 | var fork_img = this.fork_img, 196 | dig_img = this.dig_img, 197 | fork_head_img = this.fork_head_img, 198 | forks = this.forks, 199 | dead_forks = 0; 200 | 201 | this.create(); 202 | 203 | // Loop over forks and draw each of them 204 | forks.forEach(function(fork, index) { 205 | 206 | fork.x -= mit.Backgrounds.ground_bg_move_speed; 207 | 208 | if (fork.x + fork.w < 0) { 209 | ++dead_forks; 210 | return; 211 | } 212 | 213 | // Out of view port, no need to draw 214 | if (fork.x > mit.W) { 215 | // console.log('out of view port'); 216 | return; 217 | } 218 | 219 | if (fork.edge === 'top') { 220 | // ctx.lineTo(fork.x, 0); 221 | 222 | // Top forks need flippin 223 | ctx.save(); 224 | ctx.translate(fork.x, fork.y); 225 | ctx.translate(~~(fork_img.width/2), ~~(fork_img.height/2)); 226 | ctx.rotate( utils.toRadian(180) ); 227 | ctx.drawImage(fork_img, -~~(fork_img.width/2), -~~(fork_img.height/2)); 228 | ctx.restore(); 229 | 230 | 231 | fork.head_x = fork.x-~~(fork_head_img.width/8); 232 | fork.head_y = fork.y+fork_img.height; 233 | 234 | fork.head_w = fork_head_img.width; 235 | fork.head_h = fork_head_img.height; 236 | 237 | // Draw Fork Head 238 | ctx.save(); 239 | ctx.translate(fork.head_x, fork.head_y); 240 | ctx.translate(~~(fork_head_img.width/2), ~~(fork_head_img.height/2)); 241 | ctx.rotate( utils.toRadian(180) ); 242 | ctx.drawImage(fork_head_img, -~~(fork_head_img.width/2), -~~(fork_head_img.height/2)); 243 | ctx.restore(); 244 | } 245 | else if (fork.edge === 'btm') { 246 | 247 | ctx.drawImage(fork_img, fork.x, fork.y); 248 | 249 | fork.head_x = fork.x-~~(fork_head_img.width/5); 250 | fork.head_y = fork.y-fork_head_img.height; 251 | 252 | fork.head_w = fork_head_img.width; 253 | fork.head_h = fork_head_img.height; 254 | 255 | // Draw Fork Head 256 | ctx.save(); 257 | ctx.translate(fork.head_x, fork.head_y); 258 | ctx.translate(1* ~~(fork_head_img.width/2), 1* ~~(fork_head_img.height/2)); 259 | ctx.scale(-1,1); 260 | ctx.drawImage( 261 | fork_head_img, 262 | 1* -~~(fork_head_img.width/2), 263 | 1* -~~(fork_head_img.height/2) 264 | ); 265 | ctx.restore(); 266 | } 267 | 268 | }); 269 | 270 | if (dead_forks) { 271 | forks.splice(0, dead_forks); 272 | } 273 | 274 | return; 275 | }, 276 | 277 | // Forks have black digs in grounds 278 | // This function will draw those 279 | drawDigs: function(ctx) { 280 | // Loop over forks and draw digs for each of them 281 | var dig_img = this.dig_img; 282 | 283 | this.forks.forEach(function(fork, index) { 284 | 285 | if (fork.edge === 'btm') { 286 | ctx.drawImage(dig_img, fork.x - fork.dig_x, fork.dig_y); 287 | } 288 | 289 | }); 290 | }, 291 | 292 | // Check Fork Collision 293 | checkCollision: function() { 294 | var first_fork = this.forks[0]; 295 | 296 | // Useless optimization 297 | if (first_fork.x > mit.W/2) 298 | return; 299 | 300 | // Get Pappu Bounds 301 | var pappu_bounds = mit.Pappu.getBounds(), 302 | // Get Nearest Fork's Handle's Bounds 303 | fork_bounds = first_fork.getHandleBounds(); 304 | 305 | // Check whether pappu collided with the 306 | // fork handle or not. 307 | if (utils.intersect(pappu_bounds, fork_bounds)) { 308 | // console.log(pappu_bounds, fork_bounds); 309 | mit.gameOver(); 310 | } 311 | 312 | // We'll have to check for collision with fork heads. 313 | // If there's a collision pappu will be pushed! 314 | var fork_head_bounds = first_fork.getHeadBounds(); 315 | 316 | // Check whether pappu collided with the 317 | // fork head or not. With fork heads 318 | // collision detection checks would be 319 | // a little casual than super stern. 320 | 321 | // if (utils.intersect(pappu_bounds, fork_head_bounds)) { 322 | 323 | if ( 324 | pappu_bounds.end_x > fork_head_bounds.start_x+20 && 325 | fork_head_bounds.end_x-20 > pappu_bounds.start_x && 326 | pappu_bounds.end_y > fork_head_bounds.start_y+20 && 327 | fork_head_bounds.end_y-20 > pappu_bounds.start_y 328 | ) { 329 | mit.gameOver(); 330 | } 331 | } 332 | 333 | }; 334 | 335 | }()); 336 | -------------------------------------------------------------------------------- /js/loader.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var Obj = {}; 4 | Obj.size = function(obj) { 5 | var size = 0, key; 6 | for (key in obj) { 7 | if (obj.hasOwnProperty(key)) size++; 8 | } 9 | return size; 10 | }; 11 | 12 | // Preloading audio stuff 13 | var loadMusic = document.getElementById("start"), 14 | loadAngry = document.getElementById("angry_jump"), 15 | loadSad = document.getElementById("sad_jump"), 16 | loadHappy = document.getElementById("happy_jump"), 17 | loadFlap = document.getElementById("flap"), 18 | loadTing = document.getElementById("ting"); 19 | 20 | // Preloading image stuff 21 | 22 | mit.audio = [ 23 | loadMusic, 24 | loadAngry, 25 | loadSad, 26 | loadHappy, 27 | loadFlap, 28 | loadTing, 29 | ]; 30 | 31 | var images = { 32 | angry_pakia : "img/angry_pakia.png", 33 | backtrees : "img/back_trees.png", 34 | berries : "img/berries.png", 35 | bg_combined: "img/bg_combined.png", 36 | branch : "img/branch.png", 37 | clouds : "img/clouds.png", 38 | coins : "img/coins.png", 39 | controls : "img/controls.png", 40 | //dig : "img/dig.png", 41 | fork_handle : "img/fork_handle.png", 42 | fork_head : "img/fork_head.png", 43 | fronttrees : "img/front_trees.png", 44 | grass : "img/grass.png", 45 | ground : "img/ground.png", 46 | happy_pakia : "img/happy_pakia.png", 47 | log : "img/log.png", 48 | pappu : "img/pappu.png", 49 | plank_bot : "img/plank_bot.png", 50 | plank_mid : "img/plank_mid.png", 51 | plank_top : "img/plank_top.png", 52 | sad_pakia : "img/sad_pakia.png", 53 | stand : "img/stand.png", 54 | star : "img/star.png" 55 | }; 56 | 57 | mit.image = {}; 58 | 59 | // Get the size of an Obj 60 | var size = Obj.size(images); 61 | size += mit.audio.length; 62 | 63 | var counter = 0, 64 | percent = 0; 65 | 66 | var loading = document.getElementById("bar"); 67 | var loader = document.getElementById("loading"); 68 | var loadText = document.getElementById("loadText"); 69 | 70 | if(!($.browser.webkit && !$.browser.chrome)) { 71 | for(var i = 0; i < mit.audio.length; i++) { 72 | var file = mit.audio[i]; 73 | 74 | if (isNaN(file.duration)) { 75 | file.addEventListener("loadeddata", function() { 76 | counter++; 77 | percent = Math.floor((counter/size*100)); 78 | loading.style.width = percent + "%"; 79 | loadText.innerHTML = "Loading... " + percent + "%"; 80 | 81 | if(percent >= 100) { 82 | $("#loading").fadeOut(); 83 | mit.main(); 84 | } 85 | }); 86 | } 87 | 88 | else { 89 | counter++; 90 | percent = Math.floor((counter/size*100)); 91 | loading.style.width = percent + "%"; 92 | loadText.innerHTML = "Loading... " + percent + "%"; 93 | 94 | if(percent >= 100) { 95 | $("#loading").fadeOut(); 96 | mit.main(); 97 | } 98 | 99 | } 100 | } 101 | } 102 | 103 | else {counter += mit.audio.length} 104 | 105 | for(var src in images) { 106 | mit.image[src] = new Image(); 107 | mit.image[src].onload = function() { 108 | counter++; 109 | 110 | percent = Math.floor(((counter)/size*100)); 111 | loading.style.width = percent + "%"; 112 | loadText.innerHTML = "Loading... " + percent + "%"; 113 | 114 | if(percent >= 100) { 115 | $("#loading").fadeOut(); 116 | mit.main(); 117 | } 118 | 119 | }; 120 | 121 | mit.image[src].src = images[src]; 122 | } 123 | 124 | }()); 125 | -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | 2 | mit.main = function() { 3 | 4 | // rAF 5 | window.requestAnimationFrame = function() { 6 | return window.requestAnimationFrame || 7 | window.webkitRequestAnimationFrame || 8 | window.mozRequestAnimationFrame || 9 | window.msRequestAnimationFrame || 10 | window.oRequestAnimationFrame || 11 | function(f) { 12 | window.setTimeout(f,1e3/60); 13 | } 14 | }(); 15 | 16 | // cAF 17 | window.cancelAnimationFrame = function() { 18 | return window.cancelAnimationFrame || 19 | window.webkitCancelAnimationFrame || 20 | window.mozCancelAnimationFrame || 21 | window.msCancelAnimationFrame || 22 | window.oCancelAnimationFrame || 23 | function(f) { 24 | window.setTimeout(f,1e3/60); 25 | } 26 | }(); 27 | 28 | var config = mit.config = { 29 | 30 | }; 31 | 32 | var ui = mit.ui = { 33 | body: $('body'), 34 | score_board: $('#score_board'), 35 | last_score: $('#last_score'), 36 | high_score: $('#high_score'), 37 | start_screen: $('#start_screen'), 38 | start_game: $('#start_game'), 39 | tweet: $('#tweet'), 40 | fb: $('#fb'), 41 | fps_count: $('#fps_count'), 42 | invincible_timer: $('#invincible_timer'), 43 | invincible_loader: $('#invincible_loader') 44 | }; 45 | 46 | /* 47 | Basic Canvas Inits 48 | */ 49 | 50 | // Main Canvas 51 | 52 | var canvas = document.querySelector('#game_main'); 53 | var ctx = canvas.getContext('2d'); 54 | 55 | var W = canvas.width = ui.body.width(); 56 | var H = canvas.height = ui.body.height(); 57 | 58 | // Width x Height capped to 1000 x 500 59 | if (canvas.width > 1000) { 60 | W = canvas.width = 1000; 61 | } 62 | if (canvas.height > 500) { 63 | H = canvas.height = 500; 64 | } 65 | 66 | // Resizing Width/Height 67 | if (canvas.height < 500) { 68 | canvas.width = canvas.height * 1000/500; 69 | } 70 | if (canvas.width < 1000) { 71 | canvas.height = canvas.width * 500/1000; 72 | } 73 | 74 | // BG Canvas 75 | var bg_canvas = document.querySelector('#game_bg'); 76 | var bg_ctx = bg_canvas.getContext('2d'); 77 | 78 | bg_canvas.width = canvas.width; 79 | bg_canvas.height = canvas.height; 80 | 81 | var music = document.getElementById("start"); 82 | music.volume = 0.2; 83 | 84 | var isMute = false; 85 | 86 | // Mute the game if button is clicked 87 | $("#mute").click(function() { 88 | if(isMute == false) { 89 | $(this).css("backgroundPosition", "0px -40px"); 90 | music.volume = 0; 91 | isMute = true; 92 | } 93 | 94 | else { 95 | $(this).css("backgroundPosition", "0px 0px"); 96 | music.volume = 0.2; 97 | isMute = false; 98 | } 99 | 100 | return false; 101 | }); 102 | 103 | /* 104 | Game Start Screen and Lolz 105 | */ 106 | mit.game_started = 0; 107 | mit.game_over = 0; 108 | mit.start_btn_clicked = 0; 109 | 110 | ui.start_screen.css('width', canvas.width + 'px'); 111 | ui.start_screen.css('height', canvas.height + 'px'); 112 | 113 | // Start Button 114 | var startGame = function() { 115 | // Play the awesome music! Really awesome 116 | music.play(); 117 | flap.pause(); 118 | 119 | // Hide the Start Screen 120 | ui.start_screen.fadeOut(); 121 | 122 | // Start btn has been clicked 123 | // Game hasnt started. Game will 124 | // start on flight. 125 | mit.start_btn_clicked = 1; 126 | mit.game_started = 0; 127 | 128 | mit.Backgrounds.common_bg_speed = 1; 129 | mit.Backgrounds.resetAllSpeed(); 130 | 131 | // Reset all accelerations and make 132 | // pappu stationary 133 | mit.Pappu.drawStatic(ctx); 134 | mit.ax = 0; mit.ay = 0; 135 | mit.vx = 0; mit.vy = 0; 136 | 137 | // if game over due to hitting someone 138 | // he'll rotate a lot. so need ta reset 139 | // on restart 140 | mit.Pappu.rotate_angle = 0; 141 | 142 | // reset score 143 | mit.score = 0; 144 | 145 | // Nuke all forks 146 | mit.ForkUtils.forks = []; 147 | // Nuke all branches 148 | mit.BranchUtils.branches = []; 149 | // Nuke all collectibles 150 | mit.CollectibleUtils.collecs = []; 151 | // Nuke all pakias and cur_pakia 152 | mit.PakiaUtils.pakias = []; 153 | mit.PakiaUtils.cur_pakia = false; 154 | }; 155 | 156 | ui.start_game.on('mousedown', function() { 157 | startGame(); 158 | 159 | return false; 160 | }); 161 | 162 | 163 | 164 | // startGame(); 165 | 166 | // Share links 167 | var tweet = document.getElementById("tweet"); 168 | 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'; 169 | 170 | var facebook = document.getElementById("fb"); 171 | 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!'; 172 | 173 | 174 | // Score Board 175 | mit.score = 0; 176 | try { 177 | 178 | mit.highScore = JSON.parse(localStorage.getItem("highScore")); 179 | if (mit.highScore) 180 | ui.high_score.text("High Score: "+ mit.highScore); 181 | 182 | } catch (e) {} 183 | 184 | ui.score_board.css('width', canvas.width + 'px'); 185 | ui.score_board.css('height', canvas.height + 'px'); 186 | 187 | 188 | // Set Canvas Width/Height in Config 189 | mit.config.canvas_width = mit.W = W; 190 | mit.config.canvas_height = mit.H = H; 191 | 192 | // Gravity 193 | mit.gravity = 0.7; 194 | 195 | // Velocity x,y 196 | mit.vx = 0; 197 | mit.vy = 0; 198 | 199 | // Velocity cap on either sides of the 200 | // number system. 201 | // 202 | // You can console.log velocities in drawing methods 203 | // and from there decide what to set as the cap. 204 | mit.v_cap = 6.5; 205 | 206 | // Accelaration x,y 207 | mit.ax = 0; 208 | mit.ay = 0; 209 | 210 | // Flying up ? 211 | mit.flying_up = 0; 212 | 213 | mit.ascend = function() { 214 | if (!mit.start_btn_clicked) 215 | return; 216 | 217 | if (!mit.game_started) { 218 | mit.game_started = 1; 219 | mit.game_over = 0; 220 | } 221 | 222 | mit.ay = -1.5; 223 | mit.flying_up = 1; 224 | }; 225 | 226 | mit.descend = function() { 227 | if (!mit.start_btn_clicked) 228 | return; 229 | 230 | mit.ay = 0; 231 | mit.flying_up = 0; 232 | }; 233 | 234 | // Game play on mouse clicks too! 235 | window.addEventListener('mousedown', function(e) { 236 | mit.ascend(); 237 | }, false); 238 | 239 | window.addEventListener('mouseup', function(e) { 240 | mit.descend(); 241 | }, false); 242 | 243 | 244 | // Game play on touch too! 245 | window.addEventListener('touchstart', function(e) { 246 | mit.ascend(); 247 | }, false); 248 | 249 | window.addEventListener('touchend', function(e) { 250 | mit.descend(); 251 | }, false); 252 | 253 | 254 | // ... and keyzz... 255 | window.addEventListener('keydown', function(e) { 256 | 257 | // Up 258 | if (e.keyCode === 38) { 259 | mit.ascend(); 260 | 261 | e.preventDefault(); 262 | } 263 | // Down 264 | if (e.keyCode === 40) { 265 | e.preventDefault(); 266 | } 267 | 268 | // Space || Enter 269 | if (e.keyCode === 32 || e.keyCode === 13) { 270 | startGame(); 271 | 272 | e.preventDefault(); 273 | } 274 | 275 | }, false); 276 | 277 | window.addEventListener('keyup', function(e) { 278 | 279 | if (e.keyCode === 38) { 280 | mit.descend(); 281 | 282 | e.preventDefault(); 283 | } 284 | }, false); 285 | 286 | 287 | /* 288 | Performing some game over tasks 289 | */ 290 | mit.gameOver = function() { 291 | ui.start_screen.fadeIn(); 292 | 293 | // High Score 294 | if (mit.score > mit.highScore) { 295 | mit.highScore = parseInt(mit.score); 296 | localStorage.setItem("highScore", JSON.stringify(parseInt(mit.score))); 297 | 298 | ui.high_score.text("High Score: "+ mit.highScore); 299 | } 300 | 301 | // Show last_score 302 | ui.last_score.text("Last Score: " + parseInt(mit.score)); 303 | 304 | 305 | ui.start_game.html('re-start'); 306 | ui.tweet.html('tweet score'); 307 | ui.fb.html('post on fb'); 308 | 309 | mit.descend(); 310 | 311 | // Stop background 312 | mit.Backgrounds.common_bg_speed = 0; 313 | mit.Backgrounds.ground_bg_move_speed = 0; 314 | mit.Backgrounds.fps = 0; 315 | 316 | mit.game_over = 1; 317 | mit.start_btn_clicked = 0; 318 | 319 | // Pappu if invincible will be no morez 320 | mit.Pappu.undoInvincible(); 321 | 322 | // Nuke all clones 323 | mit.Pappu.clones.length = 0; 324 | 325 | // Share 326 | var tweet = document.getElementById("tweet"); 327 | 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'; 328 | 329 | var facebook = document.getElementById("fb"); 330 | 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!'; 331 | 332 | }; 333 | 334 | mit.last_time = new Date(); 335 | setInterval(function() { 336 | mit.ui.fps_count.html(mit.fps.toFixed(0) + ' FPS'); 337 | }, 1000); 338 | 339 | 340 | // Initializations 341 | mit.Backgrounds.init(ctx); 342 | mit.ForkUtils.init(); 343 | mit.BranchUtils.init(); 344 | mit.CollectibleUtils.init(); 345 | mit.Pappu.init(); 346 | mit.PakiaUtils.init(); 347 | 348 | 349 | (function renderGame() { 350 | window.requestAnimationFrame(renderGame); 351 | 352 | // Draw Backgrounds on BG Canvas 353 | mit.Backgrounds.draw(bg_ctx); 354 | 355 | ctx.clearRect(0, 0, W, H); 356 | 357 | // Draw Digs (holds forks) 358 | // I am fine without Digs, but Kushagra 359 | // just WANTS me to do this extra work :/ 360 | // mit.ForkUtils.drawDigs(ctx); 361 | 362 | // Draw Grass on Main Canvas 363 | // mit.Backgrounds.drawGrass(ctx); 364 | 365 | if (mit.flying_up || !mit.game_started) 366 | mit.Pappu.updateFlyFrameCount(); 367 | else 368 | mit.Pappu.updateFlyFrameCount(0); 369 | 370 | 371 | // Game over on reaching any boundary 372 | if (mit.Pappu.hasReachedBoundary(W, H)) { 373 | if (mit.game_over) 374 | return; 375 | 376 | // Performing some game over tasks 377 | mit.gameOver(); 378 | return; 379 | } 380 | 381 | //mit.ForkUtils.draw(ctx); 382 | //mit.BranchUtils.draw(ctx); 383 | 384 | //mit.ForkUtils.checkCollision(); 385 | 386 | // Send over Pakias (Enemies) 387 | // mit.PakiaUtils.render(ctx); 388 | 389 | // Collectibles 390 | // mit.CollectibleUtils.draw(ctx); 391 | 392 | // mit.Pappu.createClones(3); 393 | 394 | if (mit.game_started) { 395 | 396 | // Drawin stuff 397 | mit.ForkUtils.draw(ctx); 398 | mit.BranchUtils.draw(ctx); 399 | mit.CollectibleUtils.draw(ctx); 400 | mit.Pappu.drawClones(ctx); 401 | 402 | // Check Collisions with pappu 403 | if (!mit.Pappu.invincible) { 404 | mit.ForkUtils.checkCollision(); 405 | mit.BranchUtils.checkCollision(); 406 | mit.PakiaUtils.checkCollision(); 407 | } 408 | mit.CollectibleUtils.checkCollision(); 409 | mit.Pappu.checkCloneCollision(); 410 | 411 | // Send over Pakias (Enemies) 412 | if (mit.score > 199) 413 | mit.PakiaUtils.render(ctx); 414 | 415 | // Update score 416 | if (!mit.game_over) { 417 | mit.score = mit.score += 0.1; 418 | ui.score_board.text(parseInt(mit.score)); 419 | } 420 | 421 | // Acceleration + Gravity 422 | // mit.ay = mit.ay + mit.gravity; 423 | 424 | // Velocity 425 | if (!mit.game_over) { 426 | if ( 427 | (mit.vy < mit.v_cap && mit.ay+mit.gravity > 0) || 428 | (mit.vy > -mit.v_cap && mit.ay+mit.gravity < 0) 429 | ) { 430 | 431 | // console.log(mit.ay); 432 | mit.vy += mit.ay; 433 | mit.vy += mit.gravity; 434 | } 435 | 436 | // console.log(vy, ay) 437 | 438 | mit.Pappu.x += mit.vx; 439 | mit.Pappu.y += mit.vy; 440 | 441 | if (mit.vy > mit.v_cap) { 442 | mit.vy = mit.v_cap; 443 | } 444 | } 445 | else { 446 | // on game over, he's gravity is unstoppable 447 | mit.vy += mit.gravity; 448 | mit.Pappu.y += mit.vy; 449 | } 450 | 451 | mit.Pappu.draw(ctx); 452 | } 453 | else { 454 | mit.Pappu.drawStatic(ctx); 455 | } 456 | 457 | // Calculate FPS 458 | mit.cur_time = new Date; 459 | mit.fps = 1e3 / (mit.cur_time - mit.last_time); 460 | mit.last_time = mit.cur_time; 461 | 462 | return; 463 | }()); 464 | 465 | }; 466 | -------------------------------------------------------------------------------- /js/pakia.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | mit.Pakia = function() { 4 | 5 | // Default type will be angry 6 | this.type = 'angry'; 7 | this.sound = document.getElementById("jump1"); 8 | 9 | // Cheating on a bit with the physics 10 | // cant have same gravity for pappu and pakias :( 11 | this.gravity = 0.3; 12 | 13 | this.x; 14 | this.y; 15 | this.w; 16 | this.h; 17 | 18 | this.draw = function(ctx) { 19 | ctx.drawImage(mit.PakiaUtils.pakia_img[this.type], this.x, this.y); 20 | }; 21 | 22 | this.generateRandomPos = function() { 23 | this.x = mit.config.canvas_width/2 + 200; 24 | this.y = mit.config.canvas_height; 25 | }; 26 | 27 | this.generateRandomVelocity = function() { 28 | this.vx = -12; 29 | this.vy = utils.randomNumber(-18,-10); 30 | }; 31 | 32 | this.getBounds = function() { 33 | var bounds = {}; 34 | 35 | bounds.start_x = this.x; 36 | bounds.start_y = this.y; 37 | bounds.end_x = this.x + this.w; 38 | bounds.end_y = this.y + this.h; 39 | 40 | return bounds; 41 | }; 42 | }; 43 | 44 | 45 | mit.PakiaUtils = { 46 | 47 | pakias: [], 48 | 49 | // Only 1 pakia at once, to make sure 50 | // gameplay is not terribly hard 51 | // as forks and branches have already 52 | // made it quite hard. 53 | cur_pakia: false, 54 | 55 | types: [ 56 | 'sad', // pulls 57 | 'happy', // pushes 58 | 'angry' // kills 59 | ], 60 | 61 | // Sounds 62 | sounds: [ 63 | document.getElementById("angry_jump"), 64 | document.getElementById("sad_jump"), 65 | document.getElementById("happy_jump") 66 | ], 67 | 68 | pakia_img: { 69 | sad: {}, 70 | happy: {}, 71 | angry: {} 72 | }, 73 | 74 | init: function() { 75 | 76 | // Loading All Pakia Images 77 | 78 | // this.pakia_img.sad = new Image(); 79 | // this.pakia_img.sad.src = 'img/sad_pakia.png'; 80 | this.pakia_img.sad = mit.image.sad_pakia; 81 | 82 | // this.pakia_img.happy = new Image(); 83 | // this.pakia_img.happy.src = 'img/happy_pakia.png'; 84 | this.pakia_img.happy = mit.image.happy_pakia; 85 | 86 | // this.pakia_img.angry = new Image(); 87 | // this.pakia_img.angry.src = 'img/angry_pakia.png'; 88 | this.pakia_img.angry = mit.image.angry_pakia; 89 | }, 90 | 91 | createPakias: function() { 92 | 93 | for (var i = 0; i < 3; i++) { 94 | var pakia = new mit.Pakia(); 95 | pakia.w = this.pakia_img.sad.width; 96 | pakia.h = this.pakia_img.sad.height; 97 | 98 | pakia.generateRandomPos(); 99 | 100 | pakia.generateRandomVelocity(); 101 | 102 | pakia.type = this.types[i]; 103 | // pakia.type = this.types[0]; 104 | 105 | if (pakia.type == 'angry') 106 | pakia.sound = this.sounds[0]; 107 | else if (pakia.type == 'sad') 108 | pakia.sound = this.sounds[1]; 109 | else if (pakia.type == 'happy') 110 | pakia.sound = this.sounds[2]; 111 | 112 | this.pakias.push(pakia); 113 | } 114 | 115 | //console.log(this.pakias); 116 | }, 117 | 118 | reflow: function(ctx) { 119 | 120 | if (!this.cur_pakia) { 121 | // cur_pakia is one thats currently visible 122 | // that is, in the air! 123 | 124 | // Object by Reference! 125 | this.cur_pakia = this.pakias[utils.randomNumber(0,2)]; 126 | 127 | this.cur_pakia.generateRandomPos(); 128 | this.cur_pakia.generateRandomVelocity(); 129 | } 130 | 131 | this.cur_pakia.vy += this.cur_pakia.gravity; 132 | 133 | this.cur_pakia.x += this.cur_pakia.vx; 134 | this.cur_pakia.y += this.cur_pakia.vy; 135 | // console.log(this.cur_pakia.x) 136 | 137 | // Reset positions 138 | if ( 139 | this.cur_pakia.x + this.cur_pakia.w < 0 || 140 | this.cur_pakia.y > mit.H 141 | ) { 142 | this.cur_pakia.generateRandomPos(); 143 | 144 | this.cur_pakia.generateRandomVelocity(); 145 | 146 | // Important! since JS's game's all about 147 | // objects by reference. 148 | if (this.cur_pakia.has_stuck) 149 | delete this.cur_pakia.has_stuck; 150 | 151 | // wont set the referenced pointer to 152 | // false, so we're safe :D 153 | this.cur_pakia = false; 154 | } 155 | }, 156 | 157 | repaint: function(ctx) { 158 | if (this.cur_pakia) 159 | this.cur_pakia.draw(ctx); 160 | }, 161 | 162 | render: function(ctx) { 163 | if (!this.pakias.length) { 164 | this.createPakias(); 165 | } 166 | 167 | if (mit.score.toFixed(2) % 20 === 0 || this.cur_pakia) { 168 | this.reflow(ctx); 169 | this.repaint(ctx); 170 | } 171 | 172 | if (mit.score.toFixed(2) % 20 === 0 && this.cur_pakia) { 173 | this.cur_pakia.sound.play(); 174 | } 175 | }, 176 | 177 | checkCollision: function() { 178 | if (!this.cur_pakia) 179 | return; 180 | 181 | var pappu_bounds = mit.Pappu.getBounds(); 182 | var pakia_bounds = this.cur_pakia.getBounds(); 183 | 184 | if ( 185 | pappu_bounds.end_x > pakia_bounds.start_x+20 && 186 | pakia_bounds.end_x-20 > pappu_bounds.start_x && 187 | pappu_bounds.end_y > pakia_bounds.start_y+20 && 188 | pakia_bounds.end_y-20 > pappu_bounds.start_y 189 | ) { 190 | 191 | // Depending upon the type of the pakia 192 | switch (this.cur_pakia.type) { 193 | case 'angry': 194 | mit.gameOver(); 195 | break; 196 | 197 | case 'sad': 198 | // Pull 199 | 200 | if (!this.cur_pakia.has_stuck) { 201 | mit.vy += 20; 202 | this.cur_pakia.y += 20; 203 | this.cur_pakia.vx = 0; 204 | } 205 | 206 | this.cur_pakia.has_stuck = 1; 207 | 208 | break; 209 | 210 | case 'happy': 211 | // Push 212 | 213 | if (this.cur_pakia.vy < 0) 214 | mit.vy -= 10; 215 | else 216 | mit.vy += 10; 217 | 218 | break; 219 | } 220 | 221 | } 222 | 223 | return; 224 | } 225 | 226 | }; 227 | 228 | }()); 229 | -------------------------------------------------------------------------------- /js/pappu.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | // There will be only 1 Pappu 4 | 5 | mit.Pappu = { 6 | x: 50, 7 | y: 10, 8 | w: 50, 9 | h: 50, 10 | 11 | invincible: 0, 12 | invincibility_start: 0, 13 | invincibility_time: 0, 14 | clones: [], 15 | 16 | rotate_angle: 0, 17 | 18 | sprite: {}, 19 | sound: '', 20 | 21 | // Rate of sprite frame change 22 | // per animation frame. 23 | change_per_frame: 10, 24 | 25 | fly_frame_count: 0, 26 | max_fly_frame_count: 10, 27 | 28 | init: function() { 29 | this.sound = document.getElementById("flap"); 30 | 31 | // Initializing Pappu Sprite, lolzzz..! 32 | // this.sprite = new Image(); 33 | // this.sprite.src = 'img/pappu.png'; 34 | this.sprite = mit.image.pappu; 35 | 36 | //pappu.w = pappu.sprite.width; 37 | mit.Pappu.w = mit.Pappu.sprite.width; 38 | mit.Pappu.h = 60; 39 | 40 | // Sprite Frame Count 41 | mit.Pappu.max_fly_frame_count = 8; 42 | mit.Pappu.max_fly_frame_count--; 43 | 44 | // Sprite Frame Change Speed. 45 | // This will affect the flap speed. 46 | // 1.6 is the perfect value! 47 | mit.Pappu.change_per_frame = 1.6; 48 | 49 | // X Pos 50 | mit.Pappu.x = 33; 51 | }, 52 | 53 | undoInvincible: function() { 54 | this.invincible = 0; 55 | this.invincibility_start = 0; 56 | this.invincible_timer = 0; 57 | 58 | mit.ui.invincible_timer.hide(); 59 | }, 60 | 61 | draw: function(ctx) { 62 | var cur_sprite_frame = this.fly_frame_count / this.change_per_frame; 63 | 64 | if (utils.isInt(cur_sprite_frame)) { 65 | var source_y = cur_sprite_frame * 60; 66 | } 67 | 68 | else { 69 | //var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)%this.change_per_frame; 70 | 71 | // Ultra smooth animations 72 | var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame) 73 | var source_y = old_sprite_frame * 60; 74 | } 75 | 76 | // console.log(cur_sprite_frame, source_x); 77 | 78 | // Rotation on Flying 79 | if (mit.flying_up) { 80 | this.sound.play(); 81 | 82 | if (this.rotate_angle > -15) { 83 | this.rotate_angle -= 2; 84 | } 85 | } 86 | else if (mit.game_over) { 87 | // draw() is called as long as 88 | // pappu hasnt hit boundaries and over'ed the game :P 89 | 90 | // Game Over Gugglu! 91 | this.rotate_angle += 4; 92 | } 93 | else { 94 | if (this.rotate_angle < 30) { 95 | this.rotate_angle += 2; 96 | } 97 | } 98 | 99 | ctx.save(); 100 | 101 | ctx.translate(this.x, this.y); 102 | ctx.translate(this.w/2, this.h/2); 103 | ctx.rotate(utils.toRadian(this.rotate_angle)); 104 | 105 | if (this.invincible) { 106 | ctx.globalAlpha = 0.4; 107 | 108 | // Current time 109 | var cur_time = new Date().getTime(); 110 | var time_diff = cur_time - this.invincibility_start; 111 | 112 | var timer_progress = (time_diff/this.invincibility_time) * 100; 113 | 114 | if (timer_progress > 100) 115 | this.undoInvincible(); 116 | else 117 | mit.ui.invincible_loader.css('width', timer_progress + '%'); 118 | 119 | // console.log(timer_progress) 120 | } 121 | 122 | ctx.drawImage( 123 | this.sprite, 124 | 0, 125 | source_y, 126 | this.w, 127 | 60, 128 | -this.w/2, 129 | -this.h/2, 130 | this.w, 131 | 60 132 | ); 133 | 134 | ctx.restore(); 135 | }, 136 | 137 | drawStatic: function(ctx) { 138 | var cur_sprite_frame = this.fly_frame_count / this.change_per_frame; 139 | 140 | if (utils.isInt(cur_sprite_frame)) { 141 | var source_y = cur_sprite_frame * 60; 142 | } 143 | 144 | else { 145 | //var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)%this.change_per_frame; 146 | 147 | // Ultra smooth animations 148 | var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame) 149 | var source_y = old_sprite_frame * 60; 150 | } 151 | 152 | 153 | this.y = mit.Backgrounds.log_y-42; 154 | 155 | /*ctx.drawImage( 156 | this.sprite, 157 | 0, 158 | 0, 159 | this.w, 160 | 60, 161 | this.x, 162 | this.y, 163 | this.w, 164 | 60 165 | );*/ 166 | 167 | ctx.drawImage( 168 | this.sprite, 169 | 0, 170 | source_y, 171 | this.w, 172 | 60, 173 | this.x, 174 | this.y, 175 | this.w, 176 | 60 177 | ); 178 | }, 179 | 180 | updateFlyFrameCount: function(count) { 181 | if (typeof count !== 'number') { 182 | this.fly_frame_count++; 183 | 184 | if (parseInt(this.fly_frame_count/this.change_per_frame) > this.max_fly_frame_count) { 185 | this.fly_frame_count = 0; 186 | } 187 | 188 | return; 189 | } 190 | 191 | this.fly_frame_count = count; 192 | }, 193 | 194 | hasReachedBoundary: function(canvas_width, canvas_height) { 195 | // Crossed Sides ? 196 | // `c` stands for crossed 197 | 198 | var ctop = (this.y < 0 - this.h); 199 | var cbtm = (this.y > mit.H); 200 | var cleft = (this.x < 0); 201 | var crgt = (this.x > mit.W); 202 | 203 | // return true if crossed any sides 204 | if (ctop || cbtm || cleft || crgt) { 205 | return true; 206 | } 207 | 208 | return false; 209 | }, 210 | 211 | getBounds: function() { 212 | var b = {}; 213 | 214 | b.start_x = this.x; 215 | b.start_y = this.y; 216 | b.end_x = this.x + this.w; 217 | b.end_y = this.y + this.h; 218 | 219 | return b; 220 | }, 221 | 222 | createClones: function(count) { 223 | // This method will be usually called 224 | // when pappu gathers a 'clone' collectible. 225 | 226 | var pappu_clone; 227 | 228 | for (var i = 0; i < count; i++) { 229 | pappu_clone = Object.create(mit.Pappu); 230 | 231 | pappu_clone.invincible = 0; 232 | 233 | this.clones.push(pappu_clone); 234 | } 235 | 236 | return; 237 | }, 238 | 239 | drawClones: function(ctx) { 240 | 241 | var self = this; 242 | 243 | self.clones.forEach(function(clone, index) { 244 | if (clone.x > mit.W || clone.y < 0 || clone.y > mit.H) 245 | self.clones.splice(index, 1); 246 | 247 | clone.x += utils.randomNumber(500, 1000); 248 | clone.y += utils.randomNumber(-2000, 2000); 249 | 250 | clone.draw(ctx); 251 | }); 252 | 253 | return; 254 | }, 255 | 256 | checkCloneCollision: function() { 257 | 258 | var self = this; 259 | 260 | // super optimization :P 261 | if (!self.clones.length) 262 | return; 263 | 264 | var branches = mit.BranchUtils.branches; 265 | var forks = mit.ForkUtils.forks; 266 | var pakias = mit.PakiaUtils.pakias; 267 | 268 | // Check collisions with branches 269 | branches.forEach(function(branch, branch_index) { 270 | var branch_bound = branch.getBounds(); 271 | 272 | var branch_broke = 0; 273 | 274 | self.clones.forEach(function(clone) { 275 | 276 | if (branch_broke) 277 | return; 278 | 279 | var clone_bound = clone.getBounds(); 280 | 281 | if (utils.intersect(branch_bound, clone_bound)) { 282 | branches.splice(branch_index, 1); 283 | 284 | branch_broke = 1; 285 | } 286 | }); 287 | 288 | return; 289 | }); 290 | 291 | // Check collisions with forks 292 | forks.forEach(function(fork, fork_index) { 293 | var fork_head_bound = fork.getHeadBounds(); 294 | var fork_handle_bound = fork.getHandleBounds(); 295 | 296 | var fork_broke = 0; 297 | 298 | self.clones.forEach(function(clone) { 299 | 300 | if (fork_broke) 301 | return; 302 | 303 | var clone_bound = clone.getBounds(); 304 | 305 | if ( 306 | utils.intersect(fork_head_bound, clone_bound) || 307 | utils.intersect(fork_handle_bound, clone_bound) 308 | ) { 309 | 310 | // 2 pakias could kill same fork 311 | // hence just check whether it exists or not 312 | forks.splice(fork_index, 1); 313 | 314 | fork_broke = 1; 315 | } 316 | 317 | return; 318 | }); 319 | 320 | return; 321 | }); 322 | 323 | // Check collisions with pakias 324 | pakias.forEach(function(pakia, pakia_index) { 325 | var pakia_bound = pakia.getBounds(); 326 | 327 | var pakia_dead = 0; 328 | 329 | self.clones.forEach(function(clone) { 330 | 331 | if (pakia_dead) 332 | return; 333 | 334 | var clone_bound = clone.getBounds(); 335 | 336 | if (utils.intersect(pakia_bound, clone_bound)) { 337 | mit.PakiaUtils.cur_pakia = false; 338 | 339 | pakia_dead = 1; 340 | } 341 | 342 | return; 343 | }); 344 | 345 | return; 346 | }); 347 | 348 | return; 349 | } 350 | }; 351 | 352 | }()); 353 | -------------------------------------------------------------------------------- /js/utils.js: -------------------------------------------------------------------------------- 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 | if (bounds1.end_x < bounds2.start_x) { 29 | return true; 30 | } 31 | if (bounds2.end_x < bounds1.start_x) { 32 | return true; 33 | } 34 | if (bounds1.end_y < bounds2.start_y) { 35 | return true; 36 | } 37 | if (bounds2.end_y < bounds1.start_y) { 38 | return true; 39 | } 40 | return false; 41 | }; 42 | 43 | }()); 44 | -------------------------------------------------------------------------------- /kong.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Pappu Pakia | Khelein 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 |
17 |

pappu pakia

18 |

19 | by 20 | Kushagra 21 | and 22 | Rishabh 23 |

24 |

25 |

26 | 27 |
28 | 29 |
30 | 35 |
36 |
37 | 38 | 39 | 40 | 44 | 45 | 49 | 50 | 54 | 55 | 59 | 60 | 64 | 65 | 69 | 70 | 71 | 72 | 73 |
0
74 | 75 |
76 |
77 |
78 | 79 | 80 | 81 | 82 |
83 |

Loading...

84 |
85 |
86 |
87 |
88 | 89 |
90 | 91 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /sound/flap.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/sound/flap.mp3 -------------------------------------------------------------------------------- /sound/flap.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/sound/flap.ogg -------------------------------------------------------------------------------- /sound/jump1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/sound/jump1.mp3 -------------------------------------------------------------------------------- /sound/jump1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/sound/jump1.ogg -------------------------------------------------------------------------------- /sound/jump2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/sound/jump2.mp3 -------------------------------------------------------------------------------- /sound/jump2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/sound/jump2.ogg -------------------------------------------------------------------------------- /sound/jump3.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/sound/jump3.mp3 -------------------------------------------------------------------------------- /sound/jump3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/sound/jump3.ogg -------------------------------------------------------------------------------- /sound/pappu-pakia2.3.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/sound/pappu-pakia2.3.mp3 -------------------------------------------------------------------------------- /sound/pappu-pakia2.3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/sound/pappu-pakia2.3.ogg -------------------------------------------------------------------------------- /sound/ting.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/sound/ting.mp3 -------------------------------------------------------------------------------- /sound/ting.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/pappu-pakia/9682680dfd7fef54ac23d965054402c68d5c9fe5/sound/ting.ogg --------------------------------------------------------------------------------