Merge pull request #394 from aaronfranke/pong
Update and improve all Pong demos
@@ -1,16 +0,0 @@
|
||||
extends Area2D
|
||||
|
||||
const BALL_SPEED = 100
|
||||
var direction = Vector2(-1, 0)
|
||||
var speed = BALL_SPEED
|
||||
|
||||
onready var initial_pos = self.position
|
||||
|
||||
func reset():
|
||||
position = initial_pos
|
||||
speed = BALL_SPEED
|
||||
direction = Vector2(-1, 0)
|
||||
|
||||
func _process(delta):
|
||||
position += direction * speed * delta
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
extends Area2D
|
||||
|
||||
export var y_direction = 1
|
||||
|
||||
func _on_area_entered( area ):
|
||||
if area.get_name() == "ball":
|
||||
area.direction.y = y_direction
|
||||
@@ -1,19 +0,0 @@
|
||||
extends Area2D
|
||||
export var ball_dir = 1
|
||||
|
||||
const MOVE_SPEED = 100
|
||||
|
||||
func _process(delta):
|
||||
var which = get_name()
|
||||
|
||||
# move up and down based on input
|
||||
if Input.is_action_pressed(which+"_move_up") and position.y > 0:
|
||||
position.y -= MOVE_SPEED * delta
|
||||
if Input.is_action_pressed(which+"_move_down") and position.y < get_viewport_rect().size.y:
|
||||
position.y += MOVE_SPEED * delta
|
||||
|
||||
|
||||
func _on_area_entered( area ):
|
||||
if area.get_name() == "ball":
|
||||
# assign new direction
|
||||
area.direction = Vector2(ball_dir, randf() * 2 - 1).normalized()
|
||||
@@ -1,13 +1,13 @@
|
||||
[gd_scene load_steps=13 format=2]
|
||||
|
||||
[ext_resource path="res://paddle.gd" type="Script" id=1]
|
||||
[ext_resource path="res://scripts/paddle.gd" type="Script" id=1]
|
||||
[ext_resource path="res://left_pallete.png" type="Texture" id=2]
|
||||
[ext_resource path="res://right_pallete.png" type="Texture" id=3]
|
||||
[ext_resource path="res://ball.gd" type="Script" id=4]
|
||||
[ext_resource path="res://scripts/ball.gd" type="Script" id=4]
|
||||
[ext_resource path="res://ball.png" type="Texture" id=5]
|
||||
[ext_resource path="res://separator.png" type="Texture" id=6]
|
||||
[ext_resource path="res://wall.gd" type="Script" id=7]
|
||||
[ext_resource path="res://ceiling_floor.gd" type="Script" id=8]
|
||||
[ext_resource path="res://scripts/wall.gd" type="Script" id=7]
|
||||
[ext_resource path="res://scripts/ceiling_floor.gd" type="Script" id=8]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=1]
|
||||
extents = Vector2( 4, 16 )
|
||||
@@ -21,9 +21,9 @@ extents = Vector2( 10, 200 )
|
||||
[sub_resource type="RectangleShape2D" id=4]
|
||||
extents = Vector2( 320, 10 )
|
||||
|
||||
[node name="game" type="Node2D"]
|
||||
[node name="Pong" type="Node2D"]
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="."]
|
||||
[node name="Background" type="ColorRect" parent="."]
|
||||
margin_right = 640.0
|
||||
margin_bottom = 400.0
|
||||
color = Color( 0.141176, 0.152941, 0.164706, 1 )
|
||||
@@ -31,76 +31,75 @@ __meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="left" type="Area2D" parent="."]
|
||||
[node name="Left" type="Area2D" parent="."]
|
||||
position = Vector2( 67.6285, 192.594 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="sprite" type="Sprite" parent="left"]
|
||||
[node name="Sprite" type="Sprite" parent="Left"]
|
||||
texture = ExtResource( 2 )
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="left"]
|
||||
[node name="Collision" type="CollisionShape2D" parent="Left"]
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="right" type="Area2D" parent="."]
|
||||
[node name="Right" type="Area2D" parent="."]
|
||||
position = Vector2( 563.815, 188.919 )
|
||||
script = ExtResource( 1 )
|
||||
ball_dir = -1
|
||||
|
||||
[node name="sprite" type="Sprite" parent="right"]
|
||||
[node name="Sprite" type="Sprite" parent="Right"]
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="right"]
|
||||
[node name="Collision" type="CollisionShape2D" parent="Right"]
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="ball" type="Area2D" parent="."]
|
||||
[node name="Ball" type="Area2D" parent="."]
|
||||
position = Vector2( 320.5, 191.124 )
|
||||
script = ExtResource( 4 )
|
||||
|
||||
[node name="sprite" type="Sprite" parent="ball"]
|
||||
[node name="Sprite" type="Sprite" parent="Ball"]
|
||||
texture = ExtResource( 5 )
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="ball"]
|
||||
[node name="Collision" type="CollisionShape2D" parent="Ball"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="separator" type="Sprite" parent="."]
|
||||
[node name="Separator" type="Sprite" parent="."]
|
||||
position = Vector2( 320, 200 )
|
||||
texture = ExtResource( 6 )
|
||||
|
||||
[node name="left_wall" type="Area2D" parent="."]
|
||||
[node name="LeftWall" type="Area2D" parent="."]
|
||||
position = Vector2( -10, 200 )
|
||||
script = ExtResource( 7 )
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="left_wall"]
|
||||
[node name="Collision" type="CollisionShape2D" parent="LeftWall"]
|
||||
shape = SubResource( 3 )
|
||||
|
||||
[node name="right_wall" type="Area2D" parent="."]
|
||||
[node name="RightWall" type="Area2D" parent="."]
|
||||
position = Vector2( 650, 200 )
|
||||
script = ExtResource( 7 )
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="right_wall"]
|
||||
[node name="Collision" type="CollisionShape2D" parent="RightWall"]
|
||||
shape = SubResource( 3 )
|
||||
|
||||
[node name="ceiling" type="Area2D" parent="."]
|
||||
[node name="Ceiling" type="Area2D" parent="."]
|
||||
position = Vector2( 320, -10 )
|
||||
script = ExtResource( 8 )
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="ceiling"]
|
||||
[node name="Collision" type="CollisionShape2D" parent="Ceiling"]
|
||||
shape = SubResource( 4 )
|
||||
|
||||
[node name="floor" type="Area2D" parent="."]
|
||||
[node name="Floor" type="Area2D" parent="."]
|
||||
position = Vector2( 320, 410 )
|
||||
script = ExtResource( 8 )
|
||||
y_direction = -1
|
||||
_bounce_direction = -1
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="floor"]
|
||||
[node name="Collision" type="CollisionShape2D" parent="Floor"]
|
||||
shape = SubResource( 4 )
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
offset = Vector2( 320, 200 )
|
||||
current = true
|
||||
[connection signal="area_entered" from="left" to="left" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="right" to="right" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="left_wall" to="left_wall" method="_on_wall_area_entered"]
|
||||
[connection signal="area_entered" from="right_wall" to="right_wall" method="_on_wall_area_entered"]
|
||||
[connection signal="area_entered" from="ceiling" to="ceiling" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="floor" to="floor" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="Left" to="Left" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="Right" to="Right" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="LeftWall" to="LeftWall" method="_on_wall_area_entered"]
|
||||
[connection signal="area_entered" from="RightWall" to="RightWall" method="_on_wall_area_entered"]
|
||||
[connection signal="area_entered" from="Ceiling" to="Ceiling" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="Floor" to="Floor" method="_on_area_entered"]
|
||||
|
||||
@@ -15,7 +15,7 @@ _global_script_class_icons={
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Pong"
|
||||
config/name="Pong with GDScript"
|
||||
run/main_scene="pong.tscn"
|
||||
config/icon="res://icon.png"
|
||||
|
||||
@@ -36,21 +36,31 @@ singletons=[ ]
|
||||
left_move_down={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":90,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
left_move_up={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
right_move_down={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":1,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":1,"axis":1,"axis_value":1.0,"script":null)
|
||||
]
|
||||
}
|
||||
right_move_up={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":1,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":1,"axis":1,"axis_value":-1.0,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
18
2d/pong/scripts/ball.gd
Normal file
@@ -0,0 +1,18 @@
|
||||
extends Area2D
|
||||
|
||||
const DEFAULT_SPEED = 100
|
||||
|
||||
var direction = Vector2.LEFT
|
||||
|
||||
onready var _initial_pos = position
|
||||
onready var _speed = DEFAULT_SPEED
|
||||
|
||||
func _process(delta):
|
||||
_speed += delta * 2
|
||||
position += _speed * delta * direction
|
||||
|
||||
|
||||
func reset():
|
||||
direction = Vector2.LEFT
|
||||
position = _initial_pos
|
||||
_speed = DEFAULT_SPEED
|
||||
7
2d/pong/scripts/ceiling_floor.gd
Normal file
@@ -0,0 +1,7 @@
|
||||
extends Area2D
|
||||
|
||||
export var _bounce_direction = 1
|
||||
|
||||
func _on_area_entered( area ):
|
||||
if area.name == "Ball":
|
||||
area.direction = (area.direction + Vector2(0, _bounce_direction)).normalized()
|
||||
27
2d/pong/scripts/paddle.gd
Normal file
@@ -0,0 +1,27 @@
|
||||
extends Area2D
|
||||
|
||||
const MOVE_SPEED = 100
|
||||
|
||||
var _ball_dir
|
||||
var _up
|
||||
var _down
|
||||
|
||||
onready var _screen_size_y = get_viewport_rect().size.y
|
||||
|
||||
func _ready():
|
||||
var n = name.to_lower()
|
||||
_up = n + "_move_up"
|
||||
_down = n + "_move_down"
|
||||
_ball_dir = 1 if n == "left" else -1
|
||||
|
||||
|
||||
func _process(delta):
|
||||
# Move up and down based on input.
|
||||
var input = Input.get_action_strength(_down) - Input.get_action_strength(_up)
|
||||
position.y = clamp(position.y + input * MOVE_SPEED * delta, 16, _screen_size_y - 16)
|
||||
|
||||
|
||||
func _on_area_entered(area):
|
||||
if area.name == "Ball":
|
||||
# Assign new direction.
|
||||
area.direction = Vector2(_ball_dir, randf() * 2 - 1).normalized()
|
||||
@@ -1,7 +1,6 @@
|
||||
extends Area2D
|
||||
|
||||
|
||||
func _on_wall_area_entered( area ):
|
||||
if area.get_name() == "ball":
|
||||
func _on_wall_area_entered(area):
|
||||
if area.name == "Ball":
|
||||
#oops, ball went out of game place, reset
|
||||
area.reset()
|
||||
@@ -2,17 +2,12 @@ using Godot;
|
||||
|
||||
public class Ball : Area2D
|
||||
{
|
||||
private const int BallSpeed = 100;
|
||||
private const int DefaultSpeed = 100;
|
||||
|
||||
public Vector2 direction = Vector2.Left;
|
||||
|
||||
private Vector2 _initialPos;
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Position = _initialPos;
|
||||
direction = Vector2.Left;
|
||||
}
|
||||
private float _speed = DefaultSpeed;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
@@ -21,6 +16,14 @@ public class Ball : Area2D
|
||||
|
||||
public override void _Process(float delta)
|
||||
{
|
||||
Position += BallSpeed * delta * direction;
|
||||
_speed += delta * 2;
|
||||
Position += _speed * delta * direction;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
direction = Vector2.Left;
|
||||
Position = _initialPos;
|
||||
_speed = DefaultSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,11 @@ extents = Vector2( 320, 10 )
|
||||
|
||||
[node name="Pong" type="Node2D"]
|
||||
|
||||
[node name="Background" type="ColorRect" parent="."]
|
||||
margin_right = 640.0
|
||||
margin_bottom = 400.0
|
||||
color = Color( 0.141176, 0.152941, 0.164706, 1 )
|
||||
|
||||
[node name="Left" type="Area2D" parent="."]
|
||||
position = Vector2( 67.6285, 192.594 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
@@ -37,6 +37,7 @@ left_move_down={
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":90,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
left_move_up={
|
||||
@@ -44,6 +45,7 @@ left_move_up={
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
right_move_down={
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
extends Area2D
|
||||
|
||||
const DEFAULT_SPEED = 80
|
||||
|
||||
var direction = Vector2(1, 0)
|
||||
var ball_speed = DEFAULT_SPEED
|
||||
var stopped = false
|
||||
|
||||
|
||||
onready var screen_size = get_viewport_rect().size
|
||||
|
||||
|
||||
sync func _reset_ball(for_left):
|
||||
position = screen_size /2
|
||||
if for_left:
|
||||
direction = Vector2(-1, 0)
|
||||
else:
|
||||
direction = Vector2(1, 0)
|
||||
|
||||
ball_speed = DEFAULT_SPEED
|
||||
|
||||
|
||||
sync func stop():
|
||||
stopped = true
|
||||
|
||||
|
||||
func _process(delta):
|
||||
# ball will move normally for both players
|
||||
# even if it's sightly out of sync between them
|
||||
# so each player sees the motion as smooth and not jerky
|
||||
|
||||
if not stopped:
|
||||
translate( direction * ball_speed * delta )
|
||||
|
||||
# check screen bounds to make ball bounce
|
||||
|
||||
var ball_pos = position
|
||||
if (ball_pos.y < 0 and direction.y < 0) or (ball_pos.y > screen_size.y and direction.y > 0):
|
||||
direction.y = -direction.y
|
||||
|
||||
if is_network_master():
|
||||
# only master will decide when the ball is out in the left side (it's own side)
|
||||
# this makes the game playable even if latency is high and ball is going fast
|
||||
# otherwise ball might be out in the other player's screen but not this one
|
||||
|
||||
if ball_pos.x < 0:
|
||||
get_parent().rpc("update_score", false)
|
||||
rpc("_reset_ball", false)
|
||||
else:
|
||||
# only the puppet will decide when the ball is out in the right side (it's own side)
|
||||
# this makes the game playable even if latency is high and ball is going fast
|
||||
# otherwise ball might be out in the other player's screen but not this one
|
||||
|
||||
if ball_pos.x > screen_size.x:
|
||||
get_parent().rpc("update_score", true)
|
||||
rpc("_reset_ball", true)
|
||||
|
||||
|
||||
sync func bounce(left, random):
|
||||
#using sync because both players can make it bounce
|
||||
if left:
|
||||
direction.x = abs(direction.x)
|
||||
else:
|
||||
direction.x = -abs(direction.x)
|
||||
|
||||
ball_speed *= 1.1
|
||||
direction.y = random * 2.0 - 1
|
||||
direction = direction.normalized()
|
||||
@@ -1,17 +1,16 @@
|
||||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://ball.gd" type="Script" id=1]
|
||||
[ext_resource path="res://scripts/ball.gd" type="Script" id=1]
|
||||
[ext_resource path="res://ball.png" type="Texture" id=2]
|
||||
|
||||
[sub_resource type="CircleShape2D" id=1]
|
||||
radius = 5.11969
|
||||
|
||||
[node name="ball" type="Area2D"]
|
||||
[node name="Ball" type="Area2D"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="sprite" type="Sprite" parent="."]
|
||||
[node name="Sprite" type="Sprite" parent="."]
|
||||
texture = ExtResource( 2 )
|
||||
|
||||
[node name="shape" type="CollisionShape2D" parent="."]
|
||||
[node name="Shape" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource( 1 )
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://lobby.gd" type="Script" id=1]
|
||||
[ext_resource path="res://scripts/lobby.gd" type="Script" id=1]
|
||||
|
||||
[node name="lobby" type="Control"]
|
||||
[node name="Lobby" type="Control"]
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
@@ -13,12 +13,11 @@ margin_right = 320.0
|
||||
margin_bottom = 200.0
|
||||
size_flags_horizontal = 2
|
||||
size_flags_vertical = 2
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="title" type="Label" parent="."]
|
||||
[node name="Title" type="Label" parent="."]
|
||||
margin_left = 210.0
|
||||
margin_top = 40.0
|
||||
margin_right = 430.0
|
||||
@@ -29,15 +28,16 @@ text = "Multiplayer Pong"
|
||||
align = 1
|
||||
valign = 1
|
||||
|
||||
[node name="panel" type="Panel" parent="."]
|
||||
[node name="LobbyPanel" type="Panel" parent="."]
|
||||
margin_left = 210.0
|
||||
margin_top = 160.0
|
||||
margin_right = 430.0
|
||||
margin_bottom = 270.0
|
||||
size_flags_horizontal = 2
|
||||
size_flags_vertical = 2
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="address_label" type="Label" parent="panel"]
|
||||
[node name="AddressLabel" type="Label" parent="LobbyPanel"]
|
||||
margin_left = 10.0
|
||||
margin_top = 10.0
|
||||
margin_right = 62.0
|
||||
@@ -46,7 +46,7 @@ size_flags_horizontal = 2
|
||||
size_flags_vertical = 0
|
||||
text = "Address"
|
||||
|
||||
[node name="address" type="LineEdit" parent="panel"]
|
||||
[node name="Address" type="LineEdit" parent="LobbyPanel"]
|
||||
margin_left = 10.0
|
||||
margin_top = 30.0
|
||||
margin_right = 210.0
|
||||
@@ -55,7 +55,7 @@ size_flags_horizontal = 2
|
||||
size_flags_vertical = 2
|
||||
text = "127.0.0.1"
|
||||
|
||||
[node name="host" type="Button" parent="panel"]
|
||||
[node name="HostButton" type="Button" parent="LobbyPanel"]
|
||||
margin_left = 10.0
|
||||
margin_top = 60.0
|
||||
margin_right = 90.0
|
||||
@@ -64,7 +64,7 @@ size_flags_horizontal = 2
|
||||
size_flags_vertical = 2
|
||||
text = "Host"
|
||||
|
||||
[node name="join" type="Button" parent="panel"]
|
||||
[node name="JoinButton" type="Button" parent="LobbyPanel"]
|
||||
margin_left = 130.0
|
||||
margin_top = 60.0
|
||||
margin_right = 210.0
|
||||
@@ -73,7 +73,7 @@ size_flags_horizontal = 2
|
||||
size_flags_vertical = 2
|
||||
text = "Join"
|
||||
|
||||
[node name="status_ok" type="Label" parent="panel"]
|
||||
[node name="StatusOk" type="Label" parent="LobbyPanel"]
|
||||
margin_left = 10.0
|
||||
margin_top = 90.0
|
||||
margin_right = 210.0
|
||||
@@ -83,7 +83,7 @@ size_flags_vertical = 0
|
||||
custom_colors/font_color = Color( 0, 1, 0.015625, 1 )
|
||||
align = 1
|
||||
|
||||
[node name="status_fail" type="Label" parent="panel"]
|
||||
[node name="StatusFail" type="Label" parent="LobbyPanel"]
|
||||
margin_left = 10.0
|
||||
margin_top = 90.0
|
||||
margin_right = 210.0
|
||||
@@ -92,5 +92,5 @@ size_flags_horizontal = 2
|
||||
size_flags_vertical = 0
|
||||
custom_colors/font_color = Color( 1, 0, 0, 1 )
|
||||
align = 1
|
||||
[connection signal="pressed" from="panel/host" to="." method="_on_host_pressed"]
|
||||
[connection signal="pressed" from="panel/join" to="." method="_on_join_pressed"]
|
||||
[connection signal="pressed" from="LobbyPanel/HostButton" to="LobbyPanel" method="_on_host_pressed"]
|
||||
[connection signal="pressed" from="LobbyPanel/JoinButton" to="LobbyPanel" method="_on_join_pressed"]
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
extends Area2D
|
||||
|
||||
export var left=false
|
||||
|
||||
const MOTION_SPEED=150
|
||||
|
||||
var motion = 0
|
||||
var you_hidden = false
|
||||
|
||||
onready var screen_size = get_viewport_rect().size
|
||||
|
||||
#synchronize position and speed to the other peers
|
||||
puppet func set_pos_and_motion(p_pos, p_motion):
|
||||
position = p_pos
|
||||
motion = p_motion
|
||||
|
||||
func _hide_you_label():
|
||||
you_hidden = true
|
||||
get_node("you").hide()
|
||||
|
||||
func _process(delta):
|
||||
#is the master of the paddle
|
||||
if is_network_master():
|
||||
motion = 0
|
||||
if Input.is_action_pressed("move_up"):
|
||||
motion -= 1
|
||||
elif Input.is_action_pressed("move_down"):
|
||||
motion += 1
|
||||
|
||||
if not you_hidden and motion != 0:
|
||||
_hide_you_label()
|
||||
|
||||
motion *= MOTION_SPEED
|
||||
|
||||
#using unreliable to make sure position is updated as fast as possible, even if one of the calls is dropped
|
||||
rpc_unreliable("set_pos_and_motion", position, motion)
|
||||
|
||||
else:
|
||||
if not you_hidden:
|
||||
_hide_you_label()
|
||||
|
||||
translate( Vector2(0,motion*delta) )
|
||||
|
||||
# set screen limits
|
||||
var pos = position
|
||||
|
||||
if pos.y < 0:
|
||||
position = Vector2(pos.x, 0)
|
||||
elif pos.y > screen_size.y:
|
||||
position = Vector2(pos.x, screen_size.y)
|
||||
|
||||
|
||||
func _on_paddle_area_enter( area ):
|
||||
if is_network_master():
|
||||
area.rpc("bounce", left, randf()) #random for new direction generated on each peer
|
||||
@@ -1,22 +1,22 @@
|
||||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://paddle.gd" type="Script" id=1]
|
||||
[ext_resource path="res://scripts/paddle.gd" type="Script" id=1]
|
||||
[ext_resource path="res://paddle.png" type="Texture" id=2]
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id=1]
|
||||
radius = 4.78568
|
||||
height = 23.6064
|
||||
|
||||
[node name="paddle" type="Area2D"]
|
||||
[node name="Paddle" type="Area2D"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="sprite" type="Sprite" parent="."]
|
||||
[node name="Sprite" type="Sprite" parent="."]
|
||||
texture = ExtResource( 2 )
|
||||
|
||||
[node name="shape" type="CollisionShape2D" parent="."]
|
||||
[node name="Shape" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="you" type="Label" parent="."]
|
||||
[node name="You" type="Label" parent="."]
|
||||
margin_left = -26.0
|
||||
margin_top = -33.0
|
||||
margin_right = 27.0
|
||||
@@ -25,5 +25,4 @@ size_flags_horizontal = 2
|
||||
size_flags_vertical = 0
|
||||
text = "You"
|
||||
align = 1
|
||||
|
||||
[connection signal="area_entered" from="." to="." method="_on_paddle_area_enter"]
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
extends Node2D
|
||||
|
||||
const SCORE_TO_WIN = 10
|
||||
|
||||
var score_left = 0
|
||||
var score_right = 0
|
||||
|
||||
signal game_finished()
|
||||
|
||||
sync func update_score(add_to_left):
|
||||
if add_to_left:
|
||||
score_left += 1
|
||||
get_node("score_left").set_text(str(score_left))
|
||||
else:
|
||||
|
||||
score_right += 1
|
||||
get_node("score_right").set_text(str(score_right))
|
||||
|
||||
var game_ended = false
|
||||
|
||||
if score_left == SCORE_TO_WIN:
|
||||
get_node("winner_left").show()
|
||||
game_ended = true
|
||||
elif score_right == SCORE_TO_WIN:
|
||||
get_node("winner_right").show()
|
||||
game_ended = true
|
||||
|
||||
if game_ended:
|
||||
get_node("exit_game").show()
|
||||
get_node("ball").rpc("stop")
|
||||
|
||||
func _on_exit_game_pressed():
|
||||
emit_signal("game_finished")
|
||||
|
||||
func _ready():
|
||||
# by default, all nodes in server inherit from master
|
||||
# while all nodes in clients inherit from puppet
|
||||
if get_tree().is_network_server():
|
||||
#if in the server, get control of player 2 to the other peeer, this function is tree recursive by default
|
||||
get_node("player2").set_network_master(get_tree().get_network_connected_peers()[0])
|
||||
else:
|
||||
#if in the client, give control of player 2 to itself, this function is tree recursive by default
|
||||
get_node("player2").set_network_master(get_tree().get_network_unique_id())
|
||||
|
||||
#let each paddle know which one is left, too
|
||||
get_node("player1").left = true
|
||||
get_node("player2").left = false
|
||||
print("unique id: ", get_tree().get_network_unique_id())
|
||||
@@ -1,11 +1,11 @@
|
||||
[gd_scene load_steps=5 format=2]
|
||||
|
||||
[ext_resource path="res://pong.gd" type="Script" id=1]
|
||||
[ext_resource path="res://scripts/pong.gd" type="Script" id=1]
|
||||
[ext_resource path="res://separator.png" type="Texture" id=2]
|
||||
[ext_resource path="res://ball.tscn" type="PackedScene" id=3]
|
||||
[ext_resource path="res://paddle.tscn" type="PackedScene" id=4]
|
||||
[ext_resource path="res://paddle.tscn" type="PackedScene" id=3]
|
||||
[ext_resource path="res://ball.tscn" type="PackedScene" id=4]
|
||||
|
||||
[node name="pong" type="Node2D"]
|
||||
[node name="Pong" type="Node2D"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="."]
|
||||
@@ -16,26 +16,28 @@ __meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="separator" type="Sprite" parent="."]
|
||||
[node name="Separator" type="Sprite" parent="."]
|
||||
position = Vector2( 320, 200 )
|
||||
texture = ExtResource( 2 )
|
||||
|
||||
[node name="player1" parent="." instance=ExtResource( 4 )]
|
||||
[node name="Player1" parent="." instance=ExtResource( 3 )]
|
||||
position = Vector2( 32.49, 188.622 )
|
||||
left = true
|
||||
|
||||
[node name="sprite" parent="player1" index="0"]
|
||||
self_modulate = Color( 1, 0, 0.960938, 1 )
|
||||
[node name="Sprite" parent="Player1" index="0"]
|
||||
self_modulate = Color( 0, 1, 1, 1 )
|
||||
|
||||
[node name="player2" parent="." instance=ExtResource( 4 )]
|
||||
[node name="Player2" parent="." instance=ExtResource( 3 )]
|
||||
self_modulate = Color( 1, 0, 1, 1 )
|
||||
position = Vector2( 608.88, 188.622 )
|
||||
|
||||
[node name="sprite" parent="player2" index="0"]
|
||||
self_modulate = Color( 0, 0.929688, 1, 1 )
|
||||
[node name="Sprite" parent="Player2" index="0"]
|
||||
self_modulate = Color( 1, 0, 1, 1 )
|
||||
|
||||
[node name="ball" parent="." instance=ExtResource( 3 )]
|
||||
[node name="Ball" parent="." instance=ExtResource( 4 )]
|
||||
position = Vector2( 320.387, 189.525 )
|
||||
|
||||
[node name="score_left" type="Label" parent="."]
|
||||
[node name="ScoreLeft" type="Label" parent="."]
|
||||
margin_left = 240.0
|
||||
margin_top = 10.0
|
||||
margin_right = 280.0
|
||||
@@ -45,7 +47,7 @@ size_flags_vertical = 0
|
||||
text = "0"
|
||||
align = 1
|
||||
|
||||
[node name="score_right" type="Label" parent="."]
|
||||
[node name="ScoreRight" type="Label" parent="."]
|
||||
margin_left = 360.0
|
||||
margin_top = 10.0
|
||||
margin_right = 400.0
|
||||
@@ -55,7 +57,7 @@ size_flags_vertical = 0
|
||||
text = "0"
|
||||
align = 1
|
||||
|
||||
[node name="winner_left" type="Label" parent="."]
|
||||
[node name="WinnerLeft" type="Label" parent="."]
|
||||
visible = false
|
||||
margin_left = 190.0
|
||||
margin_top = 170.0
|
||||
@@ -65,7 +67,7 @@ size_flags_horizontal = 2
|
||||
size_flags_vertical = 0
|
||||
text = "The Winner!"
|
||||
|
||||
[node name="winner_right" type="Label" parent="."]
|
||||
[node name="WinnerRight" type="Label" parent="."]
|
||||
visible = false
|
||||
margin_left = 380.0
|
||||
margin_top = 170.0
|
||||
@@ -75,7 +77,7 @@ size_flags_horizontal = 2
|
||||
size_flags_vertical = 0
|
||||
text = "The Winner!"
|
||||
|
||||
[node name="exit_game" type="Button" parent="."]
|
||||
[node name="ExitGame" type="Button" parent="."]
|
||||
visible = false
|
||||
margin_left = 280.0
|
||||
margin_top = 340.0
|
||||
@@ -88,8 +90,8 @@ text = "Exit Game"
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
offset = Vector2( 320, 200 )
|
||||
current = true
|
||||
[connection signal="pressed" from="exit_game" to="." method="_on_exit_game_pressed"]
|
||||
[connection signal="pressed" from="ExitGame" to="." method="_on_exit_game_pressed"]
|
||||
|
||||
[editable path="player1"]
|
||||
[editable path="Player1"]
|
||||
|
||||
[editable path="player2"]
|
||||
[editable path="Player2"]
|
||||
|
||||
@@ -40,11 +40,19 @@ singletons=[ ]
|
||||
move_down={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":90,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_up={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
62
networking/multiplayer_pong/scripts/ball.gd
Normal file
@@ -0,0 +1,62 @@
|
||||
extends Area2D
|
||||
|
||||
const DEFAULT_SPEED = 100
|
||||
|
||||
var direction = Vector2.LEFT
|
||||
var stopped = false
|
||||
var _speed = DEFAULT_SPEED
|
||||
|
||||
onready var _screen_size = get_viewport_rect().size
|
||||
|
||||
func _process(delta):
|
||||
_speed += delta
|
||||
# Ball will move normally for both players,
|
||||
# even if it's sightly out of sync between them,
|
||||
# so each player sees the motion as smooth and not jerky.
|
||||
if not stopped:
|
||||
translate(_speed * delta * direction)
|
||||
|
||||
# Check screen bounds to make ball bounce.
|
||||
var ball_pos = position
|
||||
if (ball_pos.y < 0 and direction.y < 0) or (ball_pos.y > _screen_size.y and direction.y > 0):
|
||||
direction.y = -direction.y
|
||||
|
||||
if is_network_master():
|
||||
# Only master will decide when the ball is out in the left side (it's own side).
|
||||
# This makes the game playable even if latency is high and ball is going fast.
|
||||
# Otherwise ball might be out in the other player's screen but not this one.
|
||||
if ball_pos.x < 0:
|
||||
get_parent().rpc("update_score", false)
|
||||
rpc("_reset_ball", false)
|
||||
else:
|
||||
# Only the puppet will decide when the ball is out in the right side (it's own side).
|
||||
# This makes the game playable even if latency is high and ball is going fast.
|
||||
# Otherwise ball might be out in the other player's screen but not this one.
|
||||
if ball_pos.x > _screen_size.x:
|
||||
get_parent().rpc("update_score", true)
|
||||
rpc("_reset_ball", true)
|
||||
|
||||
|
||||
sync func bounce(left, random):
|
||||
# Using sync because both players can make it bounce.
|
||||
if left:
|
||||
direction.x = abs(direction.x)
|
||||
else:
|
||||
direction.x = -abs(direction.x)
|
||||
|
||||
_speed *= 1.1
|
||||
direction.y = random * 2.0 - 1
|
||||
direction = direction.normalized()
|
||||
|
||||
|
||||
sync func stop():
|
||||
stopped = true
|
||||
|
||||
|
||||
sync func _reset_ball(for_left):
|
||||
position = _screen_size / 2
|
||||
if for_left:
|
||||
direction = Vector2.LEFT
|
||||
else:
|
||||
direction = Vector2.RIGHT
|
||||
_speed = DEFAULT_SPEED
|
||||
@@ -1,102 +1,108 @@
|
||||
extends Control
|
||||
|
||||
const DEFAULT_PORT = 8910 # some random number, pick your port properly
|
||||
const DEFAULT_PORT = 8910 # An arbitrary number.
|
||||
|
||||
#### Network callbacks from SceneTree ####
|
||||
|
||||
# callback from SceneTree
|
||||
func _player_connected(_id):
|
||||
#someone connected, start the game!
|
||||
var pong = load("res://pong.tscn").instance()
|
||||
pong.connect("game_finished", self, "_end_game", [], CONNECT_DEFERRED) # connect deferred so we can safely erase it from the callback
|
||||
|
||||
get_tree().get_root().add_child(pong)
|
||||
hide()
|
||||
|
||||
func _player_disconnected(_id):
|
||||
|
||||
if get_tree().is_network_server():
|
||||
_end_game("Client disconnected")
|
||||
else:
|
||||
_end_game("Server disconnected")
|
||||
|
||||
# callback from SceneTree, only for clients (not server)
|
||||
func _connected_ok():
|
||||
# will not use this one
|
||||
pass
|
||||
|
||||
# callback from SceneTree, only for clients (not server)
|
||||
func _connected_fail():
|
||||
|
||||
_set_status("Couldn't connect",false)
|
||||
|
||||
get_tree().set_network_peer(null) #remove peer
|
||||
|
||||
get_node("panel/join").set_disabled(false)
|
||||
get_node("panel/host").set_disabled(false)
|
||||
|
||||
func _server_disconnected():
|
||||
_end_game("Server disconnected")
|
||||
|
||||
##### Game creation functions ######
|
||||
|
||||
func _end_game(with_error=""):
|
||||
if has_node("/root/pong"):
|
||||
#erase pong scene
|
||||
get_node("/root/pong").free() # erase immediately, otherwise network might show errors (this is why we connected deferred above)
|
||||
show()
|
||||
|
||||
get_tree().set_network_peer(null) #remove peer
|
||||
|
||||
get_node("panel/join").set_disabled(false)
|
||||
get_node("panel/host").set_disabled(false)
|
||||
|
||||
_set_status(with_error, false)
|
||||
|
||||
func _set_status(text, isok):
|
||||
#simple way to show status
|
||||
if isok:
|
||||
get_node("panel/status_ok").set_text(text)
|
||||
get_node("panel/status_fail").set_text("")
|
||||
else:
|
||||
get_node("panel/status_ok").set_text("")
|
||||
get_node("panel/status_fail").set_text(text)
|
||||
|
||||
func _on_host_pressed():
|
||||
var host = NetworkedMultiplayerENet.new()
|
||||
host.set_compression_mode(NetworkedMultiplayerENet.COMPRESS_RANGE_CODER)
|
||||
var err = host.create_server(DEFAULT_PORT, 1) # max: 1 peer, since it's a 2 players game
|
||||
if err != OK:
|
||||
#is another server running?
|
||||
_set_status("Can't host, address in use.",false)
|
||||
return
|
||||
|
||||
get_tree().set_network_peer(host)
|
||||
get_node("panel/join").set_disabled(true)
|
||||
get_node("panel/host").set_disabled(true)
|
||||
_set_status("Waiting for player..", true)
|
||||
|
||||
func _on_join_pressed():
|
||||
var ip = get_node("panel/address").get_text()
|
||||
if not ip.is_valid_ip_address():
|
||||
_set_status("IP address is invalid", false)
|
||||
return
|
||||
|
||||
var host = NetworkedMultiplayerENet.new()
|
||||
host.set_compression_mode(NetworkedMultiplayerENet.COMPRESS_RANGE_CODER)
|
||||
host.create_client(ip, DEFAULT_PORT)
|
||||
get_tree().set_network_peer(host)
|
||||
|
||||
_set_status("Connecting..", true)
|
||||
|
||||
|
||||
### INITIALIZER ####
|
||||
onready var address = $Address
|
||||
onready var host_button = $HostButton
|
||||
onready var join_button = $JoinButton
|
||||
onready var status_ok = $StatusOk
|
||||
onready var status_fail = $StatusFail
|
||||
|
||||
func _ready():
|
||||
# connect all the callbacks related to networking
|
||||
# Connect all the callbacks related to networking.
|
||||
get_tree().connect("network_peer_connected", self, "_player_connected")
|
||||
get_tree().connect("network_peer_disconnected", self, "_player_disconnected")
|
||||
get_tree().connect("connected_to_server", self, "_connected_ok")
|
||||
get_tree().connect("connection_failed", self, "_connected_fail")
|
||||
get_tree().connect("server_disconnected", self, "_server_disconnected")
|
||||
|
||||
#### Network callbacks from SceneTree ####
|
||||
|
||||
# Callback from SceneTree.
|
||||
func _player_connected(_id):
|
||||
# Someone connected, start the game!
|
||||
var pong = load("res://pong.tscn").instance()
|
||||
# Connect deferred so we can safely erase it from the callback.
|
||||
pong.connect("game_finished", self, "_end_game", [], CONNECT_DEFERRED)
|
||||
|
||||
get_tree().get_root().add_child(pong)
|
||||
hide()
|
||||
|
||||
|
||||
func _player_disconnected(_id):
|
||||
if get_tree().is_network_server():
|
||||
_end_game("Client disconnected")
|
||||
else:
|
||||
_end_game("Server disconnected")
|
||||
|
||||
|
||||
# Callback from SceneTree, only for clients (not server).
|
||||
func _connected_ok():
|
||||
pass # We don't need this function.
|
||||
|
||||
|
||||
# Callback from SceneTree, only for clients (not server).
|
||||
func _connected_fail():
|
||||
_set_status("Couldn't connect", false)
|
||||
|
||||
get_tree().set_network_peer(null) # Remove peer.
|
||||
|
||||
host_button.set_disabled(false)
|
||||
join_button.set_disabled(false)
|
||||
|
||||
|
||||
func _server_disconnected():
|
||||
_end_game("Server disconnected")
|
||||
|
||||
##### Game creation functions ######
|
||||
|
||||
func _end_game(with_error = ""):
|
||||
if has_node("/root/Pong"):
|
||||
# Erase immediately, otherwise network might show errors (this is why we connected deferred above).
|
||||
get_node("/root/Pong").free()
|
||||
show()
|
||||
|
||||
get_tree().set_network_peer(null) # Remove peer.
|
||||
host_button.set_disabled(false)
|
||||
join_button.set_disabled(false)
|
||||
|
||||
_set_status(with_error, false)
|
||||
|
||||
|
||||
func _set_status(text, isok):
|
||||
# Simple way to show status.
|
||||
if isok:
|
||||
status_ok.set_text(text)
|
||||
status_fail.set_text("")
|
||||
else:
|
||||
status_ok.set_text("")
|
||||
status_fail.set_text(text)
|
||||
|
||||
|
||||
func _on_host_pressed():
|
||||
var host = NetworkedMultiplayerENet.new()
|
||||
host.set_compression_mode(NetworkedMultiplayerENet.COMPRESS_RANGE_CODER)
|
||||
var err = host.create_server(DEFAULT_PORT, 1) # Maximum of 1 peer, since it's a 2-player game.
|
||||
if err != OK:
|
||||
# Is another server running?
|
||||
_set_status("Can't host, address in use.",false)
|
||||
return
|
||||
|
||||
get_tree().set_network_peer(host)
|
||||
host_button.set_disabled(true)
|
||||
join_button.set_disabled(true)
|
||||
_set_status("Waiting for player...", true)
|
||||
|
||||
|
||||
func _on_join_pressed():
|
||||
var ip = address.get_text()
|
||||
if not ip.is_valid_ip_address():
|
||||
_set_status("IP address is invalid", false)
|
||||
return
|
||||
|
||||
var host = NetworkedMultiplayerENet.new()
|
||||
host.set_compression_mode(NetworkedMultiplayerENet.COMPRESS_RANGE_CODER)
|
||||
host.create_client(ip, DEFAULT_PORT)
|
||||
get_tree().set_network_peer(host)
|
||||
|
||||
_set_status("Connecting...", true)
|
||||
49
networking/multiplayer_pong/scripts/paddle.gd
Normal file
@@ -0,0 +1,49 @@
|
||||
extends Area2D
|
||||
|
||||
const MOTION_SPEED = 150
|
||||
|
||||
export var left = false
|
||||
|
||||
var motion = 0
|
||||
var you_hidden = false
|
||||
|
||||
onready var _screen_size_y = get_viewport_rect().size.y
|
||||
|
||||
func _process(delta):
|
||||
# Is the master of the paddle.
|
||||
if is_network_master():
|
||||
motion = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
|
||||
|
||||
if not you_hidden and motion != 0:
|
||||
_hide_you_label()
|
||||
|
||||
motion *= MOTION_SPEED
|
||||
|
||||
# Using unreliable to make sure position is updated as fast
|
||||
# as possible, even if one of the calls is dropped.
|
||||
rpc_unreliable("set_pos_and_motion", position, motion)
|
||||
else:
|
||||
if not you_hidden:
|
||||
_hide_you_label()
|
||||
|
||||
translate(Vector2(0, motion * delta))
|
||||
|
||||
# Set screen limits.
|
||||
position.y = clamp(position.y, 16, _screen_size_y - 16)
|
||||
|
||||
|
||||
# Synchronize position and speed to the other peers.
|
||||
puppet func set_pos_and_motion(p_pos, p_motion):
|
||||
position = p_pos
|
||||
motion = p_motion
|
||||
|
||||
|
||||
func _hide_you_label():
|
||||
you_hidden = true
|
||||
get_node("You").hide()
|
||||
|
||||
|
||||
func _on_paddle_area_enter(area):
|
||||
if is_network_master():
|
||||
# Random for new direction generated on each peer.
|
||||
area.rpc("bounce", left, randf())
|
||||
51
networking/multiplayer_pong/scripts/pong.gd
Normal file
@@ -0,0 +1,51 @@
|
||||
extends Node2D
|
||||
|
||||
const SCORE_TO_WIN = 10
|
||||
|
||||
var score_left = 0
|
||||
var score_right = 0
|
||||
|
||||
signal game_finished()
|
||||
|
||||
onready var player2 = $Player2
|
||||
onready var score_left_node = $ScoreLeft
|
||||
onready var score_right_node = $ScoreRight
|
||||
onready var winner_left = $WinnerLeft
|
||||
onready var winner_right = $WinnerRight
|
||||
|
||||
func _ready():
|
||||
# By default, all nodes in server inherit from master,
|
||||
# while all nodes in clients inherit from puppet.
|
||||
# set_network_master is tree-recursive by default.
|
||||
if get_tree().is_network_server():
|
||||
# For the server, give control of player 2 to the other peer.
|
||||
player2.set_network_master(get_tree().get_network_connected_peers()[0])
|
||||
else:
|
||||
# For the client, give control of player 2 to itself.
|
||||
player2.set_network_master(get_tree().get_network_unique_id())
|
||||
print("unique id: ", get_tree().get_network_unique_id())
|
||||
|
||||
|
||||
sync func update_score(add_to_left):
|
||||
if add_to_left:
|
||||
score_left += 1
|
||||
score_left_node.set_text(str(score_left))
|
||||
else:
|
||||
score_right += 1
|
||||
score_right_node.set_text(str(score_right))
|
||||
|
||||
var game_ended = false
|
||||
if score_left == SCORE_TO_WIN:
|
||||
winner_left.show()
|
||||
game_ended = true
|
||||
elif score_right == SCORE_TO_WIN:
|
||||
winner_right.show()
|
||||
game_ended = true
|
||||
|
||||
if game_ended:
|
||||
$ExitGame.show()
|
||||
$Ball.rpc("stop")
|
||||
|
||||
|
||||
func _on_exit_game_pressed():
|
||||
emit_signal("game_finished")
|
||||
@@ -7,5 +7,4 @@ script = ExtResource( 1 )
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
autostart = true
|
||||
|
||||
[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
|
||||
|
||||
@@ -12,4 +12,3 @@ sun_energy = 16.0
|
||||
[resource]
|
||||
background_mode = 2
|
||||
background_sky = SubResource( 1 )
|
||||
|
||||
|
||||
@@ -4,4 +4,3 @@
|
||||
|
||||
[node name="Main" type="Node2D"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
|
||||
@@ -12,4 +12,3 @@ sun_energy = 16.0
|
||||
[resource]
|
||||
background_mode = 2
|
||||
background_sky = SubResource( 1 )
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 583 B After Width: | Height: | Size: 583 B |
|
Before Width: | Height: | Size: 138 B After Width: | Height: | Size: 138 B |
106
visual_script/pong/pong.tscn
Normal file
@@ -0,0 +1,106 @@
|
||||
[gd_scene load_steps=13 format=2]
|
||||
|
||||
[ext_resource path="res://scripts/paddle.vs" type="Script" id=1]
|
||||
[ext_resource path="res://left_pallete.png" type="Texture" id=2]
|
||||
[ext_resource path="res://right_pallete.png" type="Texture" id=3]
|
||||
[ext_resource path="res://scripts/ball.vs" type="Script" id=4]
|
||||
[ext_resource path="res://ball.png" type="Texture" id=5]
|
||||
[ext_resource path="res://separator.png" type="Texture" id=6]
|
||||
[ext_resource path="res://scripts/wall.vs" type="Script" id=7]
|
||||
[ext_resource path="res://scripts/ceiling_floor.vs" type="Script" id=8]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=1]
|
||||
extents = Vector2( 4, 16 )
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=2]
|
||||
extents = Vector2( 4, 4 )
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=3]
|
||||
extents = Vector2( 10, 200 )
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=4]
|
||||
extents = Vector2( 320, 10 )
|
||||
|
||||
[node name="Pong" type="Node2D"]
|
||||
|
||||
[node name="Background" type="ColorRect" parent="."]
|
||||
margin_right = 640.0
|
||||
margin_bottom = 400.0
|
||||
color = Color( 0.141176, 0.152941, 0.164706, 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="Left" type="Area2D" parent="."]
|
||||
position = Vector2( 67.6285, 192.594 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Left"]
|
||||
texture = ExtResource( 2 )
|
||||
|
||||
[node name="Collision" type="CollisionShape2D" parent="Left"]
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="Right" type="Area2D" parent="."]
|
||||
position = Vector2( 563.815, 188.919 )
|
||||
script = ExtResource( 1 )
|
||||
ball_dir = -1.0
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Right"]
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="Collision" type="CollisionShape2D" parent="Right"]
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="Ball" type="Area2D" parent="."]
|
||||
position = Vector2( 320.5, 191.124 )
|
||||
script = ExtResource( 4 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Ball"]
|
||||
texture = ExtResource( 5 )
|
||||
|
||||
[node name="Collision" type="CollisionShape2D" parent="Ball"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Separator" type="Sprite" parent="."]
|
||||
position = Vector2( 320, 200 )
|
||||
texture = ExtResource( 6 )
|
||||
|
||||
[node name="LeftWall" type="Area2D" parent="."]
|
||||
position = Vector2( -10, 200 )
|
||||
script = ExtResource( 7 )
|
||||
|
||||
[node name="Collision" type="CollisionShape2D" parent="LeftWall"]
|
||||
shape = SubResource( 3 )
|
||||
|
||||
[node name="RightWall" type="Area2D" parent="."]
|
||||
position = Vector2( 650, 200 )
|
||||
script = ExtResource( 7 )
|
||||
|
||||
[node name="Collision" type="CollisionShape2D" parent="RightWall"]
|
||||
shape = SubResource( 3 )
|
||||
|
||||
[node name="Ceiling" type="Area2D" parent="."]
|
||||
position = Vector2( 320, -10 )
|
||||
script = ExtResource( 8 )
|
||||
|
||||
[node name="Collision" type="CollisionShape2D" parent="Ceiling"]
|
||||
shape = SubResource( 4 )
|
||||
|
||||
[node name="Floor" type="Area2D" parent="."]
|
||||
position = Vector2( 320, 410 )
|
||||
script = ExtResource( 8 )
|
||||
bounce_direction = -1.0
|
||||
|
||||
[node name="Collision" type="CollisionShape2D" parent="Floor"]
|
||||
shape = SubResource( 4 )
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
offset = Vector2( 320, 200 )
|
||||
current = true
|
||||
[connection signal="area_entered" from="Left" to="Left" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="Right" to="Right" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="LeftWall" to="LeftWall" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="RightWall" to="RightWall" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="Ceiling" to="Ceiling" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="Floor" to="Floor" method="_on_area_entered"]
|
||||
@@ -15,7 +15,7 @@ _global_script_class_icons={
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Visual Pong"
|
||||
config/name="Pong with VisualScript"
|
||||
run/main_scene="pong.tscn"
|
||||
config/icon="res://icon.png"
|
||||
|
||||
@@ -36,22 +36,31 @@ singletons=[ ]
|
||||
left_move_down={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":90,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":89,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
left_move_up={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
right_move_down={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":1,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":1,"axis":1,"axis_value":1.0,"script":null)
|
||||
]
|
||||
}
|
||||
right_move_up={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":1,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":1,"axis":1,"axis_value":-1.0,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 138 B After Width: | Height: | Size: 138 B |
BIN
visual_script/pong/scripts/ball.vs
Normal file
BIN
visual_script/pong/scripts/ceiling_floor.vs
Normal file
BIN
visual_script/pong/scripts/paddle.vs
Normal file
BIN
visual_script/pong/scripts/wall.vs
Normal file
|
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 142 B |
@@ -1,106 +0,0 @@
|
||||
[gd_scene load_steps=13 format=2]
|
||||
|
||||
[ext_resource path="res://paddle.vs" type="Script" id=1]
|
||||
[ext_resource path="res://left_pallete.png" type="Texture" id=2]
|
||||
[ext_resource path="res://right_pallete.png" type="Texture" id=3]
|
||||
[ext_resource path="res://ball.vs" type="Script" id=4]
|
||||
[ext_resource path="res://ball.png" type="Texture" id=5]
|
||||
[ext_resource path="res://separator.png" type="Texture" id=6]
|
||||
[ext_resource path="res://wall.vs" type="Script" id=7]
|
||||
[ext_resource path="res://ceiling_floor.vs" type="Script" id=8]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=1]
|
||||
extents = Vector2( 4, 16 )
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=2]
|
||||
extents = Vector2( 4, 4 )
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=3]
|
||||
extents = Vector2( 10, 200 )
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=4]
|
||||
extents = Vector2( 320, 10 )
|
||||
|
||||
[node name="game" type="Node2D"]
|
||||
|
||||
[node name="TextureRect" type="ColorRect" parent="."]
|
||||
margin_right = 640.0
|
||||
margin_bottom = 400.0
|
||||
color = Color( 0.141176, 0.152941, 0.164706, 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="left" type="Area2D" parent="."]
|
||||
position = Vector2( 67.6285, 192.594 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="sprite" type="Sprite" parent="left"]
|
||||
texture = ExtResource( 2 )
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="left"]
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="right" type="Area2D" parent="."]
|
||||
position = Vector2( 563.815, 188.919 )
|
||||
script = ExtResource( 1 )
|
||||
ball_dir = -1.0
|
||||
|
||||
[node name="sprite" type="Sprite" parent="right"]
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="right"]
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="ball" type="Area2D" parent="."]
|
||||
position = Vector2( 320.5, 191.124 )
|
||||
script = ExtResource( 4 )
|
||||
|
||||
[node name="sprite" type="Sprite" parent="ball"]
|
||||
texture = ExtResource( 5 )
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="ball"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="separator" type="Sprite" parent="."]
|
||||
position = Vector2( 320, 200 )
|
||||
texture = ExtResource( 6 )
|
||||
|
||||
[node name="left_wall" type="Area2D" parent="."]
|
||||
position = Vector2( -10, 200 )
|
||||
script = ExtResource( 7 )
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="left_wall"]
|
||||
shape = SubResource( 3 )
|
||||
|
||||
[node name="right_wall" type="Area2D" parent="."]
|
||||
position = Vector2( 650, 200 )
|
||||
script = ExtResource( 7 )
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="right_wall"]
|
||||
shape = SubResource( 3 )
|
||||
|
||||
[node name="ceiling" type="Area2D" parent="."]
|
||||
position = Vector2( 320, -10 )
|
||||
script = ExtResource( 8 )
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="ceiling"]
|
||||
shape = SubResource( 4 )
|
||||
|
||||
[node name="floor" type="Area2D" parent="."]
|
||||
position = Vector2( 320, 410 )
|
||||
script = ExtResource( 8 )
|
||||
y_direction = -1.0
|
||||
|
||||
[node name="collision" type="CollisionShape2D" parent="floor"]
|
||||
shape = SubResource( 4 )
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
offset = Vector2( 320, 200 )
|
||||
current = true
|
||||
[connection signal="area_entered" from="left" to="left" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="right" to="right" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="left_wall" to="left_wall" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="right_wall" to="right_wall" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="ceiling" to="ceiling" method="_on_area_entered"]
|
||||
[connection signal="area_entered" from="floor" to="floor" method="_on_area_entered"]
|
||||