metrics: refactor RTA metrics
[nit.git] / examples / mnit_moles / src / moles.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2012-2013 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 module moles
19
20 import mnit
21 import realtime
22
23 class Hole
24 var game : Game
25 var x : Int
26 var y : Int
27 var dim : Int # Should it be removed?
28
29 # state
30 var up : Bool = false
31 var hitted : Bool = false
32
33 init ( g : Game, x, y : Int )
34 do
35 game = g
36 self.x = x
37 self.y = y
38 dim = game.img_dim
39 end
40
41 fun do_turn
42 do
43 if up then
44 if hitted then
45 if (20.0*game.speed_modifier).to_i.rand == 0 then
46 # dead / hide
47 hitted = false
48 up = false
49 end
50 else if (80.0*game.speed_modifier).to_i.rand == 0 then
51 # hide
52 up = false
53 end
54 else if (100.0*game.speed_modifier).to_i.rand == 0 then
55 # show up
56 up = true
57 end
58 end
59
60 fun intercepts( event : PointerEvent ) : Bool
61 do
62 var ex = event.x.to_i
63 var ey = event.y.to_i
64 return ex > x and ex < x + dim and
65 ey > y and ey < y + dim
66 end
67
68 fun hit
69 do
70 if hitted then return
71
72 if up then
73 hitted = true
74 game.points += 1
75 else
76 abort # should not happen
77 end
78 end
79 end
80
81 class Game
82 var holes : Sequence[Hole] = new Array[Hole].with_capacity(4)
83
84 # rule / const
85 var modifier_half_life : Float = 40.0
86 var rows : Int = 5
87 var columns : Int = 3
88
89 # state
90 var points : Int = 0
91 var speed_modifier : Float = 1.0
92
93 # configs
94 var img_ori_dim : Int = 256
95 fun img_dim : Int do return 210
96 fun global_speed_modifier : Float do return 2.0
97
98 init
99 do
100 var d = img_dim
101 for x in [ 0 .. rows [ do
102 for y in [ 0 .. columns [ do
103 holes.add( new Hole( self, x*d, y*d ) )
104 end
105 end
106 end
107
108 fun do_turn do
109 for hole in holes do hole.do_turn
110
111 speed_modifier = modifier_half_life / (modifier_half_life+points.to_f) * global_speed_modifier
112
113 print "p: {points} sm: {speed_modifier}"
114 end
115 end
116
117 # Where all the UI stuff is done
118 class Screen
119 var empty_img : Image
120 var up_img : Image
121 var hit_img : Image
122 var numbers: NumberImages
123
124 var game : Game = new Game
125
126 init ( app : App )
127 do
128 empty_img = app.load_asset( "images/empty.png" ).as(Image)
129 up_img = app.load_asset( "images/up.png" ).as(Image)
130 hit_img = app.load_asset( "images/hit.png" ).as(Image)
131 numbers = app.load_numbers("images/#.png")
132
133 var scale = game.img_dim.to_f / game.img_ori_dim.to_f
134 empty_img.scale = scale
135 up_img.scale = scale
136 hit_img.scale = scale
137 end
138
139 fun do_frame( display : Display )
140 do
141 display.clear( 0.0, 0.7, 0.0 )
142
143 for hole in game.holes do
144 var img
145
146 if hole.hitted then
147 img = hit_img
148 else if hole.up then
149 img = up_img
150 else
151 img = empty_img
152 end
153
154 display.blit( img, hole.x, hole.y-64 )
155 end
156
157 display.blit_number(numbers, game.points, 20, 20)
158 end
159
160 fun input( event : InputEvent ) : Bool
161 do
162 if event isa PointerEvent then
163 for hole in game.holes do
164 if hole.intercepts( event ) then
165 if hole.up then
166 hole.hit
167 end
168 return true
169 end
170 end
171 end
172
173 return false
174 end
175 end
176
177 class MyApp
178 super App
179
180 var screen : nullable Screen = null
181
182 var target_dt = 20000000
183
184 init do super
185
186 redef fun init_window
187 do
188 super
189
190 screen = new Screen( self )
191 end
192
193 redef fun frame_core( display )
194 do
195 var screen = self.screen
196 if screen != null then
197 var clock = new Clock
198
199 screen.game.do_turn
200 screen.do_frame( display )
201
202 var dt = clock.lapse
203 if dt.sec == 0 and dt.nanosec < target_dt then
204 var sleep_t = target_dt - dt.nanosec
205 sys.nanosleep(0, sleep_t)
206 end
207 end
208 end
209
210 redef fun input( ie )
211 do
212 var screen = screen
213 if ie isa QuitEvent or
214 ( ie isa KeyEvent and ie.to_c == 'q' ) then
215 quit = true
216 return true
217 else if screen != null then
218 return screen.input( ie )
219 else
220 print "unknown input: {ie}"
221 return false
222 end
223 end
224 end
225
226 var app = new MyApp
227 app.main_loop
228