Adds in-game debug menu addon
Adds an in-game debug menu that displays performance metrics (FPS, frame times) and hardware/software information. The menu can be toggled using the F3 key (or a custom input binding). It has different display styles, ranging from a compact FPS display to a detailed view with graphs and system information.
This commit is contained in:
parent
214e0aa5e0
commit
ff62d67f54
37 changed files with 1484 additions and 49 deletions
|
|
@ -8,6 +8,6 @@ func _init():
|
|||
description = "Increases fire rate by %0.1f shots per second" % fire_rate_bonus
|
||||
modifier_type = ModifierType.ADDITIVE
|
||||
|
||||
func apply_stats_modification(final_stats: Dictionary, base_stats: Dictionary) -> void:
|
||||
func apply_stats_modification(final_stats: Dictionary, _base_stats: Dictionary) -> void:
|
||||
if final_stats.has("fire_rate"):
|
||||
final_stats.fire_rate += fire_rate_bonus
|
||||
|
|
@ -8,6 +8,6 @@ func _init():
|
|||
description = "Increases fire rate by %d%%" % ((fire_rate_multiplier - 1.0) * 100)
|
||||
modifier_type = ModifierType.MULTIPLICATIVE
|
||||
|
||||
func apply_stats_modification(final_stats: Dictionary, base_stats: Dictionary) -> void:
|
||||
func apply_stats_modification(final_stats: Dictionary, _base_stats: Dictionary) -> void:
|
||||
if final_stats.has("fire_rate"):
|
||||
final_stats.fire_rate *= fire_rate_multiplier
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=82 format=3 uid="uid://bo5aw2cad3akl"]
|
||||
[gd_scene load_steps=83 format=3 uid="uid://bo5aw2cad3akl"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bq038uo4cm6nv" path="res://player/scripts/player.gd" id="1_oul6g"]
|
||||
[ext_resource type="Texture2D" uid="uid://dqgq2c1h6yk3k" path="res://assets/sprites/characters/pink/Pink_Monster_Attack1_4.png" id="2_yllr7"]
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
[ext_resource type="Texture2D" uid="uid://538sc3bsdell" path="res://assets/sprites/characters/pink/Pink_Monster_Throw_4.png" id="11_bjvpn"]
|
||||
[ext_resource type="Texture2D" uid="uid://efnfh4mf0ia2" path="res://assets/sprites/characters/pink/Pink_Monster_Walk_6.png" id="12_s7qer"]
|
||||
[ext_resource type="Texture2D" uid="uid://cyfq0x0h2qeof" path="res://assets/sprites/characters/pink/Pink_Monster_Walk+Attack_6.png" id="13_g4c7l"]
|
||||
[ext_resource type="PackedScene" uid="uid://cgxn1f4p4vik6" path="res://assets/weapons/ranged_weapon.tscn" id="14_kb6p2"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_rkbax"]
|
||||
|
||||
|
|
@ -541,7 +542,7 @@ animations = [{
|
|||
"speed": 5.0
|
||||
}]
|
||||
|
||||
[node name="Player" type="CharacterBody2D"]
|
||||
[node name="Player" type="CharacterBody2D" groups=["friendly"]]
|
||||
collision_mask = 14
|
||||
script = ExtResource("1_oul6g")
|
||||
|
||||
|
|
@ -551,8 +552,11 @@ shape = SubResource("CircleShape2D_rkbax")
|
|||
|
||||
[node name="PlayerSprite" type="AnimatedSprite2D" parent="."]
|
||||
sprite_frames = SubResource("SpriteFrames_qjt2w")
|
||||
animation = &"attack_2"
|
||||
frame_progress = 0.752485
|
||||
animation = &"idle"
|
||||
autoplay = "idle"
|
||||
frame_progress = 0.749332
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
zoom = Vector2(2, 2)
|
||||
|
||||
[node name="RangedWeapon" parent="." instance=ExtResource("14_kb6p2")]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
extends CharacterBody2D
|
||||
|
||||
@export var speed = 200
|
||||
@export var weapon: RangedWeapon
|
||||
@export var special_ability: Ability
|
||||
@export var movement: PlayerMovement
|
||||
|
||||
var weapon: RangedWeapon
|
||||
|
||||
var movement: PlayerMovement
|
||||
var combat: PlayerCombat
|
||||
|
||||
# Last direction for idle state
|
||||
var last_direction = Vector2.DOWN
|
||||
|
|
@ -11,19 +14,16 @@ var last_direction = Vector2.DOWN
|
|||
@onready var animated_sprite = $PlayerSprite
|
||||
|
||||
func _ready():
|
||||
weapon = RangedWeapon.new()
|
||||
Log.pr("Weapon", weapon)
|
||||
weapon = $RangedWeapon
|
||||
combat = PlayerCombat.new()
|
||||
|
||||
# Initialize the movement resource with references
|
||||
if movement:
|
||||
movement.player = self
|
||||
movement.animated_sprite = animated_sprite
|
||||
movement.last_direction = Vector2.DOWN # Default direction
|
||||
else:
|
||||
# Create a new resource instance if none was assigned in the editor
|
||||
movement = PlayerMovement.new()
|
||||
movement.player = self
|
||||
movement.animated_sprite = animated_sprite
|
||||
movement = PlayerMovement.new()
|
||||
movement.player = self
|
||||
movement.animated_sprite = animated_sprite
|
||||
movement.speed = speed
|
||||
|
||||
combat.player = self
|
||||
combat.animated_sprite = animated_sprite
|
||||
|
||||
Log.pr("Adding projectile size additive modifier")
|
||||
weapon.add_modifier(ProjectileSizeAdditive.new())
|
||||
|
|
@ -37,11 +37,15 @@ func _ready():
|
|||
# Size is now 1.5 * 1.5 = 2.25
|
||||
|
||||
# Add another additive size modifier (+0.7 or 70% increase)
|
||||
Log.pr("Adding another projectile size additive modifier", 0.7)
|
||||
Log.pr("Adding another projectile size additive modifier", 2)
|
||||
var another_size_mod = ProjectileSizeAdditive.new()
|
||||
another_size_mod.size_increase = 0.7
|
||||
weapon.add_modifier(another_size_mod)
|
||||
Log.pr(weapon.stats.get_stat("projectile_size"))
|
||||
|
||||
weapon.add_modifier(FireRateAdditive.new())
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
movement.process(delta)
|
||||
combat.process(delta)
|
||||
|
|
|
|||
30
player/scripts/player_combat.gd
Normal file
30
player/scripts/player_combat.gd
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
extends Resource
|
||||
class_name PlayerCombat
|
||||
|
||||
var player: CharacterBody2D
|
||||
var animated_sprite: AnimatedSprite2D
|
||||
|
||||
func process(_delta):
|
||||
# Get mouse position in global coordinates
|
||||
var mouse_position = player.get_global_mouse_position()
|
||||
|
||||
# Get player position (assuming this script is attached to the player)
|
||||
var player_position = player.global_position
|
||||
|
||||
# Calculate direction vector from player to mouse
|
||||
var direction = mouse_position - player_position
|
||||
|
||||
# You can normalize this vector if you want a unit vector (length of 1)
|
||||
# This is useful if you only care about direction, not distance
|
||||
var normalized_direction = direction.normalized()
|
||||
|
||||
if Input.is_action_pressed("fire"):
|
||||
player.weapon.fire(normalized_direction)
|
||||
# Update animation
|
||||
#update_animation()
|
||||
|
||||
func update_animation():
|
||||
Log.pr(animated_sprite.animation)
|
||||
if animated_sprite.animation != "throw":
|
||||
Log.pr('Throwing animation!')
|
||||
animated_sprite.play("throw")
|
||||
1
player/scripts/player_combat.gd.uid
Normal file
1
player/scripts/player_combat.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cx4ugb3hbh8t1
|
||||
|
|
@ -4,7 +4,7 @@ class_name PlayerMovement
|
|||
|
||||
var player: CharacterBody2D
|
||||
var animated_sprite: AnimatedSprite2D
|
||||
var speed: float = 300.0
|
||||
var speed: float
|
||||
var last_direction: Vector2 = Vector2.ZERO
|
||||
|
||||
func process(_delta):
|
||||
|
|
@ -36,6 +36,9 @@ func process(_delta):
|
|||
|
||||
func update_animation(direction):
|
||||
var anim_name = "idle" # Default animation
|
||||
|
||||
if animated_sprite.animation == "throw":
|
||||
return # Don't change animation if throwing
|
||||
|
||||
if direction == Vector2.ZERO:
|
||||
# Character is idle
|
||||
|
|
|
|||
110
player/weapons/projectile.gd
Normal file
110
player/weapons/projectile.gd
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
class_name Projectile extends Area2D
|
||||
|
||||
signal on_hit(projectile, target)
|
||||
signal on_spawned(projectile)
|
||||
signal on_destroyed(projectile)
|
||||
|
||||
@export var speed: float = 500.0
|
||||
@export var damage: float = 10.0
|
||||
@export var lifetime: float = 5.0
|
||||
@export var direction: Vector2 = Vector2.RIGHT
|
||||
@export var is_friendly: bool = true
|
||||
|
||||
# Modifier-related properties
|
||||
var pierce_count: int = 0
|
||||
var has_explosive_impact: bool = true
|
||||
var explosion_projectile_count: int = 2
|
||||
var explosion_projectile_damage_mult: float = 0.5
|
||||
var explosion_projectile_speed: float = 300.0
|
||||
var explosion_spread_angle: float = 360.0 # Full circle by default
|
||||
# References
|
||||
var source_weapon: RangedWeapon # Reference to the weapon that fired this
|
||||
var lifetime_timer: Timer
|
||||
# Add a variable to track the entity that triggered the explosion
|
||||
var ignore_target = null
|
||||
|
||||
func _ready():
|
||||
lifetime_timer = Timer.new()
|
||||
add_child(lifetime_timer)
|
||||
lifetime_timer.one_shot = true
|
||||
lifetime_timer.wait_time = lifetime
|
||||
lifetime_timer.connect("timeout", _on_lifetime_timeout)
|
||||
lifetime_timer.start()
|
||||
|
||||
emit_signal("on_spawned", self)
|
||||
connect("body_entered", _on_body_entered)
|
||||
|
||||
func _physics_process(delta):
|
||||
position += direction * speed * delta
|
||||
|
||||
func _on_body_entered(body):
|
||||
# Check if this is a body we should ignore
|
||||
if body == ignore_target:
|
||||
return
|
||||
|
||||
if body.is_in_group("enemies") and is_friendly:
|
||||
Log.pr("Hit enemy: ", body.name)
|
||||
# Deal damage to enemy
|
||||
if body.has_method("take_damage"):
|
||||
body.take_damage(damage)
|
||||
|
||||
# Emit signal for modifiers to react to
|
||||
emit_signal("on_hit", self, body)
|
||||
|
||||
# Handle piercing
|
||||
if pierce_count > 0:
|
||||
pierce_count -= 1
|
||||
else:
|
||||
# Handle explosive impact
|
||||
if has_explosive_impact:
|
||||
# Store the target that triggered the explosion
|
||||
ignore_target = body
|
||||
_trigger_explosion()
|
||||
|
||||
# Destroy the projectile
|
||||
destroy()
|
||||
|
||||
func _trigger_explosion():
|
||||
# Create the explosion VFX
|
||||
# var explosion = preload("res://scenes/explosion_effect.tscn").instantiate()
|
||||
# explosion.global_position = global_position
|
||||
# get_tree().root.add_child(explosion)
|
||||
# Spawn the additional projectiles
|
||||
if explosion_projectile_count > 0:
|
||||
_spawn_explosion_projectiles()
|
||||
|
||||
func _spawn_explosion_projectiles():
|
||||
# Calculate even angle distribution
|
||||
var angle_step = explosion_spread_angle / explosion_projectile_count
|
||||
var start_angle = - explosion_spread_angle / 2
|
||||
|
||||
for i in range(explosion_projectile_count):
|
||||
# Create a new projectile
|
||||
var new_proj = duplicate()
|
||||
new_proj.global_position = global_position
|
||||
|
||||
# Calculate new direction based on spread
|
||||
var random_angle = randf_range(0, 2 * PI)
|
||||
var new_dir = Vector2.RIGHT.rotated(random_angle)
|
||||
|
||||
# Set properties for the new projectile
|
||||
new_proj.direction = new_dir
|
||||
new_proj.damage = damage * explosion_projectile_damage_mult
|
||||
new_proj.speed = explosion_projectile_speed
|
||||
|
||||
# Clear explosive properties so we don't get infinite loops
|
||||
new_proj.has_explosive_impact = true
|
||||
new_proj.explosion_projectile_count = 1
|
||||
|
||||
# Pass the ignore_target to the new projectiles
|
||||
new_proj.ignore_target = ignore_target
|
||||
|
||||
# Add to scene tree
|
||||
get_tree().root.add_child(new_proj)
|
||||
|
||||
func destroy():
|
||||
emit_signal("on_destroyed", self)
|
||||
queue_free()
|
||||
|
||||
func _on_lifetime_timeout():
|
||||
destroy()
|
||||
1
player/weapons/projectile.gd.uid
Normal file
1
player/weapons/projectile.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://d5tiwy16ivu6
|
||||
|
|
@ -7,10 +7,12 @@ signal projectile_spawned(projectile)
|
|||
# Base stats - will be modified by modifiers
|
||||
var base_stats = {
|
||||
"damage": 10.0,
|
||||
"fire_rate": 2.0, # Shots per second
|
||||
"fire_rate": 2.0,
|
||||
"projectile_speed": 500.0,
|
||||
"projectile_size": 1.0,
|
||||
"projectile_lifetime": 5.0,
|
||||
"projectile_quantity": 1,
|
||||
"projectile_spread": 33,
|
||||
"max_pierce": 0
|
||||
}
|
||||
|
||||
|
|
@ -24,14 +26,15 @@ func _init() -> void:
|
|||
Log.pr(stats)
|
||||
add_child(stats)
|
||||
|
||||
func _ready():
|
||||
# Connect to stats updated signal
|
||||
stats.connect("stats_updated", _on_stats_updated)
|
||||
|
||||
# Setup fire timer
|
||||
fire_timer = Timer.new()
|
||||
add_child(fire_timer)
|
||||
fire_timer.one_shot = true
|
||||
|
||||
projectile_scene = preload("res://assets/projectiles/basic_projectile.tscn")
|
||||
|
||||
func _ready():
|
||||
stats.connect("stats_updated", _on_stats_updated)
|
||||
fire_timer.connect("timeout", _on_fire_timer_timeout)
|
||||
|
||||
# Initial update
|
||||
|
|
@ -47,30 +50,55 @@ func fire(direction: Vector2):
|
|||
fire_timer.start(1.0 / stats.get_stat("fire_rate"))
|
||||
|
||||
func _spawn_projectile(spawn_position: Vector2, spawn_direction: Vector2):
|
||||
var projectile = projectile_scene.instantiate()
|
||||
projectile.global_position = spawn_position
|
||||
projectile.direction = spawn_direction
|
||||
# Get projectile quantity and spread from stats
|
||||
var quantity = stats.get_stat("projectile_quantity")
|
||||
var spread_angle = stats.get_stat("projectile_spread")
|
||||
|
||||
# Apply stats to projectile
|
||||
projectile.speed = stats.get_stat("projectile_speed")
|
||||
projectile.damage = stats.get_stat("damage")
|
||||
projectile.lifetime = stats.get_stat("projectile_lifetime")
|
||||
projectile.pierce_count = stats.get_stat("max_pierce")
|
||||
projectile.source_weapon = self
|
||||
# Calculate the angle between each projectile
|
||||
var angle_step = 0.0
|
||||
if quantity > 1 and spread_angle > 0:
|
||||
angle_step = spread_angle / (quantity - 1)
|
||||
|
||||
# Apply size (scale)
|
||||
var size = stats.get_stat("projectile_size")
|
||||
projectile.scale = Vector2(size, size)
|
||||
# Calculate starting angle (to center the spread)
|
||||
var start_angle = - spread_angle / 2
|
||||
|
||||
# Allow modifiers to directly modify the projectile
|
||||
for modifier in stats.modifiers:
|
||||
modifier.modify_projectile(projectile)
|
||||
|
||||
get_tree().root.add_child(projectile)
|
||||
projectile.emit_signal("on_spawned", projectile)
|
||||
emit_signal("projectile_spawned", projectile)
|
||||
# Spawn each projectile
|
||||
for i in range(quantity):
|
||||
var projectile = projectile_scene.instantiate()
|
||||
projectile.global_position = spawn_position
|
||||
|
||||
# Calculate the direction with spread
|
||||
var direction = spawn_direction
|
||||
if quantity > 1:
|
||||
var current_angle = start_angle + (i * angle_step)
|
||||
direction = spawn_direction.rotated(deg_to_rad(current_angle))
|
||||
|
||||
projectile.direction = direction
|
||||
|
||||
# Apply stats to projectile
|
||||
projectile.speed = stats.get_stat("projectile_speed")
|
||||
projectile.damage = stats.get_stat("damage")
|
||||
projectile.lifetime = stats.get_stat("projectile_lifetime")
|
||||
projectile.source_weapon = self
|
||||
|
||||
# Set base size
|
||||
var size = stats.get_stat("projectile_size")
|
||||
projectile.scale = Vector2(size, size)
|
||||
|
||||
# Allow modifiers to directly modify the projectile
|
||||
for modifier in stats.modifiers:
|
||||
modifier.modify_projectile(projectile)
|
||||
|
||||
# Add to scene tree
|
||||
if get_tree() and get_tree().get_root():
|
||||
get_tree().get_root().add_child(projectile)
|
||||
|
||||
# Emit the spawn signal
|
||||
if projectile.has_signal("on_spawned"):
|
||||
projectile.emit_signal("on_spawned", projectile)
|
||||
|
||||
func add_modifier(modifier: Modifier):
|
||||
Log.pr("Adding modifier: ", modifier)
|
||||
stats.add_modifier(modifier)
|
||||
|
||||
func remove_modifier(modifier_id: String):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue