diff --git a/half-earth/Half-earth.csproj b/half-earth/Half-earth.csproj new file mode 100644 index 0000000..29905c2 --- /dev/null +++ b/half-earth/Half-earth.csproj @@ -0,0 +1,6 @@ + + + net472 + Halfearth + + \ No newline at end of file diff --git a/half-earth/Half-earth.sln b/half-earth/Half-earth.sln new file mode 100644 index 0000000..a7cf826 --- /dev/null +++ b/half-earth/Half-earth.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Half-earth", "Half-earth.csproj", "{C894A75C-991B-4000-9BD9-9B0B186304C4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + ExportDebug|Any CPU = ExportDebug|Any CPU + ExportRelease|Any CPU = ExportRelease|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C894A75C-991B-4000-9BD9-9B0B186304C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C894A75C-991B-4000-9BD9-9B0B186304C4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C894A75C-991B-4000-9BD9-9B0B186304C4}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU + {C894A75C-991B-4000-9BD9-9B0B186304C4}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU + {C894A75C-991B-4000-9BD9-9B0B186304C4}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU + {C894A75C-991B-4000-9BD9-9B0B186304C4}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU + EndGlobalSection +EndGlobal diff --git a/half-earth/materials/cursor.tres b/half-earth/materials/cursor.tres new file mode 100644 index 0000000..a3218a5 --- /dev/null +++ b/half-earth/materials/cursor.tres @@ -0,0 +1,9 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=2] + +[ext_resource path="res://shaders/tile_shader.gdshader" type="Shader" id=1] + +[resource] +shader = ExtResource( 1 ) +shader_param/baseColor = Color( 0.992157, 1, 0, 1 ) +shader_param/highlightColor = Color( 1, 0, 0.984314, 1 ) +shader_param/isHighlighted = 0 diff --git a/half-earth/materials/tile.tres b/half-earth/materials/tile.tres new file mode 100644 index 0000000..327c5eb --- /dev/null +++ b/half-earth/materials/tile.tres @@ -0,0 +1,10 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=2] + +[ext_resource path="res://shaders/tile_shader.gdshader" type="Shader" id=1] + +[resource] +resource_local_to_scene = true +shader = ExtResource( 1 ) +shader_param/baseColor = Color( 0.0823529, 0, 1, 1 ) +shader_param/highlightColor = Color( 1, 0, 0, 1 ) +shader_param/isHighlighted = null diff --git a/half-earth/nodes/game.tscn b/half-earth/nodes/game.tscn new file mode 100644 index 0000000..c7bf9d9 --- /dev/null +++ b/half-earth/nodes/game.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://nodes/grid.tscn" type="PackedScene" id=1] +[ext_resource path="res://nodes/grid_cursor.tscn" type="PackedScene" id=2] + +[node name="Root" type="Node2D"] + +[node name="Grid" parent="." instance=ExtResource( 1 )] + +[node name="Cursor" parent="." instance=ExtResource( 2 )] +Grid = NodePath("../Grid") diff --git a/half-earth/nodes/grid.tscn b/half-earth/nodes/grid.tscn new file mode 100644 index 0000000..3a19d57 --- /dev/null +++ b/half-earth/nodes/grid.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://scripts/WorldGrid.cs" type="Script" id=1] +[ext_resource path="res://nodes/tile.tscn" type="PackedScene" id=2] + +[node name="Grid" type="Node2D"] +script = ExtResource( 1 ) +TileScene = ExtResource( 2 ) +Size = 10 +CellSize = 64 diff --git a/half-earth/nodes/grid_cursor.tscn b/half-earth/nodes/grid_cursor.tscn new file mode 100644 index 0000000..668f1a2 --- /dev/null +++ b/half-earth/nodes/grid_cursor.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://textures/icon.png" type="Texture" id=1] +[ext_resource path="res://scripts/GridCursor.cs" type="Script" id=2] +[ext_resource path="res://materials/cursor.tres" type="Material" id=3] + +[node name="Grid Cursor" type="Sprite"] +material = ExtResource( 3 ) +texture = ExtResource( 1 ) +script = ExtResource( 2 ) diff --git a/half-earth/nodes/tile.tscn b/half-earth/nodes/tile.tscn new file mode 100644 index 0000000..5861ee1 --- /dev/null +++ b/half-earth/nodes/tile.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://materials/tile.tres" type="Material" id=1] +[ext_resource path="res://textures/icon.png" type="Texture" id=2] + +[node name="Tile" type="Sprite"] +material = ExtResource( 1 ) +texture = ExtResource( 2 ) diff --git a/half-earth/project.godot b/half-earth/project.godot index 4371922..93daccc 100644 --- a/half-earth/project.godot +++ b/half-earth/project.godot @@ -11,7 +11,8 @@ config_version=4 [application] config/name="Half-earth" -config/icon="res://icon.png" +run/main_scene="res://nodes/game.tscn" +config/icon="res://textures/icon.png" [gui] @@ -27,4 +28,5 @@ common/enable_pause_aware_picking=true [rendering] -environment/default_environment="res://default_env.tres" +gles3/shaders/shader_compilation_mode=1 +environment/default_environment="res://resources/default_env.tres" diff --git a/half-earth/default_env.tres b/half-earth/resources/default_env.tres similarity index 100% rename from half-earth/default_env.tres rename to half-earth/resources/default_env.tres diff --git a/half-earth/scripts/GridCursor.cs b/half-earth/scripts/GridCursor.cs new file mode 100644 index 0000000..fd97c42 --- /dev/null +++ b/half-earth/scripts/GridCursor.cs @@ -0,0 +1,51 @@ +using Godot; +using System; + +public class GridCursor : Sprite +{ + [Export] + public NodePath Grid { get; set; } + private WorldGrid _grid; + private ShaderMaterial _material; + + private const string IS_HIGHLIGHTED = "isHighlighted"; + + public override void _Ready() + { + _grid = GetNode(Grid); + _material = (ShaderMaterial)Material; + } + + public override void _Input(InputEvent @event) + { + base._Input(@event); + + if (@event is InputEventMouseMotion mouseMoveEvent) + { + var pos = mouseMoveEvent.Position; + _grid.GetGridPos(pos, out var x, out var y); + this.Visible = _grid.IsInBounds(x, y); + var position = new Vector2(x + .5f, y + .5f) * _grid.CellSize; + this.Position = position; + } + else if (@event is InputEventMouseButton mouseButtonEvent) + { + switch ((ButtonList)mouseButtonEvent.ButtonIndex) + { + case ButtonList.Left: + if (mouseButtonEvent.Pressed) + { + var pos = mouseButtonEvent.Position; + _grid.GetGridPos(pos, out var x, out var y); + _grid.ToggleTileHighlight(x, y); + _material.SetShaderParam(IS_HIGHLIGHTED, 1); + } + else + { + _material.SetShaderParam(IS_HIGHLIGHTED, 0); + } + break; + } + } + } +} diff --git a/half-earth/scripts/WorldGrid.cs b/half-earth/scripts/WorldGrid.cs new file mode 100644 index 0000000..a59855d --- /dev/null +++ b/half-earth/scripts/WorldGrid.cs @@ -0,0 +1,103 @@ +using Godot; +using System; + +public class WorldGrid : Node2D +{ + [Export] + private PackedScene TileScene { get; set; } + + [Export] + public int Size { get; set; } + + [Export] + public int CellSize { get; set; } + + private struct Tile + { + public bool isHighlighted; + public ShaderMaterial material; + } + private Tile[,] _tiles; + + // Called when the node enters the scene tree for the first time. + public override void _Ready() + { + GenerateGrid(Size); + } + + public override void _Process(float delta) + { + base._Process(delta); + + for (int x = 0; x < Size; x++) + { + for (int y = 0; y < Size; y++) + { + var tile = _tiles[x, y]; + var material = tile.material; + material.SetShaderParam("isHighlighted", tile.isHighlighted ? 1 : 0); + } + } + } + + public bool IsInBounds(int x, int y) + { + return x >= 0 && x < Size && y >= 0 && y < Size; + } + + public void ToggleTileHighlight(int x, int y) + { + if (!IsInBounds(x, y)) + return; + + _tiles[x, y].isHighlighted ^= true; + } + + public void GetGridPos(Vector2 position, out int x, out int y) + { + x = Mathf.FloorToInt(position.x / CellSize); + y = Mathf.FloorToInt(position.y / CellSize); + } + + private void Clear() + { + _tiles = null; + + int children = this.GetChildCount(); + GD.Print(children); + for (int i = 0; i < children; i++) + { + var child = this.GetChild(i); + child.QueueFree(); + } + } + + private void GenerateGrid(int size) + { + this.Clear(); + + _tiles = new Tile[size, size]; + + for (int x = 0; x < size; x++) + { + for (int y = 0; y < size; y++) + { + var tile = new Tile(); + tile.isHighlighted = false; + + var node = TileScene.Instance(); + this.AddChild(node); + var position = new Vector2 + { + x = (x + .5f) * CellSize, + y = (y + .5f) * CellSize + }; + node.Position = position; + var canvasItem = (CanvasItem)node; + tile.material = (ShaderMaterial)canvasItem.Material; + + _tiles[x, y] = tile; + } + } + } +} diff --git a/half-earth/shaders/tile_shader.gdshader b/half-earth/shaders/tile_shader.gdshader new file mode 100644 index 0000000..98f8fe0 --- /dev/null +++ b/half-earth/shaders/tile_shader.gdshader @@ -0,0 +1,9 @@ +shader_type canvas_item; + +uniform vec4 baseColor : hint_color; +uniform vec4 highlightColor : hint_color; +uniform int isHighlighted; + +void fragment() { + COLOR = mix(baseColor, highlightColor, float(isHighlighted)); +} diff --git a/half-earth/icon.png b/half-earth/textures/icon.png similarity index 100% rename from half-earth/icon.png rename to half-earth/textures/icon.png diff --git a/half-earth/icon.png.import b/half-earth/textures/icon.png.import similarity index 73% rename from half-earth/icon.png.import rename to half-earth/textures/icon.png.import index a4c02e6..b996b3c 100644 --- a/half-earth/icon.png.import +++ b/half-earth/textures/icon.png.import @@ -2,15 +2,15 @@ importer="texture" type="StreamTexture" -path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" +path="res://.import/icon.png-f931f6b997c470ed41f337ac62349254.stex" metadata={ "vram_texture": false } [deps] -source_file="res://icon.png" -dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] +source_file="res://textures/icon.png" +dest_files=[ "res://.import/icon.png-f931f6b997c470ed41f337ac62349254.stex" ] [params]