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