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