local Multiplayer support

This commit is contained in:
2024-12-04 08:48:48 +01:00
parent 15be351c86
commit bb7dbb054a
13 changed files with 233 additions and 24 deletions

View File

@@ -1,7 +1,7 @@
extends RigidBody2D extends RigidBody2D
@export var speed = 400 @export var speed = 400
@export var explosion_damage = 2000 @export var explosion_damage = 600
var velocity = Vector2.ZERO var velocity = Vector2.ZERO
var is_in_flight = false var is_in_flight = false

12
global.gd Normal file
View File

@@ -0,0 +1,12 @@
extends Node
var player_ids = []
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass

23
lob4F13.tmp Normal file
View File

@@ -0,0 +1,23 @@
[gd_scene load_steps=2 format=3 uid="uid://l4sh5qah5jln"]
[ext_resource type="Script" path="res://lobby.gd" id="1_p5ww4"]
[node name="Lobby" type="Control"]
layout_mode = 3
anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
script = ExtResource("1_p5ww4")
[node name="PlayerList" type="VBoxContainer" parent="."]
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="StartButton" type="Button" parent="."]
layout_mode = 2
offset_left = 47.0
offset_top = 12.0
offset_right = 87.0
offset_bottom = 20.0
text = "Start"

23
lob5137.tmp Normal file
View File

@@ -0,0 +1,23 @@
[gd_scene load_steps=2 format=3 uid="uid://l4sh5qah5jln"]
[ext_resource type="Script" path="res://lobby.gd" id="1_p5ww4"]
[node name="Lobby" type="Control"]
layout_mode = 3
anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
script = ExtResource("1_p5ww4")
[node name="PlayerList" type="VBoxContainer" parent="."]
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="StartButton" type="Button" parent="."]
layout_mode = 2
offset_left = 47.0
offset_top = 12.0
offset_right = 87.0
offset_bottom = 20.0
text = "Start"

23
lob7BAA.tmp Normal file
View File

@@ -0,0 +1,23 @@
[gd_scene load_steps=2 format=3 uid="uid://l4sh5qah5jln"]
[ext_resource type="Script" path="res://lobby.gd" id="1_p5ww4"]
[node name="Lobby" type="Control"]
layout_mode = 3
anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
script = ExtResource("1_p5ww4")
[node name="PlayerList" type="VBoxContainer" parent="."]
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="StartButton" type="Button" parent="."]
layout_mode = 2
offset_left = 47.0
offset_top = 12.0
offset_right = 87.0
offset_bottom = 20.0
text = "Start"

23
lobB0BD.tmp Normal file
View File

@@ -0,0 +1,23 @@
[gd_scene load_steps=2 format=3 uid="uid://l4sh5qah5jln"]
[ext_resource type="Script" path="res://lobby.gd" id="1_p5ww4"]
[node name="Lobby" type="Control"]
layout_mode = 3
anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
script = ExtResource("1_p5ww4")
[node name="PlayerList" type="VBoxContainer" parent="."]
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="StartButton" type="Button" parent="."]
layout_mode = 2
offset_left = 47.0
offset_top = 12.0
offset_right = 87.0
offset_bottom = 20.0
text = "Start"

51
lobby.gd Normal file
View File

@@ -0,0 +1,51 @@
extends Control
@export var max_players = 4
const game_scene = "res://main.tscn" # Path to the main game scene
var ready_states = {} # Dictionary to track ready states for each player ID
@onready var player_list = $PlayerList
@onready var start_button = $StartButton
func _ready() -> void:
start_button.disabled = true
start_button.connect("pressed", _on_start_game)
func _process(delta: float) -> void:
# Handle player joining
if (Input.is_action_just_pressed("throw_bomb")):
add_player(-1) # -1 for keyboard
for i in range(0, 7): # 0-7 for controllers
if (i >= 0 and Input.is_joy_button_pressed(i, JOY_BUTTON_A)):
add_player(i)
func add_player(input_id: int) -> void:
# Prevent duplicate players
if input_id in Global.player_ids:
return
if len(Global.player_ids) >= max_players:
return # Max players reached
# Add player to the list
Global.player_ids.append(input_id)
# Create a new label to display the player ID
var label = Label.new()
label.text = "Player ID: %d" % input_id
player_list.add_child(label)
# Track ready state for the player
ready_states[input_id] = false
# Update the start button state
check_all_ready()
func check_all_ready() -> void:
# Enable the start button if at least one player has joined
start_button.disabled = len(Global.player_ids) == 0
func _on_start_game() -> void:
get_tree().change_scene_to_file(game_scene)

33
lobby.tscn Normal file
View File

@@ -0,0 +1,33 @@
[gd_scene load_steps=2 format=3 uid="uid://l4sh5qah5jln"]
[ext_resource type="Script" path="res://lobby.gd" id="1_p5ww4"]
[node name="Lobby" type="Control"]
layout_mode = 3
anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
script = ExtResource("1_p5ww4")
[node name="PlayerList" type="VBoxContainer" parent="."]
layout_mode = 0
offset_left = 33.0
offset_top = 54.0
offset_right = 73.0
offset_bottom = 94.0
[node name="StartButton" type="Button" parent="."]
layout_mode = 2
offset_left = 370.0
offset_top = 165.0
offset_right = 416.0
offset_bottom = 196.0
text = "Start"
[node name="Label" type="Label" parent="."]
layout_mode = 0
offset_left = 155.0
offset_top = 31.0
offset_right = 292.0
offset_bottom = 54.0
text = "Bomber-Thorsten"

16
main.gd
View File

@@ -1,9 +1,21 @@
extends Node2D extends Node2D
@export var player_scene = preload("res://player.tscn")
@onready var spawn_points = $PlayerSpawnPoints.get_children()
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
func _ready() -> void: func _ready() -> void:
$MultiTargetCamera.add_target($Player) # Spawn players at designated spawn points
for i in range(len(Global.player_ids)):
if i >= spawn_points.size():
break # Ensure we don't exceed available spawn points
var player_instance = player_scene.instantiate()
player_instance.set_input_id(Global.player_ids[i]) # Assign the input ID to the player
player_instance.global_position = spawn_points[i].global_position
$MultiTargetCamera.add_target(player_instance)
print(Global.player_ids[i])
add_child(player_instance)
# Called every frame. 'delta' is the elapsed time since the previous frame. # Called every frame. 'delta' is the elapsed time since the previous frame.

File diff suppressed because one or more lines are too long

View File

@@ -12,20 +12,23 @@ extends RigidBody2D
@export var friction = 5 @export var friction = 5
@export var max_speed = 500.0 @export var max_speed = 500.0
@export var player_index = 0 # Default to keyboard (-1). Set to controller ID for multiplayer. var input_id = -1 # Default to keyboard (-1). Set to controller ID for multiplayer.
var charging = false var charging = false
var current_power = 0.0 var current_power = 0.0
var bomb = null # Global bomb reference var bomb = null # Global bomb reference
var aim_direction = Vector2(1, -1) # Default aiming direction var aim_direction = Vector2(1, -1) # Default aiming direction
@onready var velocity_label = $Label @onready var label = $Label
@onready var line_indicator = $Line2D # Reference to the Line2D node @onready var line_indicator = $Line2D # Reference to the Line2D node
# Dead zone for joystick input # Dead zone for joystick input
var dead_zone = 0.2 var dead_zone = 0.2
func _ready() -> void: func _ready() -> void:
label.text = str(input_id)
# Set the initial points for the Line2D to indicate the starting vector # Set the initial points for the Line2D to indicate the starting vector
line_indicator.clear_points() line_indicator.clear_points()
line_indicator.add_point(Vector2.ZERO) # Starting point at the player line_indicator.add_point(Vector2.ZERO) # Starting point at the player
@@ -43,9 +46,6 @@ func _process(delta: float) -> void:
current_power += charge_rate * delta current_power += charge_rate * delta
current_power = min(current_power, max_power) # Cap power at max_power current_power = min(current_power, max_power) # Cap power at max_power
# Update velocity on the label
velocity_label.text = "Power: " + str(current_power)
# Set the start position of the line a bit away from the player # Set the start position of the line a bit away from the player
var start_position = aim_direction * line_start_offset var start_position = aim_direction * line_start_offset
# Update the Line2D to visualize the throw direction and power # Update the Line2D to visualize the throw direction and power
@@ -67,21 +67,21 @@ func _process(delta: float) -> void:
line_indicator.set_point_position(1, Vector2.ZERO) line_indicator.set_point_position(1, Vector2.ZERO)
func update_aim_direction(): func update_aim_direction():
if player_index == -1: # Keyboard/Mouse if input_id == -1: # Keyboard/Mouse
aim_direction = (get_global_mouse_position() - global_position).normalized() aim_direction = (get_global_mouse_position() - global_position).normalized()
else: # Controller else: # Controller
var joy_x = Input.get_joy_axis(player_index, JOY_AXIS_LEFT_X) var joy_x = Input.get_joy_axis(input_id, JOY_AXIS_LEFT_X)
var joy_y = Input.get_joy_axis(player_index, JOY_AXIS_LEFT_Y) var joy_y = Input.get_joy_axis(input_id, JOY_AXIS_LEFT_Y)
# Apply dead zone # Apply dead zone
if abs(joy_x) > dead_zone or abs(joy_y) > dead_zone: if abs(joy_x) > dead_zone or abs(joy_y) > dead_zone:
aim_direction = Vector2(joy_x, joy_y).normalized() aim_direction = Vector2(joy_x, joy_y).normalized()
func is_throwing_input_pressed() -> bool: func is_throwing_input_pressed() -> bool:
if player_index == -1: # Keyboard/Mouse if input_id == -1: # Keyboard/Mouse
return Input.is_action_pressed("throw_bomb") return Input.is_action_pressed("throw_bomb")
else: # Controller (use A button for throwing) else: # Controller (use A button for throwing)
return Input.is_joy_button_pressed(player_index, JOY_BUTTON_A) return Input.is_joy_button_pressed(input_id, JOY_BUTTON_A)
func throw_bomb(power: float): func throw_bomb(power: float):
# Check if there is no bomb or if the current bomb instance is invalid # Check if there is no bomb or if the current bomb instance is invalid
@@ -97,5 +97,5 @@ func throw_bomb(power: float):
# Add the bomb to the scene # Add the bomb to the scene
add_child(bomb) add_child(bomb)
# Clear velocity display after throwing (optional) func set_input_id(id: int) -> void:
velocity_label.text = "Power: 0" input_id = id

View File

@@ -74,10 +74,10 @@ shape = SubResource("CapsuleShape2D_ogije")
one_way_collision_margin = 32.1 one_way_collision_margin = 32.1
[node name="Label" type="Label" parent="."] [node name="Label" type="Label" parent="."]
offset_left = 38.0 offset_left = -19.0
offset_top = 7.0 offset_top = -14.0
offset_right = 78.0 offset_right = 21.0
offset_bottom = 30.0 offset_bottom = 9.0
[node name="Line2D" type="Line2D" parent="."] [node name="Line2D" type="Line2D" parent="."]
scale = Vector2(2, 2) scale = Vector2(2, 2)

View File

@@ -11,10 +11,14 @@ config_version=5
[application] [application]
config/name="Bomber-Thorsten" config/name="Bomber-Thorsten"
run/main_scene="res://main.tscn" run/main_scene="res://lobby.tscn"
config/features=PackedStringArray("4.3") config/features=PackedStringArray("4.3")
config/icon="res://icon.svg" config/icon="res://icon.svg"
[autoload]
Global="*res://global.gd"
[input] [input]
throw_bomb={ throw_bomb={