diff --git a/GameBoard.cs b/GameBoard.cs new file mode 100644 index 0000000..8c822c2 --- /dev/null +++ b/GameBoard.cs @@ -0,0 +1,79 @@ +using Godot; + +public partial class GameBoard : Node2D +{ + private PuzzleTile[,] _grid = new PuzzleTile[5, 4]; + + private PuzzleTile _activeTile; + + // FIX 1: Use GD.Load and explicitly cast it to (PackedScene) + private PackedScene _tileScene = (PackedScene)GD.Load("res://PuzzleTile.tscn"); + + public override void _Ready() + { + // FIX 2: Explicitly cast the returned Node to (PuzzleTile) + _activeTile = (PuzzleTile)GetNode("PuzzleTile"); + _activeTile.GridX = 0; + _activeTile.GridY = 0; + + _grid[0, 0] = _activeTile; + + SpawnObstacle(4, 0); + } + + private void SpawnObstacle(int x, int y) + { + // FIX 3: Explicitly cast the instantiated object to (PuzzleTile) + PuzzleTile obstacle = (PuzzleTile)_tileScene.Instantiate(); + AddChild(obstacle); + + obstacle.GridX = x; + obstacle.GridY = y; + obstacle.Position = new Vector2(x * 128, y * 128); + obstacle.Modulate = new Color(1, 0, 0); + + _grid[x, y] = obstacle; + } + + public override void _Process(double delta) + { + if (_activeTile == null || _activeTile.IsMoving) return; + + Vector2 direction = Vector2.Zero; + if (Input.IsActionJustPressed("ui_right")) direction.X = 1; + else if (Input.IsActionJustPressed("ui_left")) direction.X = -1; + else if (Input.IsActionJustPressed("ui_down")) direction.Y = 1; + else if (Input.IsActionJustPressed("ui_up")) direction.Y = -1; + + if (direction != Vector2.Zero) + { + CalculateSlide(_activeTile, (int)direction.X, (int)direction.Y); + } + } + + private void CalculateSlide(PuzzleTile tile, int dirX, int dirY) + { + int testX = tile.GridX; + int testY = tile.GridY; + + while (true) + { + int nextX = testX + dirX; + int nextY = testY + dirY; + + if (nextX < 0 || nextX >= 5 || nextY < 0 || nextY >= 4) break; + + if (_grid[nextX, nextY] != null) break; + + testX = nextX; + testY = nextY; + } + + if (testX == tile.GridX && testY == tile.GridY) return; + + _grid[tile.GridX, tile.GridY] = null; + _grid[testX, testY] = tile; + + tile.SlideTo(testX, testY); + } +} \ No newline at end of file diff --git a/GameBoard.cs.uid b/GameBoard.cs.uid new file mode 100644 index 0000000..69fab16 --- /dev/null +++ b/GameBoard.cs.uid @@ -0,0 +1 @@ +uid://rpsqpmj7vt7d diff --git a/Player.cs b/Player.cs deleted file mode 100644 index 63cb867..0000000 --- a/Player.cs +++ /dev/null @@ -1,84 +0,0 @@ -using Godot; - -public partial class Player : Sprite2D -{ - // 1. Logical Grid Coordinates (0,0 is top left) - private int _gridX = 0; - private int _gridY = 0; - - // The default Godot icon is 128x128 pixels - private int _tileSize = 128; - - // State machine flag to prevent input while sliding - private bool _isMoving = false; - - public override void _Process(double delta) - { - // If we are currently animating a slide, ignore the keyboard - if (_isMoving) return; - - Vector2 direction = Vector2.Zero; - - // Trigger only once per key press - if (Input.IsActionJustPressed("ui_right")) direction.X = 1; - else if (Input.IsActionJustPressed("ui_left")) direction.X = -1; - else if (Input.IsActionJustPressed("ui_down")) direction.Y = 1; - else if (Input.IsActionJustPressed("ui_up")) direction.Y = -1; - - if (direction != Vector2.Zero) - { - SlideTile((int)direction.X, (int)direction.Y); - } - } - - private void SlideTile(int dirX, int dirY) - { - int testGridX = _gridX; - int testGridY = _gridY; - - // 1. The "Slide on Ice" Loop - while (true) - { - int nextGridX = testGridX + dirX; - int nextGridY = testGridY + dirY; - - // Check if the next step is outside the 5x4 boundary - if (nextGridX < 0 || nextGridX >= 5 || nextGridY < 0 || nextGridY >= 4) - { - break; // Stop looking, we hit a wall! - } - - // TODO: In the future, we will also check: - // if (_gridArray[nextGridX, nextGridY] != null) { break; } - - // If the space is valid, update our test coordinates and loop again - testGridX = nextGridX; - testGridY = nextGridY; - } - - // 2. Did we actually move? - if (testGridX == _gridX && testGridY == _gridY) - { - return; // We were already against a wall, do nothing - } - - // 3. Update our logical position to the final destination - _gridX = testGridX; - _gridY = testGridY; - - Vector2 targetPixelPos = new Vector2(_gridX * _tileSize, _gridY * _tileSize); - - // 4. Calculate animation time based on distance traveled - // So moving 4 tiles doesn't look 4x faster than moving 1 tile - float distance = Mathf.Abs(dirX != 0 ? _gridX - testGridX : _gridY - testGridY) * _tileSize; - // Use a base speed (e.g., 600 pixels per second) - float tweenDuration = distance / 600.0f; - - // 5. Animate the slide - _isMoving = true; - Tween tween = CreateTween(); - - tween.TweenProperty(this, "position", targetPixelPos, tweenDuration); - tween.Finished += () => _isMoving = false; - } -} \ No newline at end of file diff --git a/PuzzleTile.cs b/PuzzleTile.cs new file mode 100644 index 0000000..62ccc74 --- /dev/null +++ b/PuzzleTile.cs @@ -0,0 +1,28 @@ +using Godot; + +public partial class PuzzleTile : Sprite2D +{ + // Public properties so the GameBoard can read/write them + public int GridX { get; set; } + public int GridY { get; set; } + public bool IsMoving { get; private set; } = false; + + private int _tileSize = 128; + + // The board will call this method when it calculates a valid move + public void SlideTo(int targetX, int targetY) + { + // Calculate distance for animation speed + float distance = Mathf.Abs(targetX != GridX ? targetX - GridX : targetY - GridY) * _tileSize; + float tweenDuration = distance / 600.0f; + + GridX = targetX; + GridY = targetY; + Vector2 targetPixelPos = new Vector2(GridX * _tileSize, GridY * _tileSize); + + IsMoving = true; + Tween tween = CreateTween(); + tween.TweenProperty(this, "position", targetPixelPos, tweenDuration); + tween.Finished += () => IsMoving = false; + } +} \ No newline at end of file diff --git a/Player.cs.uid b/PuzzleTile.cs.uid similarity index 100% rename from Player.cs.uid rename to PuzzleTile.cs.uid diff --git a/PuzzleTile.tscn b/PuzzleTile.tscn new file mode 100644 index 0000000..92b0dc7 --- /dev/null +++ b/PuzzleTile.tscn @@ -0,0 +1,8 @@ +[gd_scene format=3 uid="uid://6v1r7bxv6tw0"] + +[ext_resource type="Texture2D" uid="uid://chvsugc1m4gqu" path="res://icon.svg" id="1_r1bor"] +[ext_resource type="Script" uid="uid://cw3xemcqi21rw" path="res://PuzzleTile.cs" id="2_xifec"] + +[node name="PuzzleTile" type="Sprite2D" unique_id=2135824193] +texture = ExtResource("1_r1bor") +script = ExtResource("2_xifec") diff --git a/main.tscn b/main.tscn index 1ebe5dd..4e7092a 100644 --- a/main.tscn +++ b/main.tscn @@ -1,10 +1,9 @@ [gd_scene format=3 uid="uid://cun63uvd6k6eg"] -[ext_resource type="Texture2D" uid="uid://chvsugc1m4gqu" path="res://icon.svg" id="1_0xm2m"] -[ext_resource type="Script" uid="uid://cw3xemcqi21rw" path="res://Player.cs" id="2_0xm2m"] +[ext_resource type="Script" uid="uid://rpsqpmj7vt7d" path="res://GameBoard.cs" id="1_0xm2m"] +[ext_resource type="PackedScene" uid="uid://6v1r7bxv6tw0" path="res://PuzzleTile.tscn" id="1_ig7tw"] [node name="Main" type="Node2D" unique_id=673288413] +script = ExtResource("1_0xm2m") -[node name="Player" type="Sprite2D" parent="." unique_id=1433899478] -texture = ExtResource("1_0xm2m") -script = ExtResource("2_0xm2m") +[node name="PuzzleTile" parent="." unique_id=2135824193 instance=ExtResource("1_ig7tw")]