lib/gamnit: tweak the world_camera to support devices with small depth buffer
[nit.git] / lib / gamnit / examples / asteronits / src / asteronits.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Portable game to destroy asteroids
16 module asteronits is
17 app_name "Asteronits"
18 app_namespace "org.nitlanguage.asteronits"
19 app_version(1, 0, git_revision)
20
21 android_manifest_activity """android:screenOrientation="sensorLandscape""""
22 android_api_target 15
23 end
24
25 import gamnit::simple_2d
26
27 import game_logic
28 import spritesheet
29
30 redef class Spritesheet
31 # Largest meteors, organized by color
32 var meteors_big: Array[Array[Texture]] = [
33 [meteor_brown_big1, meteor_brown_big2, meteor_brown_big3, meteor_brown_big4],
34 [meteor_grey_big1, meteor_grey_big2, meteor_grey_big3, meteor_grey_big4]]
35
36 # Medium size meteors, organized by color
37 var meteors_med: Array[Array[Texture]] = [
38 [meteor_brown_med1, meteor_brown_med3],
39 [meteor_grey_med1, meteor_grey_med2]]
40
41 # Small meteors, organized by color
42 var meteors_small: Array[Array[Texture]] = [
43 [meteor_brown_small1, meteor_brown_small2],
44 [meteor_grey_small1, meteor_grey_small2]]
45
46 # Tiny meteors, organized by color
47 #
48 # TODO use these in particles
49 var meteors_tiny: Array[Array[Texture]] = [
50 [meteor_brown_tiny1, meteor_brown_tiny2],
51 [meteor_grey_tiny1, meteor_grey_tiny2]]
52
53 # Available ships
54 var ships: Array[Texture] = [enemy_green1]
55 end
56
57 redef class App
58
59 # Current world in play
60 var world = new World(12, 2, display.aspect_ratio) is lazy
61
62 redef fun on_create
63 do
64 super
65
66 # Move the camera to show all the world world in the screen range
67 world_camera.reset_height(world.half_height * 2.0)
68 end
69
70 # Main spritesheet with ships, asteroids and beams
71 var spritesheet = new Spritesheet
72
73 redef fun update(dt)
74 do
75 # Update game logic
76 world.do_turn dt
77
78 # Setup new world if all asteroids are destroyed
79 if world.asteroids.is_empty then
80 sprites.clear
81 world = new World(world.n_asteroids*2, world.n_asteroid_parts+1, display.aspect_ratio)
82 end
83 end
84
85 redef fun accept_event(event)
86 do
87 if event isa QuitEvent then
88 exit 0
89 else if event isa KeyEvent then
90 var thrust = event.thrust
91 if thrust != 0.0 then
92 app.world.ship.applied_thrust = if event.is_down then thrust else 0.0
93 return true
94 end
95
96 var rot = event.rotation
97 if rot != 0.0 then
98 app.world.ship.applied_rotation = if event.is_down then rot else 0.0
99 return true
100 end
101
102 if event.name == "space" and event.is_down then
103 app.world.ship.fire
104 return true
105 else if event.name == "escape" then
106 exit 0
107 end
108 end
109
110 return false
111 end
112 end
113
114 redef class SpacialObject
115 # Main `Sprite` to draw for this object
116 var sprite: Sprite is noinit
117
118 # All `Sprites` composing this object
119 var sprites: Collection[Sprite] = new Ref[Sprite](sprite) is lazy
120
121 init do app.sprites.add_all sprites
122
123 redef fun do_turn(dt)
124 do
125 super
126 sprite.rotation = rotation + pi/2.0
127 end
128
129 redef fun destroy
130 do
131 super
132 for s in sprites do app.sprites.remove s
133 end
134 end
135
136 redef class Asteroid
137
138 init
139 do
140 # Select texture from `size` and `color`
141 var tex = if size == 3 then
142 app.spritesheet.meteors_big[color].rand
143 else if size == 2 then
144 app.spritesheet.meteors_med[color].rand
145 else app.spritesheet.meteors_small[color].rand
146
147 sprite = new Sprite(tex, center)
148 super
149 end
150 end
151
152 redef class Bullet
153 init
154 do
155 sprite = new Sprite(app.spritesheet.laser_blue01, center)
156 super
157 end
158 end
159
160 redef class Ship
161 init
162 do
163 sprite = new Sprite(app.spritesheet.ships.rand, center)
164 sprites = [sprite, thrust_sprite]
165
166 super
167 end
168
169 private var thrust_sprite = new Sprite(app.spritesheet.fire09, new Point3d[Float](0.0, 0.0, 0.0))
170
171 private var sprites_with_fire: Array[Sprite] = [thrust_sprite, sprite] is lazy
172
173 redef fun do_turn(dt)
174 do
175 super
176
177 # Update position of the thrust sprite
178 var dist_to_engine = 45.0
179 thrust_sprite.center.x = center.x - dist_to_engine*rotation.cos
180 thrust_sprite.center.y = center.y - dist_to_engine*rotation.sin
181 thrust_sprite.center.z = center.z
182 thrust_sprite.rotation = rotation + pi/2.0
183
184 # Show or hide the thrust sprite
185 if applied_thrust > 0.0 then
186 thrust_sprite.alpha = 1.0
187 else if thrust_sprite.alpha > 0.0 then
188 thrust_sprite.alpha -= dt*4.0
189 if thrust_sprite.alpha < 0.0 then thrust_sprite.alpha = 0.0
190 end
191
192 # HACK, the "enemy" ship used for the player points downwards
193 sprite.rotation += pi
194 end
195 end
196
197 redef class KeyEvent
198
199 # How does this event affect the ship thrust?
200 fun thrust: Float
201 do
202 if is_arrow_up or name == "w" then return 1.0
203 return 0.0
204 end
205
206 # How does this event affect the ship thrust?
207 fun rotation: Float
208 do
209 if is_arrow_right or name == "d" then return 1.0
210 if is_arrow_left or name == "a" then return -1.0
211 return 0.0
212 end
213 end