examples: update all users of mnit to the new life-cycle
[nit.git] / examples / mnit_moles / src / moles.nit
index 58ca933..c3824a4 100644 (file)
 # Classic moles game
 #
 # This is a minimal practical example of the mnit framework.
-module moles
+module moles is
+       app_version(1, 0, git_revision)
+       app_name("Crazy Groundhogs")
+end
 
 import mnit
-import realtime
 
 class Hole
        var game: Game
@@ -30,21 +32,20 @@ class Hole
        var y: Int
 
        # Half width of the hit box
-       var dx: Int
+       var dx = 200.0
        # Heigth of the hit box
-       var dy: Int
+       var dy = 800.0
 
        # state
        var up = false
        var hitted = false
+       var trap = false
 
        init (g: Game, x, y: Int)
        do
                game = g
                self.x = x
                self.y = y
-               self.dx = (200.0*display_scale).to_i
-               self.dy = (800.0*display_scale).to_i
        end
 
        fun do_turn
@@ -63,6 +64,17 @@ class Hole
                else if (100.0*game.speed_modifier).to_i.rand == 0 then
                        # show up
                        up = true
+
+                       # shot traps only at 50 points and up
+                       trap = false
+                       if game.points > 50 then
+
+                               # After 50 points we have more and more traps until point 1000
+                               var d = 1250-(game.points - 50)
+                               if d < 200 then d = 200
+
+                               if d.rand < 100 then trap = true
+                       end
                end
        end
 
@@ -70,6 +82,8 @@ class Hole
        do
                if not up or hitted then return false
 
+               var dx = (dx*display_scale).to_i
+               var dy = (dy*display_scale).to_i
                var ex = event.x.to_i - display_offset_x
                var ey = event.y.to_i - display_offset_y
                return ex > x - dx and ex < x + dx and
@@ -80,10 +94,14 @@ class Hole
        do
                if hitted then return
 
-               if up then
+               if trap then
+                       up = false
+                       game.points -= 5
+                       if game.points < 0 then game.points = 0
+               else
                        hitted = true
                        game.points += 1
-               else abort # should not happen
+               end
        end
 end
 
@@ -91,24 +109,26 @@ class Game
        var holes = new Array[Hole].with_capacity(4)
 
        # rule / const
-       var modifier_half_life = 40.0
-       var rows = 5
-       var columns = 3
+       var modifier_half_life = 1000.0
+       fun rows: Int do return 4
+       fun columns: Int do return 5
 
        # state
        var points = 0
        var speed_modifier = 1.0
 
        # configs
-       var dist_between_holes = 512
+       var dist_between_rows = 512
+       var dist_between_columns = 600
        fun global_speed_modifier: Float do return 2.0
 
        init
        do
-               var d = (dist_between_holes.to_f*display_scale).to_i
-               for x in [0 .. rows[ do
-                       for y in [0 .. columns[ do
-                               holes.add(new Hole(self, x*d, y*d))
+               var dx = (dist_between_columns.to_f*display_scale).to_i
+               var dy = (dist_between_rows.to_f*display_scale).to_i
+               for x in [0 .. columns[ do
+                       for y in [0 .. rows[ do
+                               holes.add(new Hole(self, x*dx, y*dy))
                        end
                end
        end
@@ -125,8 +145,13 @@ class Screen
        var empty_img: Image
        var up_img: Image
        var hit_img: Image
+       var trap_img: Image
        var numbers: NumberImages
 
+       var sign_warning: Image
+       var sign_cute: Image
+       var sign_hits: Image
+
        var game = new Game
 
        init (app: App)
@@ -134,40 +159,59 @@ class Screen
                empty_img = app.load_image("images/empty.png")
                up_img = app.load_image("images/up.png")
                hit_img = app.load_image("images/hit.png")
+               trap_img = app.load_image("images/trap.png")
                numbers = app.load_numbers("images/#.png")
 
-               empty_img.scale = display_scale
-               up_img.scale = display_scale
-               hit_img.scale = display_scale
+               sign_warning = app.load_image("images/sign-warning.png")
+               sign_cute = app.load_image("images/sign-cute.png")
+               sign_hits = app.load_image("images/sign-hits.png")
        end
 
        fun do_frame(display: Display)
        do
-               display.clear(0.0, 0.7, 0.0)
+               display.clear(0.1, 0.65, 0.2)
+
+               sign_warning.scale = display_scale
+               sign_cute.scale = display_scale
+               sign_hits.scale = display_scale
+               for img in numbers.imgs do img.scale = display_scale
+
+               display.blit(sign_warning, (-120.0*display_scale).to_i, (-235.0*display_scale).to_i)
+               display.blit(sign_cute, (540.0*display_scale).to_i, (-180.0*display_scale).to_i)
+               display.blit(sign_hits, (1340.0*display_scale).to_i, (55.0*display_scale).to_i)
+               display.blit_number(numbers, game.points, (1460.0*display_scale).to_i, (270.0*display_scale).to_i)
 
                for hole in game.holes do
-                       var img
-                       var dx
-                       var dy
+                       # Hole
+                       var img = empty_img
+                       var dx = 512.0*display_scale
+                       var dy = 512.0*display_scale
+                       img.scale = display_scale
+                       display.blit(img, hole.x-dx.to_i+display_offset_x, hole.y-dy.to_i+display_offset_y)
 
+                       # Mole
+                       var empty = false
                        if hole.hitted then
                                img = hit_img
                                dx = 256.0*display_scale
                                dy = 417.0*display_scale
                        else if hole.up then
-                               img = up_img
-                               dx = 512.0*display_scale
-                               dy = 830.0*display_scale
-                       else
-                               img = empty_img
-                               dx = 256.0*display_scale
-                               dy = 244.0*display_scale
-                       end
+                               if hole.trap then
+                                       img = trap_img
+                                       dx = 512.0*display_scale
+                                       dy = 830.0*display_scale
+                               else
+                                       img = up_img
+                                       dx = 512.0*display_scale
+                                       dy = 830.0*display_scale
+                               end
+                       else empty = true
 
-                       display.blit(img, hole.x-dx.to_i+display_offset_x, hole.y-dy.to_i+display_offset_y)
+                       if not empty then
+                               img.scale = display_scale
+                               display.blit(img, hole.x-dx.to_i+display_offset_x, hole.y-dy.to_i+display_offset_y)
+                       end
                end
-
-               display.blit_number(numbers, game.points, 20, 20)
        end
 
        fun input(event: InputEvent): Bool
@@ -185,36 +229,26 @@ class Screen
        end
 end
 
-class MyApp
-       super App
+redef class App
 
        var screen: nullable Screen = null
 
-       var target_dt = 20000000
-
-       init do super
-
-       redef fun init_window
+       redef fun on_create
        do
                super
 
-               screen = new Screen(self)
+               maximum_fps = 50
+               init_screen_and_game
        end
 
+       fun init_screen_and_game do screen = new Screen(self)
+
        redef fun frame_core(display)
        do
                var screen = self.screen
                if screen != null then
-                       var clock = new Clock
-
                        screen.game.do_turn
                        screen.do_frame(display)
-
-                       var dt = clock.lapse
-                       if dt.sec == 0 and dt.nanosec < target_dt then
-                               var sleep_t = target_dt - dt.nanosec
-                               sys.nanosleep(0, sleep_t)
-                       end
                end
        end
 
@@ -241,6 +275,3 @@ fun display_offset_x: Int do return (512.0*display_scale).to_i
 
 # Depends on the width of the holes
 fun display_offset_y: Int do return (800.0*display_scale).to_i
-
-var app = new MyApp
-app.main_loop