1 # This file is part of NIT ( http://www.nitlanguage.org ).
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
16 # This program is a fun game but also a good example of the scene2d module
23 # mnit specific method to draw a sprite
24 # app is used to optain the assets and the display
25 # Each sprite should implements this method
26 fun draw_on_display
(app
: ShootApp) do end
28 # Helper function to draw an image centered on the current sprite position
29 fun draw_image
(app
: ShootApp, img
: Image)
31 app
.display
.blit_centered
(img
, self.x
/100, self.y
/100)
34 # Helper function to draw an image translated and rotated on the current sprite position
35 fun draw_rotated_image
(app
: ShootApp, img
: Image, dx
, dy
: Int, angle
: Float)
37 app
.display
.blit_rotated
(img
, self.x
.to_f
/100.0, self.y
.to_f
/100.0, angle
)
42 redef fun draw_on_display
(app
)
44 if protected_ttl
> 30 and protected_ttl
%10 > 5 then return # blink on protected
45 draw_image
(app
, app
.img_player
)
50 redef fun draw_on_display
(app
)
52 var img
= if enemy
then app
.img_enemy_shoot
else app
.img_player_shoot
58 redef fun draw_on_display
(app
)
60 var angle
= velocity_angle
61 var img
= if enemy
then app
.img_enemy_missile
else app
.img_player_missile
62 draw_rotated_image
(app
, img
, 0, 0, angle
)
67 redef fun draw_on_display
(app
)
69 draw_image
(app
, app
.img_enemy0
)
74 redef fun draw_on_display
(app
)
76 draw_image
(app
, app
.img_enemy1
)
81 redef fun draw_on_display
(app
)
83 draw_image
(app
, app
.img_enemy2
)
88 redef fun draw_on_display
(app
)
90 draw_image
(app
, app
.img_enemy3
)
95 redef fun draw_on_display
(app
)
97 draw_image
(app
, app
.img_enemy4
)
98 draw_rotated_image
(app
, app
.img_enemy4_turret
, 0, 0, self.angle
)
102 redef class EnemyKamikaze
103 redef fun draw_on_display
(app
)
105 var angle
= self.velocity_angle
106 draw_rotated_image
(app
, app
.img_enemy_kamikaze
, 0, 0, angle
)
111 redef fun draw_on_display
(app
)
113 if flick_ttl
> 0 then return
114 draw_image
(app
, app
.img_boss
)
119 redef fun draw_on_display
(app
)
121 if flick_ttl
> 0 then return
123 self.boss
.draw_image
(app
, app
.img_boss_right
)
125 self.boss
.draw_image
(app
, app
.img_boss_left
)
131 redef fun draw_on_display
(app
)
133 draw_image
(app
, app
.img_money
)
137 redef class UpMissile
138 redef fun draw_on_display
(app
)
140 draw_image
(app
, app
.img_upmissile
)
144 redef class Explosion
145 redef fun draw_on_display
(app
)
147 draw_image
(app
, app
.img_explosion
)
152 redef fun draw_on_display
(app
)
155 # More a star is fast, more it requires a bright image
159 else if self.vy
< 40 then
169 fun draw_on_display
(app
: ShootApp) do end
170 fun input
(input_event
: InputEvent): Bool do return false
173 redef class PlayScene
174 redef fun draw_on_display
(app
)
176 app
.display
.clear
( 0.0, 0.0, 0.0 )
177 self.sprites
.draw
(app
)
178 for i
in [0..player
.money
[
180 app
.display
.blit
(app
.img_money
, 10, 590-i
)
182 for i
in [1..player
.nbshoots
]
184 app
.display
.blit
(app
.img_player_shoot
, 30, 590 - i
*10)
186 for i
in [1..player
.nbmissiles
]
188 app
.display
.blit
(app
.img_player_missile
, 40, 590 - i
*20)
192 redef fun input
( input_event
)
195 if input_event
isa KeyEvent then
196 if input_event
.is_arrow_down
then
197 if input_event
.is_down
then
202 else if input_event
.is_arrow_up
then
203 if input_event
.is_down
then
208 else if input_event
.is_arrow_left
then
209 if input_event
.is_down
then
214 else if input_event
.is_arrow_right
then
215 if input_event
.is_down
then
222 return false # unknown event, can be handled by something else
228 redef class MenuScene
229 redef fun draw_on_display
(app
)
231 app
.display
.blit
(app
.img_splash
, 0, 0)
233 if not play
or ttl
%10 > 5 then
234 app
.display
.blit
(app
.img_splash_play
, 0, 0)
238 redef fun input
(input_event
)
240 if input_event
isa KeyEvent then
254 var debug
: Bool = false
256 redef fun draw_sprite
(s
: Sprite)
258 s
.draw_on_display
(self)
259 if debug
and s
.width
!= 0 and s
.height
!= 0 then
260 var left
= s
.left
.to_f
/100.0
261 var right
= s
.right
.to_f
/100.0
262 var top
= s
.top
.to_f
/100.0
263 var bot
= s
.bottom
.to_f
/100.0
264 display
.blit_stretched
(img_hitbox
, right
, top
, right
, bot
, left
, bot
, left
, top
)
272 var img_hitbox
: Image
274 var img_splash
: Image
275 var img_splash_play
: Image
277 var img_player
: Image
278 var img_player_shoot
: Image
279 var img_player_missile
: Image
280 var img_enemy0
: Image
281 var img_enemy1
: Image
282 var img_enemy2
: Image
283 var img_enemy3
: Image
284 var img_enemy4
: Image
285 var img_enemy4_turret
: Image
286 var img_enemy_kamikaze
: Image
287 var img_enemy_shoot
: Image
288 var img_enemy_missile
: Image
290 var img_upmissile
: Image
291 var img_explosion
: Image
297 var img_boss_left
: Image
298 var img_boss_right
: Image
300 redef fun init_window
304 # TODO load assets here
305 # ex: img = load_image( "img.png" )
306 # to get file located at assets/img.png before deployement
307 self.img_hitbox
= load_image
("hitbox.png")
309 self.img_splash
= load_image
("splash.png")
310 self.img_splash_play
= load_image
("splash_play.png")
312 self.img_player
= load_image
("player.png")
313 self.img_player_shoot
= load_image
("player_shoot.png")
314 self.img_player_missile
= load_image
("player_missile.png")
315 self.img_enemy0
= load_image
("enemy0.png")
316 self.img_enemy1
= load_image
("enemy1.png")
317 self.img_enemy2
= load_image
("enemy2.png")
318 self.img_enemy3
= load_image
("enemy3.png")
319 self.img_enemy4
= load_image
("enemy4.png")
320 self.img_enemy4_turret
= load_image
("enemy4_turret.png")
321 self.img_enemy_kamikaze
= load_image
("enemy_kamikaze.png")
322 self.img_enemy_shoot
= load_image
("enemy_shoot.png")
323 self.img_enemy_missile
= load_image
("enemy_missile.png")
324 self.img_money
= load_image
("money.png")
325 self.img_upmissile
= load_image
("up_missile.png")
326 self.img_explosion
= load_image
("explosion.png")
327 self.img_star0
= load_image
("star0.png")
328 self.img_star1
= load_image
("star1.png")
329 self.img_star2
= load_image
("star2.png")
330 self.img_boss
= load_image
("boss.png")
331 self.img_boss_left
= load_image
("boss_left.png")
332 self.img_boss_right
= load_image
("boss_right.png")
334 self.scene
= new MenuScene
337 redef fun frame_core
( display
)
338 # the arg display is not null but otherwise the same than self.display
342 var next
= self.scene
.next_scene
346 if not self.scene
.exists
then quit
= true
348 self.scene
.draw_on_display
(self)
350 # Wait the next frame
351 sys
.nanosleep
(0, 16000000)
354 var paused
: Bool = false
356 redef fun input
( input_event
)
358 if input_event
isa QuitEvent then # close window button
359 quit
= true # orders system to quit
360 return true # this event has been handled
361 else if input_event
isa KeyEvent then
362 if input_event
.to_c
== 'p' then
363 paused
= input_event
.is_down
364 return true # this event has been handled
365 else if input_event
.to_c
== 'q' then
366 quit
= true # orders system to quit
367 return true # this event has been handled
371 # Maybe the event is specific to the scene
372 return self.scene
.input
(input_event
)
376 if args
.length
> 0 and args
.first
== "--headless" then
381 var app
= new ShootApp
382 app
.debug
= args
.length
> 0 and args
.first
== "--debug"