Reworked player controller

This commit is contained in:
2025-11-09 22:30:22 +03:00
parent 213a0d60ed
commit 22aaeab0aa
23 changed files with 181 additions and 158 deletions
@@ -1,34 +1,25 @@
class_name PlayerController
extends Node extends Node
@onready var ship := $Ship signal accelerate(direction: Vector2, delta: float)
signal shoot(weapon_index: int)
signal reload(weapon_index: int)
var position : Vector2:
set(value):
ship.position = value
get:
return ship.position
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
var input_direction := Input.get_vector("move_left", "move_right", "move_up", "move_down") var input_direction := Input.get_vector("move_left", "move_right", "move_up", "move_down")
ship.accelerate(input_direction, delta) accelerate.emit(input_direction, delta)
var weapons : Array[AbstractWeapon] = ship.weapons
var weapon_actions := { var weapon_actions := {
0: ["shoot_weapon_1", "reload_weapon_1"], 0: ["shoot_weapon_1", "reload_weapon_1"],
1: ["shoot_weapon_2", "reload_weapon_2"] 1: ["shoot_weapon_2", "reload_weapon_2"]
} }
for index : int in weapon_actions: for index : int in weapon_actions:
if index >= weapons.size(): break
if Input.is_action_pressed(weapon_actions[index][0]): if Input.is_action_pressed(weapon_actions[index][0]):
ship.shoot(weapons[index]) shoot.emit(index)
if Input.is_action_pressed(weapon_actions[index][1]): if Input.is_action_pressed(weapon_actions[index][1]):
ship.reload(weapons[index]) reload.emit(index)
func _on_ship_destroyed() -> void:
queue_free()
@@ -0,0 +1 @@
uid://dgevigih7owxd
+6
View File
@@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://dh1oj1w5wx4je"]
[ext_resource type="Script" uid="uid://dgevigih7owxd" path="res://game/controllers/player_controller.gd" id="1_cu3ev"]
[node name="PlayerController" type="Node"]
script = ExtResource("1_cu3ev")
-1
View File
@@ -1 +0,0 @@
uid://c2uf62j1im13p
-17
View File
@@ -1,17 +0,0 @@
[gd_scene load_steps=3 format=3 uid="uid://bkv8y6n7chu3f"]
[ext_resource type="Script" uid="uid://c2uf62j1im13p" path="res://game/entities/player.gd" id="1_3a8sv"]
[ext_resource type="PackedScene" uid="uid://jvyagshykmgb" path="res://game/entities/ship.tscn" id="2_ktqbp"]
[node name="Player" type="Node"]
script = ExtResource("1_3a8sv")
[node name="Ship" parent="." instance=ExtResource("2_ktqbp")]
collision_layer = 2
collision_mask = 21
size = Vector2(48, 32)
acceleration = 92
deceleration = 46
max_speed = 92
[connection signal="destroyed" from="Ship" to="." method="_on_ship_destroyed"]
-103
View File
@@ -1,103 +0,0 @@
extends CharacterBody2D
signal destroyed
@onready var sprite := $Sprite2D
@onready var collision := $CollisionShape2D
@export var size : Vector2:
set(value):
size = value
_update_texture_size()
_update_collision_shape()
get:
return size
@export_range(0, 250) var acceleration : int = 0
@export_range(0, 250) var deceleration : int = 0
@export_range(0, 250) var max_speed : int = 0
@onready var weapons : Array[AbstractWeapon]:
set(value):
pass
get:
return weapons
func _ready() -> void:
var texture := PlaceholderTexture2D.new()
sprite.texture = texture
_update_texture_size()
_update_collision_shape()
const GATLING = preload("res://game/entities/weapons/gatling/gatling.tscn")
const RAILGUN = preload("res://game/entities/weapons/railgun/railgun.tscn")
var weapons_by_offset := {
8: GATLING.instantiate(),
-8: RAILGUN.instantiate(),
}
for offset : int in weapons_by_offset:
var weapon : Node2D = weapons_by_offset[offset]
weapon.position = Vector2(0, offset)
add_child(weapon)
weapons.append(weapon)
func _physics_process(_delta: float) -> void:
var was_collided := move_and_slide()
if was_collided:
var normal := get_wall_normal()
velocity -= normal.abs() * velocity
func accelerate(direction: Vector2, delta: float) -> void:
var accel : Vector2 = direction * acceleration * delta
var decel : float = deceleration * delta
velocity.x = _get_new_speed(accel.x, decel, velocity.x)
velocity.y = _get_new_speed(accel.y, decel, velocity.y)
if velocity.length() > max_speed:
velocity = velocity.normalized() * max_speed
func _get_new_speed(accel: float, decel: float, current_speed: float) -> float:
if is_zero_approx(accel):
if absf(current_speed) < decel:
return 0.0
return current_speed + (decel if current_speed < 0 else -decel)
else:
return current_speed + accel
func shoot(weapon: Node) -> void:
if weapon in weapons:
weapon.shoot(velocity)
func reload(weapon: Node) -> void:
if weapon in weapons:
weapon.reload()
func _update_texture_size() -> void:
if sprite and sprite.texture:
sprite.texture.size = size
func _update_collision_shape() -> void:
if collision:
collision.shape.radius = 0.9 * minf(size.x, size.y)/2
collision.shape.height = 0.9 * maxf(size.x, size.y)
collision.rotation = 0.0 if size.x < size.y else PI/2
func _on_health_depleted() -> void:
destroyed.emit()
queue_free()
+59
View File
@@ -0,0 +1,59 @@
class_name AbstractShip
extends CharacterBody2D
@onready var sprite := $Sprite2D
@onready var collision := $CollisionShape2D
@export_range(0, 250) var acceleration : int = 0
@export_range(0, 250) var deceleration : int = 0
@export_range(0, 250) var max_speed : int = 0
@export var weapon_positions: Array[Vector2]
var _weapons : Array[AbstractWeapon]
func _physics_process(_delta: float) -> void:
var was_collided := move_and_slide()
if was_collided:
var normal := get_wall_normal()
velocity -= normal.abs() * velocity
func accelerate(direction: Vector2, delta: float) -> void:
var accel : Vector2 = direction * acceleration * delta
var decel : float = deceleration * delta
velocity.x = _get_new_speed(accel.x, decel, velocity.x)
velocity.y = _get_new_speed(accel.y, decel, velocity.y)
if velocity.length() > max_speed:
velocity = velocity.normalized() * max_speed
func shoot(weapon_index: int) -> void:
if weapon_index >= _weapons.size(): return
_weapons[weapon_index].shoot(velocity)
func reload(weapon_index: int) -> void:
if weapon_index >= _weapons.size(): return
_weapons[weapon_index].reload()
func _get_new_speed(accel: float, decel: float, current_speed: float) -> float:
if is_zero_approx(accel):
if absf(current_speed) < decel:
return 0.0
return current_speed + (decel if current_speed < 0 else -decel)
else:
return current_speed + accel
func _on_health_depleted() -> void:
queue_free()
@@ -1,14 +1,12 @@
[gd_scene load_steps=4 format=3 uid="uid://jvyagshykmgb"] [gd_scene load_steps=4 format=3 uid="uid://jvyagshykmgb"]
[ext_resource type="Script" uid="uid://cesibaqtrgotl" path="res://game/entities/ship.gd" id="1_6isjb"] [ext_resource type="Script" uid="uid://cesibaqtrgotl" path="res://game/entities/ships/abstract_ship.gd" id="1_6isjb"]
[ext_resource type="Script" uid="uid://d3g4xbq45qmpr" path="res://game/health_system/health.gd" id="2_n766o"] [ext_resource type="Script" uid="uid://d3g4xbq45qmpr" path="res://game/health_system/health.gd" id="2_n766o"]
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_6isjb"] [sub_resource type="CircleShape2D" id="CircleShape2D_xxtvk"]
height = 20.0
[node name="Ship" type="CharacterBody2D"] [node name="AbstractShip" type="CharacterBody2D"]
disable_mode = 1 disable_mode = 1
collision_layer = 7
motion_mode = 1 motion_mode = 1
wall_min_slide_angle = 3.1415927 wall_min_slide_angle = 3.1415927
script = ExtResource("1_6isjb") script = ExtResource("1_6isjb")
@@ -16,7 +14,7 @@ script = ExtResource("1_6isjb")
[node name="Sprite2D" type="Sprite2D" parent="."] [node name="Sprite2D" type="Sprite2D" parent="."]
[node name="CollisionShape2D" type="CollisionShape2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CapsuleShape2D_6isjb") shape = SubResource("CircleShape2D_xxtvk")
[node name="Health" type="Node" parent="."] [node name="Health" type="Node" parent="."]
script = ExtResource("2_n766o") script = ExtResource("2_n766o")
+35
View File
@@ -0,0 +1,35 @@
class_name PlayerShip
extends AbstractShip
func _ready() -> void:
@warning_ignore("unused_local_constant")
const CANNON = preload("res://game/entities/weapons/cannon/cannon.tscn")
@warning_ignore("unused_local_constant")
const GATLING = preload("res://game/entities/weapons/gatling/gatling.tscn")
@warning_ignore("unused_local_constant")
const LASER = preload("res://game/entities/weapons/laser/laser.tscn")
@warning_ignore("unused_local_constant")
const LAUNCHER = preload("res://game/entities/weapons/launcher/launcher.tscn")
@warning_ignore("unused_local_constant")
const MINELAYER = preload("res://game/entities/weapons/minelayer/minelayer.tscn")
@warning_ignore("unused_local_constant")
const PLASMA = preload("res://game/entities/weapons/plasma/plasma.tscn")
@warning_ignore("unused_local_constant")
const RAILGUN = preload("res://game/entities/weapons/railgun/railgun.tscn")
@warning_ignore("unused_local_constant")
const SHRAPNEL = preload("res://game/entities/weapons/shrapnel/shrapnel.tscn")
@warning_ignore("unused_local_constant")
const TESLA = preload("res://game/entities/weapons/tesla/tesla.tscn")
var weapons := [
GATLING.instantiate(),
RAILGUN.instantiate(),
]
for index in weapons.size():
var weapon : Node2D = weapons[index]
if index < weapon_positions.size():
weapon.position = weapon_positions[index]
add_child(weapons[index])
_weapons.append(weapon)
+1
View File
@@ -0,0 +1 @@
uid://ruxw1n03iq4i
+33
View File
@@ -0,0 +1,33 @@
[gd_scene load_steps=6 format=3 uid="uid://br074cqcnul3d"]
[ext_resource type="PackedScene" uid="uid://jvyagshykmgb" path="res://game/entities/ships/abstract_ship.tscn" id="1_6otxb"]
[ext_resource type="Script" uid="uid://ruxw1n03iq4i" path="res://game/entities/ships/player_ship.gd" id="2_625ti"]
[ext_resource type="Script" uid="uid://dgevigih7owxd" path="res://game/controllers/player_controller.gd" id="3_dj8f1"]
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_dj8f1"]
size = Vector2(48, 32)
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_dj8f1"]
height = 20.0
[node name="PlayerShip" instance=ExtResource("1_6otxb")]
collision_layer = 3
script = ExtResource("2_625ti")
acceleration = 92
deceleration = 46
max_speed = 92
weapon_positions = Array[Vector2]([Vector2(0, 8), Vector2(0, -8)])
[node name="Sprite2D" parent="." index="0"]
texture = SubResource("PlaceholderTexture2D_dj8f1")
[node name="CollisionShape2D" parent="." index="1"]
shape = SubResource("CapsuleShape2D_dj8f1")
[node name="PlayerController" type="Node" parent="." index="3"]
script = ExtResource("3_dj8f1")
metadata/_custom_type_script = "uid://dgevigih7owxd"
[connection signal="accelerate" from="PlayerController" to="." method="accelerate"]
[connection signal="reload" from="PlayerController" to="." method="reload"]
[connection signal="shoot" from="PlayerController" to="." method="shoot"]
@@ -18,6 +18,8 @@ region = Rect2(32, 16, 16, 16)
radius = 2.0 radius = 2.0
[node name="CannonProjectile" instance=ExtResource("1_20qwt")] [node name="CannonProjectile" instance=ExtResource("1_20qwt")]
collision_layer = 0
collision_mask = 0
script = ExtResource("2_x3axw") script = ExtResource("2_x3axw")
damage = SubResource("Resource_bb01p") damage = SubResource("Resource_bb01p")
speed = 600 speed = 600
@@ -18,6 +18,8 @@ region = Rect2(0, 0, 16, 16)
radius = 1.0 radius = 1.0
[node name="GatlingProjectile" instance=ExtResource("1_3tgt7")] [node name="GatlingProjectile" instance=ExtResource("1_3tgt7")]
collision_layer = 0
collision_mask = 0
script = ExtResource("2_hbgoq") script = ExtResource("2_hbgoq")
damage = SubResource("Resource_ndegg") damage = SubResource("Resource_ndegg")
speed = 600 speed = 600
@@ -16,6 +16,8 @@ size = Vector2(4, 4)
radius = 1.0 radius = 1.0
[node name="LaserProjectile" instance=ExtResource("1_3a8fg")] [node name="LaserProjectile" instance=ExtResource("1_3a8fg")]
collision_layer = 0
collision_mask = 0
script = ExtResource("2_je1a2") script = ExtResource("2_je1a2")
damage = SubResource("Resource_bytws") damage = SubResource("Resource_bytws")
speed = 500 speed = 500
@@ -47,6 +47,8 @@ radius = 1.0
height = 6.0 height = 6.0
[node name="LauncherProjectile" instance=ExtResource("1_0mcat")] [node name="LauncherProjectile" instance=ExtResource("1_0mcat")]
collision_layer = 0
collision_mask = 0
script = ExtResource("2_6hdsf") script = ExtResource("2_6hdsf")
damage = SubResource("Resource_kxgpk") damage = SubResource("Resource_kxgpk")
speed = 300 speed = 300
@@ -2,18 +2,9 @@ extends AbstractProjectile
@export var deceleration : int @export var deceleration : int
@export var livetime : int
func _ready() -> void: @onready var livetime_timer := $LivetimeTimer
super._ready()
var livetime_timer := Timer.new()
add_child(livetime_timer)
livetime_timer.wait_time = livetime
livetime_timer.one_shot = true
livetime_timer.timeout.connect(queue_free)
livetime_timer.start()
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
@@ -27,3 +18,7 @@ func _process_acceleration(delta: float) -> void:
_velocity -= _velocity.normalized() * current_deceleration _velocity -= _velocity.normalized() * current_deceleration
else: else:
_velocity = Vector2.ZERO _velocity = Vector2.ZERO
func _on_livetime_timer_timeout() -> void:
queue_free()
@@ -18,9 +18,10 @@ region = Rect2(0, 16, 16, 16)
radius = 7.0 radius = 7.0
[node name="MinelayerProjectile" instance=ExtResource("1_ufc4r")] [node name="MinelayerProjectile" instance=ExtResource("1_ufc4r")]
collision_layer = 0
collision_mask = 0
script = ExtResource("2_hwwfa") script = ExtResource("2_hwwfa")
deceleration = 100 deceleration = 100
livetime = 60
damage = SubResource("Resource_px1i2") damage = SubResource("Resource_px1i2")
speed = 200 speed = 200
@@ -29,3 +30,10 @@ texture = SubResource("AtlasTexture_ckqco")
[node name="CollisionShape2D" parent="." index="1"] [node name="CollisionShape2D" parent="." index="1"]
shape = SubResource("CircleShape2D_ufc4r") shape = SubResource("CircleShape2D_ufc4r")
[node name="LivetimeTimer" type="Timer" parent="." index="3"]
wait_time = 60.0
one_shot = true
autostart = true
[connection signal="timeout" from="LivetimeTimer" to="." method="_on_livetime_timer_timeout"]
@@ -10,13 +10,15 @@ value = 20
metadata/_custom_type_script = "uid://c27v705giygv4" metadata/_custom_type_script = "uid://c27v705giygv4"
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_dlvdm"] [sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_dlvdm"]
size = Vector2(4, 6) size = Vector2(6, 4)
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_5enq5"] [sub_resource type="CapsuleShape2D" id="CapsuleShape2D_5enq5"]
radius = 1.0 radius = 1.0
height = 4.0 height = 4.0
[node name="PlasmaProjectile" instance=ExtResource("1_x58hw")] [node name="PlasmaProjectile" instance=ExtResource("1_x58hw")]
collision_layer = 0
collision_mask = 0
script = ExtResource("2_0deih") script = ExtResource("2_0deih")
damage = SubResource("Resource_5enq5") damage = SubResource("Resource_5enq5")
speed = 450 speed = 450
@@ -23,6 +23,8 @@ radius = 1.0
height = 4.0 height = 4.0
[node name="RailgunProjectile" instance=ExtResource("1_rfd1j")] [node name="RailgunProjectile" instance=ExtResource("1_rfd1j")]
collision_layer = 0
collision_mask = 0
script = ExtResource("1_hycpq") script = ExtResource("1_hycpq")
damage = SubResource("Resource_u82jm") damage = SubResource("Resource_u82jm")
speed = 900 speed = 900
@@ -18,6 +18,8 @@ region = Rect2(48, 0, 16, 16)
radius = 1.0 radius = 1.0
[node name="ShrapnelProjectile" instance=ExtResource("1_yu2c6")] [node name="ShrapnelProjectile" instance=ExtResource("1_yu2c6")]
collision_layer = 0
collision_mask = 0
script = ExtResource("2_2jiy6") script = ExtResource("2_2jiy6")
max_distance = 350 max_distance = 350
damage = SubResource("Resource_klguu") damage = SubResource("Resource_klguu")
@@ -16,6 +16,8 @@ size = Vector2(12, 12)
radius = 5.0 radius = 5.0
[node name="TeslaProjectile" instance=ExtResource("1_1oexk")] [node name="TeslaProjectile" instance=ExtResource("1_1oexk")]
collision_layer = 0
collision_mask = 0
script = ExtResource("2_q73is") script = ExtResource("2_q73is")
damage = SubResource("Resource_1121u") damage = SubResource("Resource_1121u")
speed = 900 speed = 900
+2 -1
View File
@@ -2,6 +2,7 @@ extends Node
func _ready() -> void: func _ready() -> void:
var player : Node = load("res://game/entities/player.tscn").instantiate() const PLAYER := preload("res://game/entities/ships/player_ship.tscn")
var player : PlayerShip = PLAYER.instantiate()
add_child(player) add_child(player)
player.position = Vector2(100, 100) player.position = Vector2(100, 100)