using Godot; using System; using System.Collections.Generic; using System.Linq; public partial class Main : Node { [Export] public PackedScene BallScene; public bool _takingShot, _cueBallPotted; public float _maxPower = 8.0f, _moveThreshold = 5.0f; public Vector2 _startPosition = new Vector2(890, 340); public Ball _cueBall; public List _ballImages = new(); public List _potted = new(); public override void _Ready() { LoadBallImages(); NewGame(); List pockets = GetNode("Table").GetChildren().Where(n => n.GetName().ToString().ToLower().Contains("pocket")).Select(n => (Area2D)n).ToList(); for (int i = 0; i < pockets.Count; i++) { pockets[i].BodyEntered += PottedBall; } //GetNode
("Table").GetNode("PocketTL").BodyEntered += PottedBall; //GetNode
("Table").GetNode("PocketTR").BodyEntered += PottedBall; //GetNode
("Table").GetNode("PocketR").BodyEntered += PottedBall; //GetNode
("Table").GetNode("PocketBR").BodyEntered += PottedBall; //GetNode
("Table").GetNode("PocketBL").BodyEntered += PottedBall; //GetNode
("Table").GetNode("PocketL").BodyEntered += PottedBall; } public override void _Process(double delta_) { bool moving = false; List balls = GetTree().GetNodesInGroup("balls").Select(b => (Ball)b).ToList(); for (int i = 0; i < balls.Count; i++) { if (balls[i].LinearVelocity.Length() > 0 && balls[i].LinearVelocity.Length() < _moveThreshold) { balls[i].Sleeping = true; } else if (balls[i].LinearVelocity.Length() >= _moveThreshold) { moving = true; } } if (!moving) { if (_cueBallPotted) { ResetCueBall(); _cueBallPotted = false; } if (!_takingShot) { _takingShot = true; ShowCue(); } } else { if (_takingShot) { _takingShot = false; HideCue(); } } } public void GenerateBalls() { int count = 0; int rows = 5; int diameter = 36; for (int i = 0; i < 5; i++) { for (int j = 0; j < rows; j++) { Ball ball = BallScene.Instantiate(); Vector2 position = new Vector2(250 + (i*(diameter)), 267 + (j*(diameter)) + (i*(diameter / 2))); AddChild(ball); ball.Position = position; ball.GetNode("Texture").Texture = _ballImages[count]; count += 1; } rows -= 1; } } public void HideCue() { GetNode("Cue").SetProcess(false); GetNode("Cue").Hide(); GetNode("PowerBar").Hide(); } public void LoadBallImages() { _ballImages.Clear(); for (int i = 1; i < 17; i++) { string fileName = "res://art/ball_"+i+".png"; Texture2D image = GD.Load(fileName); _ballImages.Add(image); } } public void NewGame() { ResetCueBall(); GenerateBalls(); ShowCue(); } public void PottedBall(Node2D body) { if (body == _cueBall) { _cueBallPotted = true; RemoveCueBall(); } else { Sprite2D ballSprite = new Sprite2D(); AddChild(ballSprite); ballSprite.Texture = body.GetNode("Texture").Texture; _potted.Add(ballSprite); ballSprite.Position = new Vector2(50 * _potted.Count, 725); body.QueueFree(); } //GetNode
("Table").GetNode("Pockets").GetNode("Pockets") } public void RemoveCueBall() { Ball oldCueBall = _cueBall; RemoveChild(oldCueBall); oldCueBall.QueueFree(); } public void ResetCueBall() { _cueBall = BallScene.Instantiate(); AddChild(_cueBall); _cueBall.Position = _startPosition; _cueBall.GetNode("Texture").Texture = _ballImages[^1]; _takingShot = false; } public void ShowCue() { GetNode("Cue").SetProcess(true); GetNode("Cue").Position = _cueBall.Position; GetNode("PowerBar").Position = new Vector2(_cueBall.Position.X - GetNode("PowerBar").Size.X / 2, _cueBall.Position.Y + GetNode("PowerBar").Size.Y / 2); GetNode("Cue").Show(); GetNode("PowerBar").Show(); } private void OnCueShoot(Vector2 impulse) { _cueBall.ApplyCentralImpulse(impulse); } }