123 lines
4.3 KiB
GDScript
123 lines
4.3 KiB
GDScript
extends SceneTree
|
|
var failures := 0
|
|
var starts := 0
|
|
var wins := 0
|
|
var losses := 0
|
|
func check(value: bool, message: String) -> void:
|
|
if not value:
|
|
failures += 1
|
|
push_error(message)
|
|
func _initialize() -> void:
|
|
call_deferred("run")
|
|
func run() -> void:
|
|
var g = load("res://games/space_invaders/SpaceInvaders.tscn").instantiate()
|
|
root.add_child(g)
|
|
g.set_physics_process(false)
|
|
g.sound_enabled = false
|
|
g.game_started.connect(func(): starts += 1)
|
|
g.game_won.connect(func(): wins += 1)
|
|
g.game_lost.connect(func(): losses += 1)
|
|
check(g.aliens.size()==55 and g.shields.size()==4,"Initial fleet/shields")
|
|
check(g.start_game() and not g.start_game(),"Start guard")
|
|
g._physics_process(2.1)
|
|
check(g.phase=="play" and starts==1,"Ready and event")
|
|
check(g.fire() and not g.fire(),"One player shot")
|
|
g.remove_shot()
|
|
check(g.shot_count==1,"Shot sequence")
|
|
var a: Vector2 = g.aliens[0].position
|
|
var b: Vector2 = g.aliens[1].position
|
|
g.march()
|
|
check(g.aliens[0].position==a+Vector2(2,0) and g.aliens[1].position==b,"Ripple movement")
|
|
for alien in g.aliens: alien.alive=false
|
|
g.aliens[0].alive=true
|
|
g.aliens[0].position=Vector2(208,100)
|
|
g.fleet_cursor=0
|
|
g.march()
|
|
check(g.fleet_direction==-1 and g.aliens[0].position.y==108,"Edge descent")
|
|
var shield: Dictionary = g.shields[0]
|
|
var point := Vector2(shield.position)+Vector2(12,4)
|
|
check(g.shield_hit(point,true),"Shield collision")
|
|
check(shield.image.get_pixel(12,4).a==0,"Destructible shield pixel")
|
|
check(not g.shield_hit(point,true),"Hole allows shot through")
|
|
g.new_wave()
|
|
for alien in g.aliens: alien.alive=false
|
|
g.aliens[0].alive=true
|
|
g.aliens[0].position=Vector2(100,100)
|
|
g.hit_pause=1
|
|
g.shot_active=true
|
|
g.player_shot=Vector2(100,110)
|
|
g.step_world(.05)
|
|
check(not g.aliens[0].alive and g.score==10 and g.phase=="clear","Alien hit/clear")
|
|
g._physics_process(1.6)
|
|
check(wins==1 and not g.is_running,"Win event")
|
|
g.start_game()
|
|
g.waves_to_win=0
|
|
g.phase="clear"
|
|
g.phase_time=0
|
|
g._physics_process(.01)
|
|
check(g.wave==2 and g.aliens[44].position.y==96,"Next wave height")
|
|
g.phase="play"
|
|
g.lives=1
|
|
g.die()
|
|
g._physics_process(1.6)
|
|
check(losses==1 and g.phase=="lost","Loss event")
|
|
g.start_game()
|
|
g.add_score(1500)
|
|
var lives: int = g.lives
|
|
g.add_score(2000)
|
|
check(lives==g.starting_lives+1 and g.lives==lives,"One bonus life")
|
|
g.reset_game()
|
|
g.high_score=9999
|
|
g.last_score=420
|
|
var original_starts := starts
|
|
var original_wins := wins
|
|
var original_losses := losses
|
|
g.begin_demo()
|
|
for i in range(1600): g._physics_process(1.0/60)
|
|
check(not g.demo and not g.is_running and g.phase=="attract","Demo exit")
|
|
check(g.high_score==9999 and g.score==420,"Demo score isolation")
|
|
check(starts==original_starts and wins==original_wins and losses==original_losses,"Demo event isolation")
|
|
g.begin_demo()
|
|
check(g.start_game() and not g.demo and g.score==0,"Start interrupts demo")
|
|
g.reset_game()
|
|
check(g.phase=="attract" and not g.is_running,"Reset")
|
|
g.start_game()
|
|
g.phase="play"
|
|
g.hit_pause=1
|
|
g.saucer_active=true
|
|
g.saucer_x=100
|
|
g.shot_count=8
|
|
g.shot_active=true
|
|
g.player_shot=Vector2(100,50)
|
|
g.step_world(.025)
|
|
check(g.score==300 and not g.saucer_active and not g.shot_active,"Saucer score sequence and collision")
|
|
g.hit_pause=1
|
|
g.shot_delay=0
|
|
g.fire()
|
|
g.player_shot=Vector2(16,180)
|
|
g.bombs.clear()
|
|
g.bombs.append({"position":Vector2(16,174),"kind":0})
|
|
g.step_world(.01)
|
|
check(not g.shot_active and g.bombs.is_empty(),"Projectile interception")
|
|
g.bombs.append({"position":Vector2(g.player_x,214),"kind":0})
|
|
g.step_world(.025)
|
|
check(g.phase=="dead","Enemy projectile hits player")
|
|
g._physics_process(1.6)
|
|
g._physics_process(1.1)
|
|
check(g.phase=="play" and g.bombs.is_empty(),"Respawn clears threats")
|
|
for alien in g.aliens: alien.alive=false
|
|
g.aliens[0].alive=true
|
|
g.aliens[0].position=Vector2(100,216)
|
|
g.fleet_cursor=0
|
|
g.march()
|
|
check(g.phase=="lost" and not g.is_running,"Invasion is an immediate loss")
|
|
g._physics_process(5.1)
|
|
check(g.phase=="attract","Game over returns to attract")
|
|
var definition = load("res://data/games/space_invaders.tres")
|
|
check(definition.game_id==&"space_invaders" and definition.scene!=null,"Game resource")
|
|
var database = load("res://data/project_database.tres")
|
|
check(database.get_game(&"space_invaders")!=null,"Database registration")
|
|
print("Space Invaders checks: ",failures," failures")
|
|
g.free()
|
|
quit(failures)
|