Ball.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using Godot;
  2. using System;
  3. public partial class Ball : Area2D
  4. {
  5. private const int DefaultSpeed = 100;
  6. private Vector2 _direction = Vector2.Left;
  7. private bool _stopped = false;
  8. private float _speed = DefaultSpeed;
  9. private Vector2 _screenSize;
  10. // Called when the node enters the scene tree for the first time.
  11. public override void _Ready()
  12. {
  13. _screenSize = GetViewportRect().Size;
  14. }
  15. // Called every frame. 'delta' is the elapsed time since the previous frame.
  16. public override void _Process(float delta)
  17. {
  18. _speed += delta;
  19. // Ball will move normally for both players,
  20. // even if it's slightly out of sync between them,
  21. // so each player sees the motion as smooth and not jerky.
  22. if (!_stopped)
  23. {
  24. Translate(_speed * delta * _direction);
  25. }
  26. // Check screen bounds to make ball bounce.
  27. var ballPosition = Position;
  28. if ((ballPosition.y < 0 && _direction.y < 0) || (ballPosition.y > _screenSize.y && _direction.y > 0))
  29. {
  30. _direction.y = -_direction.y;
  31. }
  32. if (IsNetworkMaster())
  33. {
  34. // Only the master will decide when the ball is out in
  35. // the left side (it's own side). This makes the game
  36. // playable even if latency is high and ball is going
  37. // fast. Otherwise ball might be out in the other
  38. // player's screen but not this one.
  39. if (ballPosition.x < 0)
  40. {
  41. GetParent().Rpc("UpdateScore", false);
  42. Rpc("ResetBall", false);
  43. }
  44. else
  45. {
  46. // Only the puppet will decide when the ball is out in
  47. // the right side, which is it's own side. This makes
  48. // the game playable even if latency is high and ball
  49. // is going fast. Otherwise ball might be out in the
  50. // other player's screen but not this one.
  51. if (ballPosition.x > _screenSize.x)
  52. {
  53. GetParent().Rpc("UpdateScore", true);
  54. Rpc("ResetBall", true);
  55. }
  56. }
  57. }
  58. }
  59. [Sync]
  60. private void Bounce(bool left, float random)
  61. {
  62. // Using sync because both players can make it bounce.
  63. if (left)
  64. {
  65. _direction.x = Mathf.Abs(_direction.x);
  66. }
  67. else
  68. {
  69. _direction.x = -Mathf.Abs(_direction.x);
  70. }
  71. _speed *= 1.1f;
  72. _direction.y = random * 2.0f - 1;
  73. _direction = _direction.Normalized();
  74. }
  75. [Sync]
  76. private void Stop()
  77. {
  78. _stopped = true;
  79. }
  80. [Sync]
  81. private void ResetBall(bool forLeft)
  82. {
  83. Position = _screenSize / 2;
  84. _direction = forLeft ? Vector2.Left : Vector2.Right;
  85. _speed = DefaultSpeed;
  86. }
  87. }