added the game

This commit is contained in:
JHDev2006
2025-09-13 16:30:32 +01:00
parent 5ef689109b
commit 3773bdaf64
3616 changed files with 263702 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
@icon("res://Assets/Sprites/Editor/Block.png")
class_name Block
extends AnimatableBody2D
signal player_block_hit(player: Player)
signal shell_block_hit(shell: Shell)
@export var visuals: Node = null
const EMPTY_BLOCK = ("res://Scenes/Prefabs/Blocks/EmptyBlock.tscn")
@export var item: PackedScene = null
@export var destructable := true
@export var destruction_particle_scene: PackedScene = null
@export_range(1, 99) var item_amount := 1
@export var combo_meter_amount := 25
@export var mushroom_if_small := false
const SUPER_MUSHROOM = ("res://Scenes/Prefabs/Entities/Items/SuperMushroom.tscn")
var can_hit := true
var bouncing := false
const NO_SFX_ITEMS := ["res://Scenes/Prefabs/Entities/Items/SpinningRedCoin.tscn","res://Scenes/Prefabs/Entities/Items/SpinningCoin.tscn", "res://Scenes/Prefabs/Entities/Items/Vine.tscn" ]
@export var start_z := -1
signal block_emptied
signal block_destroyed
func _enter_tree() -> void:
z_index = start_z
sync_to_physics = false
if item != null:
if item.resource_path.contains(Global.current_level.scene_file_path):
Global.log_error("ITEM SCENE IS NULL! BLOCK NAME: " + str(name) + " PLEASE REPORT!")
func dispense_item() -> void:
if can_hit == false:
return
can_hit = false
await get_tree().create_timer(0.1, false).timeout
DiscoLevel.combo_meter += combo_meter_amount
var item_to_dispense = player_mushroom_check(get_tree().get_first_node_in_group("Players"))
var node = item_to_dispense.instantiate()
if node is PowerUpItem or node.has_meta("is_item"):
for i in get_tree().get_nodes_in_group("Players"):
node.position = position + Vector2(0, -1)
node.hide()
add_sibling(node)
if node is PowerUpItem:
if Global.connected_players > 1:
AudioManager.play_sfx("item_appear", global_position)
node.player_multiplayer_launch_spawn(i)
else:
node.block_dispense_tween()
else:
if item.resource_path == "res://Scenes/Prefabs/Entities/Items/SpinningRedCoin.tscn":
if has_meta("r_coin_id"):
node.id = get_meta("r_coin_id", 0)
var parent = get_parent()
node.global_position = global_position + Vector2(0, -8) + node.get_meta("block_spawn_offset", Vector2.ZERO)
if get_parent().get_parent() is TrackRider:
parent = get_parent().get_parent().get_parent()
parent.add_child(node)
parent.move_child(node, get_index() - 1)
print("FUCK: " + str(item.resource_path))
if NO_SFX_ITEMS.has(item.resource_path) == false:
AudioManager.play_sfx("item_appear", global_position)
node.set("velocity", Vector2(0, node.get_meta("block_launch_velocity", -150)))
can_hit = true
item_amount -= 1
if item_amount == 1:
if has_meta("red_coin") == true:
item = load("res://Scenes/Prefabs/Entities/Items/SpinningRedCoin.tscn")
if item_amount <= 0:
spawn_empty_block()
func player_mushroom_check(player: Player = null) -> PackedScene:
if player.power_state.hitbox_size == "Small" and mushroom_if_small:
return load(SUPER_MUSHROOM)
return item
func spawn_empty_block() -> void:
var block = load(EMPTY_BLOCK).instantiate()
block.position = position
add_sibling(block)
if get_parent().get_parent() is TrackRider:
get_parent().get_parent().attached_entity = block
block_emptied.emit()
queue_free()
func destroy() -> void:
block_destroyed.emit()
DiscoLevel.combo_meter += combo_meter_amount
AudioManager.play_sfx("block_break", global_position)
var particles = destruction_particle_scene.instantiate()
particles.global_position = global_position
add_sibling(particles)
queue_free()

View File

@@ -0,0 +1 @@
uid://b5ejlbl0vp1gm

View File

@@ -0,0 +1,43 @@
extends StaticBody2D
@export var active := false
@onready var start_active = not active
var player_in_area := false
var player_stuck := false
var awaiting_exit := false
@export var hurtbox: CollisionShape2D = null
func on_switch_hit() -> void:
player_stuck = false
active = not active
if player_in_area:
player_stuck = true
return
update()
func update() -> void:
if active:
$Sprite.play("On")
else:
$Sprite.play("Off")
$Collision.set_deferred("disabled", not active)
if hurtbox != null:
hurtbox.set_deferred("disabled", not active)
func damage_player(player: Player) -> void:
player.damage()
func on_player_entered(_player: Player) -> void:
player_in_area = true
func on_player_exited(_player: Player) -> void:
player_in_area = false
if player_stuck and active:
player_stuck = false
update()

View File

@@ -0,0 +1 @@
uid://be2x40pxmueyo

View File

@@ -0,0 +1,33 @@
extends Block
var active := false
static var has_hit := false
func _ready() -> void:
can_hit = true
has_hit = false
func on_block_hit() -> void:
if can_hit == false or has_hit:
return
has_hit = true
AudioManager.play_sfx("switch", global_position)
can_hit = false
get_tree().call_group("BooBlocks", "on_switch_hit")
await get_tree().create_timer(0.25, false).timeout
can_hit = true
has_hit = false
func on_switch_hit() -> void:
active = not active
if active:
$Sprite.play("On")
else:
$Sprite.play("Off")
func on_boo_hit() -> void:
if active:
return
AudioManager.play_global_sfx("switch")
get_tree().call_group("BooBlocks", "on_switch_hit")

View File

@@ -0,0 +1 @@
uid://bm72ggve5kda5

View File

@@ -0,0 +1,31 @@
class_name BrickBlock
extends Block
var ticking_down := false
func _ready() -> void:
$PSwitcher.enabled = item == null
if item_amount == 10 and item.resource_path == "res://Scenes/Prefabs/Entities/Items/SpinningCoin.tscn" and is_instance_valid(Global.level_editor) == false:
Global.log_warning("Coin Brick Block is wrong! please report!: " + name)
func on_block_hit(player: Player) -> void:
if player.power_state.hitbox_size == "Big":
if item == null:
await get_tree().physics_frame
destroy()
Global.score += 50
if item != null:
if mushroom_if_small:
item = player_mushroom_check(player)
dispense_item()
func on_shell_block_hit(_shell: Shell) -> void:
if item == null:
await get_tree().physics_frame
destroy()
Global.score += 50
else:
dispense_item()
func set_coin_count() -> void:
item_amount = 2

View File

@@ -0,0 +1 @@
uid://y53avulrmfx1

View File

@@ -0,0 +1,37 @@
extends StaticBody2D
var falling := false
var can_fall := false
const FALL_SPEED := 96
@onready var starting_position := global_position
func _physics_process(delta: float) -> void:
if falling:
global_position.y += FALL_SPEED * delta
if $PlayerDetection.is_player_in_area():
$Sprite.play("Fall")
elif not falling:
$Sprite.play("Idle")
func start_falling() -> void:
falling = true
$Collision.set_deferred("one_way_collision", true)
$FallTimer.start()
func respawn() -> void:
$Collision.set_deferred("one_way_collision", false)
can_fall = true
falling = false
global_position = starting_position
$AnimationPlayer.play("Grow")
func on_player_entered() -> void:
$AnimationPlayer.play("Shake")
func on_player_exited() -> void:
$AnimationPlayer.play("RESET")

View File

@@ -0,0 +1 @@
uid://dbu4juvw4veul

View File

@@ -0,0 +1,11 @@
extends StaticBody2D
func on_player_entered(_player: Player) -> void:
$Sprite.play("Turn")
await get_tree().physics_frame
$Collision.set_deferred("disabled", true)
func on_player_exited(_player: Player) -> void:
$Sprite.play("Idle")
$Collision.set_deferred("disabled", false)

View File

@@ -0,0 +1 @@
uid://cn8jml0dmf128

View File

@@ -0,0 +1,10 @@
extends Block
func on_area_entered(area: Area2D) -> void:
if area.owner is Player:
var player: Player = area.owner
if player.velocity.y < 0 and player.global_position.y > $Hitbox.global_position.y and abs(player.global_position.x - global_position.x) < 8:
player_block_hit.emit(area.owner)
player.velocity.y = 0
player.bump_ceiling()
$Collision.set_deferred("disabled", false)

View File

@@ -0,0 +1 @@
uid://s5e3ps0g7nya

View File

@@ -0,0 +1,55 @@
extends NoteBlock
const INTRUMENT_SFX := [preload("uid://dia0bsspwrqsn"), preload("uid://d2elbhakm1yfq"), preload("uid://vxox7t6qvyvu"), preload("uid://w44jys81bxjj"), preload("uid://b2lj4akov8ami"), preload("uid://c03nay4r4a2lm"), preload("uid://d0pdbnpfcm80i"), preload("uid://dodww1no4v6qh")]
var pitch := 0.0
var sfx_stream = null
static var can_play := false
@export var play_on_load := false
@export_enum("Bass", "Flute", "Marimba", "Piano", "Rhodes", "Steel", "Trumpet", "Violin") var instrument := 0:
set(value):
sfx_stream = INTRUMENT_SFX[value]
instrument = value
play_sfx_preview()
@export_enum("A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#") var note := 3:
set(value):
note = value
pitch = get_pitch_scale()
play_sfx_preview()
@export_range(1, 5) var octave := 2:
set(value):
octave = value
pitch = get_pitch_scale()
play_sfx_preview()
func _ready() -> void:
await get_tree().create_timer(0.1, true).timeout
can_play = true
func _exit_tree() -> void:
can_play = false
func get_pitch_scale() -> float:
var semitone_offset = (octave - 2) * 12 + (note - 3) # C4 is the base note (note index 3)
return 2.0 ** (semitone_offset / 12.0)
func _process(_delta: float) -> void:
%Note.frame = note
%Octave.frame = octave + 12
func play_sfx_preview() -> void:
if get_node_or_null("Instrument") != null and can_play:
print($Instrument.pitch_scale)
$Instrument.stream = sfx_stream
$Instrument.pitch_scale = pitch
$Instrument.play()
func on_screen_entered() -> void:
if play_on_load and LevelEditor.playing_level:
play_sfx_preview()

View File

@@ -0,0 +1 @@
uid://2gxl5hj6mf6a

View File

@@ -0,0 +1,70 @@
class_name NoteBlock
extends Block
var bodies: Array[CharacterBody2D] = []
signal bounced
var animating := false
@export var play_sfx := true
func bounce_up() -> void:
if bouncing or animating:
return
bounced.emit()
bouncing = true
animating = true
%Animations.play("BounceUp")
dispense_item(-1)
await %Animations.animation_finished
bouncing = false
animating = false
func _physics_process(_delta: float) -> void:
for i in %Area.get_overlapping_areas():
if i.owner is CharacterBody2D:
bounce_down(i.owner)
func bounce_down(body: PhysicsBody2D) -> void:
if bouncing or animating:
return
animating = true
bounced.emit()
if play_sfx:
AudioManager.play_sfx("note_block", global_position)
bodies.append(body)
if body is Player:
body.normal_state.jump_queued = false
body.spring_bouncing = true
%Animations.play("BounceDown")
dispense_item(1)
await %Animations.animation_finished
animating = false
bouncing = false
func bounce_bodies() -> void:
for i in bodies:
if i is Player:
i.spring_bouncing = false
if Global.player_action_pressed("jump", i.player_id):
i.jump_cancelled = false
i.has_jumped = true
i.velocity.y = -350
i.gravity = i.JUMP_GRAVITY
else:
i.velocity.y = -300
i.gravity = i.FALL_GRAVITY
else:
i.velocity.y = -200
if i is Thwomp:
i.velocity = Vector2.ZERO
bodies.clear()
func dispense_item(direction := -1) -> void:
if item == null or item_amount <= 0:
return
item_amount -= 1
var node = item.instantiate()
node.global_position = global_position + Vector2(0, 8 * direction)
node.set("velocity", Vector2(0, (100 if direction == 1 else -150)))
add_sibling(node)
AudioManager.play_sfx("item_appear", global_position)

View File

@@ -0,0 +1 @@
uid://c0diue1hemrxq

View File

@@ -0,0 +1,22 @@
extends Node2D
const TURN_BLOCK = ("uid://bn651dli8j2rj")
var can_turn_back := false
func _ready() -> void:
$Sprite.frame = 1
func _physics_process(_delta: float) -> void:
if can_turn_back:
if $PlayerDetectionArea.get_overlapping_areas().any(func(area: Area2D) -> bool: return area.owner is Player) == false:
spawn_block()
can_turn_back = false
func on_timeout() -> void:
can_turn_back = true
func spawn_block() -> void:
var block = load(TURN_BLOCK).instantiate()
block.position = position
add_sibling(block)
queue_free()

View File

@@ -0,0 +1 @@
uid://7evxxqgv6e3j

View File

@@ -0,0 +1,16 @@
extends StaticBody2D
@export var is_super := false
func on_player_entered(player: Player) -> void:
player.enemy_bounce_off(false)
play_animation()
AudioManager.play_sfx("spring", global_position)
if is_super:
await get_tree().physics_frame
player.velocity.y *= 1.5
func play_animation() -> void:
$Sprite.play("Bounce")
await $Sprite.animation_finished
$Sprite.play("Idle")

View File

@@ -0,0 +1 @@
uid://cdlufmypvdtun

View File

@@ -0,0 +1,53 @@
class_name TimedBooBlock
extends Block
var time := 3
var active := false
static var main_block = null
static var can_tick := true:
set(value):
can_tick = value
func _ready() -> void:
main_block = self
$Timer.start()
func on_timeout() -> void:
if can_tick == false or BooRaceHandler.countdown_active: return
time = clamp(time - 1, 0, 3)
if main_block == self:
if time <= 0:
get_tree().call_group("BooBlocks", "on_switch_hit")
elif time < 3:
AudioManager.play_global_sfx("timer_beep")
if active:
$Sprite.play("On" + str(time))
else:
$Sprite.play("Off" + str(time))
func block_hit() -> void:
if not can_hit:
return
can_hit = false
get_tree().call_group("BooBlocks", "on_switch_hit")
await get_tree().create_timer(0.25, false).timeout
can_hit = true
func _exit_tree() -> void:
can_tick = true
func on_switch_hit() -> void:
AudioManager.play_global_sfx("switch")
$Timer.stop()
time = 4
active = not active
if active:
$Sprite.play("BlueToRed")
else:
$Sprite.play("RedToBlue")
await $Sprite.animation_finished
$Timer.start()
time = 4
on_timeout()

View File

@@ -0,0 +1 @@
uid://du5hnwdhv7x66

View File

@@ -0,0 +1,22 @@
extends Block
const SPINNING_TURN_BLOCK = preload("uid://b8dalotrk2oci")
func on_block_hit(player: Player) -> void:
if item != null:
if mushroom_if_small:
item = player_mushroom_check(player)
dispense_item()
else:
spin()
func on_shell_block_hit(_shell: Shell) -> void:
if item != null:
dispense_item()
else:
spin()
func spin() -> void:
await get_tree().create_timer(0.15, false).timeout
var spinning = SPINNING_TURN_BLOCK.instantiate()
spinning.position = position
add_sibling(spinning)
queue_free()

View File

@@ -0,0 +1 @@
uid://dm44kedpj4m80