Added Glitch Room Source code to Gitty

This commit is contained in:
Jeff Luke committed 2026-10-04 11:31:17 -07:00
commit 1ac9eb5644
505 files changed
+28504

No files matched your search

+25
View File
@@ -0,0 +1,25 @@
[gd_scene format=3 uid="uid://da7lj6k47rotp"]
[ext_resource type="Script" uid="uid://fqff3d88cr1j" path="res://games/frogger/frogger.gd" id="1"]
[ext_resource type="Script" uid="uid://df5twn4utxg0n" path="res://games/frogger/frogger_view.gd" id="2"]
[ext_resource type="Script" uid="uid://blkjvi1sb7hmb" path="res://games/frogger/display.gd" id="3"]
[ext_resource type="Script" uid="uid://dh0mu01mar7nl" path="res://games/frogger/frogger_audio.gd" id="4"]
[node name="Frogger" type="Node" unique_id=1686543748]
script = ExtResource("1")
[node name="PixelScreen" type="SubViewport" parent="." unique_id=865659315]
disable_3d = true
size = Vector2i(224, 256)
render_target_update_mode = 4
[node name="Board" type="Node2D" parent="PixelScreen" unique_id=184374191]
texture_filter = 1
script = ExtResource("2")
[node name="Display" type="Node2D" parent="." unique_id=333917260]
texture_filter = 1
script = ExtResource("3")
[node name="Audio" type="Node" parent="." unique_id=712591344]
script = ExtResource("4")
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b242bxbbuaj5o"
path="res://.godot/imported/spr_frogger.png-7ce0f59b8e564b24229faf1647204a8e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://games/frogger/art/spr_frogger.png"
dest_files=["res://.godot/imported/spr_frogger.png-7ce0f59b8e564b24229faf1647204a8e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.
@@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://sp8rad7erusb"
path="res://.godot/imported/frogger-music.mp3-83a0af3950edf8e2ce0550d65f173319.mp3str"
[deps]
source_file="res://games/frogger/audio/frogger-music.mp3"
dest_files=["res://.godot/imported/frogger-music.mp3-83a0af3950edf8e2ce0550d65f173319.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4
Binary file not shown.
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://smtgenseeuju"
path="res://.godot/imported/sound-frogger-coin-in.wav-8633ca7444f8a7846bf6405524ad9b37.sample"
[deps]
source_file="res://games/frogger/audio/sound-frogger-coin-in.wav"
dest_files=["res://.godot/imported/sound-frogger-coin-in.wav-8633ca7444f8a7846bf6405524ad9b37.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2
Binary file not shown.
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://jdgf84jxnjus"
path="res://.godot/imported/sound-frogger-extra.wav-158c017030f00ec8317ac46cfefa90a8.sample"
[deps]
source_file="res://games/frogger/audio/sound-frogger-extra.wav"
dest_files=["res://.godot/imported/sound-frogger-extra.wav-158c017030f00ec8317ac46cfefa90a8.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2
Binary file not shown.
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://dbeeno1vhd72o"
path="res://.godot/imported/sound-frogger-hop.wav-cf3b2064d4fb4c61b75fee957fe06e77.sample"
[deps]
source_file="res://games/frogger/audio/sound-frogger-hop.wav"
dest_files=["res://.godot/imported/sound-frogger-hop.wav-cf3b2064d4fb4c61b75fee957fe06e77.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2
Binary file not shown.
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://c40g5wcvnh1a1"
path="res://.godot/imported/sound-frogger-plunk.wav-73a8475dfe1089b682fa96175c511864.sample"
[deps]
source_file="res://games/frogger/audio/sound-frogger-plunk.wav"
dest_files=["res://.godot/imported/sound-frogger-plunk.wav-73a8475dfe1089b682fa96175c511864.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2
Binary file not shown.
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://cgy6c1rwyev5e"
path="res://.godot/imported/sound-frogger-squash.wav-1b686c87ff414930a009a0fcd27650d0.sample"
[deps]
source_file="res://games/frogger/audio/sound-frogger-squash.wav"
dest_files=["res://.godot/imported/sound-frogger-squash.wav-1b686c87ff414930a009a0fcd27650d0.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2
Binary file not shown.
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://clqop5ekc2wkt"
path="res://.godot/imported/sound-frogger-time.wav-18d22f8e1a9342d25829a0bf05ddae73.sample"
[deps]
source_file="res://games/frogger/audio/sound-frogger-time.wav"
dest_files=["res://.godot/imported/sound-frogger-time.wav-18d22f8e1a9342d25829a0bf05ddae73.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2
+19
View File
@@ -0,0 +1,19 @@
@tool
extends Node2D
const LOGICAL := Vector2(224,256)
var destination := Rect2(0,0,672,768)
func _process(_delta: float) -> void:
var available := get_viewport_rect().size if not Engine.is_editor_hint() else Vector2(672,768)
var factor := minf(available.x/7.0,available.y/8.0)
var size := Vector2(7,8)*factor
destination = Rect2((available-size)*.5,size)
queue_redraw()
func to_logical(point: Vector2) -> Vector2:
return (point-destination.position)/destination.size*LOGICAL
func to_logical_delta(delta: Vector2) -> Vector2:
return delta/destination.size*LOGICAL
func _draw() -> void:
draw_rect(Rect2(Vector2.ZERO,get_viewport_rect().size),Color.BLACK)
if has_node("../PixelScreen"):
draw_texture_rect(get_node("../PixelScreen").get_texture(),destination,false)
+1
View File
@@ -0,0 +1 @@
uid://blkjvi1sb7hmb
+329
View File
@@ -0,0 +1,329 @@
@tool
extends ArcadeGame
@export_range(0,99) var boards_to_win: int = 1
@export_range(1,9) var starting_lives: int = 3
@export_range(15,120) var crossing_time: float = 60.0
@export_range(.5,2) var difficulty: float = 1.0
@export var music_enabled: bool = true
const HOME_X := [16,64,112,160,208]
var phase := "title"
var phase_time := 0.0
var clock := 0.0
var score := 0
var high_score := 0
var lives := 3
var board_number := 1
var homes: Array[bool] = [false,false,false,false,false]
var frog := Vector2(112,232)
var from := Vector2(112,232)
var destination := Vector2(112,232)
var direction := 0
var hop_left := 0.0
var repeat_left := 0.0
var time_left := 60.0
var furthest_row := 0
var warned := false
var extra_awarded := false
var death_kind := "squash"
var lanes: Array[Dictionary] = []
var leaderboard: Array[int] = []
var attract_time := 0.0
var demo_active := false
var demo_time := 0.0
var idle_score := 0
@onready var view: Node2D = $PixelScreen/Board
func _ready() -> void:
make_lanes()
lives = starting_lives
func make_lanes() -> void:
lanes.clear()
var definitions := [
[1,"car",-24.0,16.0,80.0,20.0,1], [2,"car",28.0,16.0,82.0,48.0,3],
[3,"car",-32.0,16.0,78.0,8.0,0], [4,"car",45.0,16.0,110.0,70.0,2],
[5,"car",-22.0,32.0,100.0,30.0,4], [7,"turtle",-24.0,48.0,72.0,4.0,0],
[8,"log",25.0,48.0,98.0,30.0,0], [9,"log",36.0,96.0,144.0,5.0,0],
[10,"turtle",-30.0,32.0,70.0,14.0,1], [11,"log",22.0,64.0,100.0,40.0,0]]
for item in definitions:
lanes.append({"row":item[0],"kind":item[1],"speed":item[2]*(1+(board_number-1)*.10)*difficulty,"width":item[3],"spacing":item[4],"offset":item[5],"sprite":item[6]})
func start_game() -> bool:
if not super.start_game(): return false
demo_active = false
attract_time = 0
$Audio.stop_all()
score = 0
lives = starting_lives
board_number = 1
extra_awarded = false
homes.fill(false)
make_lanes()
respawn()
phase = "ready"
phase_time = 1.5
$Audio.effect("coin-in")
return true
func reset_game() -> void:
super.reset_game()
demo_active = false
attract_time = 0
$Audio.stop_all()
phase = "title"
clock = 0
score = 0
board_number = 1
lives = starting_lives
homes.fill(false)
make_lanes()
respawn()
func respawn() -> void:
frog = Vector2(112,232)
from = frog
destination = frog
direction = 0
hop_left = 0
repeat_left = 0
time_left = crossing_time
furthest_row = 0
warned = false
func _unhandled_input(event: InputEvent) -> void:
if Engine.is_editor_hint() or (event is InputEventKey and event.echo): return
if event.is_action_pressed("arcade_start"):
if not is_running: start_game()
func pressed(action: String) -> bool:
return Input.is_action_pressed(action)
func hop(step: Vector2i) -> bool:
if phase != "play" or hop_left > 0 or absi(step.x)+absi(step.y) != 1: return false
var target := frog+Vector2(step)*16
if target.x < 8 or target.x > 216 or target.y > 232 or target.y < 40: return false
direction = 0 if step.y < 0 else (2 if step.y > 0 else (1 if step.x < 0 else 3))
from = frog
destination = target
hop_left = .12
$Audio.effect("hop")
return true
func _physics_process(delta: float) -> void:
clock += delta
if Engine.is_editor_hint():
attract_time = fmod(clock,44.0)
view.queue_redraw()
return
if phase in ["title","scores"]:
attract_time += delta
if phase == "title" and attract_time >= 44.0:
begin_demo()
view.queue_redraw()
return
elif phase == "scores" and attract_time >= 7.0:
phase = "title"
attract_time = 0
elif phase in ["ready","dead","home","clear"]:
phase_time -= delta
if phase_time <= 0:
match phase:
"ready":
phase = "play"
if music_enabled and not demo_active: $Audio.music()
"dead":
if lives <= 0 and not demo_active:
finish(false)
else:
respawn()
phase = "play"
if music_enabled and not demo_active: $Audio.music()
"home":
if not homes.has(false):
add_score(1000)
phase = "clear"
phase_time = 2.0
else:
respawn()
phase = "play"
"clear":
if demo_active:
end_demo()
elif boards_to_win > 0 and board_number >= boards_to_win:
finish(true)
else:
board_number += 1
homes.fill(false)
make_lanes()
respawn()
phase = "ready"
phase_time = 1.5
elif phase == "play":
repeat_left -= delta
if hop_left <= 0 and repeat_left <= 0:
var step := Vector2i.ZERO
if demo_active: step = demo_step()
elif pressed("arcade_up"): step = Vector2i.UP
elif pressed("arcade_down"): step = Vector2i.DOWN
elif pressed("arcade_left"): step = Vector2i.LEFT
elif pressed("arcade_right"): step = Vector2i.RIGHT
if step != Vector2i.ZERO and hop(step): repeat_left = .16
step_world(delta)
if demo_active:
demo_time += delta
if demo_time >= 32.0: end_demo()
view.queue_redraw()
func begin_demo() -> void:
idle_score = score
demo_active = true
demo_time = 0
score = 0
lives = starting_lives
board_number = 1
homes.fill(false)
clock = 0
make_lanes()
respawn()
phase = "play"
$Audio.stop_all()
func end_demo() -> void:
demo_active = false
score = idle_score
phase = "scores"
attract_time = 0
$Audio.stop_all()
# Predict the same lane positions and hitboxes used by live gameplay.
# The demo supplies ordinary hops; it has no invulnerability or scripted teleports.
func demo_safe(step: Vector2i) -> bool:
var target := frog + Vector2(step)*16
if target.x < 8 or target.x > 216 or target.y < 40 or target.y > 232: return false
if target.y == 40:
for i in range(5):
if absf(target.x-HOME_X[i]) <= 7 and not homes[i]: return true
return false
for tick in range(1,13):
var t := tick * .01
var point := frog.lerp(target,t/.12)
var row := roundi((232-point.y)/16)
for lane in lanes:
if lane.row != row: continue
var supported := false
var predicted := lane.duplicate()
predicted.offset += lane.speed*t
for x in lane_objects(predicted):
if lane.kind == "car" and point.x+6 > x+2 and point.x-6 < x+lane.width-2: return false
if lane.kind != "car" and point.x-5 >= x and point.x+5 <= x+lane.width:
supported = true
if tick == 12 and lane.kind != "car":
if not supported: return false
if lane.kind == "turtle" and lane.sprite == 1 and fposmod(clock+t,7.0) > 5.3: return false
return true
func demo_step() -> Vector2i:
if demo_safe(Vector2i.UP): return Vector2i.UP
var target_x := 112.0
var distance := INF
for i in range(5):
if not homes[i] and absf(frog.x-HOME_X[i]) < distance:
distance = absf(frog.x-HOME_X[i])
target_x = HOME_X[i]
var side := Vector2i.RIGHT if target_x > frog.x else Vector2i.LEFT
if absf(target_x-frog.x)>7 and demo_safe(side): return side
return Vector2i.ZERO
func lane_objects(lane: Dictionary) -> Array[float]:
var result: Array[float] = []
var start: float = fposmod(lane.offset,lane.spacing)-lane.spacing
while start < 224:
result.append(start)
start += lane.spacing
return result
func submerged(lane: Dictionary) -> bool:
return lane.kind == "turtle" and lane.sprite == 1 and fposmod(clock,7.0) > 5.7
func step_world(delta: float) -> void:
time_left -= delta
if time_left <= 0:
die("time")
return
if time_left <= 10 and not warned:
warned = true
$Audio.effect("time")
for lane in lanes: lane.offset = fposmod(lane.offset+lane.speed*delta,lane.spacing)
if hop_left > 0:
hop_left = maxf(0,hop_left-delta)
frog = from.lerp(destination,1.0-hop_left/.12)
if hop_left <= 0:
var row := roundi((232-frog.y)/16)
if row > furthest_row:
add_score((row-furthest_row)*10)
furthest_row = row
# Evaluate the current rendered location, including the hop trajectory.
var row := roundi((232-frog.y)/16)
if row >= 12 and hop_left <= 0:
var index := -1
for i in range(5):
if absf(frog.x-HOME_X[i]) <= 7: index = i
if index < 0 or homes[index]:
die("squash")
else:
homes[index] = true
add_score(50+int(time_left)*10)
phase = "home"
phase_time = .8
$Audio.effect("extra")
return
for lane in lanes:
if lane.row != row: continue
var supported := false
for x in lane_objects(lane):
if lane.kind == "car":
if frog.x+5 > x+2 and frog.x-5 < x+lane.width-2:
die("squash")
return
elif frog.x-4 >= x and frog.x+4 <= x+lane.width and not submerged(lane):
supported = true
if lane.kind != "car":
# Support is checked on landing; hops may cross a platform edge in flight.
if hop_left <= 0:
if not supported:
die("plunk")
return
frog.x += lane.speed*delta
if frog.x < 5 or frog.x > 219: die("plunk")
break
func die(kind: String) -> void:
if phase != "play": return
lives -= 1
death_kind = kind
phase = "dead"
phase_time = 1.1
hop_left = 0
$Audio.stop_music()
$Audio.effect(kind)
func add_score(value: int) -> void:
score += value
if not demo_active: high_score = maxi(high_score,score)
if score >= 20000 and not extra_awarded:
extra_awarded = true
lives += 1
$Audio.effect("extra")
func finish(won: bool) -> void:
if demo_active:
end_demo()
return
$Audio.stop_all()
leaderboard.append(score)
leaderboard.sort()
leaderboard.reverse()
if leaderboard.size() > 5: leaderboard.resize(5)
phase = "won" if won else "lost"
if won: win_game()
else: lose_game()
+1
View File
@@ -0,0 +1 @@
uid://fqff3d88cr1j
+35
View File
@@ -0,0 +1,35 @@
extends Node
var voices: Array[AudioStreamPlayer] = []
var tracks: Dictionary = {}
var tune: AudioStreamPlayer
var current := 0
func _ready() -> void:
for name in ["hop","plunk","squash","time","extra","coin-in"]:
tracks[name] = load("res://games/frogger/audio/sound-frogger-"+name+".wav")
for i in range(6):
var voice := AudioStreamPlayer.new()
voice.volume_db = -8
add_child(voice)
voices.append(voice)
tune = AudioStreamPlayer.new()
tune.stream = load("res://games/frogger/audio/frogger-music.mp3")
tune.volume_db = -12
add_child(tune)
tune.finished.connect(_music_finished)
func effect(name: String) -> void:
if get_parent().demo_active: return
if not tracks.has(name): return
var voice := voices[current]
current = (current+1)%voices.size()
voice.stream = tracks[name]
voice.play()
func music() -> void:
if get_parent().demo_active: return
if not tune.playing: tune.play()
func _music_finished() -> void:
if get_parent().phase in ["play","home"] and get_parent().music_enabled: tune.play()
func stop_music() -> void:
if tune: tune.stop()
func stop_all() -> void:
stop_music()
for voice in voices: voice.stop()
+1
View File
@@ -0,0 +1 @@
uid://dh0mu01mar7nl
+138
View File
@@ -0,0 +1,138 @@
@tool
extends Node2D
const SHEET = preload("res://games/frogger/art/spr_frogger.png")
const CHARACTERS := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-"
var game: Node
var atlas: ImageTexture
var regions: Dictionary = {}
var source: Image
func _ready() -> void:
game = get_parent().get_parent()
source = SHEET.get_image()
source.convert(Image.FORMAT_RGBA8)
for i in range(8): register("frog%d"%i,Rect2i(1+i*18,1,16,16))
for i in range(2): register("attract%d"%i,Rect2i(1+i*18,98,16,16))
for i in range(7): register("death%d"%i,Rect2i(1+i*18,80,16,16))
for i in range(5): register("car%d"%i,Rect2i(1+i*18,116,32 if i==4 else 16,16))
for i in range(3): register("log%d"%i,Rect2i(1+i*18,134,16,16))
for i in range(5): register("turtle%d"%i,Rect2i(1+i*18,152,16,16))
for i in range(5): register("letter%d"%i,Rect2i(1+i*18,232,16,16))
register("home",Rect2i(1,188,32,24))
register("hedge",Rect2i(35,188,8,24))
register("saved",Rect2i(45,196,16,16))
register("bank",Rect2i(135,196,16,16))
for color in range(5):
for i in range(CHARACTERS.length()):
register("font%d_%s"%[color,CHARACTERS[i]],Rect2i(1+(i%17)*9,250+color*28+int(i/17)*9,8,8))
atlas = ImageTexture.create_from_image(source)
source = null
func register(name: String,area: Rect2i) -> void:
regions[name] = Rect2(area)
# Flood only border-connected black/gray padding; preserve enclosed dark detail.
var pending: Array[Vector2i] = []
for x in range(area.size.x):
pending.append(Vector2i(x,0))
pending.append(Vector2i(x,area.size.y-1))
for y in range(area.size.y):
pending.append(Vector2i(0,y))
pending.append(Vector2i(area.size.x-1,y))
var seen: Dictionary = {}
while not pending.is_empty():
var p: Vector2i = pending.pop_back()
if p.x<0 or p.y<0 or p.x>=area.size.x or p.y>=area.size.y or seen.has(p): continue
seen[p] = true
var pixel := source.get_pixelv(area.position+p)
var key := pixel.is_equal_approx(Color.BLACK) or pixel.is_equal_approx(Color("404040")) or pixel.a == 0
if not key: continue
source.set_pixelv(area.position+p,Color.TRANSPARENT)
for offset in [Vector2i.LEFT,Vector2i.RIGHT,Vector2i.UP,Vector2i.DOWN]: pending.append(p+offset)
func sprite(name: String,point: Vector2) -> void:
var region: Rect2 = regions[name]
draw_texture_rect_region(atlas,Rect2(point.round(),region.size),region)
func text_at(value: String,point: Vector2,color: int = 0) -> void:
for i in range(value.length()):
var key := "font%d_%s"%[color,value[i]]
if regions.has(key): sprite(key,point+Vector2(i*8,0))
func label(value: String,y: float,color: int = 0) -> void:
text_at(value,Vector2((224-value.length()*8)/2.0,y),color)
func title() -> void:
var t: float = game.attract_time
for i in range(7):
var age: float = t - .5 - i*4
if age < 0: continue
var x: float = 28+i*24
var y := 136.0
if age < 3.5:
x = lerpf(232,x,floorf(age*12)/42.0)
sprite("attract1",Vector2(x,y))
elif t < 29:
sprite("attract0",Vector2(x,y))
elif t < 33:
y = lerpf(136,55,floorf((t-29)*12)/48.0)
sprite("frog%d"%(int(t*6)%2),Vector2(x,y))
elif t < 33+i*.45:
sprite("attract0",Vector2(x,55))
else:
sprite("letter%d"%[0,1,2,3,3,4,1][i],Vector2(x,55))
if t >= 36: label("-POINT TABLE-",89)
if t >= 37: label("10 PTS FOR EACH STEP",115,1)
if t >= 38:
label("50 PTS FOR EVERY FROG",139,1)
label("ARRIVED HOME SAFELY",151,2)
if t >= 39:
label("1000 PTS FOR FIVE",177,1)
label("FROGS HOME",189,1)
if int(t*2)%2 == 0: label("PUSH START",219,4)
label("FREE PLAY",247,4)
func board() -> void:
for x in range(0,224,8): sprite("hedge",Vector2(x,24))
for i in range(5):
draw_rect(Rect2(game.HOME_X[i]-16,24,32,24),Color("000047"))
sprite("home",Vector2(game.HOME_X[i]-16,24))
if game.homes[i]: sprite("saved",Vector2(game.HOME_X[i]-8,32))
for y in [128,224]:
for x in range(0,224,16): sprite("bank",Vector2(x,y))
for lane in game.lanes:
var y: float = 232-lane.row*16-8
for x in game.lane_objects(lane):
match lane.kind:
"car": sprite("car%d"%lane.sprite,Vector2(x,y))
"log":
var tiles := int(lane.width/16)
for i in range(tiles): sprite("log%d"%(0 if i==0 else (2 if i==tiles-1 else 1)),Vector2(x+i*16,y))
"turtle":
if game.submerged(lane): continue
var frame := int(game.clock*5)%3
if lane.sprite == 1 and fposmod(game.clock,7.0)>5:
frame = 3 if fposmod(game.clock,7.0)<5.4 else 4
for i in range(int(lane.width/16)): sprite("turtle%d"%frame,Vector2(x+i*16,y))
if game.phase == "dead":
var frame := clampi(int((1.1-game.phase_time)*7),0,6)
sprite("death%d"%frame,game.frog-Vector2(8,8))
elif game.phase not in ["home","clear","won","lost"]:
sprite("frog%d"%(game.direction*2+(1 if game.hop_left>0 else 0)),game.frog-Vector2(8,8))
for i in range(mini(game.lives,6)): sprite("frog0",Vector2(i*12,239))
var fraction: float = clampf(game.time_left/game.crossing_time,0,1)
draw_rect(Rect2(88,248,104*fraction,8),Color("e00000") if fraction<.167 else Color("00c000"))
text_at("TIME",Vector2(192,248),1)
if game.phase == "ready": label("PLAYER 1",135,2)
if game.phase == "clear": label("FIVE FROGS HOME",135,1)
if game.phase == "won": label("YOU WIN",135,1)
if game.phase == "lost": label("GAME OVER",135,2)
if game.demo_active and int(game.demo_time*2)%2 == 0: label("GAME OVER",135,2)
func _draw() -> void:
if game == null or atlas == null: return
draw_rect(Rect2(0,0,224,256),Color.BLACK)
draw_rect(Rect2(0,0,224,128),Color("000047"))
text_at("1-UP",Vector2(24,0))
text_at("HI-SCORE",Vector2(104,0))
text_at("%05d"%game.score,Vector2(16,8),2)
text_at("%05d"%game.high_score,Vector2(112,8),2)
if game.phase == "title": title()
elif game.phase == "scores":
label("HIGH SCORES",55,1)
for i in range(5): label("%d %05d"%[i+1,game.leaderboard[i]] if i<game.leaderboard.size() else "%d -----"%(i+1),88+i*20)
label("PUSH START",218,4)
else: board()
+1
View File
@@ -0,0 +1 @@
uid://df5twn4utxg0n