added entire game (cuz it didnt use git before)

This commit is contained in:
2025-10-18 19:43:41 +02:00
parent 4dd71382d7
commit 171ff78876
63 changed files with 2684 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
extends StaticBody2D
@export var biscuit_increment: float
@onready var sequence: Array[int] = []
@onready var is_active: bool = false
@onready var biscuit_fraction: float = 0.0
var hud: Panel
var player: CharacterBody2D
func _process(delta: float):
$ProgressBar.value = biscuit_fraction * 100
if biscuit_fraction < 1.0:
biscuit_fraction += biscuit_increment * delta
biscuit_fraction = min(biscuit_fraction, 1.0)
if not hud: return
if hud.is_fully_completed() && is_active:
sequence = hud.generate_sequence(5)
hud.set_sequence(sequence)
biscuit_fraction = 0.0
hud.hide()
player.try_add_biscuit()
if is_active && biscuit_fraction >= 1.0: hud.show()
if sequence.is_empty():
sequence = hud.generate_sequence(5)
hud.set_sequence(sequence)
func _on_trigger_body_entered(body: Node2D):
if body is not CharacterBody2D: return
is_active = true
if not hud: hud = body.get_node("KeySequence")
if not player: player = body
func _on_trigger_body_exited(body: Node2D):
if body is not CharacterBody2D: return
is_active = false
hud.hide()
+1
View File
@@ -0,0 +1 @@
uid://d2t5nkrsib24d
+23
View File
@@ -0,0 +1,23 @@
extends Control
var saved_pigs: int
@onready var has_reddend = false
func _ready():
if not saved_pigs: saved_pigs = 0
$Saved.text = "At least you saved them %s times" % saved_pigs
if saved_pigs == 0: $Saved.text = "You couldn't even save one abduction?"
$AnimationPlayer.play("fade_in")
func _process(_delta: float):
if !$AnimationPlayer.current_animation == "fade_in" \
&& saved_pigs == 0 && !has_reddend:
$AnimationPlayer.play("redden")
has_reddend = true
func _on_menu_button_pressed() -> void:
get_tree().change_scene_to_file("res://ui/main_menu.tscn")
+1
View File
@@ -0,0 +1 @@
uid://f6863j28l3ua
+32
View File
@@ -0,0 +1,32 @@
extends Control
@export var hp_animation_dur: float
var healthbar_full_size: Vector2
var hp_value: Panel
var hp_tween: Tween
func _ready():
healthbar_full_size = $HealthbarBase/HealthbarValue.size
hp_value = $HealthbarBase/HealthbarValue
## The amount is a value between 0..1
func set_health(a: float):
var f_pos: float = healthbar_full_size.y - (a * hp_value.size.y)
var user_favor: float = sin(a * PI) * 10
f_pos -= user_favor
f_pos = clamp(f_pos, 0, healthbar_full_size.y)
if hp_value.position.y == f_pos: return;
if hp_tween && hp_tween.is_running(): hp_tween.kill()
hp_tween = create_tween()
hp_tween.set_trans(Tween.TRANS_LINEAR)
hp_tween.tween_property(
hp_value,
"position:y",
f_pos,
hp_animation_dur
)
+1
View File
@@ -0,0 +1 @@
uid://de476q6oxds3o
+105
View File
@@ -0,0 +1,105 @@
extends Panel
enum Directions {
UP,
DOWN,
LEFT,
RIGHT
}
var arrow = preload("res://assets/sprites/arrow.png")
var arrow_completed = preload("res://assets/sprites/arrow_green.png")
@onready var sequence: Array[Directions] = []
@onready var completed: Array[bool] = []
var arrow_el: TextureRect
func _ready():
arrow_el = TextureRect.new()
arrow_el.size = Vector2(40.0, 40.0)
arrow_el.pivot_offset = arrow_el.size / 2
arrow_el.texture = arrow
arrow_el.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
func set_sequence(new_sequence: Array[Directions]):
sequence = new_sequence
reset_completed()
render_sequence()
func add_to_sequence(direction: Directions):
sequence.append(direction)
render_sequence()
func reset_sequence():
sequence = []
reset_sequence_render()
func reset_sequence_render():
for el in self.get_children():
self.remove_child(el)
func render_sequence():
reset_sequence_render()
for i in range(sequence.size()):
var dir = sequence[i]
var n_el = arrow_el.duplicate()
n_el.position.x = (i - sequence.size() / 2.0) * n_el.size.x
var rot_deg = 0.0
match dir:
Directions.UP: rot_deg = 0.0
Directions.RIGHT: rot_deg = 90.0
Directions.DOWN: rot_deg = 180.0
Directions.LEFT: rot_deg = 270.0
n_el.rotation = deg_to_rad(rot_deg)
if completed[i]: n_el.texture = arrow_completed
self.add_child(n_el)
func random_direction() -> Directions:
var dir = randi_range(0, Directions.keys().size() - 1)
return Directions.values()[dir]
func generate_sequence(length: int) -> Array[Directions]:
var new_sequence: Array[Directions] = []
for i in range(length):
new_sequence.append(random_direction())
return new_sequence
func try_complete_next(direction: Directions):
if !self.visible: return
var next = completed.find(false)
if direction != sequence[next]: reset_completed()
else: completed[next] = true
render_sequence()
func is_fully_completed() -> bool:
return false not in completed && !completed.is_empty()
func reset_completed():
completed = []
completed.resize(sequence.size())
completed.fill(false)
+1
View File
@@ -0,0 +1 @@
uid://dh4tox6b5ewbq
+47
View File
@@ -0,0 +1,47 @@
extends Control
var seagull = preload("res://actors/seagull_particle.tscn")
@export var square_rot: float
var play_button: Button
var quit_button: Button
var credit_button: Button
@onready var times_quit: int = 0
@onready var times_credited: int = 0
func _ready():
play_button = $InteractiblesContainer/ButtonsContainer/PlayButton
quit_button = $InteractiblesContainer/ButtonsContainer/QuitButton
credit_button = $InteractiblesContainer/ButtonsContainer/CreditsButton
func _on_play_button_pressed() -> void:
get_tree().change_scene_to_file("res://scenes/main.tscn")
func _on_quit_button_pressed() -> void:
quit_button.text = "No."
times_quit += 1
if times_quit == 10:
quit_button.disabled = true
quit_button.text = "This game is too\nSuper Epic Cool Awesome Stuff\nfor you to leave."
func _process(delta: float):
$BgSquare.rotation += square_rot * delta
var AVG_TIME_FOR_SEAGULL: float = 0.5
var should_seagull: bool = randf() < delta / AVG_TIME_FOR_SEAGULL
if should_seagull:
var s = seagull.instantiate()
$Seagulls.add_child(s)
func _on_credits_button_pressed() -> void:
credit_button.text = "Are you stupid?"
times_quit += 1
if times_quit == 3:
credit_button.disabled = true
credit_button.text = "Byte Dice"
+1
View File
@@ -0,0 +1 @@
uid://dpv5jt28axlpa
+35
View File
@@ -0,0 +1,35 @@
extends Node2D
var pig = preload("res://actors/pig.tscn")
var game_over = preload("res://ui/game_over.tscn")
@export var pig_amount: int
@onready var pigs_abducted: int = 0
@onready var pigs_saved: int = 0
func _ready():
get_tree().root.content_scale_mode = Window.CONTENT_SCALE_MODE_VIEWPORT
for _i in range(pig_amount):
var p = pig.instantiate()
p.global_position = Vector2(
randf_range($FarmTopLeft.global_position.x, $FarmBottomRight.global_position.x),
randf_range($FarmTopLeft.global_position.y, $FarmBottomRight.global_position.y)
)
self.add_child(p)
func _process(_delta: float):
if pigs_abducted > 0:
var g = game_over.instantiate()
g.saved_pigs = pigs_saved
var tree = get_tree()
tree.root.add_child(g)
var old_scene = tree.current_scene
tree.current_scene = g
old_scene.free()
+1
View File
@@ -0,0 +1 @@
uid://c8udxism1aby4
+174
View File
@@ -0,0 +1,174 @@
extends CharacterBody2D
enum States {
WALKING,
PANIC,
WAITING
}
@export var min_state_dur: float
@export var max_state_dur: float
@export var min_time_till_attack: float
@export var max_time_till_attack: float
@export var min_attack_duration: float
@export var max_attack_duration: float
@export var walk_speed: float
@export var panic_speed: float
@export var seagull_speed: float
@onready var is_attacked: bool = false # I shouldve made these an enum tbh
@onready var attack_approaching: bool = false
@onready var is_retreating: bool = false
@onready var walk_dir = Vector2.ZERO
@onready var is_flipped: bool = false
@onready var seagull_is_flipped: bool = false
@onready var seagull_dir = Vector2.ZERO
@onready var seagull_home_pos = Vector2.ZERO
@onready var received_biscuit: bool = false
var time_till_attacked: float
var time_till_abducted: float
var current_state: States
var state_duration: float
func _ready():
time_till_attacked = randf_range(min_time_till_attack, max_time_till_attack)
change_walk_dir()
new_state()
func _physics_process(delta: float):
if !is_attacked:
match current_state:
States.WALKING: act_walking(delta)
States.PANIC: act_walking(delta, true)
States.WAITING:
if !$PigAnimations.current_animation == "flip":
$PigAnimations.stop()
else:
if time_till_abducted > 0: act_walking(delta, true)
else: pass
attack_logic(delta)
if walk_dir.x < 0 && !is_flipped:
$PigAnimations.play("flip")
is_flipped = true
elif walk_dir.x > 0 && is_flipped:
$PigAnimations.play_backwards("flip")
is_flipped = false
state_duration -= delta
if time_till_attacked > 0: time_till_attacked -= delta
if state_duration <= 0.0: new_state()
func new_state():
state_duration = randf_range(min_state_dur, max_state_dur)
var next_state = randi_range(0, States.size() - 1)
if next_state == States.PANIC && randf() < 0.95:
next_state = States.WALKING if randi_range(0, 1) == 0 else States.WAITING
current_state = States.values()[next_state]
func act_walking(delta: float, panicked: bool = false):
var average_time_to_switch_dir: float = 2.0 if !panicked else 0.2
var should_switch_dir = randf() < delta / average_time_to_switch_dir
if should_switch_dir: change_walk_dir()
self.velocity = walk_dir * (walk_speed if !panicked else panic_speed)
self.move_and_slide()
if !$PigAnimations.current_animation == "flip":
$PigAnimations.play("walk")
func change_walk_dir():
walk_dir = Vector2(
randf_range(-1, 1),
randf_range(-1, 1)
).normalized()
func attack_logic(delta: float):
if time_till_attacked <= 0.0 && !(is_attacked || attack_approaching || is_retreating):
attack_approaching = true
seagull_home_pos = Vector2(
randf_range(-3000.0, 3000.0),
randf_range(-1920.0, -2500.0)
)
$Seagull.global_position = seagull_home_pos
$Seagull.visible = true
$Seagull.play("fly")
attack_approaching_logic(delta)
is_attacked_logic(delta)
retreating_logic(delta)
if seagull_dir.x < 0 && !seagull_is_flipped:
$SeagullAnimations.play("flip")
seagull_is_flipped = true
elif seagull_dir.x > 0 && seagull_is_flipped:
$SeagullAnimations.play_backwards("flip")
seagull_is_flipped = false
func attack_approaching_logic(delta: float):
if !attack_approaching: return
seagull_dir = ($PigSprite/SeagullAttackPos.global_position - $Seagull.global_position).normalized()
$Seagull.global_position += seagull_dir * seagull_speed * delta
var dist = $Seagull.global_position.distance_to($PigSprite/SeagullAttackPos.global_position)
if dist < 15.0:
$Seagull.global_position = $PigSprite/SeagullAttackPos.global_position
attack_approaching = false
is_attacked = true
$Seagull.play("attack")
if !$PigAnimations.current_animation == "flip": $PigAnimations.stop()
time_till_abducted = randf_range(min_attack_duration, max_attack_duration)
func is_attacked_logic(delta: float):
if !is_attacked: return
if time_till_abducted <= 0.0:
seagull_dir = (seagull_home_pos - $Seagull.global_position).normalized()
self.global_position += seagull_dir * seagull_speed * delta
$PigSprite.self_modulate.a = 0.5
$Collision.disabled = true
if self.global_position.y < -get_viewport_rect().size.y - 300.0:
get_tree().current_scene.pigs_abducted += 1
get_parent().remove_child(self)
if received_biscuit:
is_attacked = false
received_biscuit = false
is_retreating = true
get_tree().current_scene.pigs_saved += 1
time_till_abducted -= delta
func retreating_logic(delta: float):
if !is_retreating: return
seagull_dir = (seagull_home_pos - $Seagull.global_position).normalized()
$Seagull.global_position += seagull_dir * seagull_speed * delta
if $Seagull.global_position.y < -get_viewport_rect().size.y - 300.0:
is_retreating = false
$Seagull.global_position = seagull_home_pos
func _on_feed_zone_body_entered(body: Node2D):
if body is not CharacterBody2D: return
if body.name != "PlayerCharacter": return
if is_attacked && body.biscuit_count > 0 && time_till_abducted > 0.0:
received_biscuit = true
body.remove_biscuit()
+1
View File
@@ -0,0 +1 @@
uid://qtb3s2euymob
+160
View File
@@ -0,0 +1,160 @@
extends CharacterBody2D
var biscuit = preload("res://assets/sprites/biscuit.png")
@export_group("Movement")
@export var movement_type: LibCharMove.MovementType
@export_subgroup("Moving")
@export var speed: float
@export var sprint_speed: float
@export_subgroup("Jumping")
@export var jump_power: float
@export var extra_jumps: int
@export var coyote_time: float
@export var jump_buffer_timer: float
@export_subgroup("Dashing")
@export var dash_type: LibCharMove.DashType
@export var aerial_dash_count: int
@export var vel_multiplier_after_dash: float
@export var dash_speed: float
@export var dash_dur: float
@export var dash_cd: float
@export_subgroup("Physics")
@export var gravity: float
@export var terminal_vel: float
@export_group("Generic")
@export_subgroup("Health")
@export var max_health: float
@export var starting_health: float
@export var iframe_dur: float
@export_subgroup("Camera")
@export var camera_type: LibCharCam.CameraType
@export var camera_offset: Vector2
@export_group("Biscuit")
@export var max_biscuits: int
var character: LibChar.Char
var hud: Control
@onready var is_flipped: bool = false
@onready var biscuit_count: int = 0
func _ready():
floor_max_angle = deg_to_rad(40.0)
match movement_type:
LibCharMove.MovementType.PLATFORMER:
motion_mode = CharacterBody2D.MOTION_MODE_GROUNDED
LibCharMove.MovementType.TOP_DOWN:
motion_mode = CharacterBody2D.MOTION_MODE_FLOATING
# custom movement so we do this
motion_mode = CharacterBody2D.MOTION_MODE_GROUNDED
var char_movement = LibCharMove.CharMovement.new(
movement_type,
speed, sprint_speed,
jump_power, extra_jumps, coyote_time, jump_buffer_timer,
dash_type, aerial_dash_count, vel_multiplier_after_dash,
dash_speed, dash_dur, dash_cd,
gravity, terminal_vel
)
var char_camera = LibCharCam.CharCamera.new(
$Camera,
camera_type,
camera_offset,
Vector2.ZERO
)
character = LibChar.Char.new(
char_movement, char_camera,
max_health, starting_health, iframe_dur
)
character.movement.custom_movement_func = move_logic
character.camera.make_current()
character.camera.pos = $Camera.global_position
var mouse_pos: Vector2 = Vector2.ZERO
var look_dir: Vector2 = Vector2.ZERO
func _process(delta: float):
mouse_pos = get_viewport().get_mouse_position()
look_dir = (mouse_pos - self.global_position).normalized()
character.process(look_dir, mouse_pos, delta)
sequence_logic()
func _physics_process(delta: float):
character.phys_process(delta)
# move_and_slide() automatically computes delta :(
velocity = character.movement.velocity / delta
move_and_slide()
character.movement.is_grounded = is_on_floor()
func move_logic(delta: float):
var dir_vector = (mouse_pos - (get_viewport_rect().size / 2)) - self.global_position
character.movement.velocity = dir_vector * character.movement.speed * delta
if dir_vector.x < 0 && !is_flipped:
$AnimationPlayer.play("flip")
is_flipped = true
if dir_vector.x > 0 && is_flipped:
$AnimationPlayer.play_backwards("flip")
is_flipped = false
func sequence_logic():
var dir: int = -1
if Input.is_action_just_pressed("up"):
dir = $KeySequence.Directions.UP
elif Input.is_action_just_pressed("down"):
dir = $KeySequence.Directions.DOWN
elif Input.is_action_just_pressed("left"):
dir = $KeySequence.Directions.LEFT
elif Input.is_action_just_pressed("right"):
dir = $KeySequence.Directions.RIGHT
if dir != -1: $KeySequence.try_complete_next(dir)
func reset_biscuits():
for el in $Sprite/BiscuitPos.get_children():
$Sprite/BiscuitPos.remove_child(el)
func render_biscuits():
const BISCUIT_OFFSET = 5.0
reset_biscuits()
for i in range(biscuit_count):
var offset = BISCUIT_OFFSET
if i == 0: offset = 0
var b = Sprite2D.new()
b.texture = biscuit
b.position.y = -i * (biscuit.get_height() - offset)
$Sprite/BiscuitPos.add_child(b)
func try_add_biscuit() -> bool:
if biscuit_count >= max_biscuits: return false
biscuit_count += 1
render_biscuits()
return true
func remove_biscuit():
if biscuit_count <= 0: return
biscuit_count -= 1
render_biscuits()
+1
View File
@@ -0,0 +1 @@
uid://cknbo3ltp5mc3
+27
View File
@@ -0,0 +1,27 @@
extends AnimatedSprite2D
@export var speed: float
var dir: Vector2
@onready var pos = Vector2(
-100.0 if randi_range(0, 1) else get_viewport_rect().size.x,
randf_range(0, 1)
)
func _ready():
dir = Vector2(
randf_range(0, 1) * (-1 if pos.x > 0 else 1),
randf_range(-0.2, 0.2)
).normalized()
pos.y *= get_viewport_rect().size.y
self.global_position = pos
if dir.x < 0: self.flip_h = true
func _process(delta: float):
self.global_position += dir * speed * delta
self.play("default")
+1
View File
@@ -0,0 +1 @@
uid://dms2mkhl6pbyo