The code probably sucks but here it is:
extends CharacterBody3D
var speed = 0.0
var angle = 0.0
var direction = Vector3.ZERO
var tagged = -1
var buffered_speed = 0.0
@onready var stall_detect = $StallDetect
var hit_sounds = { # did this instead of load(), no difference. :(
"small": {
"new": [
preload("res://sound/althitsmall1.mp3"),
preload("res://sound/althitsmall2.mp3"),
preload("res://sound/althitsmall3.mp3"),
preload("res://sound/althitsmall4.mp3")
],
"old": [
preload("res://sound/hitsmall1.mp3"),
preload("res://sound/hitsmall2.mp3"),
preload("res://sound/hitsmall3.mp3"),
preload("res://sound/hitsmall4.mp3")
]
},
"mid": {
"new": [
preload("res://sound/althitmid1.mp3"),
preload("res://sound/althitmid2.mp3"),
preload("res://sound/althitmid3.mp3"),
preload("res://sound/althitmid4.mp3")
],
"old": [
preload("res://sound/hitmid1.mp3"),
preload("res://sound/hitmid2.mp3"),
preload("res://sound/hitmid3.mp3"),
preload("res://sound/hitmid4.mp3")
]
},
"large": {
"new": [
preload("res://sound/althitlarge1.mp3"),
preload("res://sound/althitlarge2.mp3"),
preload("res://sound/althitlarge3.mp3"),
preload("res://sound/althitlarge4.mp3")
],
"old": [
preload("res://sound/hitlarge1.mp3"),
preload("res://sound/hitlarge2.mp3"),
preload("res://sound/hitlarge3.mp3"),
preload("res://sound/hitlarge4.mp3")
]
},
"ultra": {
"new": [
preload("res://sound/althitultra1.mp3"),
preload("res://sound/althitultra2.mp3"),
preload("res://sound/althitultra3.mp3"),
preload("res://sound/althitultra4.mp3")
],
"old": [
preload("res://sound/hitultra1.mp3"),
preload("res://sound/hitultra2.mp3"),
preload("res://sound/hitultra3.mp3"),
preload("res://sound/hitultra4.mp3")
]
}
}
var last_hit_by = -1
signal goal(player)
func _ready():
set_direction_from_angle(angle)
self.show()
$CollisionShape3D.set_deferred("disabled", false)
$Collision/CollisionShape3D.set_deferred("disabled", false)
var ticks = 5
func _physics_process(delta):
if $Collision/CollisionShape3D.disabled:
$StallDetect/CollisionShape3D.set_deferred("disabled", true)
else:
$StallDetect/CollisionShape3D.set_deferred("disabled", false)
if speed > 5:
if ticks > 0:
ticks -= 1
if ticks <= 0:
if Global.decay and !Global.cooldown:
speed *= Global.decay_rate
ticks = 5
if speed <= 5:
if speed != 0:
speed = 5
velocity = direction * speed
move_and_slide()
check_wall_collisions()
if tagged != last_tag:
update_ball_tag()
last_tag = tagged
$Label3D.text = str(tagged)
if Global.debug:
if Input.is_action_just_pressed("debug"):
Global.players[0].sp = 100 # fill p1's sp meter :D :D :D
func set_direction_from_angle(angle_degrees):
var angle_radians = deg_to_rad(angle_degrees)
direction.x = cos(angle_radians)
direction.z = -sin(angle_radians)
func check_wall_collisions():
for i in range(get_slide_collision_count()):
var collision = get_slide_collision(i)
if collision:
var normal = collision.get_normal()
$wall.pitch_scale = 0.9 + randf() * 0.2
$wall.play()
if abs(normal.x) > abs(normal.z):
direction.x = -direction.x
else:
direction.z = -direction.z
break
var p1_hit = false
var p2_hit = false
func _on_collision_area_entered(area):
if area.name == "PARRY" and speed > 0 and area.attacker != tagged:
$parried.pitch_scale = 0.9 + randf() * 0.2
$parried.play()
set_direction_from_angle(0)
speed = 0
tagged = -1
$parryrandtimer.start()
Global.players[area.attacker].parry_cancel = true
position.x = Global.players[area.attacker].position.x
if area.attacker == 0:
position.x += 1
else:
position.x -= 1
position.z = Global.players[area.attacker].position.z
if area.name != "WallArea" and !area.name.begins_with("Goal") and !area.name == "hurtbox" and area.name != "PARRY":
if area.attacker == 0 and !p1_hit or area.attacker == 1 and !p2_hit:
print(area.name)
print(area.attacker)
if Global.tagging:
tagged = area.attacker
# increase attacker's sp
if Global.players[area.attacker].sp != 100:
if area.name == "ATK":
Global.players[area.attacker].sp += 2
elif area.name == "DATK":
Global.players[area.attacker].sp += 4
elif area.name == "TAUNT":
Global.players[area.attacker].sp += 1
$hit.stream = hit_sounds[area.sound][Global.sfx_type][randi_range(0,3)] # get and play random hit sound from preloaded assets
if Global.sfx_type == "alt": # adjust volume for alt sounds so you don't go deaf
$hit.volume_db = 5
else:
$hit.volume_db = 10
$hit.pitch_scale = 0.9 + randf() * 0.2
$hit.play()
set_direction_from_angle(area.angle)
if Global.old_speed:
speed = area.power
print("old speed")
else:
speed += area.power
print("no old speed")
if area.attacker == 0:
p1_hit = true
else:
p2_hit = true
elif area.name.begins_with("Goal"):
speed = 0
angle = 0
kill_ball()
if area.name == "GoalLeft":
Global.scores[1] += 1
emit_signal("goal", 1)
elif area.name == "GoalRight":
Global.scores[0] += 1
emit_signal("goal", 0)
func _on_collision_area_exited(area):
if area.name != "WallArea" and !area.name.begins_with("Goal") and area.name != "hurtbox" and area.name != "PARRY":
if area.attacker == 0:
p1_hit = false
else:
p2_hit = false
func kill_ball():
self.hide()
$CollisionShape3D.set_deferred("disabled", true)
$Collision/CollisionShape3D.set_deferred("disabled", true)
func reset():
self.show()
$CollisionShape3D.set_deferred("disabled", false)
$Collision/CollisionShape3D.set_deferred("disabled", false)
func _on_parryrandtimer_timeout():
if tagged == -1:
$whee.play()
set_direction_from_angle(randi_range(0,360))
speed = 5
else:
print("ball tagged, no punish here")
var last_tag = -1
func update_ball_tag():
if tagged == -1:
$mesh.mesh.surface_get_material(0).set_shader_parameter("base_color", Color.html("ffffff"))
elif tagged == 0:
$mesh.mesh.surface_get_material(0).set_shader_parameter("base_color", Color.html("ff0000"))
elif tagged == 1:
$mesh.mesh.surface_get_material(0).set_shader_parameter("base_color", Color.html("0051ff"))
I disabled the stall timer and the player hit mechanic as it seemed to happen a ton when those were in play. Same thing kind of happens though, plus tabbing in and out?? That shouldn’t increase memory use, right? This only happens to this extreme degree when the game is maximised. Here’s another video showing more memory issues: