Selaa lähdekoodia

War battles tutorial complete but not proofread.
Rebuilt all tutorial builds and explicitly set engine version on pages.
Fix in 2dgraphics manual.

Mikael Säker 8 vuotta sitten
vanhempi
commit
ddf6896ccd
85 muutettua tiedostoa jossa 452 lisäystä ja 27 poistoa
  1. 1 1
      docs/assets/car/archive_files.json
  2. BIN
      docs/assets/car/game.arcd0
  3. BIN
      docs/assets/car/game.arci0
  4. BIN
      docs/assets/car/game.darc0
  5. BIN
      docs/assets/car/game.dmanifest0
  6. 1 0
      docs/assets/car/game.projectc0
  7. BIN
      docs/assets/car/game.public.der0
  8. 0 0
      docs/assets/dmengine.js
  9. 0 0
      docs/assets/dmengine_1_2_106.js
  10. 1 1
      docs/assets/magic-link/archive_files.json
  11. BIN
      docs/assets/magic-link/game.arcd0
  12. BIN
      docs/assets/magic-link/game.arcd1
  13. BIN
      docs/assets/magic-link/game.arci0
  14. BIN
      docs/assets/magic-link/game.darc0
  15. BIN
      docs/assets/magic-link/game.darc1
  16. BIN
      docs/assets/magic-link/game.dmanifest0
  17. 4 1
      docs/assets/magic-link/game.projectc0
  18. BIN
      docs/assets/magic-link/game.public.der0
  19. 1 1
      docs/assets/platformer/archive_files.json
  20. BIN
      docs/assets/platformer/game.arcd0
  21. BIN
      docs/assets/platformer/game.arcd1
  22. BIN
      docs/assets/platformer/game.arcd2
  23. BIN
      docs/assets/platformer/game.arcd3
  24. BIN
      docs/assets/platformer/game.arcd4
  25. BIN
      docs/assets/platformer/game.arcd5
  26. BIN
      docs/assets/platformer/game.arcd6
  27. BIN
      docs/assets/platformer/game.arci0
  28. BIN
      docs/assets/platformer/game.darc0
  29. BIN
      docs/assets/platformer/game.darc1
  30. BIN
      docs/assets/platformer/game.darc2
  31. BIN
      docs/assets/platformer/game.darc3
  32. BIN
      docs/assets/platformer/game.darc4
  33. BIN
      docs/assets/platformer/game.darc5
  34. BIN
      docs/assets/platformer/game.darc6
  35. BIN
      docs/assets/platformer/game.dmanifest0
  36. BIN
      docs/assets/platformer/game.public.der0
  37. 1 1
      docs/assets/runner/archive_files.json
  38. BIN
      docs/assets/runner/game.arcd0
  39. BIN
      docs/assets/runner/game.arcd1
  40. BIN
      docs/assets/runner/game.arci0
  41. BIN
      docs/assets/runner/game.darc0
  42. BIN
      docs/assets/runner/game.dmanifest0
  43. 1 1
      docs/assets/runner/game.projectc0
  44. BIN
      docs/assets/runner/game.public.der0
  45. 1 1
      docs/assets/shadertoy/archive_files.json
  46. BIN
      docs/assets/shadertoy/game.dmanifest0
  47. 1 1
      docs/assets/shadertoy/game.projectc0
  48. BIN
      docs/assets/shadertoy/game.public.der0
  49. 1 1
      docs/assets/side-scroller/archive_files.json
  50. BIN
      docs/assets/side-scroller/game.arcd0
  51. BIN
      docs/assets/side-scroller/game.arci0
  52. BIN
      docs/assets/side-scroller/game.darc0
  53. BIN
      docs/assets/side-scroller/game.dmanifest0
  54. BIN
      docs/assets/side-scroller/game.public.der0
  55. 1 0
      docs/assets/war-battles/archive_files.json
  56. BIN
      docs/assets/war-battles/game.arcd0
  57. BIN
      docs/assets/war-battles/game.arci0
  58. BIN
      docs/assets/war-battles/game.dmanifest0
  59. 20 0
      docs/assets/war-battles/game.projectc0
  60. BIN
      docs/assets/war-battles/game.public.der0
  61. BIN
      docs/assets/war-battles/preview.jpg
  62. 7 5
      docs/en/manuals/2dgraphics.md
  63. 11 0
      docs/en/manuals/animation.md
  64. 1 1
      docs/en/tutorials/car.md
  65. BIN
      docs/en/tutorials/images/war-battles/done.png
  66. BIN
      docs/en/tutorials/images/war-battles/explosion_animation.png
  67. BIN
      docs/en/tutorials/images/war-battles/fire_rocket_2.png
  68. BIN
      docs/en/tutorials/images/war-battles/fire_rocket_3.png
  69. BIN
      docs/en/tutorials/images/war-battles/fire_rockets.png
  70. BIN
      docs/en/tutorials/images/war-battles/flip_rocket.png
  71. BIN
      docs/en/tutorials/images/war-battles/main_gui.png
  72. BIN
      docs/en/tutorials/images/war-battles/rocket_collision.png
  73. BIN
      docs/en/tutorials/images/war-battles/tank_animation.png
  74. BIN
      docs/en/tutorials/images/war-battles/tank_collision.png
  75. BIN
      docs/en/tutorials/images/war-battles/tanks.png
  76. BIN
      docs/en/tutorials/images/war-battles/text_font.png
  77. BIN
      docs/en/tutorials/images/war-battles/ui.png
  78. BIN
      docs/en/tutorials/images/war-battles/ui_script.png
  79. 1 1
      docs/en/tutorials/magic-link.md
  80. 1 1
      docs/en/tutorials/platformer.md
  81. 1 1
      docs/en/tutorials/runner.md
  82. 1 1
      docs/en/tutorials/shadertoy.md
  83. 1 1
      docs/en/tutorials/side-scroller.md
  84. 389 5
      docs/en/tutorials/war-battles.md
  85. 5 2
      docs/sass/preview-md.sass

+ 1 - 1
docs/assets/car/archive_files.json

@@ -1 +1 @@
-{"content":[{"name":"game.projectc","size":228,"pieces":[{"name":"game.projectc0","offset":0}]},{"name":"game.darc","size":22996,"pieces":[{"name":"game.darc0","offset":0}]}]}
+{"content":[{"name":"game.projectc","size":244,"pieces":[{"name":"game.projectc0","offset":0}]},{"name":"game.arci","size":928,"pieces":[{"name":"game.arci0","offset":0}]},{"name":"game.arcd","size":20960,"pieces":[{"name":"game.arcd0","offset":0}]},{"name":"game.dmanifest","size":1553,"pieces":[{"name":"game.dmanifest0","offset":0}]},{"name":"game.public.der","size":162,"pieces":[{"name":"game.public.der0","offset":0}]}]}

BIN
docs/assets/car/game.arcd0


BIN
docs/assets/car/game.arci0


BIN
docs/assets/car/game.darc0


BIN
docs/assets/car/game.dmanifest0


+ 1 - 0
docs/assets/car/game.projectc0

@@ -1,5 +1,6 @@
 [project]
 title = Getting started
+dependencies = 
 
 [bootstrap]
 main_collection = /main/main.collectionc

BIN
docs/assets/car/game.public.der0


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
docs/assets/dmengine.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
docs/assets/dmengine_1_2_106.js


+ 1 - 1
docs/assets/magic-link/archive_files.json

@@ -1 +1 @@
-{"content":[{"name":"game.projectc","size":414,"pieces":[{"name":"game.projectc0","offset":0}]},{"name":"game.darc","size":3137432,"pieces":[{"name":"game.darc0","offset":0},{"name":"game.darc1","offset":2097152}]}]}
+{"content":[{"name":"game.projectc","size":455,"pieces":[{"name":"game.projectc0","offset":0}]},{"name":"game.arci","size":3888,"pieces":[{"name":"game.arci0","offset":0}]},{"name":"game.arcd","size":3079673,"pieces":[{"name":"game.arcd0","offset":0},{"name":"game.arcd1","offset":2097152}]},{"name":"game.dmanifest","size":9288,"pieces":[{"name":"game.dmanifest0","offset":0}]},{"name":"game.public.der","size":162,"pieces":[{"name":"game.public.der0","offset":0}]}]}

BIN
docs/assets/magic-link/game.arcd0


BIN
docs/assets/magic-link/game.arcd1


BIN
docs/assets/magic-link/game.arci0


BIN
docs/assets/magic-link/game.darc0


BIN
docs/assets/magic-link/game.darc1


BIN
docs/assets/magic-link/game.dmanifest0


+ 4 - 1
docs/assets/magic-link/game.projectc0

@@ -1,5 +1,5 @@
 [project]
-title = magic_link
+title = Magic Link
 
 [bootstrap]
 main_collection = /main/main.collectionc
@@ -31,3 +31,6 @@ max_count = 512
 [android]
 package = com.example.linker
 
+[library]
+include_dirs = def-magic-link
+

BIN
docs/assets/magic-link/game.public.der0


+ 1 - 1
docs/assets/platformer/archive_files.json

@@ -1 +1 @@
-{"content":[{"name":"game.projectc","size":317,"pieces":[{"name":"game.projectc0","offset":0}]},{"name":"game.darc","size":14546436,"pieces":[{"name":"game.darc0","offset":0},{"name":"game.darc1","offset":2097152},{"name":"game.darc2","offset":4194304},{"name":"game.darc3","offset":6291456},{"name":"game.darc4","offset":8388608},{"name":"game.darc5","offset":10485760},{"name":"game.darc6","offset":12582912}]}]}
+{"content":[{"name":"game.projectc","size":317,"pieces":[{"name":"game.projectc0","offset":0}]},{"name":"game.arci","size":5248,"pieces":[{"name":"game.arci0","offset":0}]},{"name":"game.arcd","size":14497420,"pieces":[{"name":"game.arcd0","offset":0},{"name":"game.arcd1","offset":2097152},{"name":"game.arcd2","offset":4194304},{"name":"game.arcd3","offset":6291456},{"name":"game.arcd4","offset":8388608},{"name":"game.arcd5","offset":10485760},{"name":"game.arcd6","offset":12582912}]},{"name":"game.dmanifest","size":9345,"pieces":[{"name":"game.dmanifest0","offset":0}]},{"name":"game.public.der","size":162,"pieces":[{"name":"game.public.der0","offset":0}]}]}

BIN
docs/assets/platformer/game.arcd0


BIN
docs/assets/platformer/game.arcd1


BIN
docs/assets/platformer/game.arcd2


BIN
docs/assets/platformer/game.arcd3


BIN
docs/assets/platformer/game.arcd4


BIN
docs/assets/platformer/game.arcd5


BIN
docs/assets/platformer/game.arcd6


BIN
docs/assets/platformer/game.arci0


BIN
docs/assets/platformer/game.darc0


BIN
docs/assets/platformer/game.darc1


BIN
docs/assets/platformer/game.darc2


BIN
docs/assets/platformer/game.darc3


BIN
docs/assets/platformer/game.darc4


BIN
docs/assets/platformer/game.darc5


BIN
docs/assets/platformer/game.darc6


BIN
docs/assets/platformer/game.dmanifest0


BIN
docs/assets/platformer/game.public.der0


+ 1 - 1
docs/assets/runner/archive_files.json

@@ -1 +1 @@
-{"content":[{"name":"game.projectc","size":375,"pieces":[{"name":"game.projectc0","offset":0}]},{"name":"game.darc","size":1595204,"pieces":[{"name":"game.darc0","offset":0}]}]}
+{"content":[{"name":"game.projectc","size":378,"pieces":[{"name":"game.projectc0","offset":0}]},{"name":"game.arci","size":6448,"pieces":[{"name":"game.arci0","offset":0}]},{"name":"game.arcd","size":2144408,"pieces":[{"name":"game.arcd0","offset":0},{"name":"game.arcd1","offset":2097152}]},{"name":"game.dmanifest","size":14545,"pieces":[{"name":"game.dmanifest0","offset":0}]},{"name":"game.public.der","size":162,"pieces":[{"name":"game.public.der0","offset":0}]}]}

BIN
docs/assets/runner/game.arcd0


BIN
docs/assets/runner/game.arcd1


BIN
docs/assets/runner/game.arci0


BIN
docs/assets/runner/game.darc0


BIN
docs/assets/runner/game.dmanifest0


+ 1 - 1
docs/assets/runner/game.projectc0

@@ -2,7 +2,7 @@
 title = platformer
 
 [bootstrap]
-main_collection = /main/main.collectionc
+main_collection = /level/level1.collectionc
 
 [input]
 game_binding = /input/game.input_bindingc

BIN
docs/assets/runner/game.public.der0


+ 1 - 1
docs/assets/shadertoy/archive_files.json

@@ -1 +1 @@
-{"content":[{"name":"game.projectc","size":237,"pieces":[{"name":"game.projectc0","offset":0}]},{"name":"game.arci","size":848,"pieces":[{"name":"game.arci0","offset":0}]},{"name":"game.arcd","size":2296,"pieces":[{"name":"game.arcd0","offset":0}]},{"name":"game.dmanifest","size":1438,"pieces":[{"name":"game.dmanifest0","offset":0}]},{"name":"game.public.der","size":162,"pieces":[{"name":"game.public.der0","offset":0}]}]}
+{"content":[{"name":"game.projectc","size":236,"pieces":[{"name":"game.projectc0","offset":0}]},{"name":"game.arci","size":848,"pieces":[{"name":"game.arci0","offset":0}]},{"name":"game.arcd","size":2296,"pieces":[{"name":"game.arcd0","offset":0}]},{"name":"game.dmanifest","size":1438,"pieces":[{"name":"game.dmanifest0","offset":0}]},{"name":"game.public.der","size":162,"pieces":[{"name":"game.public.der0","offset":0}]}]}

BIN
docs/assets/shadertoy/game.dmanifest0


+ 1 - 1
docs/assets/shadertoy/game.projectc0

@@ -1,5 +1,5 @@
 [project]
-title = My project
+title = Shadertoy
 version = 0.1
 
 [bootstrap]

BIN
docs/assets/shadertoy/game.public.der0


+ 1 - 1
docs/assets/side-scroller/archive_files.json

@@ -1 +1 @@
-{"content":[{"name":"game.projectc","size":226,"pieces":[{"name":"game.projectc0","offset":0}]},{"name":"game.darc","size":1492624,"pieces":[{"name":"game.darc0","offset":0}]}]}
+{"content":[{"name":"game.projectc","size":226,"pieces":[{"name":"game.projectc0","offset":0}]},{"name":"game.arci","size":3168,"pieces":[{"name":"game.arci0","offset":0}]},{"name":"game.arcd","size":1519171,"pieces":[{"name":"game.arcd0","offset":0}]},{"name":"game.dmanifest","size":5779,"pieces":[{"name":"game.dmanifest0","offset":0}]},{"name":"game.public.der","size":162,"pieces":[{"name":"game.public.der0","offset":0}]}]}

BIN
docs/assets/side-scroller/game.arcd0


BIN
docs/assets/side-scroller/game.arci0


BIN
docs/assets/side-scroller/game.darc0


BIN
docs/assets/side-scroller/game.dmanifest0


BIN
docs/assets/side-scroller/game.public.der0


+ 1 - 0
docs/assets/war-battles/archive_files.json

@@ -0,0 +1 @@
+{"content":[{"name":"game.projectc","size":236,"pieces":[{"name":"game.projectc0","offset":0}]},{"name":"game.arci","size":1888,"pieces":[{"name":"game.arci0","offset":0}]},{"name":"game.arcd","size":143174,"pieces":[{"name":"game.arcd0","offset":0}]},{"name":"game.dmanifest","size":3184,"pieces":[{"name":"game.dmanifest0","offset":0}]},{"name":"game.public.der","size":162,"pieces":[{"name":"game.public.der0","offset":0}]}]}

BIN
docs/assets/war-battles/game.arcd0


BIN
docs/assets/war-battles/game.arci0


BIN
docs/assets/war-battles/game.dmanifest0


+ 20 - 0
docs/assets/war-battles/game.projectc0

@@ -0,0 +1,20 @@
+[project]
+title = My project
+version = 0.1
+
+[bootstrap]
+main_collection = /main/main.collectionc
+
+[input]
+game_binding = /input/game.input_bindingc
+
+[display]
+width = 720
+height = 720
+
+[physics]
+scale = 0.02
+
+[script]
+shared_state = 1
+

BIN
docs/assets/war-battles/game.public.der0


BIN
docs/assets/war-battles/preview.jpg


+ 7 - 5
docs/en/manuals/2dgraphics.md

@@ -193,15 +193,17 @@ You can attach physics to the Tile Map to do collision detection or physics simu
 
 ## Changing tiles from script
 
-You can change the content of a Tile Map dynamically while your game is running. To do so, send [`set_tile`](/ref/tilemap#set_tile) messages to the Tile Map:
+You can change the content of a Tile Map dynamically while your game is running. To do so, call the [`tilemap.set_tile()`](/ref/tilemap/#tilemap.set_tile) function:
 
 ```lua
 -- Replace the two door-tiles with "open door" tiles.
 -- The door is two tiles, one on top of the other.
-local doorpos = vmath.vector3(174, 305, 0)
-msg.post("/level#tilemap", "set_tile", { layer_id = hash("layer1"), position = doorpos, tile = 58 })
--- Upper part of door can be adressed with same position and "dy" set to 1.
-msg.post("/level#tilemap", "set_tile", { layer_id = hash("layer1"), position = doorpos, tile = 46, dy = 1 })
+local x = 3
+local y = 4
+-- Lower part of door
+tilemap.set_tile("/level#tilemap", "layer1", x, y, 58)
+-- Upper part of door
+tilemap.set_tile("/level#tilemap", "layer1", x, y+1, 46)
 ```
 
 ## Adding a Tile Map to your game

+ 11 - 0
docs/en/manuals/animation.md

@@ -335,6 +335,17 @@ The corresponding value to use when calling `go.animate()` are `go.EASING_LINEAR
 
 For `gui.animate()` the values are named `gui.EASING_LINEAR`, `gui.EASING_INBACK`, `gui.EASING_OUTBACK` and so forth.
 
+```linechart
+{
+  "labels": [1, "Tuesday", "Wednesday", "Thursday", "Friday"],
+  "series": [
+    [12, 9, 7, 8, 5],
+    [2, 1, 3.5, 7, 3],
+    [1, 3, 4, 5, 6]
+  ]
+}
+```
+
 ![Linear interpolation](images/properties/easing_linear.png){.inline}
 ![In back](images/properties/easing_inback.png){.inline}
 ![Out back](images/properties/easing_outback.png){.inline}

+ 1 - 1
docs/en/tutorials/car.md

@@ -241,7 +241,7 @@ Now, select <kbd>Project ▸ Build And Launch</kbd> from the main menu and take
     </button>
     <script src="//storage.googleapis.com/defold-doc/assets/dmloader.js">
     </script>
-    <script src="//storage.googleapis.com/defold-doc/assets/dmengine.js" async>
+    <script src="//storage.googleapis.com/defold-doc/assets/dmengine_1_2_106.js" async>
     </script>
     <script>
         /* Load app on click in container. */

BIN
docs/en/tutorials/images/war-battles/done.png


BIN
docs/en/tutorials/images/war-battles/explosion_animation.png


BIN
docs/en/tutorials/images/war-battles/fire_rocket_2.png


BIN
docs/en/tutorials/images/war-battles/fire_rocket_3.png


BIN
docs/en/tutorials/images/war-battles/fire_rockets.png


BIN
docs/en/tutorials/images/war-battles/flip_rocket.png


BIN
docs/en/tutorials/images/war-battles/main_gui.png


BIN
docs/en/tutorials/images/war-battles/rocket_collision.png


BIN
docs/en/tutorials/images/war-battles/tank_animation.png


BIN
docs/en/tutorials/images/war-battles/tank_collision.png


BIN
docs/en/tutorials/images/war-battles/tanks.png


BIN
docs/en/tutorials/images/war-battles/text_font.png


BIN
docs/en/tutorials/images/war-battles/ui.png


BIN
docs/en/tutorials/images/war-battles/ui_script.png


+ 1 - 1
docs/en/tutorials/magic-link.md

@@ -17,7 +17,7 @@ This tutorial is written as a step-by-step guide where we build the game on a co
         START GAME <span class="icon"></span>
     </button>
     <script src="//storage.googleapis.com/defold-doc/assets/dmloader.js"></script>
-    <script src="//storage.googleapis.com/defold-doc/assets/dmengine.js" async></script>
+    <script src="//storage.googleapis.com/defold-doc/assets/dmengine_1_2_106.js" async></script>
     <script>
         /* Load app on click in container. */
         document.getElementById("game-button").onclick = function (e) {

+ 1 - 1
docs/en/tutorials/platformer.md

@@ -15,7 +15,7 @@ In this article, we go through the implementation of a basic tile-based 2D platf
     START GAME <span class="icon"></span>
   </button>
   <script src="//storage.googleapis.com/defold-doc/assets/dmloader.js"></script>
-  <script src="//storage.googleapis.com/defold-doc/assets/dmengine.js" async></script>
+  <script src="//storage.googleapis.com/defold-doc/assets/dmengine_1_2_106.js" async></script>
   <script>
       /* Load app on click in container. */
       document.getElementById("game-button").onclick = function (e) {

+ 1 - 1
docs/en/tutorials/runner.md

@@ -15,7 +15,7 @@ In this tutorial we start with an empty project and build a complete runner game
     START GAME <span class="icon"></span>
   </button>
   <script type='text/javascript' src="//storage.googleapis.com/defold-doc/assets/dmloader.js"></script>
-  <script type='text/javascript' src="//storage.googleapis.com/defold-doc/assets/dmengine.js" async></script>
+  <script type='text/javascript' src="//storage.googleapis.com/defold-doc/assets/dmengine_1_2_106.js" async></script>
   <script type='text/javascript'>
       /* Load app on click in container. */
       document.getElementById("game-button").onclick = function (e) {

+ 1 - 1
docs/en/tutorials/shadertoy.md

@@ -255,7 +255,7 @@ You can view the results here:
     START GAME <span class="icon"></span>
   </button>
   <script type='text/javascript' src="//storage.googleapis.com/defold-doc/assets/dmloader.js"></script>
-  <script type='text/javascript' src="//storage.googleapis.com/defold-doc/assets/dmengine_1_2_103.js" async></script>
+  <script type='text/javascript' src="//storage.googleapis.com/defold-doc/assets/dmengine_1_2_106.js" async></script>
   <script type='text/javascript'>
       /* Load app on click in container. */
       document.getElementById("game-button").onclick = function (e) {

+ 1 - 1
docs/en/tutorials/side-scroller.md

@@ -17,7 +17,7 @@ The game is extremely simple. The player controls a space ship and is supposed t
     START GAME <span class="icon"></span>
   </button>
   <script src="//storage.googleapis.com/defold-doc/assets/dmloader.js"></script>
-  <script src="//storage.googleapis.com/defold-doc/assets/dmengine.js" async></script>
+  <script src="//storage.googleapis.com/defold-doc/assets/dmengine_1_2_106.js" async></script>
   <script>
       /* Load app on click in container. */
       document.getElementById("game-button").onclick = function (e) {

+ 389 - 5
docs/en/tutorials/war-battles.md

@@ -7,6 +7,37 @@ brief: In this tutorial you will create a small shooter game. This is a good sta
 
 This tutorial goes through all the steps needed to create a small playable game in Defold. You do not need to have any prior experience with Defold, but if you have done some programming in Lua, Javascript, Python or similar, that will help.
 
+To get an idea about what you will build, you can try the result here:
+
+<div id="game-container" class="game-container">
+    <img id="game-preview" src="//storage.googleapis.com/defold-doc/assets/war-battles/preview.jpg"/>
+    <canvas id="game-canvas" tabindex="1" width="720" height="720">
+    </canvas>
+    <button id="game-button">
+        START GAME <span class="icon"></span>
+    </button>
+    <script src="//storage.googleapis.com/defold-doc/assets/dmloader.js"></script>
+    <script src="//storage.googleapis.com/defold-doc/assets/dmengine_1_2_106.js" async></script>
+    <script>
+        /* Load app on click in container. */
+        document.getElementById("game-button").onclick = function (e) {
+            var extra_params = {
+                archive_location_filter: function( path ) {
+                    return ("//storage.googleapis.com/defold-doc/assets/war-battles" + path + "");
+                },
+                load_done: function() {},
+                game_start: function() {
+                    var e = document.getElementById("game-preview");
+                    e.parentElement.removeChild(e);
+                }
+            }
+            Module.runApp("game-canvas", extra_params);
+            document.getElementById("game-button").style.display = 'none';
+            document.getElementById("game-button").onclick = null;
+        };
+    </script>
+</div>
+
 ## Setting up the project
 
 You need to create an empty project in Defold and download the asset package.
@@ -265,9 +296,9 @@ Consider the main collection for a second. Now it contains two game objects: the
 
 1. <kbd>Right click</kbd> the folder *main* in the *Assets* view and select <kbd>New ▸ Game object</kbd>. Name this file *rocket.go*. Note that by creating this file, you do not create a game object but a file can be used as a *blueprint* when creating an actual game object.
 
-2. Drag the folder *buildings/turret-rocket* in the asset package to the *main* folder in the *Assets* view.
+2. Drag the folder *buildings/turret-rocket* from the asset package to the *main* folder in the *Assets* view.
 
-3. Open *sprites.atlas* and create a new animation group (right click the root node and select <kbd>New ▸ Animation group</kbd>).
+3. Open *sprites.atlas* and create a new animation group (right click the root node and select <kbd>New ▸ Animation group</kbd>). Name the animation "rocket".
 
 4. Add the three rocket images to the animation group and set the *Fps* property to a value that makes the animation look good when you preview.
 
@@ -291,20 +322,373 @@ Now you have a basic rocket game object blueprint. The next step is to add funct
 
     ![input](images/war-battles/input_bindings_fire.png)
 
-5. Open *main/player.script* and scroll down to the `on_input()` function. Add a fourth `elseif` for the case where the function is called with the "fire" action:
+5. Open *main/player.script* and add a flag to track if the player is firing in the `init()` function:
+
+    ```lua
+    function init(self)
+        msg.post("#", "acquire_input_focus")
+    
+        self.moving = false
+        self.firing = false -- <1>
+        
+        self.input = vmath.vector3()
+        self.dir = vmath.vector3(0, 1, 0)
+        self.speed = 50
+    end
+    ```
+    1. Whenever the player is firing this value will be set to `true`.
+
+6. Add what should happen when the flag is set in `update()`. The factory should create a new game object instance:
+
+    ```lua
+    function update(self, dt)
+        if self.moving then
+            local pos = go.get_position()
+            pos = pos + self.dir * self.speed * dt
+            go.set_position(pos)
+        end
+        
+        if self.firing then
+            factory.create("#rocketfactory") -- <1>
+        end
+        
+        self.input.x = 0
+        self.input.y = 0
+        
+        self.moving = false
+        self.firing = false -- <2>
+    end
+    ```
+    1. If the `firing` flag is true, tell the factory component called "rocketfactory" that you just created to spawn a new game object.
+    2. Set the flag to false. This flag will be set in `on_input()` each frame the player presses the fire key.
+
+7. Scroll down to the `on_input()` function. Add a fourth `elseif` for the case where the function is called with the "fire" action:
 
     ```lua
         ...
         elseif action_id == hash("right") then
             self.input.x = 1
         elseif action_id == hash("fire") and action.pressed then
-            factory.create("#rocketfactory")
+            self.firing = true
+        end
+        ...
+    ```
+
+If you run the game now you should be able to move around and drop rockets all over the map by hammering the fire key. This is a good start, now you only need to fix three things:
+
+1. When the rocket is spawned, it should be oriented in the player's direction and it should move straight ahead.
+2. The rocket should explode after a second or so.
+
+Let's do these things one by one:
+
+## Setting the direction of the rocket
+
+1. Open *main/player.script* and scroll down to the `on_input()` function.
+
+    ```lua
+        ...
+        elseif action_id == hash("right") then
+            self.input.x = 1
+        elseif action_id == hash("fire") and action.pressed then
+            local angle = math.atan2(self.dir.y, self.dir.x) -- <1>
+            local rot = vmath.quat_rotation_z(angle) -- <2>
+            local props = { dir = self.dir } -- <3>
+            factory.create("#rocketfactory", nil, rot, props) -- <4>
         end
 
         ...
     ```
+    1. Compute the angle (in radians) of the player.
+    2. Create a quaternion for that angular rotation around Z.
+    3. Create a table containing property values to pass to the rocket. The player's direction is the only data the rocket needs.
+    3. Add explicit position (`nil`, the rocket will spawn at the player's position), rotation (the calculated quaternion) and spawn property values.
+
+    Note that the rocket needs a movement direction in addition to the game object rotation (`rot`). It would be possible to make the rocket calculate its movement vector based on its rotation, but it is easier and more flexible to separate the two values. For instance, with a separate rotation it is possible to add rotation wobble to the rocket without it affecting the movement direction.
 
+3.  <kbd>Right click</kbd> the folder *main* in the *Assets* view and select <kbd>New ▸ Script</kbd>. Name the new script file "rocket.script". Replace the code of the file with the following:
+
+    ```lua
+    go.property("dir", vmath.vector3()) -- <1>
+    
+    function init(self)
+        self.speed = 200 -- <2>
+    end
+    
+    function update(self, dt)
+        local pos = go.get_position() -- <3>
+        pos = pos + self.dir * self.speed * dt -- <4>
+        go.set_position(pos) -- <5>
+    end
+    ```
+    1. Define a new script property named `dir` and initialize the property with a default empty vector (`vmath.vector3()`). The default value can be overrided by passing values to the `factory.create()` function. The current property value is accessed as `self.dir`.
+    2. A rocket speed value, expressed in pixels per second.
+    3. Get the current rocket position.
+    4. Calculate a new position based on the old position, the movement direction (unit vector) and the speed.
+    5. Set the new position.
+
+4. Open *rocket.go* and <kbd>Right click</kbd> the root in the *Outline* and select <kbd>Add component ▸ Script</kbd>. Select "rocket.script" for the component.
+
+5. Run the game and try the new mechanic. Notice that the rockets fly in the right direction but are oriented 180 degrees wrong.
+
+    ![fire rockets](images/war-battles/fire_rockets.png)
+
+6. Open *sprites.atlas*, select the "rocket" animation and click the *Flip horizontal* property.
+
+    ![flip rocket](images/war-battles/flip_rocket.png)
+
+7. Run the game again to verify that everything looks ok.
+
+    ![fire rockets](images/war-battles/fire_rocket_2.png)
+
+Now you only need to make the rockets explode.
 
 ## Explosions
 
-## 
+1. Drag the folder *fx/explosion* from the asset package to the main folder in the Assets view.
+
+2. Open *sprites.atlas* and create a new animation group (right click the root node and select <kbd>New ▸ Animation group</kbd>). Call the animation "explosion".
+
+3. Add the nine explosion images to the animation group and set the *Fps* property to a value that makes the animation look good when you preview. Also make sure that this animation has the *Playback* property set to `Once Forward`.
+
+    ![explosion animation](images/war-battles/explosion_animation.png)
+
+4. Open *main/rocket.script* and scroll down to the `init()` function and change it to:
+
+    ```lua
+    function init(self)
+        self.speed = 200
+        self.life = 1 -- <1>
+    end
+    ```
+    1. This value will act as a timer to track the lifetime of the rocket.
+
+5. Scroll down to the `update()` function and change it to:
+
+    ```lua
+    function update(self, dt)
+        local pos = go.get_position()
+        pos = pos + self.dir * self.speed * dt
+        go.set_position(pos)
+        
+        self.life = self.life - dt -- <1>
+        if self.life < 0 then -- <2>
+            self.life = 1000 -- <3>
+            go.set_rotation(vmath.quat()) -- <4>
+            self.speed = 0 -- <5>
+            msg.post("#sprite", "play_animation", { id = hash("explosion") }) -- <6>
+        end
+    end
+    ```
+    1. Decrease the life timer with delta time. It will decrease with 1.0 per second.
+    2. When the life timer has reached zero.
+    3. Set the life timer to a large value so this code won't run every subsequent update.
+    4. Set the game object rotation to 0, otherwise the explosion graphics will be rotated.
+    5. Set the movement speed to 0, otherwise the explosion graphics will move.
+    6. Play the "explosion" animation on the game object's "sprite" component.
+
+6. Below the `update()` function, add a new `on_message()` function:
+
+    ```lua
+    function on_message(self, message_id, message, sender) -- <1>
+        if message_id == hash("animation_done") then -- <2>
+            go.delete() -- <3>
+        end 
+    end
+    ```
+    1. The function `on_message()` gets called whenever a message is posted to this script component.
+    2. If the message posted has the hashed name (or id) "animation_done", then. The engine runtime sends back this message when a sprite animation initiated with "play_animation" has finished playing.
+    3. When the animation is done, delete the current game object.
+
+Run the game. Now it starts feeling like the embryo for a nice little game, don't you think?
+
+![fire rockets](images/war-battles/fire_rocket_3.png)
+
+But now you need something to fire the rockets at. Enter tanks!
+
+## The tank game object
+
+1. <kbd>Right click</kbd> the folder *main* in the *Assets* view and select <kbd>New ▸ Game object</kbd>. Name this file *tank.go*. Like the rocket game object, this is a file that can be used as a *blueprint* when creating the actual tank game objects.
+
+2. Drag the folder *units/tank* from the asset package to the *main* folder in the *Assets* view.
+
+3. Open *sprites.atlas* and create a new animation group (right click the root node and select <kbd>New ▸ Animation group</kbd>). Name the animation "tank-down".
+
+4. Add the two downwards facing images (*/main/tank/down/1.png* and */main/tank/down/2.png*) to the animation and set it's *Fps* value to something that looks good.
+
+    ![tank animation](images/war-battles/tank_animation.png)
+
+5. Open *tank.go* and <kbd>Right click</kbd> the root in the *Outline* and select <kbd>Add component ▸ Sprite</kbd>.
+
+6. Set the *Image* property of the sprite to "/main/sprites.atlas" and the *Default animation* to "tank-down".
+
+7. Open *main.collection*
+
+8. <kbd>Right click</kbd> the root node of the collection in the *Outline* and select <kbd>Add Game Object File</kbd>. Select *tank.go* as blueprint for the new game object.
+
+9. Create a few more tanks and position them on the map with the *Move Tool*. Make sure to set the Z position to 1.0 so they are rendered on top of the map.
+
+    ![tanks](images/war-battles/tanks.png)
+
+Run the game and check that the tanks look okay. You will notice that the rockets fly straight through the tanks so the next step is to add collision between the tanks and the rockets. To do this you need to add a new component to the tank and the rocket game object:
+
+## Adding collision objects
+
+1. Open *tank.go* and <kbd>Right click</kbd> the root in the *Outline* and select <kbd>Add component ▸ Collision Object</kbd>.
+
+2. Set the *Type* property to "Kinematic". This means that the physics engine will not simulate any gravity or collision on this object. Instead it will detect collisions and leave it to you to code the response.
+
+3. Set the *Group* property to "tanks" and *Mask* to "rockets". This causes this game object to detect collisions against object in the group "rockets" that has the mask set to "tanks".
+
+4. <kbd>Right click</kbd> the "collisionobject" component in the *Outline* and select <kbd>Add Shape ▸ Box</kbd>. Set the size of the box shape to match the tank graphics.
+
+    ![tank collision](images/war-battles/tank_collision.png)
+
+6. Open *rocket.go* and <kbd>Right click</kbd> the root in the *Outline* and select <kbd>Add component ▸ Collision Object</kbd>.
+
+7. Set the *Type* property to "Kinematic".
+
+8. Set the *Group* property to "rockets" and *Mask* to "tanks". This causes this game object to detect collisions against object in the group "tanks" that has the mask set to "rockets". Since that is what you set the group and mask to in *tank.go* the rockets and tanks will interact physically.
+
+    ![rocket collision](images/war-battles/rocket_collision.png)
+
+Now the engine will detect when these game objects intersect and send messages to them when that happens. The last piece of the puzzle is an addition to the rocket's script.
+
+## Reacting to collisions
+
+1. Open *rocket.script* and scroll down to the `update()` function. There are a couple of things to do here:
+
+    ```lua
+    local function explode(self) -- <1>
+        self.life = 1000
+        go.set_rotation(vmath.quat())
+        self.speed = 0
+        msg.post("#sprite", "play_animation", { id = hash("explosion") })       
+    end
+    
+    function update(self, dt)
+        local pos = go.get_position()
+        pos = pos + self.dir * self.speed * dt
+        go.set_position(pos)
+        
+        self.life = self.life - dt
+        if self.life < 0 then
+            explode(self) -- <2>
+        end
+    end
+    
+    function on_message(self, message_id, message, sender)
+        if message_id == hash("animation_done") then
+            go.delete()
+        elseif message_id == hash("collision_response") then -- <3>
+            explode(self) -- <4>
+            go.delete(message.other_id) -- <5>
+        end
+    end
+    ```
+    1. Since you want the rocket to explode either when the timer runs out (in `update()`) or when the rocket hits a tank (in `on_message()`) you should break out that piece of code to avoid duplication. There are a few options, the easiest is probably to just create a local function. The function is declared `local` meaning it only exist for the rocket script. Therefore it must be placed before it is used, above `update()`, this is how Lua's scoping rules work. Also note that you should pass `self` as a parameter to the function to be able to access `self.life` etc.
+    2. The code that used to live here has been moved to the `explode()` function.
+    3. The engine sends a message called "collision_response" when the shapes collide, if the group and mask pairing is correct.
+    4. Call the `explode()` function if there is a collision.
+    5. Finally delete the tank. You get the id of the game object the rocket collided with in the `message.other_id` variable.
+
+And now you can run the game and try to destroy some tanks. The tanks aren't very interesting enemies, but they should nevertheless give you some score.
+
+## Scoring GUI
+
+1. Drag the the file *fonts/04B_03.TTF* from the asset pack folder to the *main* folder in the *Assets* view.
+
+2. <kbd>Right click</kbd> the folder *main* in the *Assets* view and select <kbd>New ▸ Font</kbd>. Name this file *text.font*.
+
+    ![text font](images/war-battles/text_font.png)
+
+3. <kbd>Right click</kbd> the folder *main* in the *Assets* view and select <kbd>New ▸ Gui</kbd>. Name this file *ui.gui*. It will contain the user interface where you will place the score counter.
+
+4. Open *ui.gui*. <kbd>Right click</kbd> *Fonts* in the *Outline* view and select <kbd>Add ▸ Fonts</kbd>. Select the */main/text.font* file.
+
+5. <kbd>Right click</kbd> *Nodes* in the *Outline* view and select <kbd>Add ▸ Text</kbd>.
+
+6. Select the new text node in the outline and set its *Id* property to "score", its *Text* property to "SCORE: 0", its *Font* property to the font "text" and its *Pivot* property to "West".
+
+7. Place the text node in the top left corner of the screen.
+
+    ![ui gui](images/war-battles/ui.png)
+
+8. <kbd>Right click</kbd> the folder *main* in the *Assets* view and select <kbd>New ▸ Gui Script</kbd>. Name this file *ui.gui_script*.
+
+9. Go back to *ui.gui* and select the root node in the *Outline*. Set the *Script* property to the file */main/ui.gui_script* that you just created. Now if we add this Gui as a component to a game object the script will run for the component.
+
+10. Open *main.collection*.
+
+11. <kbd>Right click</kbd> the root node of the collection in the *Outline* and select <kbd>Add game object</kbd>.
+
+11. Set the id of the game object to "gui", then <kbd>Right click</kbd> it and select <kbd>Add Component File</kbd>. Select the file */main/ui.gui*.
+
+    ![main gui](images/war-battles/main_gui.png)
+
+Now there is a score counter on screen. You only need to add functionality in the Gui script so the score can be updated.
+
+## Updating the score
+
+1. Open *ui.gui_script*
+
+2. Replace the template code with the following:
+
+    ```lua
+    function init(self)
+        self.score = 0 -- <1>
+    end
+    
+    function on_message(self, message_id, message, sender)
+        if message_id == hash("add_score") then -- <2>
+            self.score = self.score + message.score -- <3>
+            local scorenode = gui.get_node("score") -- <4>
+            gui.set_text(scorenode, "SCORE: " .. self.score) -- <5>
+        end 
+    end
+    ```
+    1. Store the current score in `self`. Start from 0.
+    2. Reaction to a message named "add_score".
+    3. Increase the current score value in `self` with the value passed in the message.
+    4. Get hold of the text node named "score" that you created in the Gui.
+    5. Update the text of the node to the string "SCORE: " and the current score value concatenated to the end of the string.
+
+3. Open *rocket.script* and scroll down to the `on_message()` function where you need to add a line of code:
+
+    ```lua
+    function on_message(self, message_id, message, sender)
+        if message_id == hash("animation_done") then
+            go.delete()
+        elseif message_id == hash("collision_response") then
+            explode(self)
+            go.delete(message.other_id)
+            msg.post("/gui#gui", "add_score", {score = 100}) -- <1>
+        end
+    end
+    ```
+    1. Post a message named "add_score" to the component "gui" in the game object named "gui" at the root of the main collection. Pass along a table where the entry `score` has been set to 100.
+
+4. Try the game!
+
+![done](images/war-battles/done.png)
+
+Well done! We hope you enjoyed this tutorial and that it was helpful.
+
+## What next?
+
+To get to know Defold better, we suggest that you to continue working with this little game. Here are a few good exercises:
+
+1. Add directional animations for the player character. Tip, add a function called `update_animation(self)` to the `update()` function and change the animation depending on the value of the `self.dir` vector. It is also worth remembering that if you send a "play_animation" message each frame to a sprite, the animation will restart from the beginning, each frame---so you should only send "play_animation" when the animation should change.
+
+2. Add an "idle" state to the player character so it only plays a walking animation when moving.
+
+3. Make the tanks spawn dynamically. Look at how the rockets are spawned and do a similar setup for the tanks. You might want to create a new game object in the main collection with a script that controls the tank spawning.
+
+4. Make the tanks patrol the map. One simple option is to have the tank pick a random point on the map and move towards that point. When it is within a short distance of the point, it picks a new point.
+
+5. Make the tanks chase the player. One option is to add a new collision object to the tank with a spherical shape. If the player collides with the collision object, have the tank drive towards the player.
+
+6. Make the tanks fire at the player.
+
+7. Add sound effects.
+
+If you are stuck, please head over to the [Defold Forum](//forum.defold.com) where you can talk to the Defold developers and many friendly users.

+ 5 - 2
docs/sass/preview-md.sass

@@ -1,5 +1,8 @@
-@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro');
-@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro');
+@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro')
+@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro')
+@import url('//cdn.jsdelivr.net/chartist.js/latest/chartist.min.css')
+@import url('//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css')
+
 @font-face
   font-family: 'fontello'
   src: url('//www.defold.com/static/fonts/fontello.eot')

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä