├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── assets ├── dust.particlefx ├── hero.atlas ├── images │ ├── Pink │ │ ├── alienPink_climb1.png │ │ ├── alienPink_climb2.png │ │ ├── alienPink_duck.png │ │ ├── alienPink_front.png │ │ ├── alienPink_hit.png │ │ ├── alienPink_jump.png │ │ ├── alienPink_stand.png │ │ ├── alienPink_swim1.png │ │ ├── alienPink_swim2.png │ │ ├── alienPink_walk1.png │ │ └── alienPink_walk2.png │ ├── background.atlas │ ├── blue_grass.png │ └── spritesheet_tiles.png ├── jump.sound ├── land.sound ├── level.tilemap ├── level.tilesource └── sounds │ ├── footstep_grass_000.ogg │ └── phaseJump1.ogg ├── game.project ├── input └── game.input_binding └── main ├── hero.script └── main.collection /.gitattributes: -------------------------------------------------------------------------------- 1 | # Defold Protocol Buffer Text Files (https://github.com/github/linguist/issues/5091) 2 | *.animationset linguist-language=JSON5 3 | *.atlas linguist-language=JSON5 4 | *.camera linguist-language=JSON5 5 | *.collection linguist-language=JSON5 6 | *.collectionfactory linguist-language=JSON5 7 | *.collectionproxy linguist-language=JSON5 8 | *.collisionobject linguist-language=JSON5 9 | *.cubemap linguist-language=JSON5 10 | *.display_profiles linguist-language=JSON5 11 | *.factory linguist-language=JSON5 12 | *.font linguist-language=JSON5 13 | *.gamepads linguist-language=JSON5 14 | *.go linguist-language=JSON5 15 | *.gui linguist-language=JSON5 16 | *.input_binding linguist-language=JSON5 17 | *.label linguist-language=JSON5 18 | *.material linguist-language=JSON5 19 | *.mesh linguist-language=JSON5 20 | *.model linguist-language=JSON5 21 | *.particlefx linguist-language=JSON5 22 | *.render linguist-language=JSON5 23 | *.sound linguist-language=JSON5 24 | *.sprite linguist-language=JSON5 25 | *.spinemodel linguist-language=JSON5 26 | *.spinescene linguist-language=JSON5 27 | *.texture_profiles linguist-language=JSON5 28 | *.tilemap linguist-language=JSON5 29 | *.tilesource linguist-language=JSON5 30 | 31 | # Defold JSON Files 32 | *.buffer linguist-language=JSON 33 | 34 | # Defold GLSL Shaders 35 | *.fp linguist-language=GLSL 36 | *.vp linguist-language=GLSL 37 | 38 | # Defold Lua Files 39 | *.editor_script linguist-language=Lua 40 | *.render_script linguist-language=Lua 41 | *.script linguist-language=Lua 42 | *.gui_script linguist-language=Lua 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.internal 2 | /build 3 | .externalToolBuilders 4 | .DS_Store 5 | Thumbs.db 6 | .lock-wscript 7 | *.pyc 8 | .project 9 | .cproject 10 | builtins 11 | /.editor_settings -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT license 2 | 3 | Copyright 2023 Paweł Jarosz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Defold Platformer Tutorial 2 | 3 | This repository follows the [Platformer Tutorial for Defold Game Engine video series](https://www.youtube.com/watch?v=R4oEB6e8G0A&list=PL4_orbQ0JeQtiQMHMC4gFI5JhPGKHaVB_) on my [Unfolding Gamedev channel](https://www.youtube.com/@unfolding_gamedev). 4 | 5 | Each commit here is made at the end of each video, so you can travel through the history or look up the final code whenever needed. 6 | 7 | ## Part 1 - v0.1 - Atlases and Tilemaps 8 | 9 | [▶️ Part 1 video](https://youtu.be/R4oEB6e8G0A?si=-VAiJ0RatwqrcsjO) 10 | 11 | * Setting up project. 12 | * Adding basic visual assets ([thanks to Kenney!](https://kenney.nl)). 13 | * Making atlas with images. 14 | * Making tilesource. 15 | * Creating level scene with tilemaps. 16 | * Adding sprite representing our hero. 17 | * Running game. 18 | 19 | ## Part 2 - v0.2 - Script, movement and animations 20 | 21 | [▶️ Part 2 video](https://youtu.be/R4oEB6e8G0A?si=R2uOHRyPF8PNp_wH) 22 | 23 | * Setting up input bindings. 24 | * Writing script for handling inputs. 25 | * Adding functionality to move game object according to inputs. 26 | * Adding functionality to play animations and flip sprites according to direction. 27 | * Attaching script to game object as component. 28 | 29 | ## Part 3 - v0.3 - Gravity and Collisions 30 | 31 | [▶️ Part 3 video](https://youtu.be/V3iJtpvAOxU?si=yo4clxnFh0PcUWrS) 32 | 33 | * Adding gravity and velocity based movement implementation. 34 | * Adding collision objects to level and hero character. 35 | * Adding collision shapes based on primitive shape and tilesource. 36 | * Adding collision handling between hero and level. 37 | 38 | ## Part 4 - v0.4 - Jumping 39 | 40 | [▶️ Part 4 video](https://youtu.be/F5XMemcAwmE?si=iWULSENETaeVGoun) 41 | 42 | * Adding jumping mechanics. 43 | * Adding compensation function for collision handling. 44 | 45 | ## Part 5 - v0.5 - Particle and Sound FX 46 | 47 | [▶️ Part 5 video](https://youtu.be/XCLh54jkzCw?si=zHd0p97N76oaCgp_) 48 | 49 | * Improving compensation function. 50 | * Adding particleFX and changing script to play it when jumping and landing. 51 | * Adding sound components and playing them when jumping and landing. 52 | 53 | ## Part 6 - v0.6 - Camera 54 | 55 | [▶️ Part 6 video](https://youtu.be/9OTxUPEu_s4?si=_zHubkKYARhJLJU0) 56 | 57 | * Adding camera component following player character. 58 | * Difference between perspective and orthographic camera and other properties. 59 | 60 | 61 | 62 | --- 63 | 64 | LICENSE: MIT 65 | 66 | If you run into trouble, ask on the [Defold forum](https://forum.defold.com) or [Discord](https://discord.gg/cHBde7J) 67 | 68 | ❤️ If you like what I create, you can also support me on: 69 | * [Github Sponsors](https://github.com/sponsors/paweljarosz) 70 | * [Patreon](https://www.patreon.com/witchcrafter_rpg) 71 | * [Ko-fi](https://ko-fi.com/witchcrafter) 72 | 73 | Also, wishlist a game I'm working on: [Witchcrafter: Empire Legends](https://witchcrafter.carrd.co) 74 | 75 | Happy Defolding! 76 | 77 | Pawel 78 | 79 | --- 80 | -------------------------------------------------------------------------------- /assets/dust.particlefx: -------------------------------------------------------------------------------- 1 | emitters { 2 | id: "emitter" 3 | mode: PLAY_MODE_ONCE 4 | duration: 0.1 5 | space: EMISSION_SPACE_WORLD 6 | position { 7 | x: 0.0 8 | y: 0.0 9 | z: 0.0 10 | } 11 | rotation { 12 | x: 0.0 13 | y: 0.0 14 | z: 0.60901403 15 | w: 0.7931594 16 | } 17 | tile_source: "/builtins/graphics/particle_blob.tilesource" 18 | animation: "anim" 19 | material: "/builtins/materials/particlefx.material" 20 | blend_mode: BLEND_MODE_ADD 21 | particle_orientation: PARTICLE_ORIENTATION_DEFAULT 22 | inherit_velocity: 0.0 23 | max_particle_count: 128 24 | type: EMITTER_TYPE_2DCONE 25 | start_delay: 0.0 26 | properties { 27 | key: EMITTER_KEY_SPAWN_RATE 28 | points { 29 | x: 0.0 30 | y: 30.0 31 | t_x: 1.0 32 | t_y: 0.0 33 | } 34 | spread: 0.0 35 | } 36 | properties { 37 | key: EMITTER_KEY_SIZE_X 38 | points { 39 | x: 0.0 40 | y: 8.0 41 | t_x: 1.0 42 | t_y: 0.0 43 | } 44 | spread: 0.0 45 | } 46 | properties { 47 | key: EMITTER_KEY_SIZE_Y 48 | points { 49 | x: 0.0 50 | y: 12.0 51 | t_x: 1.0 52 | t_y: 0.0 53 | } 54 | spread: 0.0 55 | } 56 | properties { 57 | key: EMITTER_KEY_SIZE_Z 58 | points { 59 | x: 0.0 60 | y: 0.0 61 | t_x: 1.0 62 | t_y: 0.0 63 | } 64 | spread: 0.0 65 | } 66 | properties { 67 | key: EMITTER_KEY_PARTICLE_LIFE_TIME 68 | points { 69 | x: 0.0 70 | y: 1.0 71 | t_x: 1.0 72 | t_y: 0.0 73 | } 74 | spread: 0.5 75 | } 76 | properties { 77 | key: EMITTER_KEY_PARTICLE_SPEED 78 | points { 79 | x: 0.0 80 | y: 150.0 81 | t_x: 1.0 82 | t_y: 0.0 83 | } 84 | spread: 0.0 85 | } 86 | properties { 87 | key: EMITTER_KEY_PARTICLE_SIZE 88 | points { 89 | x: 0.0 90 | y: 70.0 91 | t_x: 1.0 92 | t_y: 0.0 93 | } 94 | spread: 20.0 95 | } 96 | properties { 97 | key: EMITTER_KEY_PARTICLE_RED 98 | points { 99 | x: 0.0 100 | y: 1.0 101 | t_x: 1.0 102 | t_y: 0.0 103 | } 104 | spread: 0.0 105 | } 106 | properties { 107 | key: EMITTER_KEY_PARTICLE_GREEN 108 | points { 109 | x: 0.0 110 | y: 1.0 111 | t_x: 1.0 112 | t_y: 0.0 113 | } 114 | spread: 0.0 115 | } 116 | properties { 117 | key: EMITTER_KEY_PARTICLE_BLUE 118 | points { 119 | x: 0.0 120 | y: 1.0 121 | t_x: 1.0 122 | t_y: 0.0 123 | } 124 | spread: 0.0 125 | } 126 | properties { 127 | key: EMITTER_KEY_PARTICLE_ALPHA 128 | points { 129 | x: 0.0 130 | y: 1.0 131 | t_x: 1.0 132 | t_y: 0.0 133 | } 134 | spread: 0.0 135 | } 136 | properties { 137 | key: EMITTER_KEY_PARTICLE_ROTATION 138 | points { 139 | x: 0.0 140 | y: 0.0 141 | t_x: 1.0 142 | t_y: 0.0 143 | } 144 | spread: 0.0 145 | } 146 | properties { 147 | key: EMITTER_KEY_PARTICLE_STRETCH_FACTOR_X 148 | points { 149 | x: 0.0 150 | y: 0.0 151 | t_x: 1.0 152 | t_y: 0.0 153 | } 154 | spread: 0.0 155 | } 156 | properties { 157 | key: EMITTER_KEY_PARTICLE_STRETCH_FACTOR_Y 158 | points { 159 | x: 0.0 160 | y: 0.0 161 | t_x: 1.0 162 | t_y: 0.0 163 | } 164 | spread: 0.0 165 | } 166 | properties { 167 | key: EMITTER_KEY_PARTICLE_ANGULAR_VELOCITY 168 | points { 169 | x: 0.0 170 | y: 0.0 171 | t_x: 1.0 172 | t_y: 0.0 173 | } 174 | spread: 0.0 175 | } 176 | particle_properties { 177 | key: PARTICLE_KEY_SCALE 178 | points { 179 | x: 0.0 180 | y: 1.0 181 | t_x: 1.0 182 | t_y: 0.0 183 | } 184 | } 185 | particle_properties { 186 | key: PARTICLE_KEY_RED 187 | points { 188 | x: 0.0 189 | y: 1.0 190 | t_x: 1.0 191 | t_y: 0.0 192 | } 193 | } 194 | particle_properties { 195 | key: PARTICLE_KEY_GREEN 196 | points { 197 | x: 0.0 198 | y: 1.0 199 | t_x: 1.0 200 | t_y: 0.0 201 | } 202 | } 203 | particle_properties { 204 | key: PARTICLE_KEY_BLUE 205 | points { 206 | x: 0.0 207 | y: 1.0 208 | t_x: 1.0 209 | t_y: 0.0 210 | } 211 | points { 212 | x: 0.82541084 213 | y: 0.6466615 214 | t_x: 0.5583563 215 | t_y: -0.8296012 216 | } 217 | points { 218 | x: 1.0 219 | y: 0.0032692305 220 | t_x: 1.0 221 | t_y: 0.0 222 | } 223 | } 224 | particle_properties { 225 | key: PARTICLE_KEY_ALPHA 226 | points { 227 | x: 0.0 228 | y: 0.0 229 | t_x: 0.07194582 230 | t_y: 0.99740857 231 | } 232 | points { 233 | x: 0.11320755 234 | y: 0.99277455 235 | t_x: 0.99418455 236 | t_y: 0.10768964 237 | } 238 | points { 239 | x: 0.7112546 240 | y: 0.555656 241 | t_x: 0.5694311 242 | t_y: -0.82203907 243 | } 244 | points { 245 | x: 1.0 246 | y: 0.0072254334 247 | t_x: 0.4737472 248 | t_y: -0.8806609 249 | } 250 | } 251 | particle_properties { 252 | key: PARTICLE_KEY_ROTATION 253 | points { 254 | x: 0.0 255 | y: 0.0 256 | t_x: 1.0 257 | t_y: 0.0 258 | } 259 | } 260 | particle_properties { 261 | key: PARTICLE_KEY_STRETCH_FACTOR_X 262 | points { 263 | x: 0.0 264 | y: 0.0 265 | t_x: 1.0 266 | t_y: 0.0 267 | } 268 | } 269 | particle_properties { 270 | key: PARTICLE_KEY_STRETCH_FACTOR_Y 271 | points { 272 | x: 0.0 273 | y: 0.0 274 | t_x: 1.0 275 | t_y: 0.0 276 | } 277 | } 278 | particle_properties { 279 | key: PARTICLE_KEY_ANGULAR_VELOCITY 280 | points { 281 | x: 0.0 282 | y: 1.0 283 | t_x: 1.0 284 | t_y: 0.0 285 | } 286 | } 287 | modifiers { 288 | type: MODIFIER_TYPE_DRAG 289 | use_direction: 0 290 | position { 291 | x: 0.0 292 | y: 0.0 293 | z: 0.0 294 | } 295 | rotation { 296 | x: 0.0 297 | y: 0.0 298 | z: 0.0 299 | w: 1.0 300 | } 301 | properties { 302 | key: MODIFIER_KEY_MAGNITUDE 303 | points { 304 | x: 0.0 305 | y: 1.0 306 | t_x: 1.0 307 | t_y: 0.0 308 | } 309 | spread: 0.0 310 | } 311 | } 312 | modifiers { 313 | type: MODIFIER_TYPE_ACCELERATION 314 | use_direction: 0 315 | position { 316 | x: 0.0 317 | y: 0.0 318 | z: 0.0 319 | } 320 | rotation { 321 | x: 0.0 322 | y: 0.0 323 | z: 0.80150837 324 | w: 0.59798354 325 | } 326 | properties { 327 | key: MODIFIER_KEY_MAGNITUDE 328 | points { 329 | x: 0.0 330 | y: -100.0 331 | t_x: 1.0 332 | t_y: 0.0 333 | } 334 | spread: 0.0 335 | } 336 | } 337 | size_mode: SIZE_MODE_MANUAL 338 | start_delay_spread: 0.0 339 | duration_spread: 0.05 340 | stretch_with_velocity: false 341 | start_offset: 0.0 342 | pivot { 343 | x: 0.0 344 | y: 0.0 345 | z: 0.0 346 | } 347 | } 348 | emitters { 349 | id: "emitter1" 350 | mode: PLAY_MODE_ONCE 351 | duration: 0.1 352 | space: EMISSION_SPACE_WORLD 353 | position { 354 | x: 0.0 355 | y: 0.0 356 | z: 0.0 357 | } 358 | rotation { 359 | x: 0.60901064 360 | y: 0.79316205 361 | z: 3.7291145E-17 362 | w: 4.856717E-17 363 | } 364 | tile_source: "/builtins/graphics/particle_blob.tilesource" 365 | animation: "anim" 366 | material: "/builtins/materials/particlefx.material" 367 | blend_mode: BLEND_MODE_ADD 368 | particle_orientation: PARTICLE_ORIENTATION_DEFAULT 369 | inherit_velocity: 0.0 370 | max_particle_count: 128 371 | type: EMITTER_TYPE_2DCONE 372 | start_delay: 0.0 373 | properties { 374 | key: EMITTER_KEY_SPAWN_RATE 375 | points { 376 | x: 0.0 377 | y: 30.0 378 | t_x: 1.0 379 | t_y: 0.0 380 | } 381 | spread: 0.0 382 | } 383 | properties { 384 | key: EMITTER_KEY_SIZE_X 385 | points { 386 | x: 0.0 387 | y: 8.0 388 | t_x: 1.0 389 | t_y: 0.0 390 | } 391 | spread: 0.0 392 | } 393 | properties { 394 | key: EMITTER_KEY_SIZE_Y 395 | points { 396 | x: 0.0 397 | y: 12.0 398 | t_x: 1.0 399 | t_y: 0.0 400 | } 401 | spread: 0.0 402 | } 403 | properties { 404 | key: EMITTER_KEY_SIZE_Z 405 | points { 406 | x: 0.0 407 | y: 0.0 408 | t_x: 1.0 409 | t_y: 0.0 410 | } 411 | spread: 0.0 412 | } 413 | properties { 414 | key: EMITTER_KEY_PARTICLE_LIFE_TIME 415 | points { 416 | x: 0.0 417 | y: 1.0 418 | t_x: 1.0 419 | t_y: 0.0 420 | } 421 | spread: 0.5 422 | } 423 | properties { 424 | key: EMITTER_KEY_PARTICLE_SPEED 425 | points { 426 | x: 0.0 427 | y: 150.0 428 | t_x: 1.0 429 | t_y: 0.0 430 | } 431 | spread: 0.0 432 | } 433 | properties { 434 | key: EMITTER_KEY_PARTICLE_SIZE 435 | points { 436 | x: 0.0 437 | y: 70.0 438 | t_x: 1.0 439 | t_y: 0.0 440 | } 441 | spread: 20.0 442 | } 443 | properties { 444 | key: EMITTER_KEY_PARTICLE_RED 445 | points { 446 | x: 0.0 447 | y: 1.0 448 | t_x: 1.0 449 | t_y: 0.0 450 | } 451 | spread: 0.0 452 | } 453 | properties { 454 | key: EMITTER_KEY_PARTICLE_GREEN 455 | points { 456 | x: 0.0 457 | y: 1.0 458 | t_x: 1.0 459 | t_y: 0.0 460 | } 461 | spread: 0.0 462 | } 463 | properties { 464 | key: EMITTER_KEY_PARTICLE_BLUE 465 | points { 466 | x: 0.0 467 | y: 1.0 468 | t_x: 1.0 469 | t_y: 0.0 470 | } 471 | spread: 0.0 472 | } 473 | properties { 474 | key: EMITTER_KEY_PARTICLE_ALPHA 475 | points { 476 | x: 0.0 477 | y: 1.0 478 | t_x: 1.0 479 | t_y: 0.0 480 | } 481 | spread: 0.0 482 | } 483 | properties { 484 | key: EMITTER_KEY_PARTICLE_ROTATION 485 | points { 486 | x: 0.0 487 | y: 0.0 488 | t_x: 1.0 489 | t_y: 0.0 490 | } 491 | spread: 0.0 492 | } 493 | properties { 494 | key: EMITTER_KEY_PARTICLE_STRETCH_FACTOR_X 495 | points { 496 | x: 0.0 497 | y: 0.0 498 | t_x: 1.0 499 | t_y: 0.0 500 | } 501 | spread: 0.0 502 | } 503 | properties { 504 | key: EMITTER_KEY_PARTICLE_STRETCH_FACTOR_Y 505 | points { 506 | x: 0.0 507 | y: 0.0 508 | t_x: 1.0 509 | t_y: 0.0 510 | } 511 | spread: 0.0 512 | } 513 | properties { 514 | key: EMITTER_KEY_PARTICLE_ANGULAR_VELOCITY 515 | points { 516 | x: 0.0 517 | y: 0.0 518 | t_x: 1.0 519 | t_y: 0.0 520 | } 521 | spread: 0.0 522 | } 523 | particle_properties { 524 | key: PARTICLE_KEY_SCALE 525 | points { 526 | x: 0.0 527 | y: 1.0 528 | t_x: 1.0 529 | t_y: 0.0 530 | } 531 | } 532 | particle_properties { 533 | key: PARTICLE_KEY_RED 534 | points { 535 | x: 0.0 536 | y: 1.0 537 | t_x: 1.0 538 | t_y: 0.0 539 | } 540 | } 541 | particle_properties { 542 | key: PARTICLE_KEY_GREEN 543 | points { 544 | x: 0.0 545 | y: 1.0 546 | t_x: 1.0 547 | t_y: 0.0 548 | } 549 | } 550 | particle_properties { 551 | key: PARTICLE_KEY_BLUE 552 | points { 553 | x: 0.0 554 | y: 1.0 555 | t_x: 1.0 556 | t_y: 0.0 557 | } 558 | points { 559 | x: 0.82541084 560 | y: 0.6466615 561 | t_x: 0.5583563 562 | t_y: -0.8296012 563 | } 564 | points { 565 | x: 1.0 566 | y: 0.0032692305 567 | t_x: 1.0 568 | t_y: 0.0 569 | } 570 | } 571 | particle_properties { 572 | key: PARTICLE_KEY_ALPHA 573 | points { 574 | x: 0.0 575 | y: 0.0 576 | t_x: 0.07194582 577 | t_y: 0.99740857 578 | } 579 | points { 580 | x: 0.11320755 581 | y: 0.99277455 582 | t_x: 0.99418455 583 | t_y: 0.10768964 584 | } 585 | points { 586 | x: 0.7112546 587 | y: 0.555656 588 | t_x: 0.5694311 589 | t_y: -0.82203907 590 | } 591 | points { 592 | x: 1.0 593 | y: 0.0072254334 594 | t_x: 0.4737472 595 | t_y: -0.8806609 596 | } 597 | } 598 | particle_properties { 599 | key: PARTICLE_KEY_ROTATION 600 | points { 601 | x: 0.0 602 | y: 0.0 603 | t_x: 1.0 604 | t_y: 0.0 605 | } 606 | } 607 | particle_properties { 608 | key: PARTICLE_KEY_STRETCH_FACTOR_X 609 | points { 610 | x: 0.0 611 | y: 0.0 612 | t_x: 1.0 613 | t_y: 0.0 614 | } 615 | } 616 | particle_properties { 617 | key: PARTICLE_KEY_STRETCH_FACTOR_Y 618 | points { 619 | x: 0.0 620 | y: 0.0 621 | t_x: 1.0 622 | t_y: 0.0 623 | } 624 | } 625 | particle_properties { 626 | key: PARTICLE_KEY_ANGULAR_VELOCITY 627 | points { 628 | x: 0.0 629 | y: 1.0 630 | t_x: 1.0 631 | t_y: 0.0 632 | } 633 | } 634 | modifiers { 635 | type: MODIFIER_TYPE_ACCELERATION 636 | use_direction: 0 637 | position { 638 | x: 0.0 639 | y: 0.0 640 | z: 0.0 641 | } 642 | rotation { 643 | x: 0.0 644 | y: 0.0 645 | z: 0.80150837 646 | w: 0.59798354 647 | } 648 | properties { 649 | key: MODIFIER_KEY_MAGNITUDE 650 | points { 651 | x: 0.0 652 | y: -100.0 653 | t_x: 1.0 654 | t_y: 0.0 655 | } 656 | spread: 0.0 657 | } 658 | } 659 | modifiers { 660 | type: MODIFIER_TYPE_DRAG 661 | use_direction: 0 662 | position { 663 | x: 0.0 664 | y: 0.0 665 | z: 0.0 666 | } 667 | rotation { 668 | x: 0.0 669 | y: 0.0 670 | z: 0.0 671 | w: 1.0 672 | } 673 | properties { 674 | key: MODIFIER_KEY_MAGNITUDE 675 | points { 676 | x: 0.0 677 | y: 1.0 678 | t_x: 1.0 679 | t_y: 0.0 680 | } 681 | spread: 0.0 682 | } 683 | } 684 | size_mode: SIZE_MODE_MANUAL 685 | start_delay_spread: 0.0 686 | duration_spread: 0.05 687 | stretch_with_velocity: false 688 | start_offset: 0.0 689 | pivot { 690 | x: 0.0 691 | y: 0.0 692 | z: 0.0 693 | } 694 | } 695 | -------------------------------------------------------------------------------- /assets/hero.atlas: -------------------------------------------------------------------------------- 1 | animations { 2 | id: "idle" 3 | images { 4 | image: "/assets/images/Pink/alienPink_stand.png" 5 | sprite_trim_mode: SPRITE_TRIM_MODE_OFF 6 | } 7 | playback: PLAYBACK_NONE 8 | fps: 12 9 | flip_horizontal: 0 10 | flip_vertical: 0 11 | } 12 | animations { 13 | id: "run" 14 | images { 15 | image: "/assets/images/Pink/alienPink_walk1.png" 16 | sprite_trim_mode: SPRITE_TRIM_MODE_OFF 17 | } 18 | images { 19 | image: "/assets/images/Pink/alienPink_walk2.png" 20 | sprite_trim_mode: SPRITE_TRIM_MODE_OFF 21 | } 22 | playback: PLAYBACK_LOOP_FORWARD 23 | fps: 10 24 | flip_horizontal: 0 25 | flip_vertical: 0 26 | } 27 | animations { 28 | id: "jump" 29 | images { 30 | image: "/assets/images/Pink/alienPink_jump.png" 31 | sprite_trim_mode: SPRITE_TRIM_MODE_OFF 32 | } 33 | playback: PLAYBACK_NONE 34 | fps: 60 35 | flip_horizontal: 0 36 | flip_vertical: 0 37 | } 38 | margin: 0 39 | extrude_borders: 2 40 | inner_padding: 0 41 | max_page_width: 0 42 | max_page_height: 0 43 | rename_patterns: "" 44 | -------------------------------------------------------------------------------- /assets/images/Pink/alienPink_climb1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/images/Pink/alienPink_climb1.png -------------------------------------------------------------------------------- /assets/images/Pink/alienPink_climb2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/images/Pink/alienPink_climb2.png -------------------------------------------------------------------------------- /assets/images/Pink/alienPink_duck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/images/Pink/alienPink_duck.png -------------------------------------------------------------------------------- /assets/images/Pink/alienPink_front.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/images/Pink/alienPink_front.png -------------------------------------------------------------------------------- /assets/images/Pink/alienPink_hit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/images/Pink/alienPink_hit.png -------------------------------------------------------------------------------- /assets/images/Pink/alienPink_jump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/images/Pink/alienPink_jump.png -------------------------------------------------------------------------------- /assets/images/Pink/alienPink_stand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/images/Pink/alienPink_stand.png -------------------------------------------------------------------------------- /assets/images/Pink/alienPink_swim1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/images/Pink/alienPink_swim1.png -------------------------------------------------------------------------------- /assets/images/Pink/alienPink_swim2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/images/Pink/alienPink_swim2.png -------------------------------------------------------------------------------- /assets/images/Pink/alienPink_walk1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/images/Pink/alienPink_walk1.png -------------------------------------------------------------------------------- /assets/images/Pink/alienPink_walk2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/images/Pink/alienPink_walk2.png -------------------------------------------------------------------------------- /assets/images/background.atlas: -------------------------------------------------------------------------------- 1 | images { 2 | image: "/assets/images/blue_grass.png" 3 | sprite_trim_mode: SPRITE_TRIM_MODE_OFF 4 | } 5 | margin: 0 6 | extrude_borders: 0 7 | inner_padding: 0 8 | max_page_width: 0 9 | max_page_height: 0 10 | -------------------------------------------------------------------------------- /assets/images/blue_grass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/images/blue_grass.png -------------------------------------------------------------------------------- /assets/images/spritesheet_tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/images/spritesheet_tiles.png -------------------------------------------------------------------------------- /assets/jump.sound: -------------------------------------------------------------------------------- 1 | sound: "/assets/sounds/phaseJump1.ogg" 2 | looping: 0 3 | group: "master" 4 | gain: 1.0 5 | pan: 0.0 6 | speed: 1.0 7 | loopcount: 0 8 | -------------------------------------------------------------------------------- /assets/land.sound: -------------------------------------------------------------------------------- 1 | sound: "/assets/sounds/footstep_grass_000.ogg" 2 | looping: 0 3 | group: "master" 4 | gain: 1.0 5 | pan: 0.0 6 | speed: 1.0 7 | loopcount: 0 8 | -------------------------------------------------------------------------------- /assets/level.tilemap: -------------------------------------------------------------------------------- 1 | tile_set: "/assets/level.tilesource" 2 | layers { 3 | id: "layer1" 4 | z: 0.0 5 | is_visible: 1 6 | cell { 7 | x: 0 8 | y: 0 9 | tile: 12 10 | h_flip: 0 11 | v_flip: 0 12 | rotate90: 0 13 | } 14 | cell { 15 | x: 1 16 | y: 0 17 | tile: 12 18 | h_flip: 0 19 | v_flip: 0 20 | rotate90: 0 21 | } 22 | cell { 23 | x: 2 24 | y: 0 25 | tile: 12 26 | h_flip: 0 27 | v_flip: 0 28 | rotate90: 0 29 | } 30 | cell { 31 | x: 3 32 | y: 0 33 | tile: 12 34 | h_flip: 0 35 | v_flip: 0 36 | rotate90: 0 37 | } 38 | cell { 39 | x: 4 40 | y: 0 41 | tile: 12 42 | h_flip: 0 43 | v_flip: 0 44 | rotate90: 0 45 | } 46 | cell { 47 | x: 5 48 | y: 0 49 | tile: 12 50 | h_flip: 0 51 | v_flip: 0 52 | rotate90: 0 53 | } 54 | cell { 55 | x: 6 56 | y: 0 57 | tile: 12 58 | h_flip: 0 59 | v_flip: 0 60 | rotate90: 0 61 | } 62 | cell { 63 | x: 7 64 | y: 0 65 | tile: 12 66 | h_flip: 0 67 | v_flip: 0 68 | rotate90: 0 69 | } 70 | cell { 71 | x: 8 72 | y: 0 73 | tile: 12 74 | h_flip: 0 75 | v_flip: 0 76 | rotate90: 0 77 | } 78 | cell { 79 | x: 9 80 | y: 0 81 | tile: 12 82 | h_flip: 0 83 | v_flip: 0 84 | rotate90: 0 85 | } 86 | cell { 87 | x: 10 88 | y: 0 89 | tile: 12 90 | h_flip: 0 91 | v_flip: 0 92 | rotate90: 0 93 | } 94 | cell { 95 | x: 11 96 | y: 0 97 | tile: 12 98 | h_flip: 0 99 | v_flip: 0 100 | rotate90: 0 101 | } 102 | cell { 103 | x: 12 104 | y: 0 105 | tile: 12 106 | h_flip: 0 107 | v_flip: 0 108 | rotate90: 0 109 | } 110 | cell { 111 | x: 13 112 | y: 0 113 | tile: 12 114 | h_flip: 0 115 | v_flip: 0 116 | rotate90: 0 117 | } 118 | cell { 119 | x: 14 120 | y: 0 121 | tile: 20 122 | h_flip: 0 123 | v_flip: 0 124 | rotate90: 0 125 | } 126 | cell { 127 | x: 15 128 | y: 0 129 | tile: 20 130 | h_flip: 0 131 | v_flip: 0 132 | rotate90: 0 133 | } 134 | cell { 135 | x: 16 136 | y: 0 137 | tile: 20 138 | h_flip: 0 139 | v_flip: 0 140 | rotate90: 0 141 | } 142 | cell { 143 | x: 17 144 | y: 0 145 | tile: 20 146 | h_flip: 0 147 | v_flip: 0 148 | rotate90: 0 149 | } 150 | cell { 151 | x: 18 152 | y: 0 153 | tile: 20 154 | h_flip: 0 155 | v_flip: 0 156 | rotate90: 0 157 | } 158 | cell { 159 | x: 19 160 | y: 0 161 | tile: 20 162 | h_flip: 0 163 | v_flip: 0 164 | rotate90: 0 165 | } 166 | cell { 167 | x: 20 168 | y: 0 169 | tile: 20 170 | h_flip: 0 171 | v_flip: 0 172 | rotate90: 0 173 | } 174 | cell { 175 | x: 21 176 | y: 0 177 | tile: 20 178 | h_flip: 0 179 | v_flip: 0 180 | rotate90: 0 181 | } 182 | cell { 183 | x: 22 184 | y: 0 185 | tile: 1 186 | h_flip: 0 187 | v_flip: 0 188 | rotate90: 0 189 | } 190 | cell { 191 | x: 23 192 | y: 0 193 | tile: 1 194 | h_flip: 0 195 | v_flip: 0 196 | rotate90: 0 197 | } 198 | cell { 199 | x: 24 200 | y: 0 201 | tile: 1 202 | h_flip: 0 203 | v_flip: 0 204 | rotate90: 0 205 | } 206 | cell { 207 | x: 25 208 | y: 0 209 | tile: 1 210 | h_flip: 0 211 | v_flip: 0 212 | rotate90: 0 213 | } 214 | cell { 215 | x: 26 216 | y: 0 217 | tile: 1 218 | h_flip: 0 219 | v_flip: 0 220 | rotate90: 0 221 | } 222 | cell { 223 | x: 27 224 | y: 0 225 | tile: 1 226 | h_flip: 0 227 | v_flip: 0 228 | rotate90: 0 229 | } 230 | cell { 231 | x: 28 232 | y: 0 233 | tile: 1 234 | h_flip: 0 235 | v_flip: 0 236 | rotate90: 0 237 | } 238 | cell { 239 | x: 29 240 | y: 0 241 | tile: 1 242 | h_flip: 0 243 | v_flip: 0 244 | rotate90: 0 245 | } 246 | cell { 247 | x: 30 248 | y: 0 249 | tile: 1 250 | h_flip: 0 251 | v_flip: 0 252 | rotate90: 0 253 | } 254 | cell { 255 | x: -7 256 | y: 0 257 | tile: 1 258 | h_flip: 0 259 | v_flip: 0 260 | rotate90: 0 261 | } 262 | cell { 263 | x: -6 264 | y: 0 265 | tile: 1 266 | h_flip: 0 267 | v_flip: 0 268 | rotate90: 0 269 | } 270 | cell { 271 | x: -5 272 | y: 0 273 | tile: 1 274 | h_flip: 0 275 | v_flip: 0 276 | rotate90: 0 277 | } 278 | cell { 279 | x: -4 280 | y: 0 281 | tile: 1 282 | h_flip: 0 283 | v_flip: 0 284 | rotate90: 0 285 | } 286 | cell { 287 | x: -3 288 | y: 0 289 | tile: 1 290 | h_flip: 0 291 | v_flip: 0 292 | rotate90: 0 293 | } 294 | cell { 295 | x: -2 296 | y: 0 297 | tile: 1 298 | h_flip: 0 299 | v_flip: 0 300 | rotate90: 0 301 | } 302 | cell { 303 | x: -1 304 | y: 0 305 | tile: 1 306 | h_flip: 0 307 | v_flip: 0 308 | rotate90: 0 309 | } 310 | cell { 311 | x: 1 312 | y: 1 313 | tile: 10 314 | h_flip: 0 315 | v_flip: 0 316 | rotate90: 0 317 | } 318 | cell { 319 | x: 6 320 | y: 1 321 | tile: 24 322 | h_flip: 0 323 | v_flip: 0 324 | rotate90: 0 325 | } 326 | cell { 327 | x: 7 328 | y: 1 329 | tile: 32 330 | h_flip: 0 331 | v_flip: 0 332 | rotate90: 0 333 | } 334 | cell { 335 | x: 10 336 | y: 1 337 | tile: 26 338 | h_flip: 0 339 | v_flip: 0 340 | rotate90: 0 341 | } 342 | cell { 343 | x: 12 344 | y: 1 345 | tile: 51 346 | h_flip: 0 347 | v_flip: 0 348 | rotate90: 0 349 | } 350 | cell { 351 | x: 13 352 | y: 1 353 | tile: 59 354 | h_flip: 0 355 | v_flip: 0 356 | rotate90: 0 357 | } 358 | cell { 359 | x: 16 360 | y: 1 361 | tile: 43 362 | h_flip: 0 363 | v_flip: 0 364 | rotate90: 0 365 | } 366 | cell { 367 | x: 18 368 | y: 1 369 | tile: 43 370 | h_flip: 0 371 | v_flip: 0 372 | rotate90: 0 373 | } 374 | cell { 375 | x: 20 376 | y: 1 377 | tile: 60 378 | h_flip: 0 379 | v_flip: 0 380 | rotate90: 0 381 | } 382 | cell { 383 | x: 7 384 | y: 2 385 | tile: 16 386 | h_flip: 0 387 | v_flip: 0 388 | rotate90: 0 389 | } 390 | } 391 | material: "/builtins/materials/tile_map.material" 392 | blend_mode: BLEND_MODE_ALPHA 393 | -------------------------------------------------------------------------------- /assets/level.tilesource: -------------------------------------------------------------------------------- 1 | image: "/assets/images/spritesheet_tiles.png" 2 | tile_width: 128 3 | tile_height: 128 4 | collision: "/assets/images/spritesheet_tiles.png" 5 | convex_hulls { 6 | index: 0 7 | count: 16 8 | collision_group: "level" 9 | } 10 | convex_hulls { 11 | index: 16 12 | count: 7 13 | collision_group: "" 14 | } 15 | convex_hulls { 16 | index: 23 17 | count: 6 18 | collision_group: "" 19 | } 20 | convex_hulls { 21 | index: 29 22 | count: 7 23 | collision_group: "" 24 | } 25 | convex_hulls { 26 | index: 36 27 | count: 16 28 | collision_group: "" 29 | } 30 | convex_hulls { 31 | index: 52 32 | count: 0 33 | collision_group: "" 34 | } 35 | convex_hulls { 36 | index: 52 37 | count: 0 38 | collision_group: "" 39 | } 40 | convex_hulls { 41 | index: 52 42 | count: 0 43 | collision_group: "" 44 | } 45 | convex_hulls { 46 | index: 52 47 | count: 16 48 | collision_group: "" 49 | } 50 | convex_hulls { 51 | index: 68 52 | count: 4 53 | collision_group: "" 54 | } 55 | convex_hulls { 56 | index: 72 57 | count: 11 58 | collision_group: "" 59 | } 60 | convex_hulls { 61 | index: 83 62 | count: 7 63 | collision_group: "" 64 | } 65 | convex_hulls { 66 | index: 90 67 | count: 16 68 | collision_group: "level" 69 | } 70 | convex_hulls { 71 | index: 106 72 | count: 0 73 | collision_group: "" 74 | } 75 | convex_hulls { 76 | index: 106 77 | count: 0 78 | collision_group: "" 79 | } 80 | convex_hulls { 81 | index: 106 82 | count: 0 83 | collision_group: "" 84 | } 85 | convex_hulls { 86 | index: 106 87 | count: 16 88 | collision_group: "level" 89 | } 90 | convex_hulls { 91 | index: 122 92 | count: 15 93 | collision_group: "" 94 | } 95 | convex_hulls { 96 | index: 137 97 | count: 13 98 | collision_group: "" 99 | } 100 | convex_hulls { 101 | index: 150 102 | count: 4 103 | collision_group: "" 104 | } 105 | convex_hulls { 106 | index: 154 107 | count: 16 108 | collision_group: "level" 109 | } 110 | convex_hulls { 111 | index: 170 112 | count: 0 113 | collision_group: "" 114 | } 115 | convex_hulls { 116 | index: 170 117 | count: 0 118 | collision_group: "" 119 | } 120 | convex_hulls { 121 | index: 170 122 | count: 0 123 | collision_group: "" 124 | } 125 | convex_hulls { 126 | index: 170 127 | count: 16 128 | collision_group: "level" 129 | } 130 | convex_hulls { 131 | index: 186 132 | count: 14 133 | collision_group: "" 134 | } 135 | convex_hulls { 136 | index: 200 137 | count: 16 138 | collision_group: "level" 139 | } 140 | convex_hulls { 141 | index: 216 142 | count: 10 143 | collision_group: "" 144 | } 145 | convex_hulls { 146 | index: 226 147 | count: 16 148 | collision_group: "" 149 | } 150 | convex_hulls { 151 | index: 242 152 | count: 0 153 | collision_group: "" 154 | } 155 | convex_hulls { 156 | index: 242 157 | count: 0 158 | collision_group: "" 159 | } 160 | convex_hulls { 161 | index: 242 162 | count: 0 163 | collision_group: "" 164 | } 165 | convex_hulls { 166 | index: 242 167 | count: 16 168 | collision_group: "level" 169 | } 170 | convex_hulls { 171 | index: 258 172 | count: 14 173 | collision_group: "" 174 | } 175 | convex_hulls { 176 | index: 272 177 | count: 16 178 | collision_group: "" 179 | } 180 | convex_hulls { 181 | index: 288 182 | count: 4 183 | collision_group: "" 184 | } 185 | convex_hulls { 186 | index: 292 187 | count: 16 188 | collision_group: "" 189 | } 190 | convex_hulls { 191 | index: 308 192 | count: 0 193 | collision_group: "" 194 | } 195 | convex_hulls { 196 | index: 308 197 | count: 0 198 | collision_group: "" 199 | } 200 | convex_hulls { 201 | index: 308 202 | count: 0 203 | collision_group: "" 204 | } 205 | convex_hulls { 206 | index: 308 207 | count: 16 208 | collision_group: "level" 209 | } 210 | convex_hulls { 211 | index: 324 212 | count: 10 213 | collision_group: "" 214 | } 215 | convex_hulls { 216 | index: 334 217 | count: 11 218 | collision_group: "" 219 | } 220 | convex_hulls { 221 | index: 345 222 | count: 11 223 | collision_group: "" 224 | } 225 | convex_hulls { 226 | index: 356 227 | count: 16 228 | collision_group: "" 229 | } 230 | convex_hulls { 231 | index: 372 232 | count: 0 233 | collision_group: "" 234 | } 235 | convex_hulls { 236 | index: 372 237 | count: 0 238 | collision_group: "" 239 | } 240 | convex_hulls { 241 | index: 372 242 | count: 0 243 | collision_group: "" 244 | } 245 | convex_hulls { 246 | index: 372 247 | count: 16 248 | collision_group: "" 249 | } 250 | convex_hulls { 251 | index: 388 252 | count: 10 253 | collision_group: "" 254 | } 255 | convex_hulls { 256 | index: 398 257 | count: 11 258 | collision_group: "" 259 | } 260 | convex_hulls { 261 | index: 409 262 | count: 10 263 | collision_group: "" 264 | } 265 | convex_hulls { 266 | index: 419 267 | count: 16 268 | collision_group: "" 269 | } 270 | convex_hulls { 271 | index: 435 272 | count: 0 273 | collision_group: "" 274 | } 275 | convex_hulls { 276 | index: 435 277 | count: 0 278 | collision_group: "" 279 | } 280 | convex_hulls { 281 | index: 435 282 | count: 0 283 | collision_group: "" 284 | } 285 | convex_hulls { 286 | index: 435 287 | count: 16 288 | collision_group: "" 289 | } 290 | convex_hulls { 291 | index: 451 292 | count: 10 293 | collision_group: "" 294 | } 295 | convex_hulls { 296 | index: 461 297 | count: 14 298 | collision_group: "" 299 | } 300 | convex_hulls { 301 | index: 475 302 | count: 10 303 | collision_group: "" 304 | } 305 | convex_hulls { 306 | index: 485 307 | count: 16 308 | collision_group: "" 309 | } 310 | convex_hulls { 311 | index: 501 312 | count: 0 313 | collision_group: "" 314 | } 315 | convex_hulls { 316 | index: 501 317 | count: 0 318 | collision_group: "" 319 | } 320 | convex_hulls { 321 | index: 501 322 | count: 0 323 | collision_group: "" 324 | } 325 | convex_hulls { 326 | index: 501 327 | count: 16 328 | collision_group: "" 329 | } 330 | convex_hulls { 331 | index: 517 332 | count: 10 333 | collision_group: "" 334 | } 335 | convex_hulls { 336 | index: 527 337 | count: 14 338 | collision_group: "" 339 | } 340 | convex_hulls { 341 | index: 541 342 | count: 10 343 | collision_group: "" 344 | } 345 | convex_hulls { 346 | index: 551 347 | count: 0 348 | collision_group: "" 349 | } 350 | convex_hulls { 351 | index: 551 352 | count: 0 353 | collision_group: "" 354 | } 355 | convex_hulls { 356 | index: 551 357 | count: 0 358 | collision_group: "" 359 | } 360 | convex_hulls { 361 | index: 551 362 | count: 0 363 | collision_group: "" 364 | } 365 | convex_hulls { 366 | index: 551 367 | count: 16 368 | collision_group: "" 369 | } 370 | convex_hulls { 371 | index: 567 372 | count: 10 373 | collision_group: "" 374 | } 375 | convex_hulls { 376 | index: 577 377 | count: 16 378 | collision_group: "" 379 | } 380 | convex_hulls { 381 | index: 593 382 | count: 4 383 | collision_group: "" 384 | } 385 | convex_hulls { 386 | index: 597 387 | count: 0 388 | collision_group: "" 389 | } 390 | convex_hulls { 391 | index: 597 392 | count: 0 393 | collision_group: "" 394 | } 395 | convex_hulls { 396 | index: 597 397 | count: 0 398 | collision_group: "" 399 | } 400 | convex_hulls { 401 | index: 597 402 | count: 0 403 | collision_group: "" 404 | } 405 | convex_hulls { 406 | index: 597 407 | count: 15 408 | collision_group: "" 409 | } 410 | convex_hulls { 411 | index: 612 412 | count: 10 413 | collision_group: "" 414 | } 415 | convex_hulls { 416 | index: 622 417 | count: 16 418 | collision_group: "" 419 | } 420 | convex_hulls { 421 | index: 638 422 | count: 10 423 | collision_group: "" 424 | } 425 | convex_hulls { 426 | index: 648 427 | count: 0 428 | collision_group: "" 429 | } 430 | convex_hulls { 431 | index: 648 432 | count: 0 433 | collision_group: "" 434 | } 435 | convex_hulls { 436 | index: 648 437 | count: 0 438 | collision_group: "" 439 | } 440 | convex_hulls { 441 | index: 648 442 | count: 0 443 | collision_group: "" 444 | } 445 | convex_hulls { 446 | index: 648 447 | count: 15 448 | collision_group: "" 449 | } 450 | convex_hulls { 451 | index: 663 452 | count: 10 453 | collision_group: "" 454 | } 455 | convex_hulls { 456 | index: 673 457 | count: 16 458 | collision_group: "" 459 | } 460 | convex_hulls { 461 | index: 689 462 | count: 4 463 | collision_group: "" 464 | } 465 | convex_hulls { 466 | index: 693 467 | count: 0 468 | collision_group: "" 469 | } 470 | convex_hulls { 471 | index: 693 472 | count: 0 473 | collision_group: "" 474 | } 475 | convex_hulls { 476 | index: 693 477 | count: 0 478 | collision_group: "" 479 | } 480 | convex_hulls { 481 | index: 693 482 | count: 0 483 | collision_group: "" 484 | } 485 | convex_hulls { 486 | index: 693 487 | count: 10 488 | collision_group: "" 489 | } 490 | convex_hulls { 491 | index: 703 492 | count: 10 493 | collision_group: "" 494 | } 495 | convex_hulls { 496 | index: 713 497 | count: 16 498 | collision_group: "" 499 | } 500 | convex_hulls { 501 | index: 729 502 | count: 15 503 | collision_group: "" 504 | } 505 | convex_hulls { 506 | index: 744 507 | count: 0 508 | collision_group: "" 509 | } 510 | convex_hulls { 511 | index: 744 512 | count: 0 513 | collision_group: "" 514 | } 515 | convex_hulls { 516 | index: 744 517 | count: 0 518 | collision_group: "" 519 | } 520 | convex_hulls { 521 | index: 744 522 | count: 0 523 | collision_group: "" 524 | } 525 | convex_hulls { 526 | index: 744 527 | count: 16 528 | collision_group: "" 529 | } 530 | convex_hulls { 531 | index: 760 532 | count: 12 533 | collision_group: "" 534 | } 535 | convex_hulls { 536 | index: 772 537 | count: 9 538 | collision_group: "" 539 | } 540 | convex_hulls { 541 | index: 781 542 | count: 13 543 | collision_group: "" 544 | } 545 | convex_hulls { 546 | index: 794 547 | count: 0 548 | collision_group: "" 549 | } 550 | convex_hulls { 551 | index: 794 552 | count: 0 553 | collision_group: "" 554 | } 555 | convex_hulls { 556 | index: 794 557 | count: 0 558 | collision_group: "" 559 | } 560 | convex_hulls { 561 | index: 794 562 | count: 0 563 | collision_group: "" 564 | } 565 | convex_hulls { 566 | index: 794 567 | count: 16 568 | collision_group: "" 569 | } 570 | convex_hulls { 571 | index: 810 572 | count: 12 573 | collision_group: "" 574 | } 575 | convex_hulls { 576 | index: 822 577 | count: 8 578 | collision_group: "" 579 | } 580 | convex_hulls { 581 | index: 830 582 | count: 12 583 | collision_group: "" 584 | } 585 | convex_hulls { 586 | index: 842 587 | count: 0 588 | collision_group: "" 589 | } 590 | convex_hulls { 591 | index: 842 592 | count: 0 593 | collision_group: "" 594 | } 595 | convex_hulls { 596 | index: 842 597 | count: 0 598 | collision_group: "" 599 | } 600 | convex_hulls { 601 | index: 842 602 | count: 0 603 | collision_group: "" 604 | } 605 | convex_hulls { 606 | index: 842 607 | count: 7 608 | collision_group: "" 609 | } 610 | convex_hulls { 611 | index: 849 612 | count: 7 613 | collision_group: "" 614 | } 615 | convex_hulls { 616 | index: 856 617 | count: 9 618 | collision_group: "" 619 | } 620 | convex_hulls { 621 | index: 865 622 | count: 16 623 | collision_group: "" 624 | } 625 | convex_hulls { 626 | index: 881 627 | count: 0 628 | collision_group: "" 629 | } 630 | convex_hulls { 631 | index: 881 632 | count: 0 633 | collision_group: "" 634 | } 635 | convex_hulls { 636 | index: 881 637 | count: 0 638 | collision_group: "" 639 | } 640 | convex_hulls { 641 | index: 881 642 | count: 0 643 | collision_group: "" 644 | } 645 | collision_groups: "default" 646 | collision_groups: "level" 647 | animations { 648 | id: "anim" 649 | start_tile: 1 650 | end_tile: 1 651 | } 652 | extrude_borders: 2 653 | -------------------------------------------------------------------------------- /assets/sounds/footstep_grass_000.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/sounds/footstep_grass_000.ogg -------------------------------------------------------------------------------- /assets/sounds/phaseJump1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paweljarosz/defold-platformer-tutorial/79fa6aeae1977831c2d39333c9680fc6b2f6557b/assets/sounds/phaseJump1.ogg -------------------------------------------------------------------------------- /game.project: -------------------------------------------------------------------------------- 1 | [bootstrap] 2 | main_collection = /main/main.collectionc 3 | 4 | [script] 5 | shared_state = 1 6 | 7 | [display] 8 | width = 960 9 | height = 640 10 | update_frequency = 60 11 | 12 | [android] 13 | input_method = HiddenInputField 14 | 15 | [project] 16 | title = MyTutorialPlatformer 17 | developer = Paweł Jarosz 18 | version = 0.6 19 | publisher = Paweł Jarosz 20 | 21 | [physics] 22 | use_fixed_timestep = 1 23 | debug = 0 24 | 25 | -------------------------------------------------------------------------------- /input/game.input_binding: -------------------------------------------------------------------------------- 1 | key_trigger { 2 | input: KEY_LEFT 3 | action: "left" 4 | } 5 | key_trigger { 6 | input: KEY_RIGHT 7 | action: "right" 8 | } 9 | key_trigger { 10 | input: KEY_SPACE 11 | action: "jump" 12 | } 13 | -------------------------------------------------------------------------------- /main/hero.script: -------------------------------------------------------------------------------- 1 | local DIRECTION_RIGHT = 1 2 | local DIRECTION_LEFT = -1 3 | local BASE_VELOCITY = 500 4 | local GRAVITY = 1000 5 | local JUMP_TAKEOFF = 600 6 | 7 | function init(self) 8 | msg.post("#", "acquire_input_focus") -- tell this component to acquire input focus 9 | msg.post("@render:", "use_camera_projection") 10 | msg.post("operator#camera", "acquire_camera_focus") 11 | 12 | self.velocity = vmath.vector3(0, 0, 0) 13 | self.ground_contact = false 14 | self.previous_ground_contact = false 15 | self.correction = vmath.vector3(0, 0, 0) 16 | end 17 | 18 | local function walk(self) 19 | self.velocity.x = BASE_VELOCITY * self.direction 20 | end 21 | 22 | local function flip(direction) 23 | sprite.set_hflip("#sprite", direction < 0) 24 | end 25 | 26 | local function play_animation(self, new_animation) 27 | if self.animation ~= new_animation then 28 | sprite.play_flipbook("#sprite", new_animation) 29 | self.animation = new_animation 30 | end 31 | end 32 | 33 | local function animate(self) 34 | if self.ground_contact then 35 | if self.velocity.x == 0 then 36 | play_animation(self, "idle") 37 | else 38 | play_animation(self, "run") 39 | end 40 | else 41 | play_animation(self, "jump") 42 | end 43 | end 44 | 45 | -- clamp a number between a min and max value 46 | local function clamp(v, min, max) 47 | if v < min then return min 48 | elseif v > max then return max 49 | else return v end 50 | end 51 | 52 | function fixed_update(self, dt) 53 | --gravity 54 | self.velocity.y = self.velocity.y - GRAVITY * dt -- gravity is acceleration so G * dt is velocity 55 | self.velocity.y = clamp(self.velocity.y, -2000, 2000) 56 | 57 | if self.ground_contact then 58 | self.velocity.y = 0 59 | end 60 | self.previous_ground_contact = self.ground_contact 61 | 62 | local position = go.get_position() -- get current game object's position 63 | position = position + self.velocity * dt 64 | go.set_position(position) -- set the new position to the current game object 65 | 66 | animate(self) 67 | 68 | self.velocity.x = 0 69 | self.ground_contact = false 70 | self.correction.x = 0 71 | self.correction.y = 0 72 | end 73 | 74 | local function handle_level_collisions(self, normal, distance) 75 | 76 | if distance > 0 then 77 | -- project accumulated correction onto the penetration vector 78 | local extent = vmath.project(self.correction, normal * distance) 79 | if extent < 1 then -- exclude overshoot projection 80 | local compensation = (distance - distance * extent) * normal 81 | go.set_position(go.get_position() + compensation) -- appply compensation instantly 82 | self.correction = self.correction + compensation -- accumulate the correction 83 | end 84 | end 85 | 86 | -- wall on left or right 87 | if math.abs(normal.x) > 0 then 88 | self.velocity.x = 0 89 | end 90 | 91 | -- on the ground 92 | if normal.y > 0 then 93 | if not self.previous_ground_contact then 94 | particlefx.play("#dust") 95 | sound.play("#land") 96 | end 97 | self.ground_contact = true 98 | self.velocity.y = 0 99 | end 100 | 101 | -- hit the ceiling 102 | if normal.y < 0 then 103 | self.velocity.y = 0 104 | end 105 | end 106 | 107 | function on_message(self, message_id, message, sender) 108 | if (message_id == hash("contact_point_response")) 109 | and message.other_group == hash("level") then 110 | handle_level_collisions(self, message.normal, message.distance) 111 | end 112 | end 113 | 114 | function on_input(self, action_id, action) 115 | if action_id ~= hash("jump") then 116 | self.direction = (action_id == hash("right")) and DIRECTION_RIGHT or DIRECTION_LEFT 117 | walk(self) 118 | flip(self.direction) 119 | elseif action.pressed and self.ground_contact then 120 | self.velocity.y = JUMP_TAKEOFF 121 | self.ground_contact = false 122 | particlefx.play("#dust") 123 | sound.play("#jump") 124 | end 125 | end 126 | -------------------------------------------------------------------------------- /main/main.collection: -------------------------------------------------------------------------------- 1 | name: "main" 2 | scale_along_z: 0 3 | embedded_instances { 4 | id: "hero" 5 | children: "operator" 6 | data: "components {\n" 7 | " id: \"hero\"\n" 8 | " component: \"/main/hero.script\"\n" 9 | "}\n" 10 | "components {\n" 11 | " id: \"jump\"\n" 12 | " component: \"/assets/jump.sound\"\n" 13 | "}\n" 14 | "components {\n" 15 | " id: \"land\"\n" 16 | " component: \"/assets/land.sound\"\n" 17 | "}\n" 18 | "components {\n" 19 | " id: \"dust\"\n" 20 | " component: \"/assets/dust.particlefx\"\n" 21 | " position {\n" 22 | " y: -127.0\n" 23 | " }\n" 24 | "}\n" 25 | "embedded_components {\n" 26 | " id: \"sprite\"\n" 27 | " type: \"sprite\"\n" 28 | " data: \"default_animation: \\\"idle\\\"\\n" 29 | "material: \\\"/builtins/materials/sprite.material\\\"\\n" 30 | "textures {\\n" 31 | " sampler: \\\"texture_sampler\\\"\\n" 32 | " texture: \\\"/assets/hero.atlas\\\"\\n" 33 | "}\\n" 34 | "\"\n" 35 | " position {\n" 36 | " z: 0.5\n" 37 | " }\n" 38 | "}\n" 39 | "embedded_components {\n" 40 | " id: \"collisionobject\"\n" 41 | " type: \"collisionobject\"\n" 42 | " data: \"type: COLLISION_OBJECT_TYPE_KINEMATIC\\n" 43 | "mass: 0.0\\n" 44 | "friction: 0.1\\n" 45 | "restitution: 0.5\\n" 46 | "group: \\\"player\\\"\\n" 47 | "mask: \\\"level\\\"\\n" 48 | "embedded_collision_shape {\\n" 49 | " shapes {\\n" 50 | " shape_type: TYPE_BOX\\n" 51 | " position {\\n" 52 | " y: -78.0\\n" 53 | " }\\n" 54 | " rotation {\\n" 55 | " }\\n" 56 | " index: 0\\n" 57 | " count: 3\\n" 58 | " }\\n" 59 | " data: 50.0\\n" 60 | " data: 50.0\\n" 61 | " data: 10.0\\n" 62 | "}\\n" 63 | "\"\n" 64 | "}\n" 65 | "" 66 | position { 67 | x: 452.0 68 | y: 454.0 69 | } 70 | } 71 | embedded_instances { 72 | id: "level" 73 | data: "components {\n" 74 | " id: \"level\"\n" 75 | " component: \"/assets/level.tilemap\"\n" 76 | "}\n" 77 | "embedded_components {\n" 78 | " id: \"collisionobject\"\n" 79 | " type: \"collisionobject\"\n" 80 | " data: \"collision_shape: \\\"/assets/level.tilemap\\\"\\n" 81 | "type: COLLISION_OBJECT_TYPE_STATIC\\n" 82 | "mass: 0.0\\n" 83 | "friction: 0.1\\n" 84 | "restitution: 0.5\\n" 85 | "group: \\\"level\\\"\\n" 86 | "mask: \\\"player\\\"\\n" 87 | "\"\n" 88 | "}\n" 89 | "" 90 | } 91 | embedded_instances { 92 | id: "background" 93 | data: "embedded_components {\n" 94 | " id: \"sprite\"\n" 95 | " type: \"sprite\"\n" 96 | " data: \"default_animation: \\\"blue_grass\\\"\\n" 97 | "material: \\\"/builtins/materials/sprite.material\\\"\\n" 98 | "textures {\\n" 99 | " sampler: \\\"texture_sampler\\\"\\n" 100 | " texture: \\\"/assets/images/background.atlas\\\"\\n" 101 | "}\\n" 102 | "\"\n" 103 | "}\n" 104 | "embedded_components {\n" 105 | " id: \"sprite1\"\n" 106 | " type: \"sprite\"\n" 107 | " data: \"default_animation: \\\"blue_grass\\\"\\n" 108 | "material: \\\"/builtins/materials/sprite.material\\\"\\n" 109 | "textures {\\n" 110 | " sampler: \\\"texture_sampler\\\"\\n" 111 | " texture: \\\"/assets/images/background.atlas\\\"\\n" 112 | "}\\n" 113 | "\"\n" 114 | " position {\n" 115 | " x: 1024.0\n" 116 | " }\n" 117 | "}\n" 118 | "embedded_components {\n" 119 | " id: \"sprite2\"\n" 120 | " type: \"sprite\"\n" 121 | " data: \"default_animation: \\\"blue_grass\\\"\\n" 122 | "material: \\\"/builtins/materials/sprite.material\\\"\\n" 123 | "textures {\\n" 124 | " sampler: \\\"texture_sampler\\\"\\n" 125 | " texture: \\\"/assets/images/background.atlas\\\"\\n" 126 | "}\\n" 127 | "\"\n" 128 | " position {\n" 129 | " x: 2048.0\n" 130 | " }\n" 131 | "}\n" 132 | "" 133 | position { 134 | x: 510.0 135 | y: 537.0 136 | z: -100.0 137 | } 138 | scale3 { 139 | x: 1.5 140 | y: 1.5 141 | z: 1.5 142 | } 143 | } 144 | embedded_instances { 145 | id: "operator" 146 | data: "embedded_components {\n" 147 | " id: \"camera\"\n" 148 | " type: \"camera\"\n" 149 | " data: \"aspect_ratio: 1.0\\n" 150 | "fov: 0.7854\\n" 151 | "near_z: 0.1\\n" 152 | "far_z: 800.0\\n" 153 | "auto_aspect_ratio: 1\\n" 154 | "orthographic_projection: 1\\n" 155 | "\"\n" 156 | "}\n" 157 | "" 158 | position { 159 | z: 540.0 160 | } 161 | } 162 | --------------------------------------------------------------------------------