-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
Copy pathBall.cs
97 lines (87 loc) · 3.05 KB
/
Ball.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
using Godot;
using System;
public partial class Ball : Area2D
{
private const int DefaultSpeed = 100;
private Vector2 _direction = Vector2.Left;
private bool _stopped = false;
private double _speed = DefaultSpeed;
private Vector2 _screenSize;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
_screenSize = GetViewportRect().Size;
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
_speed += delta;
// Ball will move normally for both players,
// even if it's slightly out of sync between them,
// so each player sees the motion as smooth and not jerky.
if (!_stopped)
{
Translate((float)(_speed * delta) * _direction);
}
// Check screen bounds to make ball bounce.
var ballPosition = Position;
if ((ballPosition.Y < 0 && _direction.Y < 0) || (ballPosition.Y > _screenSize.Y && _direction.Y > 0))
{
_direction.Y = -_direction.Y;
}
if (IsMultiplayerAuthority())
{
// Only the server (Multiplayer Authority) 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 (ballPosition.X < 0)
{
GetParent().Rpc("UpdateScore", false);
Rpc("ResetBall", false);
}
else
{
// Only the peer will decide when the ball is out in
// the right side, which is 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 (ballPosition.X > _screenSize.X)
{
GetParent().Rpc("UpdateScore", true);
Rpc("ResetBall", true);
}
}
}
}
[Rpc(mode: MultiplayerApi.RpcMode.AnyPeer, CallLocal = true)]
private void Bounce(bool left, float random)
{
// Using sync because both players can make it bounce.
if (left)
{
_direction.X = Mathf.Abs(_direction.X);
}
else
{
_direction.X = -Mathf.Abs(_direction.X);
}
_speed *= 1.1f;
_direction.Y = random * 2.0f - 1;
_direction = _direction.Normalized();
}
[Rpc(mode: MultiplayerApi.RpcMode.AnyPeer, CallLocal = true)]
private void Stop()
{
_stopped = true;
}
[Rpc(mode: MultiplayerApi.RpcMode.AnyPeer, CallLocal = true)]
private void ResetBall(bool forLeft)
{
Position = _screenSize / 2;
_direction = forLeft ? Vector2.Left : Vector2.Right;
_speed = DefaultSpeed;
}
}