Browse Source

:tada: First try with 2D

DricomDragon 2 years ago
parent
commit
96ad62ba59

BIN
netnet/component/entity/jumper/green_astronaut.png


+ 34 - 0
netnet/component/entity/jumper/green_astronaut.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cojbjngjjhoe0"
+path="res://.godot/imported/green_astronaut.png-ff14009a8ac3a35c99c20c60a9705796.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://component/entity/jumper/green_astronaut.png"
+dest_files=["res://.godot/imported/green_astronaut.png-ff14009a8ac3a35c99c20c60a9705796.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1

+ 36 - 0
netnet/component/entity/jumper/jumper.gd

@@ -0,0 +1,36 @@
+class_name Jumper
+extends RigidBody2D
+
+const SPEED = 5.0
+const JUMP_IMPULSE = 4.5
+const MOVE_FORCE = 1
+
+# Set by the authority, synchronized on spawn.
+@export var player := 1 :
+	set(id):
+		player = id
+		# Give authority over the player input to the appropriate peer.
+		$JumperInput.set_multiplayer_authority(id)
+
+# Player synchronized input
+@onready var input: JumperInput = $JumperInput
+
+
+func _ready():
+	pass
+
+
+func _physics_process(delta):
+
+	# Handle Jump.
+	if input.jumping:
+		apply_impulse(Vector2.UP * JUMP_IMPULSE)
+
+	# Reset jump state.
+	input.jumping = false
+
+	# Handle movement.
+	var direction = input.direction
+	direction.y = 0
+	if direction:
+		apply_force(direction * MOVE_FORCE)

+ 40 - 0
netnet/component/entity/jumper/jumper.tscn

@@ -0,0 +1,40 @@
+[gd_scene load_steps=7 format=3 uid="uid://ckph60svia3xr"]
+
+[ext_resource type="Script" path="res://component/entity/jumper/jumper.gd" id="1_smoki"]
+[ext_resource type="Texture2D" uid="uid://cojbjngjjhoe0" path="res://component/entity/jumper/green_astronaut.png" id="2_xm8at"]
+[ext_resource type="Script" path="res://component/entity/jumper/jumper_input.gd" id="3_trrhr"]
+
+[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_raoy1"]
+radius = 18.0
+height = 50.0
+
+[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_wnop5"]
+properties/0/path = NodePath(".:position")
+properties/0/spawn = true
+properties/0/sync = true
+properties/1/path = NodePath(".:player")
+properties/1/spawn = true
+properties/1/sync = false
+
+[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_74ldf"]
+properties/0/path = NodePath("JumperInput:direction")
+properties/0/spawn = false
+properties/0/sync = true
+
+[node name="Jumper" type="RigidBody2D"]
+lock_rotation = true
+script = ExtResource("1_smoki")
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
+position = Vector2(0, -2)
+shape = SubResource("CapsuleShape2D_raoy1")
+
+[node name="Sprite2D" type="Sprite2D" parent="."]
+texture = ExtResource("2_xm8at")
+
+[node name="ServerSynchronizer" type="MultiplayerSynchronizer" parent="."]
+replication_config = SubResource("SceneReplicationConfig_wnop5")
+
+[node name="JumperInput" type="MultiplayerSynchronizer" parent="."]
+replication_config = SubResource("SceneReplicationConfig_74ldf")
+script = ExtResource("3_trrhr")

+ 26 - 0
netnet/component/entity/jumper/jumper_input.gd

@@ -0,0 +1,26 @@
+class_name JumperInput
+extends MultiplayerSynchronizer
+
+# Set via RPC to simulate is_action_just_pressed.
+@export var jumping: bool = false
+
+# Synchronized property.
+@export var direction := Vector2()
+
+
+func _ready():
+	# Only process for the local player
+	set_process(get_multiplayer_authority() == multiplayer.get_unique_id())
+
+
+@rpc("call_local")
+func jump() -> void:
+	jumping = true
+
+
+func _process(delta: float) -> void:
+	# Get the input direction and handle the movement/deceleration.
+	# As good practice, you should replace UI actions with custom gameplay actions.
+	direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
+	if Input.is_action_just_pressed("ui_accept"):
+		jump.rpc()

+ 26 - 0
netnet/run/levels/destination/final.tscn

@@ -0,0 +1,26 @@
+[gd_scene load_steps=3 format=3 uid="uid://cf2fnyf7gud6c"]
+
+[ext_resource type="Script" path="res://run/levels/player_manager.gd" id="1_hhmm0"]
+
+[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_kbpyq"]
+
+[node name="Final" type="Node2D"]
+script = ExtResource("1_hhmm0")
+
+[node name="Floor" type="StaticBody2D" parent="."]
+position = Vector2(2, 653)
+
+[node name="Limit" type="CollisionShape2D" parent="Floor"]
+shape = SubResource("WorldBoundaryShape2D_kbpyq")
+
+[node name="PlayerPool" type="Node2D" parent="."]
+
+[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="."]
+_spawnable_scenes = PackedStringArray("res://component/entity/jumper/jumper.tscn")
+spawn_path = NodePath("../PlayerPool")
+spawn_limit = 4
+
+[node name="Line2D" type="Line2D" parent="."]
+position = Vector2(4, 653)
+points = PackedVector2Array(700, 0, 0, 0)
+default_color = Color(0, 1, 1, 1)

+ 46 - 0
netnet/run/levels/player_manager.gd

@@ -0,0 +1,46 @@
+class_name PlayerManager
+extends Node2D
+
+const SPAWN_RANDOM := 100.0
+const SPAWN_HEIGHT := 200.0
+
+@onready var player_pool: Node2D = $PlayerPool
+
+func _ready():
+	# We only need to spawn players on the server.
+	if not multiplayer.is_server():
+		return
+
+	multiplayer.peer_connected.connect(add_player)
+	multiplayer.peer_disconnected.connect(del_player)
+
+	# Spawn already connected players
+	for id in multiplayer.get_peers():
+		add_player(id)
+
+	# Spawn the local player unless this is a dedicated server export.
+	if not OS.has_feature("dedicated_server"):
+		add_player(1)
+
+
+func _exit_tree():
+	if not multiplayer.is_server():
+		return
+	multiplayer.peer_connected.disconnect(add_player)
+	multiplayer.peer_disconnected.disconnect(del_player)
+
+
+func add_player(id: int):
+	var character = preload("res://component/entity/jumper/jumper.tscn").instantiate()
+	# Set player id.
+	character.player = id
+	# Randomize character position.
+	character.position = Vector2(randf() * SPAWN_RANDOM, SPAWN_HEIGHT)
+	character.name = str(id)
+	player_pool.add_child(character, true)
+
+
+func del_player(id: int):
+	if not player_pool.has_node(str(id)):
+		return
+	player_pool.get_node(str(id)).queue_free()

+ 8 - 8
netnet/run/multiplayer.gd

@@ -2,7 +2,7 @@ extends Node
 
 const PORT = 4433
 
-func _ready():
+func _ready() -> void:
 	# Start paused
 	get_tree().paused = true
 	# You can save bandwith by disabling server relay and peer notifications.
@@ -14,7 +14,7 @@ func _ready():
 		_on_host_pressed.call_deferred()
 
 
-func _on_host_pressed():
+func _on_host_pressed() -> void:
 	# Start as server
 	var peer = ENetMultiplayerPeer.new()
 	peer.create_server(PORT)
@@ -25,7 +25,7 @@ func _on_host_pressed():
 	start_game()
 
 
-func _on_connect_pressed():
+func _on_connect_pressed() -> void:
 	# Start as client
 	var txt : String = $UI/Net/Options/Remote.text
 	if txt == "":
@@ -40,18 +40,18 @@ func _on_connect_pressed():
 	start_game()
 
 
-func start_game():
+func start_game() -> void:
 	# Hide the UI and unpause to start the game.
 	$UI.hide()
 	get_tree().paused = false
 	# Only change level on the server.
 	# Clients will instantiate the level via the spawner.
 	if multiplayer.is_server():
-		change_level.call_deferred(load("res://run/levels/flatland/level.tscn"))
+		change_level.call_deferred(load("res://run/levels/destination/final.tscn"))
 
 
 # Call this function deferred and only on the main authority (server).
-func change_level(scene: PackedScene):
+func change_level(scene: PackedScene) -> void:
 	# Remove old level if any.
 	var level = $Level
 	for c in level.get_children():
@@ -62,8 +62,8 @@ func change_level(scene: PackedScene):
 
 
 # The server can restart the level by pressing HOME.
-func _input(event):
+func _input(event: InputEvent) -> void:
 	if not multiplayer.is_server():
 		return
 	if event.is_action("ui_home") and Input.is_action_just_pressed("ui_home"):
-		change_level.call_deferred(load("res://run/levels/flatland/level.tscn"))
+		change_level.call_deferred(load("res://run/levels/destination/final.tscn"))

+ 1 - 1
netnet/run/multiplayer.tscn

@@ -8,7 +8,7 @@ script = ExtResource("1_t2go4")
 [node name="Level" type="Node" parent="."]
 
 [node name="LevelSpawner" type="MultiplayerSpawner" parent="."]
-_spawnable_scenes = PackedStringArray("res://run/levels/flatland/level.tscn")
+_spawnable_scenes = PackedStringArray("res://run/levels/destination/final.tscn")
 spawn_path = NodePath("../Level")
 spawn_limit = 1