examples/moles: update to inkscape_tools instead of the old bash script
[nit.git] / examples / mnit_moles / src / moles.nit
1 # This file is part of NIT (http://www.nitlanguage.org).
2 #
3 # Copyright 2012-2014 Alexis Laferrière <alexis.laf@xymus.net>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Classic moles game
18 #
19 # This is a minimal practical example of the mnit framework.
20 module moles is
21 app_version(1, 0, git_revision)
22 app_name("Crazy Groundhogs")
23 end
24
25 import mnit
26
27 import drawing
28
29 class Hole
30 var game: Game
31
32 # Center of the hole
33 var x: Int
34 var y: Int
35
36 # Half width of the hit box
37 var dx = 200.0
38 # Heigth of the hit box
39 var dy = 800.0
40
41 # state
42 var up = false
43 var hitted = false
44 var trap = false
45
46 init (g: Game, x, y: Int)
47 do
48 game = g
49 self.x = x
50 self.y = y
51 end
52
53 fun do_turn
54 do
55 if up then
56 if hitted then
57 if (20.0*game.speed_modifier).to_i.rand == 0 then
58 # dead / hide
59 hitted = false
60 up = false
61 end
62 else if (80.0*game.speed_modifier).to_i.rand == 0 then
63 # hide
64 up = false
65 end
66 else if (100.0*game.speed_modifier).to_i.rand == 0 then
67 # show up
68 up = true
69
70 # shot traps only at 50 points and up
71 trap = false
72 if game.points > 50 then
73
74 # After 50 points we have more and more traps until point 1000
75 var d = 1250-(game.points - 50)
76 if d < 200 then d = 200
77
78 if d.rand < 100 then trap = true
79 end
80 end
81 end
82
83 fun intercepts(event: PointerEvent): Bool
84 do
85 if not up or hitted then return false
86
87 var dx = (dx*display_scale).to_i
88 var dy = (dy*display_scale).to_i
89 var ex = event.x.to_i - display_offset_x
90 var ey = event.y.to_i - display_offset_y
91 return ex > x - dx and ex < x + dx and
92 ey > y - dy and ey < y
93 end
94
95 fun hit
96 do
97 if hitted then return
98
99 if trap then
100 up = false
101 game.points -= 5
102 if game.points < 0 then game.points = 0
103 else
104 hitted = true
105 game.points += 1
106 end
107 end
108 end
109
110 class Game
111 var holes = new Array[Hole].with_capacity(4)
112
113 # rule / const
114 var modifier_half_life = 1000.0
115 fun rows: Int do return 4
116 fun columns: Int do return 5
117
118 # state
119 var points = 0
120 var speed_modifier = 1.0
121
122 # configs
123 var dist_between_rows = 512
124 var dist_between_columns = 600
125 fun global_speed_modifier: Float do return 2.0
126
127 init
128 do
129 var dx = (dist_between_columns.to_f*display_scale).to_i
130 var dy = (dist_between_rows.to_f*display_scale).to_i
131 for x in [0 .. columns[ do
132 for y in [0 .. rows[ do
133 holes.add(new Hole(self, x*dx, y*dy))
134 end
135 end
136 end
137
138 fun do_turn do
139 for hole in holes do hole.do_turn
140
141 speed_modifier = modifier_half_life / (modifier_half_life+points.to_f) * global_speed_modifier
142 end
143 end
144
145 # Where all the UI stuff is done
146 class Screen
147 var game = new Game
148
149 fun do_frame(display: Display)
150 do
151 display.clear(0.1, 0.65, 0.2)
152
153 app.assets.sign_warning.scale = display_scale
154 app.assets.sign_cute.scale = display_scale
155 app.assets.sign_hits.scale = display_scale
156 for img in app.numbers.imgs do img.scale = display_scale
157
158 display.blit(app.assets.sign_warning, (0.0*display_scale).to_i, (0.0*display_scale).to_i)
159 display.blit(app.assets.sign_cute, (740.0*display_scale).to_i, (0.0*display_scale).to_i)
160 display.blit(app.assets.sign_hits, (1640.0*display_scale).to_i, (55.0*display_scale).to_i)
161 display.blit_number(app.numbers, game.points, (1720.0*display_scale).to_i, (170.0*display_scale).to_i)
162
163 for hole in game.holes do
164 # Hole
165 var img = app.assets.empty
166 var dx = 300.0*display_scale
167 var dy = 256.0*display_scale
168 img.scale = display_scale
169 display.blit(img, hole.x-dx.to_i+display_offset_x, hole.y-dy.to_i+display_offset_y)
170
171 # Mole
172 var empty = false
173 if hole.hitted then
174 img = app.assets.hit
175 dx = 250.0*display_scale
176 dy = 512.0*display_scale
177 else if hole.up then
178 if hole.trap then
179 img = app.assets.trap
180 dx = 212.0*display_scale
181 dy = 830.0*display_scale
182 else
183 img = app.assets.up
184 dx = 212.0*display_scale
185 dy = 820.0*display_scale
186 end
187 else empty = true
188
189 if not empty then
190 img.scale = display_scale
191 display.blit(img, hole.x-dx.to_i+display_offset_x, hole.y-dy.to_i+display_offset_y)
192 end
193 end
194 end
195
196 fun input(event: InputEvent): Bool
197 do
198 if event isa PointerEvent then
199 for hole in game.holes do
200 if hole.intercepts(event) then
201 if hole.up then hole.hit
202 return true
203 end
204 end
205 end
206
207 return false
208 end
209 end
210
211 redef class App
212
213 var screen: nullable Screen = null
214
215 # Image set generate by inkscape_tools
216 var assets = new DrawingImages
217
218 # Numbers to display the score
219 var numbers = new NumberImages(assets.n)
220
221 redef fun on_start
222 do
223 super
224 assets.load_all self
225 end
226
227 redef fun on_create
228 do
229 super
230
231 maximum_fps = 50
232 init_screen_and_game
233 end
234
235 fun init_screen_and_game do screen = new Screen
236
237 redef fun frame_core(display)
238 do
239 var screen = self.screen
240 if screen != null then
241 screen.game.do_turn
242 screen.do_frame(display)
243 end
244 end
245
246 redef fun input(ie)
247 do
248 var screen = screen
249 if ie isa QuitEvent or
250 (ie isa KeyEvent and ie.to_c == 'q') then
251 quit = true
252 return true
253 else if screen != null then
254 return screen.input(ie)
255 else
256 print "unknown input: {ie}"
257 return false
258 end
259 end
260 end
261
262 fun display_scale: Float do return 1.0
263
264 # Depends on the hole center in the uo image
265 fun display_offset_x: Int do return (512.0*display_scale).to_i
266
267 # Depends on the width of the holes
268 fun display_offset_y: Int do return (800.0*display_scale).to_i