'
' Finalisation de la démo
'

' Config Gameplay
?asteroids = 3

' position caméra
?distance = 0
?distance_cible = 50
?distance_finale = 150

' taille zone de jeu
?zone_x = ?distance_finale * 2
?zone_y = ?distance_finale

' nombre de collisions nécessaires :
?stat_total = ?asteroids * 15' 1+2+4+8
?stat_hits = 0

' index particules
?dust_min = 0
?dust_max = 0

'autobuild off

'
goto "prepare etoiles"
goto "prepare nebuleuse"
goto "prepare asteroides"

'
goto "prepare cargo"
goto "prepare scene"

'
' ship
'

?player_x = 0
?player_y = 0
?player_angle = 0
?player_speed = 0
?player_roll = 0
?player_vx = 0
?player_vy = 0

' anim impact cargo
?impact_fx = 0
?impact_fx_angle = 0

'
goto "intro debut"

' ===
' === BOUCLE PRINCIPALE
' ===

do
	
	if ?mode_intro <> 0
		goto "intro"
	else
		goto "interface"
	end
	
	goto "gestion joueur"
	
	goto "gestion collisions"
	
	goto "gestion asteroides"
	
	goto "gestion scene"
	
	
	' particules collisions
	goto "gestion fx"
	
	update
	
loop

'
'
'


label "prepare scene"
	
	' reconfig lumière par défaut
	delete "light"
	
	' bleu espace
	power "glow" to 80
	color "glow" to #04e
	
	' lumière arrière
	create light as "sun"
	power "sun" to 150
	move "sun" to -30, 20, 20
	color "sun" to #f80
	target "sun" to 0, 0, 0
	
	' lumière générale
	create light as "light"
	power "light" to 100
	color "light" to #fed
	'glue "light-ship" to "ship"
	move "light" to -20, 20, -20
	target "light" to 0, 0, 0
	
	' lumière joueur
	create orb as "orb"
	power "orb" to 150
	color "orb" to #fff
	glue "orb" to "ship"
	move "orb" to 0, 0, -20
	target "orb" auto "ship"
	
	
	clear screen
	free "camera"
	
return


'
'
'

label "debut niveau"
	
	reset timer
	
	for 1 to ?asteroids as ?n
		clone "t-32" as "ast-?n"
		
		' position aleatoire autour du joueur
		[ast, ?n, x] = (random -?zone_x to ?zone_x) + ?player_x
		[ast, ?n, y] = (random -?zone_y to ?zone_y) + ?player_y
		
		' mouvement
		[ast, ?n, roll] = (random 0 to 360)
		[ast, ?n, angle] = (random 0 to 360)
		[ast, ?n, speed] = (.5 + (random) / 2) * .7
		
		' hp
		[ast, ?n, size] = 32
		[ast, ?n, lock] = 0
		[ast, ?n, alive] = 1
		'[ast,?n,touch] = 0
		
	next
	
return


'
'
'

label "prepare asteroides"
	' création de la collection nécessaire
	' Précréation x4 asteroïdes
	' 8, 16, 24, 32
	
	?size = 8
	
	do
		goto "loading", ?size / 32
		?template = "t-?size"
		goto "craft asteroide"
		hide ?template
		?size + 8
	loop if ?size <= 32
	
return

'

label "craft asteroide"
	
	' astéroide... 
	
	?benchmark = timer
	?step = 1
	
	
	?mid = ?size / 2
	?rx = ?size / 3.0
	?rz = ?size / 3.5
	?ry = ?size / 2.4
	
	create sprite ?size as ?template
	hide ?template
	
	?rgb = #999
	?add_rgb = #987
	
	?an = (random 0 to 360)
	?evo = (random 20 to 40) / 10
	?ff = (random 15 to 15) / 10
	?fe = (random 10 to 20) / 10
	
	for 0 to 180 step ?step as ?ay
		
		?an + 1.5
		?f = 1 + .3 * (cos ?an / ?ff)
		
		for 0 to 360 step 8 as ?az
			
			?r = .2 * (abs (sin ?an))
			?e = 1 - ?r
			
			?cx = (cos ?ay * ?evo)
			?cy = (sin ?ay)
			?cz = (sin ?an / ?ff)
			
			' tentative cubique :
			'?cx = (sign ?cx) * (pow (abs ?cx), 2 / 4)
			'?cy = (sign ?cy) * (pow (abs ?cy), 2 / 4)
			'?cz = (sign ?cz) * (pow (abs ?cz), 2 / 4)
			
			?midx = ?mid + ?fe * ?cx' e * (cos ?ay * ?evo)
			?midz = ?mid + ?fe * ?cz'e * (sin ?an / ?ff)
			?midy = ?mid
			
			?x = 1 + ?midx + ?rx * (cos ?az) * ?cy * ?e
			?z = 1 + ?midz + ?rz * (sin ?az) * ?cy * ?e
			?y = 1 + ?midy + ?ry * (cos ?ay)
			
				
			color ?rgb
			add ?template dot ?x, ?y, ?z
			
			' 2% d'aspérités
			?o = (random 0 to 100)
			if ?o < 2
				color ?add_rgb
				for -1 to 1 as ?xx
					for -1 to 1 as ?yy
						for -1 to 1 as ?zz
							?dist = (abs ?xx) + (abs ?yy) + (abs ?zz)
							if ?dist < 3
								add ?template dot ?x + ?xx, ?y + ?yy, ?z + ?zz
							end
						next
					next
				next
			end
		next
	next
	
	
	
return

'
'
'

label "prepare nebuleuse"
	' background = nébuleuses
	'
	clear screen
	mix trace "screen"
	
	for 1 to 4 as ?yy
		?x = random -100 to 200
		?y = -100 + ?yy * 50' random 0 to 600
		for 40
			color 0, 0, 2, 25
			trace circle (random 20 to 60) to ?x + (random -100 to 100), ?y + (random -100 to 100)
			trace fill
		next
	next
	
return

'
'
'

label "prepare cargo"
	
	create sprite 20 as "ship"
	paint "ship" to "glass"
	
	color #a31
	add "ship" box 5, 6, 2 to 13, 15, 6
	color #999
	add "ship" frame 3, 4, 5 to 15, 17, 5
	add "ship" frame 4, 5, 5 to 14, 16, 5
	color #a31
	add "ship" frame 7, 5, 2 to 11, 16, 4
	
	
	' 4 airpads
	for 2 to 5 step 3 as ?z
		if ?z = 1
			color #123
		else
			color #821
		end
		
		add "ship" box 1, 1, ?z to 7, 7, ?z + 1
		add "ship" box 1, 14, ?z to 7, 19, ?z + 1
		add "ship" box 11, 1, ?z to 17, 7, ?z + 1
		add "ship" box 11, 14, ?z to 17, 19, ?z + 1
		
		color #777
		
		add "ship" frame 1, 1, ?z to 7, 7, ?z
		add "ship" frame 1, 14, ?z to 7, 19, ?z
		add "ship" frame 11, 1, ?z to 17, 7, ?z
		add "ship" frame 11, 14, ?z to 17, 19, ?z
	next
	
	' cockpit
	color #888
	add "ship" box 8, 7, 1 to 15, 14, 8
	color #111
	add "ship" box 10, 8, 1 to 14, 13, 7
	
	
	'	move "ship" to 0,0,70
	'scale "ship" to .5
	
return

'
'
'

label "prepare etoiles"
	
	select screen "back"
	
	for 1 to 2 as ?s
		
		create sprite 256 as "stars?s-1"
		'paint "stars?s-1" to "neon"
		
		if ?s = 1
			color #468
		else
			color #68a
		end
		
		for 50
			add "stars?s-1" dot (random 1 to 256), (random 1 to 256), 1
		next
		
		for 2 to 6 as ?n
			clone "stars?s-1" as "stars?s-?n"
		next
	next
	
	
return

'
' -----------------------------
'

label "gestion asteroides"
	
	?stat_alive = 0
	
	for 1 to ?asteroids as ?n
		if [ast, ?n, alive] = 1
			
			?stat_alive + 1
			
			[ast, ?n, x] + [ast, ?n, speed] * (cos [ast, ?n, angle])
			[ast, ?n, y] + [ast, ?n, speed] * (sin [ast, ?n, angle])
			
			if [ast, ?n, x] < -?zone_x + ?player_x
				[ast, ?n, x] + ?zone_x * 2
			end
			
			if [ast, ?n, x] > ?zone_x + ?player_x
				[ast, ?n, x] - ?zone_x * 2
			end
			
			if [ast, ?n, y] < -?zone_y + ?player_y
				[ast, ?n, y] + ?zone_y * 2
			end
			
			if [ast, ?n, y] > ?zone_y + ?player_y
				[ast, ?n, y] - ?zone_y * 2
			end
			
			move "ast-?n" to [ast, ?n, x], [ast, ?n, y], 0
			
			?roll_speed = [ast, ?n, speed] / 2
			?tax = (sin [ast, ?n, roll]) * ?roll_speed
			?tay = (cos [ast, ?n, roll]) * ?roll_speed
			?taz = (cos [ast, ?n, roll] / 3) * ?roll_speed
			turn "ast-?n" by ?tax, ?tay, ?taz
			
			[ast, ?n, lock] - 1
		end
	next
	
return

' ===
' === INTERFACE
' ===

label "loading"
	param ?p
	
	select screen "front"
	font size 3
	clear screen
	color #fff
	
	?label = "Loading " + (round ?p * 100) + "%"
	trace text ?label center 0, 0
	update
return

'
label "intro debut"
	
	select screen "front"
	?mode_intro = 1
	color 1
	trace text "Foncez dans les Asteroïdes pour TOUS les détruire..." center 0, -50
	trace text "Utilisez les touches fléchées pour diriger" center 0, -60
	trace text "Bougez pour débuter !" center 0, -70
	
	create text "ASTEROIDZ" as "titre"
	paint "titre" to "metal"
return


label "intro"
	?player_speed = 1
	move "titre" to ?player_x - 50, 0, ?player_y
	turn "titre" to -20, 0, 0
return

'

label "intro fin"
	' vaisseau tourne = début de partie !
	if ?mode_intro <> 0
		?mode_intro = 0
		?distance_cible = ?distance_finale
		goto "debut niveau"
		
		delete "titre"
	end
return

'

label "interface"
	
	select screen "front"
	
	if (is "final") = 1
		' partie achevée : score final
		move "final" to ?camera_x, ?camera_y + 25, -?distance / 2
	else if ?stat_hits = ?stat_total
		' partie achevée
		?chrono_victoire = (timer)
		color #088
		create text (format timer ?chrono_victoire) as "final"
		paint "final" to "ui"
		clear screen
		color 1
		font size 8
		?name = (user)
		trace text "Bien joué ?name !" center 0, -50
	else
		
		if (mod (frame), 30) = 1
			clear screen
			color #0af
			?chrono = (timer)
			font size 5
			trace text (format timer ?chrono) center 0, 90
			
			
			?pct = ?stat_hits / ?stat_total
			font size 3
			trace text (round ?pct * 100) + "% nettoyé" center 0, -85
			color #0484
			trace frame -80, -93 to 80, -96
			trace fill
			color #af8
			trace frame -80, -93 to -80 + 160 * ?pct, -96
			trace fill
			
		end
	end
	
return

' ===
' === GESTION PARTIE
' ===

label "gestion joueur"
	
	?tangle = 0' tangage
	if (key "left") = 1
		?player_angle + 2
		?tangle = -45
		goto "intro fin"
	end
	if (key "right") = 1
		?player_angle - 2
		?tangle = 45
		goto "intro fin"
	end
	
	?player_roll + (?tangle - ?player_roll) / 30
	
	'?angle + (?player_roll - ?angle) / 30
	
	
	
	if ?player_speed > 0
		?ps = ?player_speed * .05
		?player_vx + ?ps * (cos ?player_angle)
		?player_vy + ?ps * (sin ?player_angle)
	end
	
	?player_vx - ?player_vx / 60
	?player_vy - ?player_vy / 60
	
	
	if (key "up") = 1
		?speed = 1
	else if (key "down") = 1 and ?player_speed > 0
		?speed = 0
		?player_vx * .95
		?player_vy * .95
	else
		?speed = 0
	end
	
	
	?player_speed + (?speed - ?player_speed) / 30
	
	?player_x + ?player_vx
	?player_y + ?player_vy
	
	
	move "ship" to ?player_x, ?player_y, 2
	turn "ship" to ?player_roll * (cos ?player_angle), ?player_roll * (sin ?player_angle), ?player_angle
	
	'move "light-ship" to ?player_x, ?player_y, -50
	
	
return

'
'
'

label "gestion scene"
	
	?distance + (?distance_cible - ?distance) / 50
	?camera_x + (?player_x - ?camera_x) / 15
	?camera_y + (?player_y - ?camera_y) / 15
	move "camera" to ?camera_x, ?camera_y, -?distance
	
	' fx impact
	if ?impact_fx > 0
		?impact_fx * .96
		?impact_fx_angle + ?impact_fx
	end
	move z "camera" by ?impact_fx * (abs (sin ?impact_fx_angle))
	
	
	for 1 to 2 as ?s
		
		?pos_z = 25
		
		if ?s = 1
			?pos_z = 75
		end
		
		?ox = (floor ?player_x / 256) * 256 - 128
		?oy = (floor ?player_y / 256) * 256' + 128
		
		
		'move "stars"
		move "stars?s-1" to ?ox, ?oy, ?pos_z
		move "stars?s-2" to ?ox + 256, ?oy, ?pos_z
		move "stars?s-3" to ?ox + 512, ?oy, ?pos_z
		move "stars?s-4" to ?ox, ?oy + 256, ?pos_z
		move "stars?s-5" to ?ox + 256, ?oy + 256, ?pos_z
		move "stars?s-6" to ?ox + 512, ?oy + 256, ?pos_z
		
	next
	
return

'
'
'

label "gestion collisions"
	
	for 1 to ?asteroids as ?n
		
		if [ast, ?n, alive] = 1 and [ast, ?n, lock] < 0
			
			if (hit "ast-?n" to "ship") = 1
				
				update
				[ast, ?n, angled] = [ast, ?n, angle]' conserve
				
				?impact_fx = [ast, ?n, size] * 1.25
				
				goto "asteroid hit", ?n
				
				?stat_hits + 1
				
				goto "fx impact", ?n
			end
		end
	next
	
return

'
'
'

label "asteroid hit"
	' astéroide touché = duplication !
	param ?hit
	update
	
	' ?h = hit #
	' 32,16,8
	if [ast, ?hit, size] <= 8
		' destruction
		[ast, ?hit, alive] = 0
		hide "ast-?hit"
	else
		' brisé x 2
		[ast, ?hit, size] - 8
		[ast, ?hit, lock] = 20
		'[ast,?hit,speed] * 1.5
		[ast, ?hit, speed] + ?player_speed / 2
		'[ast,?hit,move] = random 0 to 360
		[ast, ?hit, angle] = ((mod [ast, ?hit, angle], 360) + (mod ?player_angle, 360)) / 2
		[ast, ?hit, angle] - 45
		?size = [ast, ?hit, size]
		clone "t-?size" as "ast-?hit"
		
		
		' add
		?asteroids + 1
		?new = ?asteroids
		
		[ast, ?new, x] = [ast, ?hit, x]
		[ast, ?new, y] = [ast, ?hit, y]
		[ast, ?new, angle] = [ast, ?hit, angle] + 90
		[ast, ?new, roll] = random -900 to 900
		[ast, ?new, speed] = [ast, ?hit, speed]
		[ast, ?new, size] = [ast, ?hit, size]
		[ast, ?new, alive] = [ast, ?hit, alive]
		[ast, ?new, lock] = [ast, ?hit, lock]
		
		clone "t-?size" as "ast-?new"
		turn "ast-?new" to (random 0 to 360), (random 0 to 180), (random 0 to 90)
		
	end
	
	
return

'
'
'

label "fx impact"
	param ?hit
	
	?q = 8' [ast, ?n, size]
	?s = [ast, ?n, size] / 2
	
	color #987
	
	for 1 to ?q
		'[dust, ?dust_max, x] = ([ast, ?hit, x] + ?player_x) / 2
		'[dust, ?dust_max, y] = ([ast, ?hit, y] + ?player_y) / 2
		
		[dust, ?dust_max, x] = [ast, ?hit, x] + (random -?s to ?s)
		[dust, ?dust_max, y] = [ast, ?hit, y] + (random -?s to ?s)
		
		[dust, ?dust_max, angle] = random 0 to 360
		[dust, ?dust_max, speed] = .2 + (random) / 4
		[dust, ?dust_max, lp] = random 1 to 2' taille aléatoire
		[dust, ?dust_max, angled] = [ast, ?hit, angled]' sens de l'asteroid initial
		'[dust, ?dust_max, angled] = -[dust, ?dust_max, angled]
		
		?vox = "dust-?dust_max"
		create sprite 1 as ?vox
		'paint ?vox to "neon"
		
		add ?vox dot 1, 1, 1
		'add ?vox dot (dice 1 to 4), (dice 1 to 4), 4
		zoom ?vox to 2
		move ?vox to ?player_x, ?player_y, 0
		?dust_max + 1
	next
	
return

'
'
'

label "gestion fx"
	' animation des particules d'impact
	for ?dust_min to ?dust_max as ?d
		if (is "dust-?d") = 1
			if [dust, ?d, lp] > 0
				
				[dust, ?d, lp] - .01
				[dust, ?d, x] + [dust, ?d, speed] * .5 * (sin [dust, ?d, angle])
				[dust, ?d, y] + [dust, ?d, speed] * .5 * (cos [dust, ?d, angle])
				
				[dust, ?d, x] + [dust, ?d, speed] * 3 * (cos [dust, ?d, angled])
				[dust, ?d, y] + [dust, ?d, speed] * 3 * (sin [dust, ?d, angled])
				
				move "dust-?d" to [dust, ?d, x], [dust, ?d, y], 0
				zoom "dust-?d" to [dust, ?d, lp]' * 100
			else
				if ?d = ?dust_min
					?dust_min + 1
					delete "dust-?d"
				end
				if ?d = ?dust_max
					' on pourrait faire l'inverse avec dust_min
					?dust_max - 1
					delete "dust-?d"
				end
			end
		end
	next
	
return

'
' FIN
'
x