examples: delete the `shoot` game
[nit.git] / examples / shoot / src / shoot_logic.nit
diff --git a/examples/shoot/src/shoot_logic.nit b/examples/shoot/src/shoot_logic.nit
deleted file mode 100644 (file)
index 824af57..0000000
+++ /dev/null
@@ -1,1077 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Space shooter.
-# This program is a fun game but also a good example of the scene2d module
-module shoot_logic
-
-import scene2d
-
-# The ship of the player
-class Player
-       super Sprite
-
-       # Where the player is going
-       var going_target = new GoingTarget
-
-       # Activate the `going_target`
-       fun goes_to(x,y: Int, speed: Int)
-       do
-               going_target.x = x
-               going_target.y = y
-               going_target.active = true
-               var angle = angle_to(going_target)
-               set_velocity(angle, speed)
-       end
-
-       # Current forture of the player
-       var money: Int = 0 is writable
-
-       # Number of basic bullets fired together
-       var nbshoots: Int = 1 is writable
-
-       # Time bebore the player shoot again a basic bullet (cooldown)
-       # Shoot if 0
-       var shoot_ttl = 0
-
-       # Number of missiles
-       var nbmissiles: Int = 0 is writable
-
-       # Time bebore the player shoot again a missile (cooldown)
-       # Shoot if 0
-       var missile_ttl = 0
-
-       # Remainind time when the player is protected from impacts
-       var protected_ttl = 0
-
-       # The associated play scene
-       # (mainly used to registed shoots)
-       var scene: PlayScene
-
-       init(scene: PlayScene) do
-               self.scene = scene
-               self.width = 2400
-               self.height = 2400
-       end
-
-       redef fun update
-       do
-               super
-
-               # Out of screen?
-               if self.y < 0 then
-                       self.y = 0
-                       self.vy = 0
-               else if self.y > scene.height then
-                       self.y = scene.height
-                       self.vy = 0
-               end
-               if self.x < 0 then
-                       self.x = 0
-                       self.vx = 0
-               else if self.x > scene.width then
-                       self.x = scene.width
-                       self.vx = 0
-               end
-
-               # Update of the player protection if any
-               if protected_ttl > 0 then protected_ttl -= 1
-
-               # Need to shoot basic bullets?
-               if shoot_ttl > 0 then
-                       shoot_ttl -= 1
-               else
-                       shoot_ttl = 30
-                       for i in [0..nbshoots[ do
-                               var shoot = new Shoot(scene)
-                               shoot.x = x
-                               shoot.y = top
-                               shoot.vy = -500
-                               shoot.vx = (i - nbshoots / 2) * 100
-                               scene.player_shoots.add(shoot)
-                       end
-               end
-
-               # Need to shoot missiles?
-               if missile_ttl > 0 then
-                       missile_ttl -= 1
-               else if nbmissiles > 0 then
-                       missile_ttl = 500 / nbmissiles
-                       var shoot = new Missile(scene)
-                       shoot.x = x
-                       shoot.y = top
-                       shoot.vy = -300
-                       shoot.vx = 0
-                       scene.player_shoots.add(shoot)
-               end
-
-       end
-
-       # Time before the player is respawned by the scene
-       var respawn_ttl: Int = 0
-
-       fun hit
-       do
-               if self.protected_ttl > 0 then return
-               self.scene.explosion(self.x, self.y, 10)
-               self.exists = false
-
-               # Reset the position for respawn
-               self.x = scene.width / 2
-               self.y = scene.height - 10000
-               self.vx = 0
-               self.vy = 0
-               self.respawn_ttl = 50
-       end
-
-end
-
-# Sprites that may be hit by the player.
-# Eq. enemies, bullets, loots, etc.
-class Hitable
-       super Sprite
-
-       # What do do when self is hit by the player.
-       # By defaut, do nothing
-       fun hit_by_player(player: Player) do end
-end
-
-# Destination for the player (pointer position)
-class GoingTarget
-       super Hitable
-
-       # true in on move, false if player is at rest
-       var active = false is writable
-
-       init do
-               self.width = 500
-               self.height = 500
-       end
-
-       redef fun hit_by_player(player)
-       do
-               if not active then return
-               active = false
-               player.vx = 0
-               player.vy = 0
-       end
-end
-
-# A bullet shooted by a ship
-class Shoot
-       super Hitable
-
-       # Was the shoot fired by an enemy.
-       # Since there is no frendly fire, it is important to distinguish ownership
-       var enemy: Bool = false
-
-       # The scene of the sprite
-       # Is used with bound limits
-       var scene: PlayScene
-
-       init(scene: PlayScene)
-       do
-               self.scene = scene
-               self.width = 800
-               self.height = 800
-       end
-
-       redef fun update
-       do
-               super
-
-               # Out of screen ?
-               if self.y < -100 * 100 or self.y > scene.height + 10000 or self.x < -100 * 100 or self.x > scene.width + 10000 then
-                       self.exists = false
-               end
-       end
-
-       redef fun hit_by_player(player)
-       do
-               player.hit
-               self.exists = false
-       end
-end
-
-# A advanced bullet that aims a target (player or enemy)
-class Missile
-       super Shoot
-
-       # The target aquired by the missile
-       var target: nullable Sprite = null
-
-       # When ttl is 0 then the angle stay fixed
-       # The angle is updated toward the target if ttl>0
-       var ttl: Int = 200
-
-       redef fun update
-       do
-               super
-
-               # Do we still update the angle ?
-               if ttl <= 0 then return
-               ttl -= 1
-
-               # Do we have a target?
-               var target = self.target
-               if target == null or not target.exists then return
-
-               # Just update the angle
-               var angle = self.angle_to(target)
-               self.set_velocity(angle, 300)
-       end
-end
-
-# A enemy ship
-# Various enemies exists, each kind has its own subclass
-abstract class Enemy
-       super Hitable
-
-       # The scene of the ship
-       # Is used to store created bullets or to get info about the player
-       var scene: PlayScene
-
-       # Time bebore the enemy shoot again (cooldown)
-       # Shoot if 0
-       # The default value is used as a grace period to avoid a first shoot on
-       # the first update
-       var shoot_ttl = 50
-
-       init(scene: PlayScene)
-       do
-               self.width = 2400
-               self.height = 2400
-               self.scene = scene
-               scene.enemies.add(self)
-       end
-
-       redef fun update
-       do
-               super
-
-               # Out of screen ?
-               if self.y > scene.height + 10000 or self.x < -100 * 100 or self.x > scene.width + 10000 then
-                       # Note: no control on the top to let ennemies appear
-                       self.exists = false
-               end
-
-               # Need to shoot?
-               if shoot_ttl > 0 then
-                       shoot_ttl -= 1
-               else
-                       shoot
-               end
-       end
-
-       # Each enemy has its own kind of shoot strategy
-       # Note: is automatically called by update when shoot_ttl is expired
-       fun shoot do end
-
-       # Money given when the enemy is destroyed
-       fun loot: Int is abstract
-
-       # What to do when the enemy is hit by a player shoot (or by the player himself)?
-       # By default it kill the enemy in an explosion and generate a loot
-       fun hit
-       do
-               self.exists = false
-               scene.explosion(self.x, self.y, 5)
-               if 100.rand < 3 then
-                       var upmissile = new UpMissile(scene)
-                       upmissile.x = self.x
-                       upmissile.y = self.y
-                       upmissile.vx = 0
-                       upmissile.vy = 0
-                       scene.loots.add(upmissile)
-                       scene.hitables.add(new LootArea(upmissile, 2000))
-               else
-                       for i in [0..self.loot[ do
-                               var money = new Money(scene)
-                               money.x = self.x
-                               money.y = self.y
-                               money.set_velocity(100.rand.to_f*pi/50.0, (500+self.loot).rand)
-                               scene.loots.add(money)
-                               scene.hitables.add(new LootArea(money, 2000))
-                       end
-               end
-       end
-
-       redef fun hit_by_player(player)
-       do
-               player.hit
-               hit
-       end
-end
-
-# Basic enemy, do not shoot
-class Enemy0
-       super Enemy
-
-       redef fun loot do return 3
-
-       redef init(scene)
-       do
-               self.width = 3600
-               self.height = 3600
-       end
-end
-
-# Simple shooter of pairs of basic bullets
-class Enemy1
-       super Enemy
-
-       redef init(scene)
-       do
-               self.width = 4400
-               self.height = 4400
-       end
-
-       redef fun shoot
-       do
-               # Next shoot
-               shoot_ttl = 50
-
-               # two bullets shoot each time
-               for dx in [-11, 11] do
-                       var shoot = new Shoot(scene)
-                       shoot.enemy = true
-                       shoot.x = self.x + dx * 100
-                       shoot.y = self.bottom
-                       shoot.vy = 500
-                       scene.enemy_shoots.add(shoot)
-               end
-       end
-
-       redef fun loot do return 5
-end
-
-# Enemy that shoot missiles
-class Enemy2
-       super Enemy
-
-       redef init(scene)
-       do
-               self.width = 6000
-               self.height = 6000
-       end
-
-       redef fun shoot
-       do
-               # Next shoot
-               shoot_ttl = 200
-
-               # The missile targets the player
-               var shoot = new Missile(scene)
-               shoot.enemy = true
-               shoot.x = self.x
-               shoot.y = self.bottom
-               shoot.vy = 500
-               shoot.target = scene.player
-               scene.enemy_shoots.add(shoot)
-       end
-
-       redef fun loot do return 10
-end
-
-# Enemy that shoot rings of basic bullets
-class Enemy3
-       super Enemy
-
-       redef init(scene)
-       do
-               self.width = 5800
-               self.height = 5800
-       end
-
-       redef fun shoot
-       do
-               # Next shoot
-               shoot_ttl = 50
-
-               for i in [0..10[ do
-                       var shoot = new Shoot(scene)
-                       shoot.enemy = true
-                       shoot.x = self.x
-                       shoot.y = self.bottom
-                       shoot.set_velocity(pi/5.0*i.to_f, 500)
-                       scene.enemy_shoots.add(shoot)
-               end
-       end
-
-       redef fun loot do return 20
-end
-
-# Enemy with a turret that shoot burst of bullets toward the player
-class Enemy4
-       super Enemy
-
-       # The angle of the turret
-       var angle: Float = 0.0
-
-       redef init(scene)
-       do
-               self.width = 4200
-               self.height = 4200
-       end
-
-       redef fun update
-       do
-               super
-
-               # Rotate the turret toward the player
-               var target = scene.player
-               if target.exists then
-                       angle = self.angle_to(target)
-               end
-       end
-
-       # Shoots come in burst
-       var nbshoots: Int = 0
-
-       redef fun shoot
-       do
-               # Next shoot: is there still bullets in the burst?
-               if self.nbshoots < 10 then
-                       # Is ther
-                       self.nbshoots += 1
-                       shoot_ttl = 5
-               else
-                       self.nbshoots = 0
-                       shoot_ttl = 80
-               end
-
-               # Shoot with the turret angle
-               var shoot = new Shoot(scene)
-               shoot.enemy = true
-               shoot.x = self.x
-               shoot.y = self.y
-               shoot.set_velocity(angle, 500)
-               scene.enemy_shoots.add(shoot)
-       end
-
-       redef fun loot do return 20
-end
-
-# Enemy that rush directly on the player
-class EnemyKamikaze
-       super Enemy
-
-       redef init(scene)
-       do
-               self.width = 3200
-               self.height = 3200
-       end
-
-       redef fun update
-       do
-               super
-
-               # Try to target the player
-               var target = scene.player
-               if not target.exists then return
-
-               var angle = self.angle_to(target)
-               self.set_velocity(angle, 600)
-       end
-
-       redef fun loot do return 5
-end
-
-# The boss has two semi-independent arms
-class Boss
-       super Enemy
-
-       # Left arm
-       var left_part: BossPart
-
-       # Right arm
-       var right_part: BossPart
-
-       init(scene)
-       do
-               super
-               self.width = 140 * 100
-               self.height = 96 * 100
-               self.x = scene.width / 2
-               self.y = -100 * 100
-               self.left_part = new BossPart(self, -66*100)
-               self.right_part = new BossPart(self, 66*100)
-       end
-
-       var flick_ttl: Int = 0
-
-       redef fun update
-       do
-               if flick_ttl > 0 then flick_ttl -= 1
-
-               # Path of the boss (down then left<->right)
-               if self.y < 20000 then
-                       self.vx = 0
-                       self.vy = 100
-               else if self.vx == 0 then
-                       self.vx = 100
-                       self.vy = 0
-               else if self.x > scene.width - 10000 and self.vx > 0 then
-                       self.vx = -self.vx
-               else if self.x < 10000 and self.vx < 0 then
-                       self.vx = -self.vx
-               end
-
-               super
-       end
-
-       redef fun shoot
-       do
-               # Do not shoot if not ready
-               if self.vy != 0 then return
-
-               # Try to target the player
-               var target = scene.player
-               if not target.exists then return
-
-               # Next shoot: burst if no arms remains
-               if left_part.exists or right_part.exists then
-                       shoot_ttl = 60
-               else
-                       shoot_ttl = 20
-               end
-
-               # Shoot the player with a basic bullet
-               var shoot = new Shoot(scene)
-               shoot.enemy = true
-               shoot.x = self.x
-               shoot.y = self.bottom
-               var angle = shoot.angle_to(target)
-               shoot.set_velocity(angle, 500)
-               scene.enemy_shoots.add(shoot)
-       end
-
-       redef fun loot do return 100
-
-       var live: Int = 20
-
-       redef fun hit
-       do
-               # Protected while an arm remains
-               if left_part.exists or right_part.exists then return
-
-               if live > 0 then
-                       live -= 1
-                       flick_ttl = 2
-               else
-                       super
-                       scene.explosion(self.x, self.y, 30)
-               end
-       end
-end
-
-# An arm of a boss
-class BossPart
-       super Enemy
-
-       # The associated boss
-       var boss: Boss
-
-       # Relative x coordonate (center to center) of the arm
-       var relx: Int
-
-       # Relative y coordonate (center to center) of the arm
-       var rely: Int = 36 * 100
-
-       var live: Int = 10
-
-       init(boss: Boss, relx: Int)
-       do
-               self.boss = boss
-               self.relx = relx
-               super(boss.scene)
-               self.width = 38 * 100
-               self.height = 48 * 100
-
-               # Alternate the shoots of the arms
-               if relx > 0 then
-                       shoot_ttl += 300
-               end
-               self.x = boss.x + relx
-               self.y = boss.y + rely
-       end
-
-       redef fun update
-       do
-               self.x = boss.x + relx
-               self.y = boss.y + rely
-
-               super
-
-               if flick_ttl > 0 then flick_ttl -= 1
-       end
-
-       redef fun shoot
-       do
-               # Do not shoot if not ready
-               if self.boss.vy != 0 then return
-
-               # Next shoot
-               shoot_ttl = 600
-
-               # Shoot a missile that targets the player
-               var shoot = new Missile(scene)
-               shoot.enemy = true
-               shoot.x = self.x
-               shoot.y = self.bottom
-               shoot.vy = 500
-               shoot.target = scene.player
-               scene.enemy_shoots.add(shoot)
-       end
-
-       var flick_ttl: Int = 0
-
-       redef fun hit
-       do
-               if live > 0 then
-                       live -= 1
-                       flick_ttl = 2
-               else
-                       super
-               end
-       end
-
-       redef fun loot do return 10
-end
-
-# Whatever reward or bonus that can be picked by the player
-abstract class Loot
-       super Hitable
-
-       var scene: PlayScene
-
-       init(scene: PlayScene)
-       do
-               self.scene = scene
-               self.width = 400
-               self.height = 400
-       end
-
-       # Magnet effect: The loot will move to the target if set
-       # See LootArea for details
-       var target: nullable Sprite = null
-
-       redef fun update
-       do
-               super
-
-               # Out of screen ?
-               if self.y > scene.height + 10000 then
-                       self.exists = false
-               end
-
-               var target = self.target
-               if target == null then
-                       # Not magneted: deploy
-
-                       # Heavy fuild friction to stops the explosion
-                       # Loots are placed with a explosion, see `Enemy::hit'
-                       self.vx = self.vx*7/8
-                       self.vy = self.vy*7/8
-
-                       # Background scroling
-                       self.y += 50
-
-               else if target.exists then
-                       # Magneted: rush toward the target
-                       var angle = self.angle_to(target)
-                       self.set_velocity(angle, 800)
-
-               else
-                       # Magneted but dead target: reset the loot
-                       self.vx = 0
-                       self.vy = 0
-                       self.target = null
-               end
-       end
-end
-
-# Basic money loot
-class Money
-       super Loot
-
-       redef fun hit_by_player(player)
-       do
-               self.exists = false
-               player.money += 1
-               if player.money > 100 then
-                       player.money -= 100
-                       player.nbshoots += 1
-               end
-       end
-end
-
-# Increase the number of missiles
-class UpMissile
-       super Loot
-
-       redef fun hit_by_player(player)
-       do
-               self.exists = false
-               player.nbmissiles += 1
-       end
-end
-
-# A loot area is an invisible field used to implement the magnet effets of loots
-# The principle is:
-#  * the loot is an invisible sprite with a hitbox larger than the loot hitbox
-#  * the lootbox remains centered on the loot
-#  * when the player hit the lootarea, then the loot is set to target the player
-#  * when the player hit the loot, then the player gains effectively the loot
-class LootArea
-       super Hitable
-
-       # The associated loot
-       var loot: Loot
-
-       init(loot: Loot, radius: Int)
-       do
-               self.loot = loot
-               self.width = radius * 2 + loot.width
-               self.height = radius * 2 + loot.height
-       end
-
-       redef fun update
-       do
-               # position remains centered on the loot
-               self.x = loot.x
-               self.y = loot.y
-
-               # No area if no loot
-               if not loot.exists then self.exists = false
-
-               # the super is useless but it is a good practice to call it
-               super
-       end
-
-       redef fun hit_by_player(player)
-       do
-               # Kill the area
-               self.exists = false
-
-               # The loot now targets the player
-               loot.target = player
-       end
-end
-
-# A non interactive element of an explosion
-# A real explosion is made of many Explosion object
-# Use the `PlayScene::explosion` method to generate a full explosion
-class Explosion
-       super Sprite
-
-       # Time before the sprite vanishes
-       var ttl: Int = 10
-
-       redef fun update
-       do
-               # Heavy fuild friction to stops the explosion
-               self.vx = self.vx*7/8
-               self.vy = self.vy*7/8
-
-               # Background scrolling
-               self.y += 50
-
-               super
-
-               # Vanishes?
-               if ttl > 0 then
-                       ttl -= 1
-               else
-                       exists = false
-               end
-       end
-end
-
-# A star is a non-interactive background element
-# Stars are used to simulate a continuous global scroling
-class Star
-       super Sprite
-
-       # The scene of the sprite
-       # Is used with bound limits
-       var scene: ShotScene
-
-       init(scene: ShotScene)
-       do
-               self.scene = scene
-               # Randomely places stars on the plane
-               self.x = scene.width.rand
-               self.y = scene.height.rand
-               self.vy = 40.rand + 11
-       end
-
-       redef fun update
-       do
-               super
-
-               # Replace the star on the top
-               if self.y > scene.height then
-                       self.y = 200.rand * -100
-                       self.x = scene.width.rand
-                       self.vy = 40.rand + 11
-               end
-       end
-end
-
-class ShotScene
-       super Scene
-
-       # When a scene need to be replaced, just assign the next_scene to a non null value
-       var next_scene: nullable ShotScene = null is writable
-
-       # The width of the whole scene
-       var width: Int is writable
-
-       # The height of the whole scene
-       var height: Int is writable
-
-       init(w,h: Int)
-       do
-               width = w
-               height = h
-       end
-end
-
-# The main play state
-class PlayScene
-       super ShotScene
-
-       # The player ship
-       var player: Player
-
-       # Shoots of the player
-       var player_shoots = new LiveGroup[Shoot]
-
-       # Enemy ships
-       var enemies = new LiveGroup[Enemy]
-
-       # Soots of the enemy
-       var enemy_shoots = new LiveGroup[Shoot]
-
-       # Collectible loots
-       var loots = new LiveGroup[Loot]
-
-       # Non active stuff like explosions
-       var pasive_stuff = new LiveGroup[LiveObject]
-
-       # Background stuff like stars
-       var background = new LiveGroup[LiveObject]
-
-       # All other hitable sprites
-       var hitables = new LiveGroup[Hitable]
-
-       # All sprites
-       var sprites = new LiveGroup[LiveObject]
-
-       init(w,h)
-       do
-               super
-               self.player = new Player(self)
-               player.x = self.width / 2
-               player.y = self.height - 10000
-               self.sprites.add(background)
-               self.sprites.add(pasive_stuff)
-               self.sprites.add(loots)
-               self.sprites.add(player_shoots)
-               self.sprites.add(enemy_shoots)
-               self.sprites.add(enemies)
-               self.sprites.add(self.player)
-               self.sprites.add(hitables)
-
-               for i in [0..100[ do
-                       background.add(new Star(self))
-               end
-
-               hitables.add(player.going_target)
-       end
-
-       # Generate an explosion
-       fun explosion(x, y: Int, radius: Int)
-       do
-               # Project explosion parts from the given position
-               # The strong friction and the short ttl of each part will achieve the effect
-               for i in [0..radius[ do
-                       var ex = new Explosion
-                       ex.x = x
-                       ex.y = y
-                       ex.set_velocity(100.rand.to_f*pi/50.0, (50*radius).rand)
-                       ex.ttl += radius.rand
-                       pasive_stuff.add(ex)
-               end
-       end
-
-       var enemy_remains: Int = 15
-       var boss_wait_ttl: Int = 0
-       var boss: nullable Boss
-
-       redef fun update
-       do
-               sprites.gc
-               sprites.update
-
-               if enemy_remains == 0 then
-                       if boss_wait_ttl > 0 then
-                               boss_wait_ttl -= 1
-                       else if boss == null then
-                               boss = new Boss(self)
-                               enemy_remains = 15
-                       else if not boss.exists then
-                               boss = null
-                       end
-               else if 100.rand < 1 then
-                       enemy_remains -= 1
-                       if enemy_remains == 0 then
-                               boss_wait_ttl = 500
-                       end
-                       var rnd = 100.rand
-                       var enemy: Enemy
-                       if rnd < 40 then
-                               enemy = new Enemy0(self)
-                       else if rnd < 60 then
-                               enemy = new Enemy1(self)
-                       else if rnd < 70 then
-                               enemy = new EnemyKamikaze(self)
-                       else if rnd < 90 then
-                               enemy = new Enemy2(self)
-                       else if rnd < 95 then
-                               enemy = new Enemy3(self)
-                       else
-                               enemy = new Enemy4(self)
-                       end
-                       enemy.x = (self.width - 20000).rand + 10000
-                       enemy.vy = 200.rand + 100
-                       if 10.rand < 3 then
-                               enemy.vx = 200.rand - 100
-                       end
-               end
-
-               for ps in player_shoots do
-                       if not ps.exists then continue
-                       var target: nullable Enemy = null
-                       var td = 100000 # big int
-                       for e in enemies do
-                               if not e.exists then continue
-                               if ps.overlaps(e) then
-                                       ps.exists = false
-                                       e.hit
-                               end
-                               var d = (e.x - ps.x).abs + (e.y - ps.y).abs
-                               if td > d then
-                                       target = e
-                                       td = d
-                               end
-                       end
-                       if ps isa Missile and (ps.target == null or not ps.target.exists) then
-                               ps.target = target
-                       end
-               end
-
-               for e in enemies do
-                       if not e.exists then continue
-                       if player.exists and player.overlaps(e) then
-                               e.hit_by_player(player)
-                       end
-               end
-               for s in enemy_shoots do
-                       if not s.exists then continue
-                       if player.exists and player.overlaps(s) then
-                               s.hit_by_player(player)
-                       end
-               end
-               for l in loots do
-                       if not l.exists then continue
-                       if player.exists and player.overlaps(l) then
-                               l.hit_by_player(player)
-                       end
-               end
-               for l in hitables do
-                       if not l.exists then continue
-                       if player.exists and player.overlaps(l) then
-                               l.hit_by_player(player)
-                       end
-               end
-               if not player.exists then
-                       if player.respawn_ttl > 0 then
-                               player.respawn_ttl -= 1
-                       else
-                               player.exists = true
-                               player.protected_ttl = 100
-                               self.sprites.add(self.player)
-                       end
-               end
-       end
-end
-
-###
-
-class MenuScene
-       super ShotScene
-
-       var sprites = new LiveGroup[LiveObject]
-
-       init(w,h)
-       do
-               super
-               for i in [0..100[ do
-                       sprites.add(new Star(self))
-               end
-       end
-
-       var play: Bool = false is writable
-       var ttl: Int = 50
-
-       redef fun update
-       do
-               sprites.update
-
-               if not play then return
-               if ttl > 0 then
-                       ttl -= 1
-                       return
-               end
-               next_scene = new PlayScene(width,height)
-       end
-end
-
-fun headless_run
-do
-       srand_from 0
-       print "Headless run"
-       # Only run the playscene
-       var scene = new PlayScene(80000,60000)
-       # beefup the player
-       scene.player.nbshoots = 5
-       scene.player.nbmissiles = 5
-       # play
-       print "Play"
-       var turns = 10
-       if args.length > 0 then
-               turns = args.first.to_i
-       end
-       for i in [0..turns[ do
-               for j in [0..10000[ do
-                       scene.update
-               end
-               print "{i}: money={scene.player.money} enemies={scene.enemies.length} shoots={scene.player_shoots.length}"
-       end
-       print "Game Over"
-end
-
-headless_run