view org/games.org @ 429:b5d0f0adf19f

improvements by Dylan!
author Robert McIntyre <rlm@mit.edu>
date Fri, 21 Mar 2014 20:56:56 -0400
parents 7e7f8d6d9ec5
children
line wrap: on
line source
1 #+title: jMonkeyEngine3 from Clojure
2 #+author: Robert McIntyre
3 #+email: rlm@mit.edu
4 #+description: Using jMonkeyEngine3 from clojure
5 #+keywords: clojure, jMonkeyEngine3, tutorial, examples
6 #+SETUPFILE: ../../aurellem/org/setup.org
7 #+INCLUDE: ../../aurellem/org/level-0.org
8 #+babel: :mkdirp yes :noweb yes :exports both
10 [TABLE-OF-CONTENTS]
13 Here are the jMonkeyEngine "Hello" programs translated to clojure.
15 * Hello Simple App
16 Here is the hello world example for jme3 in clojure. It's a more or
17 less direct translation from the java source [[http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_simpleapplication][here]].
19 Of note is the fact that since we don't have access to the
20 =AssetManager= via extending =SimpleApplication=, we have to build one
21 ourselves.
23 #+name: hello-simple-app
24 #+begin_src clojure :results silent
25 (ns hello.hello-simple-app
26 (:use cortex.world)
27 (:import com.jme3.math.Vector3f)
28 (:import com.jme3.material.Material)
29 (:import com.jme3.scene.Geometry)
30 (:import com.jme3.math.ColorRGBA)
31 (:import com.jme3.app.SimpleApplication)
32 (:import com.jme3.scene.shape.Box))
34 (def cube (Box. Vector3f/ZERO 1 1 1))
36 (def geom (Geometry. "Box" cube))
38 (def mat (Material. (asset-manager) "Common/MatDefs/Misc/Unshaded.j3md"))
40 (.setColor mat "Color" ColorRGBA/Blue)
42 (.setMaterial geom mat)
44 (defn simple-app []
45 (doto
46 (proxy [SimpleApplication] []
47 (simpleInitApp
48 []
49 ;; Don't take control of the mouse
50 (org.lwjgl.input.Mouse/setGrabbed false)
51 (.attachChild (.getRootNode this) geom)))
52 ;; don't show a menu to change options.
53 (.setShowSettings false)
54 (.setPauseOnLostFocus false)
55 (.setSettings *app-settings*)))
56 #+end_src
58 Running this program will begin a new jMonkeyEngine game which
59 displays a single blue cube.
61 #+begin_src clojure :exports code :results silent
62 (.start (hello.hello-simple-app/simple-app))
63 #+end_src
65 #+caption: the simplest JME game.
66 [[../images/simple-app.jpg]]
68 * Simpler HelloSimpleApp
70 #+name: hello-simpler-app
71 #+begin_src clojure
72 (ns hello.hello-simpler-app
73 (:use cortex.world)
74 (:use cortex.util)
75 (:import com.jme3.math.ColorRGBA)
76 (:import com.jme3.scene.Node))
78 (defn simpler-world
79 "The jMonkeyEngine3 Hello World program. Displays a blue 3D cube in
80 a basic 3D world."
81 []
82 (world (doto (Node.)
83 (.attachChild
84 (box 1 1 1
85 :color ColorRGBA/Blue :physical? false)))
86 {} no-op no-op))
87 #+end_src
89 More information about the jMonkeyEngine3 hello world program can be
90 found [[http://jmonkeyengine.org/wiki/doku.php/starter:hello_world][here]].
92 * COMMENT Hello Physics
93 From http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_physics
95 #+name: brick-wall-header
96 #+begin_src clojure :results silent
97 (ns hello.brick-wall)
98 (require 'cortex.import)
99 (use 'clojure.contrib.def)
100 (rlm.rlm-commands/help)
101 (cortex.import/mega-import-jme3)
102 (use '[pokemon [lpsolve :only [constant-map]]])
103 (use 'cortex.world)
104 (use 'cortex.util)
105 #+end_src
107 #+name: brick-wall-body
108 #+begin_src clojure :results silent
109 (in-ns 'hello.brick-wall)
111 (defn floor
112 "make a sturdy, unmovable physical floor"
113 []
114 (box 20 1 20 :mass 0 :color false :position (Vector3f. 0 -2 0)))
116 (def brick-length 0.48)
117 (def brick-width 0.24)
118 (def brick-height 0.12)
119 (def gravity (Vector3f. 0 -9.81 0))
121 (defn brick* [position]
122 (doto (box brick-length brick-height brick-width
123 :position position :name "brick"
124 :material "Common/MatDefs/Misc/Unshaded.j3md"
125 :texture "Textures/Terrain/BrickWall/BrickWall.jpg"
126 :mass 36)
127 (->
128 (.getMesh)
129 (.scaleTextureCoordinates (Vector2f. 1 0.5)))
130 ;;(.setShadowMode RenderQueue$ShadowMode/CastAndReceive)
131 )
132 )
134 (defn inception-brick-wall
135 "construct a physical brick wall"
136 []
137 (let [node (Node. "brick-wall")]
138 (dorun
139 (map (comp #(.attachChild node %) brick*)
140 (for
141 [x (range 15)
142 y (range 10)
143 z (range 1)]
144 (Vector3f.
145 (* brick-length x 1.03)
146 (* brick-width y y 10)
147 (* brick-height z)))))
148 node))
150 (defn gravity-toggle
151 [new-value]
152 (fn [game value]
153 (println-repl "set gravity to " new-value)
154 (if value
155 (set-gravity game new-value)
156 (set-gravity game gravity))))
158 (defn floor* []
159 (doto (box 10 0.1 5 :name "floor" ;10 0.1 5 ; 240 0.1 240
160 :material "Common/MatDefs/Misc/Unshaded.j3md"
161 :texture "Textures/Terrain/Pond/Pond.png"
162 :position (Vector3f. 0 -0.1 0 )
163 :mass 0)
164 (->
165 (.getMesh)
166 (.scaleTextureCoordinates (Vector2f. 3 6)));64 64
167 (->
168 (.getMaterial)
169 (.getTextureParam "ColorMap")
170 (.getTextureValue)
171 (.setWrap Texture$WrapMode/Repeat))
172 (.setShadowMode RenderQueue$ShadowMode/Receive)
173 ))
175 (defn brick-wall* []
176 (let [node (Node. "brick-wall")]
177 (dorun
178 (map
179 (comp #(.attachChild node %) brick*)
180 (for [y (range 15)
181 x (range 4)
182 z (range 1)]
183 (Vector3f.
184 (+ (* 2 x brick-length)
185 (if (even? (+ y z))
186 (/ brick-length 4) (/ brick-length -4)))
187 (+ (* brick-height (inc (* 2 y))))
188 (* 2 z brick-width) ))))
189 (.setShadowMode node RenderQueue$ShadowMode/CastAndReceive)
190 node))
192 (defn brick-wall-game-run []
193 (doto
194 (world
195 (doto (Node.) (.attachChild (floor*))
196 (.attachChild (brick-wall*))
197 )
198 {"key-i" (gravity-toggle (Vector3f. 0 0 -9.81))
199 "key-m" (gravity-toggle (Vector3f. 0 0 9.81))
200 "key-l" (gravity-toggle (Vector3f. 9.81 0 0))
201 "key-j" (gravity-toggle (Vector3f. -9.81 0 0))
202 "key-k" (gravity-toggle Vector3f/ZERO)
203 "key-u" (gravity-toggle (Vector3f. 0 9.81 0))
204 "key-o" (gravity-toggle (Vector3f. 0 -9.81 0))
205 "key-f" (fn[game value]
206 (if (not value) (add-element game (brick-wall*))))
207 "key-return" (fire-cannon-ball)}
208 position-camera
209 (fn [& _]))
210 (.start)))
211 #+end_src
213 #+begin_src clojure :results silent
214 (hello.brick-wall/brick-wall-game-run)
215 #+end_src
217 #+caption: the brick wall standing
218 [[../images/brick-wall-standing.jpg]]
220 #+caption: the brick wall after it has been knocked over by a "pok\eacute{}ball"
221 [[../images/brick-wall-knocked-down.jpg]]
223 * COMMENT Other Brick Games
224 #+name: other-games
225 #+begin_src clojure :results silent
226 (ns hello.other-games
227 {:author "Dylan Holmes"})
228 (use 'cortex.world)
229 (use 'hello.brick-wall)
230 (use 'cortex.import)
231 (cortex.import/mega-import-jme3)
233 (defn scad [position]
234 (doto (box 0.1 0.1 0.1
235 :position position :name "brick"
236 :material "Common/MatDefs/Misc/Unshaded.j3md"
237 :texture "Textures/Terrain/BrickWall/BrickWall.jpg"
238 :mass 20)
239 (->
240 (.getMesh)
241 (.scaleTextureCoordinates (Vector2f. 1 0.5))
242 )
243 (-> (.getControl RigidBodyControl)
244 (.setLinearVelocity (Vector3f. 0 100 0))
245 )
247 ;;(.setShadowMode RenderQueue$ShadowMode/Cast)
248 ))
251 (defn shrapnel []
252 (let [node (Node. "explosion-day")]
253 (dorun
254 (map
255 (comp #(.attachChild node %) scad)
256 (for [y (range 15)
257 x (range 4)
258 z (range 1)]
259 (Vector3f.
260 (+ (* 2 x brick-height)
261 (if (even? (+ y z)) (/ brick-height 4) (/ brick-height -4)))
262 (+ (* brick-height (inc (* 2 y))))
263 (* 2 z brick-height) ))))
264 node))
267 (def domino-height 0.48)
268 (def domino-thickness 0.12)
269 (def domino-width 0.24)
271 (def domino-thickness 0.05)
272 (def domino-width 0.5)
273 (def domino-height 1)
275 (defn domino
276 ([position]
277 (domino position (Quaternion/IDENTITY)))
278 ([position rotation]
279 (doto (box domino-width domino-height domino-thickness
280 :position position :name "domino"
281 :material "Common/MatDefs/Misc/Unshaded.j3md"
282 :texture "Textures/Terrain/BrickWall/BrickWall.jpg"
283 :mass 1
284 :rotation rotation)
285 (.setShadowMode RenderQueue$ShadowMode/CastAndReceive)
286 )))
289 (defn domino-row []
290 (let [node (Node. "domino-row")]
291 (dorun
292 (map
293 (comp #(.attachChild node %) domino)
294 (for [
295 z (range 10)
296 x (range 5)
297 ]
298 (Vector3f.
299 (+ (* z domino-width) (* x 5 domino-width))
300 (/ domino-height 1)
301 (* -5.5 domino-thickness z) ))))
303 node))
305 (defn domino-cycle []
306 (let [node (Node. "domino-cycle")]
307 (dorun
308 (map
309 (comp #(.attachChild node %) (partial apply domino) )
310 (for [n (range 720)]
311 (let [space (* domino-height 5.5)
312 r (fn[n] (* (+ n 3) domino-width 0.5))
313 t (fn[n] (reduce
314 +
315 (map
316 (fn dt[n] (/ space (* 2 (Math/PI) (r n))))
317 (range n))))
318 t (t n)
319 r (r n)
320 ct (Math/cos t)
321 st (Math/sin t)
322 ]
323 (list
324 (Vector3f.
325 (* -1 r st)
326 (/ domino-height 1)
327 (* r ct))
328 (.fromAngleAxis (Quaternion.)
329 (- (/ 3.1415926 2) t) (Vector3f. 0 1 0))
330 )))
331 ))
332 node))
335 (defn domino-game-run []
336 (doto
337 (world
338 (doto (Node.) (.attachChild (floor*))
339 )
340 {"key-i" (gravity-toggle (Vector3f. 0 0 -9.81))
341 "key-m" (gravity-toggle (Vector3f. 0 0 9.81))
342 "key-l" (gravity-toggle (Vector3f. 9.81 0 0))
343 "key-j" (gravity-toggle (Vector3f. -9.81 0 0))
344 "key-k" (gravity-toggle (Vector3f. 0 9.81 0) )
345 "key-u" (fn[g v] ((gravity-toggle (Vector3f. 0 -0 0)) g true))
346 "key-o" (gravity-toggle (Vector3f. 0 -9.81 0))
348 "key-space"
349 (fn[game value]
351 (if (not value)
352 (let [d (domino (Vector3f. 0 (/ domino-height 0.25) 0)
353 (.fromAngleAxis (Quaternion.)
354 (/ Math/PI 2) (Vector3f. 0 1 0)))]
355 (add-element game d))))
356 "key-f"
357 (fn[game value](if (not value) (add-element game (domino-cycle))))
358 "key-return" (fire-cannon-ball)}
359 position-camera
360 (fn [& _]))
361 (.start)))
362 #+end_src
364 #+begin_src clojure :results silent
365 (cortex.other-games/domino-game-run)
366 #+end_src
368 #+caption: floating dominos
369 [[../images/dominos.jpg]]
371 * Hello Loop
372 #+name: hello-loop
373 #+begin_src clojure :results silent
374 (ns hello.loop
375 (:use cortex.world)
376 (:use cortex.util)
377 (:import com.jme3.math.ColorRGBA)
378 (:import com.jme3.scene.Node))
380 (defn blue-cube []
381 (box 1 1 1
382 :color ColorRGBA/Blue
383 :texture false
384 :material "Common/MatDefs/Misc/Unshaded.j3md"
385 :name "blue-cube"
386 :physical? false))
388 (defn blue-cube-game []
389 (let [cube (blue-cube)
390 root (doto (Node.) (.attachChild cube))]
391 (world root
392 {}
393 no-op
394 (fn [game tpf]
395 (.rotate cube 0.0 (* 2 tpf) 0.0)))))
396 #+end_src
398 * COMMENT Hello Collision
400 #+name: hello-collision
401 #+begin_src clojure :results silent
402 (ns hello.collision)
403 (use 'cortex.world)
404 (use 'cortex.import)
405 (use 'clojure.contrib.def)
408 (cortex.import/mega-import-jme3)
409 (rlm.rlm-commands/help)
410 (use '[hello [brick-wall :only [fire-cannon-ball brick-wall*]]])
413 (defn environment []
414 (let
415 [scene-model
416 (doto
417 (.loadModel
418 (doto (asset-manager)
419 (.registerLocator
420 "/home/r/cortex/assets/zips/town.zip" ZipLocator))
421 "main.scene")
422 (.setLocalScale (float 2.0)))
423 collision-shape
424 (CollisionShapeFactory/createMeshShape #^Node scene-model)
425 landscape (RigidBodyControl. collision-shape 0)]
426 (.setShadowMode scene-model RenderQueue$ShadowMode/CastAndReceive)
427 (.addControl scene-model landscape)
428 scene-model))
430 (defn player-fn []
431 (doto
432 (CharacterControl.
433 (CapsuleCollisionShape. (float 1.5) (float 6)(float 1))
434 (float 0.05))
435 (.setJumpSpeed 20)
436 (.setFallSpeed 30)
437 (.setGravity 30) ;30
438 (.setPhysicsLocation (Vector3f. 0 10 0))))
440 (defn lights []
441 [(doto (AmbientLight.) (.setColor (.mult (ColorRGBA. 1 1 1 1) (float 1))))
442 (doto (AmbientLight.) (.setColor (.mult (ColorRGBA. 1 0.7 0 1) (float 1))))
443 (doto (DirectionalLight.)
444 (.setColor (.mult ColorRGBA/White (float 0.9) ))
445 (.setDirection (.normalizeLocal (Vector3f. 2.8 -28 2.8))))])
447 (defn night-lights []
448 [(doto (AmbientLight.) (.setColor (.mult (ColorRGBA. 0.275 0.467 0.784 1) (float 0.3))))
449 (doto (DirectionalLight.)
450 (.setColor (.mult ColorRGBA/White (float 0.2) ))
451 (.setDirection (.normalizeLocal (Vector3f. 2.8 -28 2.8))))])
453 (def player (atom (player-fn)))
455 (defn setup-fn [game]
456 (dorun (map #(.addLight (.getRootNode game) %) (lights)))
457 ;; set the color of the sky
458 (.setBackgroundColor (.getViewPort game) (ColorRGBA. 0.3 0.4 0.9 1))
459 ;(.setBackgroundColor (.getViewPort game) (ColorRGBA. 0 0 0 1)
460 (doto (.getFlyByCamera game)
461 (.setMoveSpeed (float 100))
462 (.setRotationSpeed 3))
463 (.add
464 (.getPhysicsSpace
465 (.getState (.getStateManager game) BulletAppState))
466 @player)
468 (doto (Node.) (.attachChild (.getRootNode game))
469 (.attachChild (brick-wall*))
470 )
472 )
475 (def walking-up? (atom false))
476 (def walking-down? (atom false))
477 (def walking-left? (atom false))
478 (def walking-right? (atom false))
480 (defn set-walk [walk-atom game value]
481 ;;(println-repl "setting stuff to " value)
482 (reset! walk-atom value))
484 (defn responses []
485 {"key-w" (partial set-walk walking-up?)
486 "key-d" (partial set-walk walking-right?)
487 "key-s" (partial set-walk walking-down?)
488 "key-a" (partial set-walk walking-left?)
489 "key-return" (fire-cannon-ball)
490 "key-space" (fn [game value] (.jump @player))
491 })
493 (defn update-fn
494 [game tpf]
495 (let [camera (.getCamera game)
496 cam-dir (.multLocal
497 (.clone
498 (.getDirection camera)) (float 0.6))
499 cam-left (.multLocal
500 (.clone
501 (.getLeft camera)) (float 0.4))
502 walk-direction (Vector3f. 0 0 0)]
504 (cond
505 @walking-up? (.addLocal walk-direction cam-dir)
506 @walking-right? (.addLocal walk-direction (.negate cam-left))
507 @walking-down? (.addLocal walk-direction (.negate cam-dir))
508 @walking-left? (.addLocal walk-direction cam-left))
509 (.setWalkDirection @player walk-direction)
510 (.setLocation camera (.getPhysicsLocation @player))))
512 (defn run-game []
513 (.start
514 (world (environment)
515 (responses)
516 setup-fn
517 update-fn)))
518 #+end_src
520 * COMMENT Hello Terrain
521 #+name: hello-terrain
522 #+begin_src clojure :results silent
523 (ns hello.terrain)
524 (use 'cortex.world)
525 (use 'cortex.import)
526 (use 'clojure.contrib.def)
527 (import jme3tools.converters.ImageToAwt)
530 (cortex.import/mega-import-jme3)
531 (rlm.rlm-commands/help)
532 (use '[hello [brick-wall :only [fire-cannon-ball brick-wall*]]])
535 (defn setup-fn [type game]
536 (.setMoveSpeed (.getFlyByCamera game) 50)
537 (.setFrustumFar (.getCamera game) 10000)
538 (let [env (environment type)
539 cameras [(.getCamera game)]
540 control (TerrainLodControl. env cameras)]
541 ;;(.addControl env control)
542 (.attachChild (.getRootNode game) env)))
544 (defn environment [type]
545 (let
546 [mat_terrain
547 (Material. (asset-manager) "Common/MatDefs/Terrain/Terrain.j3md")
548 grass (.loadTexture (asset-manager) "Textures/Terrain/splat/grass.jpg")
549 dirt (.loadTexture (asset-manager) "Textures/Terrain/splat/dirt.jpg")
550 rock (.loadTexture (asset-manager) "Textures/Terrain/splat/road.jpg")
551 heightmap-image (.loadTexture (asset-manager)
552 ({:mountain "Textures/Terrain/splat/mountains512.png"
553 :fortress "Textures/Terrain/splat/fortress512.png"
554 }type))
555 heightmap (ImageBasedHeightMap.
556 (ImageToAwt/convert (.getImage heightmap-image) false true 0))
557 terrain (do (.load heightmap)
558 (TerrainQuad. "my terrain" 65 513 (.getHeightMap heightmap)))
559 ]
561 (dorun (map #(.setWrap % Texture$WrapMode/Repeat)
562 [grass dirt rock]))
564 (doto mat_terrain
565 (.setTexture "Tex1" grass)
566 (.setFloat "Tex1Scale" (float 64))
568 (.setTexture "Tex2" dirt)
569 (.setFloat "Tex2Scale" (float 32))
571 (.setTexture "Tex3" rock)
572 (.setFloat "Tex3Scale" (float 128))
574 (.setTexture "Alpha"
575 (.loadTexture
576 (asset-manager)
577 ({:mountain "Textures/Terrain/splat/alphamap.png"
578 :fortress "Textures/Terrain/splat/alphamap2.png"} type))))
580 (doto terrain
581 (.setMaterial mat_terrain)
582 (.setLocalTranslation 0 -100 0)
583 (.setLocalScale 2 1 2))))
587 (defn run-terrain-game [type]
588 (.start
589 (world
590 (Node.)
591 {}
592 (partial setup-fn type)
593 no-op)))
594 #+end_src
598 #+name: hello-animation
599 #+begin_src clojure :results silent
600 (ns hello.animation)
601 (use 'cortex.world)
602 (use 'cortex.import)
603 (use 'clojure.contrib.def)
604 (cortex.import/mega-import-jme3)
605 (rlm.rlm-commands/help)
606 (use '[hello [collision :only [lights]]])
608 (defn stand
609 [channel]
610 (doto channel
611 (.setAnim "stand" (float 0.5))
612 (.setLoopMode LoopMode/DontLoop)
613 (.setSpeed (float 1))))
615 (defn anim-listener []
616 (proxy [AnimEventListener] []
617 (onAnimChange
618 [control channel animation-name]
619 (println-repl "RLM --- onAnimChange"))
620 (onAnimCycleDone
621 [control channel animation-name]
622 (if (= animation-name "Walk")
623 (stand channel)
624 ))))
626 (defn setup-fn [channel game]
627 (dorun (map #(.addLight (.getRootNode game) %) (lights)))
628 ;; set the color of the sky
629 (.setBackgroundColor (.getViewPort game) (ColorRGBA. 0.3 0.4 0.9 1))
630 ;(.setBackgroundColor (.getViewPort game) (ColorRGBA. 0 0 0 1)
631 (.setAnim channel "stand")
632 (doto (.getFlyByCamera game)
633 (.setMoveSpeed (float 10))
634 (.setRotationSpeed 1)))
636 (defn walk [channel]
637 (println-repl "zzz")
638 (doto channel
639 (.setAnim "Walk" (float 0.5))
640 (.setLoopMode LoopMode/Loop)))
643 (defn key-map [channel]
644 {"key-space" (fn [game value]
645 (if (not value)
646 (walk channel)))})
648 (defn player []
649 (let [model (.loadModel (asset-manager) "Models/Oto/Oto.mesh.xml")
650 control (.getControl model AnimControl)]
651 (.setLocalScale model (float 0.5))
652 (.clearListeners control)
653 (.addListener control (anim-control))
654 model))
658 (defn run-anim-game []
659 (let [ninja (player)
660 control (.getControl ninja AnimControl)
661 channel (.createChannel control)]
662 (.start
663 (world
664 ninja
665 (key-map channel)
666 (partial setup-fn channel)
667 no-op))))
668 #+end_src
670 * COMMENT Hello Materials
671 #+name: material
672 #+begin_src clojure :results silent
673 (ns hello.material)
674 (use 'cortex.world)
675 (use 'cortex.import)
676 (use 'cortex.util)
677 (use 'clojure.contrib.def)
678 (cortex.import/mega-import-jme3)
679 (rlm.rlm-commands/help)
681 (defn simple-cube []
682 (box 1 1 1
683 :position (Vector3f. -3 1.1 0)
684 :material "Common/MatDefs/Misc/Unshaded.j3md"
685 :texture "Interface/Logo/Monkey.jpg"
686 :physical? false))
688 (defn leaky-box []
689 (box 1 1 1
690 :position (Vector3f. 3 -1 0)
691 :material "Common/MatDefs/Misc/ColoredTextured.j3md"
692 :texture "Textures/ColoredTex/Monkey.png"
693 :color (ColorRGBA. 1 0 1 1)
694 :physical? false))
696 (defn transparent-box []
697 (doto
698 (box 1 1 0.1
699 :position Vector3f/ZERO
700 :name "window frame"
701 :material "Common/MatDefs/Misc/Unshaded.j3md"
702 :texture "Textures/ColoredTex/Monkey.png"
703 :physical? false)
704 (-> (.getMaterial)
705 (.getAdditionalRenderState)
706 (.setBlendMode RenderState$BlendMode/Alpha))
707 (.setQueueBucket RenderQueue$Bucket/Transparent)))
709 (defn bumpy-sphere []
710 (doto
711 (sphere 2
712 :position (Vector3f. 0 2 -2)
713 :name "Shiny rock"
714 :material "Common/MatDefs/Light/Lighting.j3md"
715 :texture false
716 :physical? false)
717 (-> (.getMesh)
718 (doto
719 (.setTextureMode Sphere$TextureMode/Projected)
720 (TangentBinormalGenerator/generate)))
721 (-> (.getMaterial)
722 (doto
723 (.setTexture "DiffuseMap"
724 (.loadTexture (asset-manager)
725 "Textures/Terrain/Pond/Pond.jpg"))
726 (.setTexture "NormalMap"
727 (.loadTexture (asset-manager)
728 "Textures/Terrain/Pond/Pond_normal.png"))
729 (.setFloat "Shininess" (float 5))))
730 (.rotate (float 1.6) 0 0)))
733 (defn start-game []
734 (.start
735 (world
736 (let [root (Node.)]
737 (dorun (map #(.attachChild root %)
738 [(simple-cube) (leaky-box) (transparent-box) (bumpy-sphere)]))
739 root)
740 {}
741 (fn [world]
742 (let [sun (doto (DirectionalLight.)
743 (.setDirection (.normalizeLocal (Vector3f. 1 0 -2)))
744 (.setColor ColorRGBA/White))]
745 (.addLight (.getRootNode world) sun)))
746 no-op
747 )))
748 #+end_src
752 * COMMENT code generation
754 #+begin_src clojure :tangle ../src/hello/brick_wall.clj
755 <<brick-wall-header>>
756 <<brick-wall-body>>
757 #+end_src
759 #+begin_src clojure :tangle ../src/hello/hello_simple_app.clj
760 <<hello-simple-app>>
761 #+end_src
763 #+begin_src clojure :tangle ../src/hello/hello_simpler_app.clj
764 <<hello-simpler-app>>
765 #+end_src
768 #+begin_src clojure :tangle ../src/hello/other_games.clj
769 <<other-games>>
770 #+end_src
772 #+begin_src clojure :tangle ../src/hello/loop.clj
773 <<hello-loop>>
774 #+end_src
776 #+begin_src clojure :tangle ../src/hello/collision.clj
777 <<hello-collision>>
778 #+end_src
780 #+begin_src clojure :tangle ../src/hello/terrain.clj
781 <<hello-terrain>>
782 #+end_src
784 #+begin_src clojure :tangle ../src/hello/animation.clj
785 <<hello-animation>>
786 #+end_src
788 #+begin_src clojure :tangle ../src/hello/material.clj
789 <<material>>
790 #+end_src