Merge: Nitunit: mass compile non-simple docunits
[nit.git] / lib / gamnit / examples / template / src / template.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the Do What The Fuck You Want To
5 # Public License, Version 2, as published by Sam Hocevar. See
6 # http://sam.zoy.org/projects/COPYING.WTFPL for more details.
7
8 # Template for a 2D gamnit game
9 module template is
10 example
11 app_name "gamnit template"
12 app_namespace "org.gamnit.template"
13 app_version(0, 1, git_revision)
14 android_api_target 10
15 end
16
17 import gamnit::flat # The 2D API, use `gamnit::depth` for 3D
18
19 redef class App
20
21 # Texture, loaded in `create_scene`
22 var texture = new Texture("fighter.png")
23
24 # Sound effect, lazy loaded at first use
25 var sound = new Sound("laser.mp3")
26
27 # Sprite, must be loaded in or after `on_create`
28 var sprite = new Sprite(texture, new Point3d[Float](0.0, 0.0, 0.0)) is lazy
29
30 redef fun create_scene
31 do
32 super
33
34 # Report errors on all loaded textures.
35 # Root textures are associated to pixel data,
36 # whereas other texture may be subtextures of root textures.
37 for tex in all_root_textures do
38 var error = tex.error
39 if error != null then print_error "Texture '{tex}' failed to load: {error}"
40 end
41
42 # Draw the texture as pixelated, it looks better for such
43 # a small texture.
44 texture.as(TextureAsset).pixelated = true
45
46 # Create the sprite and make it visible.
47 sprites.add sprite
48
49 # Make the sprite smaller, by default each pixel corresponds to 1 world unit.
50 # However, it is often preferable to make 1 world unit correspond to
51 # something meaningful in the game world, such as 1 meter.
52 #
53 # Scale the ship so it is approximately 5 world units wide.
54 sprite.scale = 5.0 / texture.width
55
56 # Move the camera to show 20 world units on the Y axis at Z = 0.
57 # The `sprite` should take approximately 1/4 of the height of the screen.
58 world_camera.reset_height 20.0
59
60 # Move the near clip wall closer to the camera because our world unit
61 # range is small. Moving the clip wall too close to the camera can
62 # cause glitches on mobiles devices with small depth buffer.
63 world_camera.near = 1.0
64
65 # Make the background sky blue and opaque.
66 glClearColor(0.5, 0.8, 1.0, 1.0)
67
68 # If the first command line argument is an integer, add extra sprites.
69 if args.not_empty and args.first.is_int then
70 # It's a performance test, unlock the framerate.
71 maximum_fps = -1.0
72
73 # Add `args.first` sprites.
74 for i in args.first.to_i.times do
75 var s = new Sprite(texture, new Point3d[Float](30.0.rand - 15.0, 20.0.rand - 10.0, 0.0 - 30.0.rand))
76 s.scale = 0.1
77 sprites.add s
78 end
79 end
80 end
81
82 redef fun update(dt)
83 do
84 # Update game logic here.
85 sprite.rotation += 0.1*pi*dt
86
87 # Move `sprite` with the keyboard arrows.
88 # Set the speed according to the elapsed time since the last frame `dt`
89 # for a smooth animation.
90 var unit_per_second = 2.0
91 for key in pressed_keys do
92 if key == "left" then
93 sprite.center.x -= unit_per_second*dt
94 else if key == "right" then
95 sprite.center.x += unit_per_second*dt
96 else if key == "up" then
97 sprite.center.y += unit_per_second*dt
98 else if key == "down" then
99 sprite.center.y -= unit_per_second*dt
100 end
101 end
102 end
103
104 redef fun accept_event(event)
105 do
106 if super then return true
107
108 if event isa QuitEvent or
109 (event isa KeyEvent and event.name == "escape" and event.is_up) then
110 # When window close button, escape or back key is pressed
111 print "Ran at {current_fps} FPS in the last few seconds"
112
113 print "Performance statistics to detect bottlenecks:"
114 print sys.perfs
115
116 # Quit abruptly
117 exit 0
118 else if event isa KeyEvent and event.is_down then
119 if event.name == "space" then
120 # Play a sound when space bar is pressed.
121 sound.play
122 return true
123 else if event.name == "s" then
124 # Remove a random sprite.
125 if sprites.not_empty then sprites.remove sprites.rand
126 else if event.name == "w" then
127 # Add a random sprite.
128 var s = new Sprite(texture, new Point3d[Float](30.0.rand - 15.0, 20.0.rand - 10.0, 0.0 - 30.0.rand))
129 s.scale = 0.1
130 s.tint[1] = 0.0
131 s.tint[2] = 0.0
132 sprites.add s
133 end
134 end
135
136 return false
137 end
138 end