Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • s476696/pulsgamejam2025
1 result
Show changes
Commits on Source (2)
extends CharacterBody2D
@export var center: Vector2 = Vector2(550, 370) # The point to circle around
@export var radius: float = 300.0 # Distance from the center
@export var speed: float = 0.5 # Speed of rotation (radians per second)
@export var dash_speed: float = 0.1 # Speed of the dash
@export var return_speed: float = 0.02 #Speed of returning to the circle
@export var center: Vector2 = Vector2(550, 370) # Center of the orbit
@export var radius: float = 300.0 # Orbit radius
@export var orbit_speed: float = 0.5 # Angular speed (radians per second)
@export var dash_speed: float = 600.0 # Dash speed in pixels per second
@export var return_speed: float = 200.0 # Return speed in pixels per second
var angle: float = 0.0 # Current angle of rotation
var dashing: bool = false
var dash_target: Vector2
var returning: bool = false
var return_target: Vector2
var angle: float = 0.0 # Current orbit angle
var start_pos:Vector2
# --- STATE FLAGS ---
var dashing: bool = false # Currently dashing toward a penguin?
var returning: bool = false # Returning back to orbit?
var charging: bool = false # In charge/lock-on phase
# --- DASH VARIABLES ---
var dash_target: Vector2 # Final dash destination (locked penguin position)
var start_pos: Vector2 # Position at dash start
var return_target: Vector2 # Target point on orbit for returning
# --- LOCK/CHARGE VARIABLES ---
var lock_target_pos: Vector2 = Vector2.ZERO # The locked penguin’s global position
var lock_direction: Vector2 = Vector2.ZERO # Unit vector from orca to penguin
var lock_elapsed: float = 0.0 # Elapsed time during charging (2 sec)
var charge_target: Vector2 = Vector2.ZERO # Position on the orbit aligned with the penguin
var target_penguin: Penguin
var target_rotation: float = 0.0 # Rotation the orca must have to face the penguin
func _ready() -> void:
$OrcaTimer.start(2)
# Start in orbit; after 8 seconds we’ll try to lock on.
$LockTimer.start(8)
func _process(delta):
if dashing:
global_position = global_position.lerp(dash_target, dash_speed)
rotation = (dash_target - global_position).angle() + 90 # Rotate towards dash direction
# --- DASHING STATE ---
# Smoothly move toward the dash target.
global_position = global_position.move_toward(dash_target, dash_speed * delta)
var target_rot = (dash_target - global_position).angle() + deg_to_rad(90)
rotation = lerp_angle(rotation, target_rot, delta * 5)
if global_position.distance_to(dash_target) < 10.0:
slice_floes(start_pos, dash_target)
# On reaching the target, slice one ice floe using a unit line:
var slice_start = self.global_position
var slice_end = dash_target
slice_floes(slice_start, slice_end)
dashing = false
returning = true
return_target = find_closest_point_on_radius()
elif returning:
# --- RETURNING STATE ---
# Smoothly return to the orbit.
global_position = global_position.move_toward(return_target, return_speed * delta)
var target_rot = (return_target - global_position).angle() + deg_to_rad(90)
rotation = lerp_angle(rotation, target_rot, delta * 5)
if global_position.distance_to(return_target) < 10.0:
returning = false
$LockTimer.start(8)
elif charging:
# --- CHARGING (LOCK-ON) STATE ---
# Stop movement while charging by not updating global_position.
# Instead, you can still update the rotation if desired.
rotation = lerp_angle(rotation, target_rotation, delta * 5)
# Animate the dash line (a TextureRect child called "DashLine")
lock_elapsed += delta
# Over 2 seconds, scale the y–size from 0 to 1000
var t = clamp(lock_elapsed / 2.0, 0, 1)
$DashLine.size.y = t * 1000
if lock_elapsed >= 2.0:
# Just before dashing, reset the dash line (y size to 0), then dash.
$DashLine.size.y = 0
charging = false
dash(lock_target_pos)
else:
# Handle return to the circle if needed
if returning:
global_position = global_position.lerp(return_target, return_speed)
rotation = (return_target - global_position).angle() + 90 # Rotate towards return direction
# If close enough to the return target, stop returning and resume orbit
if global_position.distance_to(return_target) < 10.0:
returning = false
$OrcaTimer.start(8)
# Otherwise continue with normal circular movement
if not returning:
angle += speed * delta # Update the angle
var new_position = center + Vector2(cos(angle), sin(angle)) * radius
global_position = new_position
rotation = angle + deg_to_rad(180) # Adjust rotation to move in the orbit
# --- NORMAL ORBITING STATE ---
angle += orbit_speed * delta
var new_position = center + Vector2(cos(angle), sin(angle)) * radius
# Use linear interpolation for smooth movement.
global_position = global_position.lerp(new_position, 0.1)
var target_rot = angle + deg_to_rad(180)
rotation = lerp_angle(rotation, target_rot, delta * 5)
func dash(target: Vector2):
start_pos=position
dashing = true
# Called to initiate the dash. The target is the locked penguin’s position.
func dash(target: Vector2) -> void:
start_pos = global_position
dash_target = target
# Rotate towards dash direction
dashing = true
# Make sure the dash line is hidden.
$DashLine.size.y = 0
print("dash initiated")
# Finds the closest point on the orbit (used when returning).
func find_closest_point_on_radius() -> Vector2:
angle = (global_position - center).angle()
return center + Vector2(cos(angle), sin(angle)) * radius
var current_angle = (global_position - center).angle()
return center + Vector2(cos(current_angle), sin(current_angle)) * radius
# This timer callback starts the lock-on phase.
func _on_LockTimer_timeout() -> void:
# Get a random penguin from Globals.pengu_group.
var pengu_group: Node2D = Globals.pengu_group
var penguins = pengu_group.penguins
if penguins.is_empty():
return
var random_index: int = randi() % penguins.size()
while not is_instance_valid(penguins[random_index]) or penguins[random_index].is_queued_for_deletion():
random_index = randi() % penguins.size()
var p = penguins[random_index]
self.target_penguin = p
# Lock onto the selected penguin.
lock_target_pos = p.global_position
lock_direction = (lock_target_pos - global_position).normalized()
# Begin the 2–second charging phase.
charging = true
lock_elapsed = 0.0
# Compute the charge target: the point on the orbit directly aligned with the penguin.
var target_angle = (lock_target_pos - center).angle()
charge_target = center + Vector2(cos(target_angle), sin(target_angle)) * radius
# Set the target rotation so the orca faces the penguin.
target_rotation = (lock_target_pos - global_position).angle() + deg_to_rad(90)
func _on_orca_timer_timeout() -> void:
var Scholle: Node2D = $SchollenSpektakel
var Pengu:Node2D= Scholle.get_node("PenguGroup")
var PenguLength= Pengu.penguins.size
var randomPengu:Node2D= Pengu.penguins[randi_range(0,PenguLength)]
dash(to_global(randomPengu.position))
func slice_floes(splice_start: Vector2, splice_end: Vector2) -> void:
var Scholle: Node2D = $SchollenSpektakel
for child in Scholle.get_children():
if child is IceFloe:
if child.will_line_cut_polygon(splice_start, splice_end):
var poly_node: Polygon2D = child.get_node("Polygon2D")
child.splice_with_line(splice_start, splice_end)
# Slices the first ice floe that the given unit–length line (with one end at the penguin) cuts.
func slice_floes(slice_start: Vector2, slice_end: Vector2) -> void:
for child in Globals.ice_floes:
if child == target_penguin.get_parent(): # Only cut the slice with the target
if child.will_line_cut_polygon(slice_start, slice_end):
child.splice_with_line(slice_start, slice_end)
break
pulsjam2025/NPC/orca/orca.png

139 KiB | W: 0px | H: 0px

pulsjam2025/NPC/orca/orca.png

50.6 KiB | W: 0px | H: 0px

pulsjam2025/NPC/orca/orca.png
pulsjam2025/NPC/orca/orca.png
pulsjam2025/NPC/orca/orca.png
pulsjam2025/NPC/orca/orca.png
  • 2-up
  • Swipe
  • Onion skin
[gd_scene load_steps=3 format=3 uid="uid://k0xsan4kntww"]
[gd_scene load_steps=7 format=3 uid="uid://k0xsan4kntww"]
[ext_resource type="Script" uid="uid://vgm02fxo6pe3" path="res://NPC/orca/orca.gd" id="1_jmt3e"]
[ext_resource type="Texture2D" uid="uid://dqmo5ufusgf76" path="res://NPC/orca/orcaShadow.png" id="2_jmt3e"]
[ext_resource type="Texture2D" uid="uid://d3caevtq02wc3" path="res://NPC/orca/orca.png" id="2_jmt3e"]
[ext_resource type="Texture2D" uid="uid://ct80ox3ffphif" path="res://icon.svg" id="3_113yi"]
[sub_resource type="Animation" id="Animation_113yi"]
resource_name = "blink"
length = 0.2
loop_mode = 1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 1,
"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 0.375), Color(1, 1, 1, 1)]
}
[sub_resource type="Animation" id="Animation_1gx0u"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(1, 1, 1, 1)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_f5vvu"]
_data = {
&"RESET": SubResource("Animation_1gx0u"),
&"blink": SubResource("Animation_113yi")
}
[node name="Orca" type="CharacterBody2D"]
modulate = Color(1, 1, 1, 0.435294)
z_index = 2
script = ExtResource("1_jmt3e")
[node name="Sprite2D" type="Sprite2D" parent="."]
scale = Vector2(0.22, 0.22)
texture = ExtResource("2_jmt3e")
[node name="OrcaTimer" type="Timer" parent="."]
one_shot = true
[node name="LockTimer" type="Timer" parent="."]
[node name="DashLine" type="TextureRect" parent="."]
unique_name_in_owner = true
self_modulate = Color(100, 0.053, 0.029, 1)
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -2.70492
offset_top = -117.674
offset_right = 3.50508
offset_bottom = -117.674
grow_horizontal = 2
grow_vertical = 0
rotation = 3.14159
pivot_offset = Vector2(2.82829, -0.133759)
texture = ExtResource("3_113yi")
expand_mode = 1
stretch_mode = 1
[node name="AnimationPlayer" type="AnimationPlayer" parent="DashLine"]
libraries = {
&"": SubResource("AnimationLibrary_f5vvu")
}
autoplay = "blink"
[connection signal="timeout" from="OrcaTimer" to="." method="_on_orca_timer_timeout"]
[connection signal="timeout" from="LockTimer" to="." method="_on_LockTimer_timeout"]
[gd_scene load_steps=7 format=3 uid="uid://k0xsan4kntww"]
[ext_resource type="Script" uid="uid://vgm02fxo6pe3" path="res://NPC/orca/orca.gd" id="1_jmt3e"]
[ext_resource type="Texture2D" uid="uid://d3caevtq02wc3" path="res://NPC/orca/orca.png" id="2_jmt3e"]
[ext_resource type="Texture2D" uid="uid://ct80ox3ffphif" path="res://icon.svg" id="3_113yi"]
[sub_resource type="Animation" id="Animation_113yi"]
resource_name = "blink"
length = 0.2
loop_mode = 1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 1,
"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 0.375), Color(1, 1, 1, 1)]
}
[sub_resource type="Animation" id="Animation_1gx0u"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(1, 1, 1, 1)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_f5vvu"]
_data = {
&"RESET": SubResource("Animation_1gx0u"),
&"blink": SubResource("Animation_113yi")
}
[node name="Orca" type="CharacterBody2D"]
modulate = Color(1, 1, 1, 0.435294)
z_index = 2
script = ExtResource("1_jmt3e")
[node name="Sprite2D" type="Sprite2D" parent="."]
scale = Vector2(0.22, 0.22)
texture = ExtResource("2_jmt3e")
[node name="LockTimer" type="Timer" parent="."]
one_shot = true
[node name="DashLine" type="TextureRect" parent="."]
unique_name_in_owner = true
self_modulate = Color(100, 0.053, 0.029, 1)
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -2.70492
offset_top = -117.674
offset_right = 3.50508
offset_bottom = -117.674
grow_horizontal = 2
grow_vertical = 0
rotation = 3.14159
pivot_offset = Vector2(2.82829, -0.133759)
texture = ExtResource("3_113yi")
expand_mode = 1
stretch_mode = 1
[node name="AnimationPlayer" type="AnimationPlayer" parent="DashLine"]
libraries = {
&"": SubResource("AnimationLibrary_f5vvu")
}
autoplay = "blink"
[connection signal="timeout" from="LockTimer" to="." method="_on_LockTimer_timeout"]
......@@ -317,7 +317,7 @@ _data = {
}
[node name="Penguin" type="Node2D"]
z_index = 1
z_index = 3
scale = Vector2(0.5, 0.5)
script = ExtResource("1_ru475")
......
......@@ -300,7 +300,7 @@ _data = {
}
[node name="PlayerScene" type="CharacterBody2D" node_paths=PackedStringArray("area2D")]
z_index = 3
z_index = 4
collision_layer = 8
collision_mask = 8
script = ExtResource("1_ihrqt")
......
......@@ -16,4 +16,4 @@ position = Vector2(-17, 66)
position = Vector2(502, 306)
[node name="Orca" parent="." instance=ExtResource("3_ixcwh")]
position = Vector2(-17, 66)
position = Vector2(-9, 25)
......@@ -41,7 +41,6 @@ func check_for_drown(poly):
if polygon_area(poly) < min_area:
$AnimationPlayer.play("drown")
await get_tree().create_timer(0.3).timeout
print(get_children())
for child in get_children():
if child is Penguin:
Globals.create_skull(child.global_position)
......