Refactoring
This commit is contained in:
parent
fb97d172f4
commit
491d0a0b32
22 changed files with 361 additions and 230 deletions
79
main.tscn
79
main.tscn
|
@ -1,66 +1,73 @@
|
|||
[gd_scene load_steps=12 format=3 uid="uid://cdaf4bh0jaa45"]
|
||||
[gd_scene load_steps=21 format=3 uid="uid://cdaf4bh0jaa45"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://dq00mi6jwsa1f" path="res://scenes/planet/planet.tscn" id="1_0p552"]
|
||||
[ext_resource type="Script" path="res://scripts/game_logic.gd" id="1_kb05v"]
|
||||
[ext_resource type="Script" path="res://scenes/player/player.gd" id="2_plgh6"]
|
||||
[ext_resource type="Script" path="res://scripts/game_logic.gd" id="1_uj8ti"]
|
||||
[ext_resource type="Resource" uid="uid://cp0dudi0f5r62" path="res://scenes/templates/templates.tres" id="2_1lypt"]
|
||||
[ext_resource type="Script" path="res://scripts/player.gd" id="2_plgh6"]
|
||||
[ext_resource type="Texture2D" uid="uid://bydmcc5d53ldx" path="res://icons/paw_print.svg" id="3_mxakn"]
|
||||
[ext_resource type="Texture2D" uid="uid://1xh0qil16bkh" path="res://icons/character.svg" id="3_qxmev"]
|
||||
[ext_resource type="Script" path="res://scenes/player/local_player.gd" id="4_7rlmh"]
|
||||
[ext_resource type="Script" path="res://scripts/player_local.gd" id="4_7rlmh"]
|
||||
[ext_resource type="Texture2D" uid="uid://dx1wjviioa8u5" path="res://icons/chip.svg" id="4_pgo63"]
|
||||
[ext_resource type="Script" path="res://ui.gd" id="7_khbdl"]
|
||||
[ext_resource type="PackedScene" uid="uid://dtlatmtuggp6x" path="res://scenes/nebula/nebula.tscn" id="7_sv4lv"]
|
||||
[ext_resource type="Script" path="res://scripts/ui/planets_ui.gd" id="7_khbdl"]
|
||||
[ext_resource type="PackedScene" uid="uid://dtlatmtuggp6x" path="res://scenes/background_nebula/background_nebula.tscn" id="7_sv4lv"]
|
||||
[ext_resource type="Script" path="res://scripts/player_ai.gd" id="7_v73fw"]
|
||||
[ext_resource type="Script" path="res://scripts/planet.gd" id="8_ve3b1"]
|
||||
[ext_resource type="PackedScene" uid="uid://cpffyaoh8x5bp" path="res://scenes/ships_fleet/ships_fleet.tscn" id="9_be18b"]
|
||||
[ext_resource type="PackedScene" uid="uid://ckfk1xgxfk1c3" path="res://scenes/trail/trail.tscn" id="10_b5ql7"]
|
||||
|
||||
[node name="Main" type="Node"]
|
||||
|
||||
[node name="Logic" type="Node" parent="." node_paths=PackedStringArray("neutral_player", "players", "planets")]
|
||||
script = ExtResource("1_kb05v")
|
||||
neutral_player = NodePath("Players/0_Nature")
|
||||
players = [NodePath("Players/1_LocalPlayer"), NodePath("Players/2_AI")]
|
||||
planets = [NodePath("../Game/Planets/Planet1"), NodePath("../Game/Planets/Planet2"), NodePath("../Game/Planets/Planet3"), NodePath("../Game/Planets/Planet4")]
|
||||
|
||||
[node name="Players" type="Node" parent="Logic"]
|
||||
|
||||
[node name="0_Nature" type="Node" parent="Logic/Players"]
|
||||
[sub_resource type="Resource" id="Resource_mxp7y"]
|
||||
script = ExtResource("2_plgh6")
|
||||
color = Color(0.745, 0.745, 0.745, 1)
|
||||
icon = ExtResource("3_mxakn")
|
||||
|
||||
[node name="1_LocalPlayer" type="Node" parent="Logic/Players" node_paths=PackedStringArray("ui")]
|
||||
[sub_resource type="Resource" id="Resource_1dtpf"]
|
||||
script = ExtResource("4_7rlmh")
|
||||
ui = NodePath("../../../UI")
|
||||
color = Color(0.184314, 0.329412, 1, 1)
|
||||
color = Color(0.236993, 0.373968, 1, 1)
|
||||
icon = ExtResource("3_qxmev")
|
||||
|
||||
[node name="2_AI" type="Node" parent="Logic/Players"]
|
||||
script = ExtResource("2_plgh6")
|
||||
[sub_resource type="Resource" id="Resource_7wtc7"]
|
||||
script = ExtResource("7_v73fw")
|
||||
color = Color(0.835294, 0.160784, 0, 1)
|
||||
icon = ExtResource("4_pgo63")
|
||||
|
||||
[node name="Nebula" parent="." instance=ExtResource("7_sv4lv")]
|
||||
[sub_resource type="Resource" id="Resource_50eg2"]
|
||||
script = ExtResource("8_ve3b1")
|
||||
location = Vector2(200, 200)
|
||||
type = 0
|
||||
|
||||
[node name="Game" type="Node2D" parent="."]
|
||||
[sub_resource type="Resource" id="Resource_2525o"]
|
||||
script = ExtResource("8_ve3b1")
|
||||
location = Vector2(952, 448)
|
||||
type = 0
|
||||
|
||||
[node name="Planets" type="Node2D" parent="Game"]
|
||||
[sub_resource type="Resource" id="Resource_irtww"]
|
||||
script = ExtResource("8_ve3b1")
|
||||
location = Vector2(450, 234)
|
||||
type = 0
|
||||
|
||||
[node name="Planet1" parent="Game/Planets" instance=ExtResource("1_0p552")]
|
||||
position = Vector2(200, 200)
|
||||
[sub_resource type="Resource" id="Resource_wdycy"]
|
||||
script = ExtResource("8_ve3b1")
|
||||
location = Vector2(702, 414)
|
||||
type = 0
|
||||
|
||||
[node name="Planet2" parent="Game/Planets" instance=ExtResource("1_0p552")]
|
||||
position = Vector2(952, 448)
|
||||
[node name="Main" type="Node"]
|
||||
|
||||
[node name="Planet3" parent="Game/Planets" instance=ExtResource("1_0p552")]
|
||||
position = Vector2(450, 234)
|
||||
[node name="GameLogic" type="Node" parent="." node_paths=PackedStringArray("planets_container", "planets_ui")]
|
||||
script = ExtResource("1_uj8ti")
|
||||
templates = ExtResource("2_1lypt")
|
||||
planets_container = NodePath("../Planets")
|
||||
planets_ui = NodePath("../PlanetsUI")
|
||||
players = Array[ExtResource("2_plgh6")]([SubResource("Resource_mxp7y"), SubResource("Resource_1dtpf"), SubResource("Resource_7wtc7")])
|
||||
planets = Array[ExtResource("8_ve3b1")]([SubResource("Resource_50eg2"), SubResource("Resource_2525o"), SubResource("Resource_irtww"), SubResource("Resource_wdycy")])
|
||||
|
||||
[node name="Planet4" parent="Game/Planets" instance=ExtResource("1_0p552")]
|
||||
position = Vector2(702, 414)
|
||||
[node name="BackgroundNebula" parent="." instance=ExtResource("7_sv4lv")]
|
||||
|
||||
[node name="Planets" type="Node2D" parent="."]
|
||||
|
||||
[node name="ShipsFleet" parent="." instance=ExtResource("9_be18b")]
|
||||
position = Vector2(246, 394)
|
||||
count = 29
|
||||
|
||||
[node name="UI" type="Control" parent="." node_paths=PackedStringArray("trail")]
|
||||
[node name="PlanetsUI" type="Control" parent="." node_paths=PackedStringArray("trail")]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
|
@ -71,5 +78,5 @@ mouse_filter = 2
|
|||
script = ExtResource("7_khbdl")
|
||||
trail = NodePath("Trail")
|
||||
|
||||
[node name="Trail" parent="UI" instance=ExtResource("10_b5ql7")]
|
||||
[node name="Trail" parent="PlanetsUI" instance=ExtResource("10_b5ql7")]
|
||||
visible = false
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://dtlatmtuggp6x"]
|
||||
|
||||
[ext_resource type="Shader" path="res://scenes/nebula/nebula.gdshader" id="1_nqp0c"]
|
||||
[ext_resource type="Shader" path="res://scenes/background_nebula/background_nebula.gdshader" id="1_nqp0c"]
|
||||
|
||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_8c2xm"]
|
||||
|
||||
|
@ -14,7 +14,7 @@ noise = SubResource("FastNoiseLite_8c2xm")
|
|||
shader = ExtResource("1_nqp0c")
|
||||
shader_parameter/noise = SubResource("NoiseTexture2D_cukca")
|
||||
|
||||
[node name="Nebula" type="ColorRect"]
|
||||
[node name="BackgroundNebula" type="ColorRect"]
|
||||
material = SubResource("ShaderMaterial_y72ex")
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
|
@ -1,5 +1,5 @@
|
|||
extends Node2D
|
||||
class_name Planet
|
||||
class_name ControlPlanet
|
||||
|
||||
## The player currenly controlling this planet.
|
||||
var player: Player :
|
||||
|
@ -32,7 +32,7 @@ var is_selected: bool :
|
|||
set(value):
|
||||
%Selection.visible = value
|
||||
|
||||
func _on_input_listener_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
|
||||
func _on_input_listener_input_event(_viewport: Node, event: InputEvent, _shape_idx: int) -> void:
|
||||
# TODO: handle touch appropriately (InputEventScreenTouch).
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed():
|
||||
selected.emit(self)
|
|
@ -1,8 +1,8 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://dq00mi6jwsa1f"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://dnerbdusnaofr" path="res://scenes/procedural_planet/procedural_planet.tscn" id="1_8mf3x"]
|
||||
[ext_resource type="Script" path="res://scenes/planet/planet.gd" id="1_e208c"]
|
||||
[ext_resource type="Shader" path="res://scenes/planet/planet_selection.gdshader" id="2_bl05u"]
|
||||
[ext_resource type="Script" path="res://scenes/control_planet/control_planet.gd" id="1_e208c"]
|
||||
[ext_resource type="Shader" path="res://scenes/control_planet/planet_selection.gdshader" id="2_bl05u"]
|
||||
[ext_resource type="Texture2D" uid="uid://1xh0qil16bkh" path="res://icons/character.svg" id="2_kglxp"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_tsywx"]
|
|
@ -1,10 +0,0 @@
|
|||
extends Player
|
||||
class_name LocalPlayer
|
||||
|
||||
@export var ui: GameUI
|
||||
|
||||
func _on_game_start(game: GameLogic) -> void:
|
||||
ui._on_game_started(game)
|
||||
|
||||
func _on_game_tick(game: GameLogic, tick: int) -> void:
|
||||
pass
|
|
@ -1,14 +0,0 @@
|
|||
extends Node
|
||||
class_name Player
|
||||
|
||||
@export var color: Color = Color.MAGENTA
|
||||
|
||||
@export var icon: Texture2D
|
||||
|
||||
var pending_operations: Array[GameOperation] = []
|
||||
|
||||
func _on_game_start(game: GameLogic) -> void:
|
||||
pass
|
||||
|
||||
func _on_game_tick(game: GameLogic, tick: int) -> void:
|
||||
pass
|
|
@ -1,13 +1,26 @@
|
|||
extends Node2D
|
||||
class_name ShipFleet
|
||||
|
||||
@export var departed_at: int
|
||||
|
||||
@export var arrives_at: int
|
||||
|
||||
@export var from: Vector2
|
||||
|
||||
@export var to: Vector2
|
||||
|
||||
@export var count: int :
|
||||
set(value):
|
||||
count = value
|
||||
_update_instances_count()
|
||||
|
||||
#region Graphics
|
||||
|
||||
var instances: Array[Node2D] = []
|
||||
|
||||
@export var ship_template: PackedScene
|
||||
|
||||
@export var count: int :
|
||||
set(value):
|
||||
count = value
|
||||
|
||||
func _update_instances_count() -> void :
|
||||
var diff = count - instances.size()
|
||||
|
||||
for i in range(diff):
|
||||
|
@ -20,3 +33,5 @@ var instances: Array[Node2D] = []
|
|||
for i in range(-diff):
|
||||
var ship: Node2D = instances.pop_back()
|
||||
remove_child(ship)
|
||||
|
||||
#endregion
|
||||
|
|
4
scenes/templates/template_scenes.gd
Normal file
4
scenes/templates/template_scenes.gd
Normal file
|
@ -0,0 +1,4 @@
|
|||
class_name TemplateScenes
|
||||
extends Resource
|
||||
|
||||
@export var control_planet: PackedScene
|
8
scenes/templates/templates.tres
Normal file
8
scenes/templates/templates.tres
Normal file
|
@ -0,0 +1,8 @@
|
|||
[gd_resource type="Resource" script_class="TemplateScenes" load_steps=3 format=3 uid="uid://cp0dudi0f5r62"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://dq00mi6jwsa1f" path="res://scenes/control_planet/control_planet.tscn" id="1_3rbtf"]
|
||||
[ext_resource type="Script" path="res://scenes/templates/template_scenes.gd" id="1_yvn3m"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_yvn3m")
|
||||
control_planet = ExtResource("1_3rbtf")
|
|
@ -1,69 +1,77 @@
|
|||
extends Node
|
||||
class_name GameLogic
|
||||
extends Node
|
||||
|
||||
const LOGIC_TICKS_PER_SECOND: float = 20.
|
||||
const LOGIC_SECONDS_PER_TICK = 1. / LOGIC_TICKS_PER_SECOND
|
||||
const LOGIC_TICKS_PER_SECOND := 20.
|
||||
const LOGIC_SECONDS_PER_TICK := 1. / LOGIC_TICKS_PER_SECOND
|
||||
|
||||
## Neutral player owning all non-conquered planets.
|
||||
@export var neutral_player: Player
|
||||
## Templates for spawnable stuff.
|
||||
@export var templates: TemplateScenes
|
||||
|
||||
## Container for planets.
|
||||
@export var planets_container: Node2D
|
||||
|
||||
## Interface to interact with planets.
|
||||
@export var planets_ui: PlanetsUI
|
||||
|
||||
## Game players.
|
||||
@export var players: Array[Player] = []
|
||||
@export var players: Array[Player]
|
||||
|
||||
## Game planets.
|
||||
@export var planets: Array[Planet] = []
|
||||
@export var planets: Array[Planet]
|
||||
|
||||
var ticks_count: int
|
||||
var extra_time: float
|
||||
var _game: GameState
|
||||
var _planet_controls: Array[ControlPlanet]
|
||||
|
||||
signal game_start(game: GameLogic)
|
||||
signal game_tick(game: GameLogic, tick: int)
|
||||
var _extra_time: float
|
||||
|
||||
func _ready() -> void:
|
||||
_game_init()
|
||||
game_start.emit(self)
|
||||
# New game.
|
||||
_game = GameState.new()
|
||||
|
||||
# Add players.
|
||||
for i in range(players.size()):
|
||||
_game.add_player()
|
||||
|
||||
# Add planets.
|
||||
for i in range(planets.size()):
|
||||
# Data.
|
||||
var data := GameState.PlanetData.new()
|
||||
data.position = Vector2i(planets[i].location)
|
||||
data.grow_every_ticks = 10
|
||||
data.player_id = (i + 1) if (i < players.size() - 1) else 0
|
||||
data.population = 0
|
||||
_game.add_planet(data)
|
||||
|
||||
# UI control.
|
||||
var control: ControlPlanet = templates.control_planet.instantiate()
|
||||
control.position = planets[i].location
|
||||
control.player = players[data.player_id]
|
||||
control.population = data.population
|
||||
_planet_controls.push_back(control)
|
||||
planets_container.add_child(control)
|
||||
planets_ui.register_planet(control)
|
||||
|
||||
# Register UI signals.
|
||||
_game.planet_player_changed.connect(_set_planet_player)
|
||||
_game.planet_population_changed.connect(_set_planet_population)
|
||||
planets_ui.fleet_dispatched.connect(_dispatch_fleet)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
extra_time += delta
|
||||
_extra_time += delta
|
||||
|
||||
while extra_time > LOGIC_SECONDS_PER_TICK:
|
||||
extra_time -= LOGIC_SECONDS_PER_TICK
|
||||
_game_tick(ticks_count)
|
||||
ticks_count += 1
|
||||
while _extra_time > LOGIC_SECONDS_PER_TICK:
|
||||
_extra_time -= LOGIC_SECONDS_PER_TICK
|
||||
_game.tick()
|
||||
|
||||
func _game_init() -> void:
|
||||
ticks_count = 0
|
||||
extra_time = 0.
|
||||
func _set_planet_player(planet_id: int, player_id: int) -> void:
|
||||
_planet_controls[planet_id].player = players[player_id]
|
||||
|
||||
for player in players:
|
||||
game_start.connect(player._on_game_start)
|
||||
game_tick.connect(player._on_game_tick)
|
||||
func _set_planet_population(planet_id: int, population: int) -> void:
|
||||
_planet_controls[planet_id].population = population
|
||||
|
||||
for i in range(planets.size()):
|
||||
var planet := planets[i]
|
||||
planet.player = players[i] if i < players.size() else neutral_player
|
||||
planet.is_selected = false
|
||||
|
||||
func _game_tick(tick: int) -> void:
|
||||
for planet in planets:
|
||||
if planet.player != neutral_player and tick % 10 == 0:
|
||||
planet.population += 1
|
||||
|
||||
for player in players:
|
||||
for op in player.pending_operations:
|
||||
if op is GameOperationSendFleet:
|
||||
var count = min(op.max_count, op.from.population)
|
||||
op.from.population -= count
|
||||
if op.from.player == op.to.player:
|
||||
op.to.population += count
|
||||
else:
|
||||
op.to.population -= count
|
||||
if op.to.population <= 0:
|
||||
op.to.player = op.from.player
|
||||
op.to.population = abs(op.from.population)
|
||||
else:
|
||||
assert(false, "Unknown GameOperation: %s" % [op])
|
||||
|
||||
player.pending_operations.clear()
|
||||
|
||||
game_tick.emit(self, tick)
|
||||
func _dispatch_fleet(from: ControlPlanet, to: ControlPlanet) -> void:
|
||||
var player_id := players.find(from.player)
|
||||
var from_planet_id := _planet_controls.find(from)
|
||||
var to_planet_id := _planet_controls.find(to)
|
||||
var max_count: int = ceil(from.population / 2.)
|
||||
_game.dispatch_fleet(player_id, from_planet_id, to_planet_id, max_count)
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
extends RefCounted
|
||||
class_name GameOperation
|
|
@ -1,8 +0,0 @@
|
|||
extends GameOperation
|
||||
class_name GameOperationSendFleet
|
||||
|
||||
var from: Planet
|
||||
|
||||
var to: Planet
|
||||
|
||||
var max_count: int
|
102
scripts/game_state.gd
Normal file
102
scripts/game_state.gd
Normal file
|
@ -0,0 +1,102 @@
|
|||
class_name GameState
|
||||
extends Resource
|
||||
|
||||
class PlayerData:
|
||||
var commands: Array[Command] = []
|
||||
|
||||
class PlanetData:
|
||||
var position: Vector2i
|
||||
var grow_every_ticks: int
|
||||
var player_id: int ## 0 = none
|
||||
var population: int
|
||||
|
||||
class FleetData:
|
||||
var count: int
|
||||
|
||||
enum CommandType {
|
||||
DISPATCH_FLEET,
|
||||
}
|
||||
|
||||
class Command:
|
||||
var type: CommandType
|
||||
var wait_tick: int
|
||||
|
||||
class DispatchFleedCommand extends Command:
|
||||
var from_planet_id: int
|
||||
var to_planet_id: int
|
||||
var max_count: int
|
||||
func _init():
|
||||
type = CommandType.DISPATCH_FLEET
|
||||
|
||||
signal game_ticked(tick: int)
|
||||
signal planet_population_changed(planet_id: int, population: int)
|
||||
signal planet_player_changed(planet_id: int, player_id: int)
|
||||
|
||||
var _players: Array[PlayerData] = []
|
||||
var _planets: Array[PlanetData] = []
|
||||
var _fleets: Array[FleetData] = []
|
||||
|
||||
var current_tick: int
|
||||
|
||||
## Add a player to the game.
|
||||
## The first player is expected to be the game master / neutral player,
|
||||
## who does not play and for whom the population never increases.
|
||||
func add_player(data := PlayerData.new()) -> int:
|
||||
_players.push_back(data)
|
||||
return _players.size() - 1
|
||||
|
||||
## Add a planet to the game.
|
||||
func add_planet(data := PlanetData.new()) -> int:
|
||||
_planets.push_back(data)
|
||||
return _planets.size() - 1
|
||||
|
||||
## Advance game status by one tick.
|
||||
func tick() -> void:
|
||||
current_tick += 1
|
||||
|
||||
for planet_id in range(_planets.size()):
|
||||
var planet := _planets[planet_id]
|
||||
if planet.player_id != 0 and current_tick % planet.grow_every_ticks == 0:
|
||||
planet.population += 1
|
||||
planet_population_changed.emit(planet_id, planet.population)
|
||||
|
||||
for player_id in range(_players.size()):
|
||||
var player := _players[player_id]
|
||||
if player.commands.size() > 0 && current_tick >= player.commands[0].wait_tick:
|
||||
var command: Command = player.commands.pop_back()
|
||||
match command.type:
|
||||
CommandType.DISPATCH_FLEET:
|
||||
_handle_dispatch_fleet(player_id, command)
|
||||
_:
|
||||
assert(false, "Unknown command: %s" % [command])
|
||||
|
||||
game_ticked.emit(current_tick)
|
||||
|
||||
## Dispatch a fleet.
|
||||
func dispatch_fleet(player_id: int, from_planet_id: int, to_planet_id: int, max_count: int) -> void:
|
||||
var dispatch := DispatchFleedCommand.new()
|
||||
dispatch.from_planet_id = from_planet_id
|
||||
dispatch.to_planet_id = to_planet_id
|
||||
dispatch.max_count = max_count
|
||||
_issue_command(player_id, dispatch)
|
||||
|
||||
func _issue_command(player_id: int, command: Command) -> void:
|
||||
var commands := _players[player_id].commands
|
||||
var index := commands.map(func (x): return x.wait_tick).bsearch(command.wait_tick, false)
|
||||
commands.insert(index, command)
|
||||
|
||||
func _handle_dispatch_fleet(player_id: int, dispatch: DispatchFleedCommand) -> void:
|
||||
var from = _planets[dispatch.from_planet_id]
|
||||
var to = _planets[dispatch.to_planet_id]
|
||||
var count = min(dispatch.max_count, from.population)
|
||||
from.population -= count
|
||||
if from.player_id == to.player_id:
|
||||
to.population += count
|
||||
else:
|
||||
to.population -= count
|
||||
if to.population <= 0:
|
||||
to.player_id = from.player_id
|
||||
to.population = abs(from.population)
|
||||
planet_player_changed.emit(dispatch.to_planet_id, to.player_id)
|
||||
planet_population_changed.emit(dispatch.from_planet_id, from.population)
|
||||
planet_population_changed.emit(dispatch.to_planet_id, to.population)
|
10
scripts/planet.gd
Normal file
10
scripts/planet.gd
Normal file
|
@ -0,0 +1,10 @@
|
|||
class_name Planet
|
||||
extends Resource
|
||||
|
||||
enum PlanetType {
|
||||
TERRESTRIAL,
|
||||
}
|
||||
|
||||
@export var location: Vector2
|
||||
|
||||
@export var type: PlanetType
|
9
scripts/player.gd
Normal file
9
scripts/player.gd
Normal file
|
@ -0,0 +1,9 @@
|
|||
class_name Player
|
||||
extends Resource
|
||||
|
||||
@export var color: Color = Color.MAGENTA
|
||||
|
||||
@export var icon: Texture2D
|
||||
|
||||
func process_game_tick(_game: GameLogic) -> void:
|
||||
pass
|
5
scripts/player_ai.gd
Normal file
5
scripts/player_ai.gd
Normal file
|
@ -0,0 +1,5 @@
|
|||
class_name AIPlayer
|
||||
extends Player
|
||||
|
||||
func process_game_tick(_game: GameLogic) -> void:
|
||||
pass
|
5
scripts/player_local.gd
Normal file
5
scripts/player_local.gd
Normal file
|
@ -0,0 +1,5 @@
|
|||
class_name LocalPlayer
|
||||
extends Player
|
||||
|
||||
func process_game_tick(_game: GameLogic) -> void:
|
||||
pass
|
80
scripts/ui/planets_ui.gd
Normal file
80
scripts/ui/planets_ui.gd
Normal file
|
@ -0,0 +1,80 @@
|
|||
class_name PlanetsUI
|
||||
extends Control
|
||||
|
||||
@export var trail: Trail
|
||||
|
||||
signal fleet_dispatched(from: ControlPlanet, to: ControlPlanet)
|
||||
|
||||
func register_planet(control: ControlPlanet) -> void:
|
||||
control.selected.connect(_on_planet_selected)
|
||||
control.pointer_entered.connect(_on_planet_pointer_entered)
|
||||
control.pointer_exited.connect(_on_planet_pointer_exited)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
_update_trail(delta, false)
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouse:
|
||||
_handle_mouse_input(event)
|
||||
|
||||
#region Mouse input
|
||||
|
||||
var _last_cursor_position: Vector2
|
||||
|
||||
func _handle_mouse_input(event: InputEventMouse) -> void:
|
||||
if event is InputEventMouseMotion:
|
||||
# The trail follows the cursor.
|
||||
_last_cursor_position = event.global_position
|
||||
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_released():
|
||||
# The trail disappears when no longer dragging.
|
||||
_dragging_from_planet = false
|
||||
|
||||
# Detect mouse released on a planet and spawn a fleet.
|
||||
if _selected_planet != null and _selected_planet.player is LocalPlayer and _pointed_planet != null:
|
||||
fleet_dispatched.emit(_selected_planet, _pointed_planet)
|
||||
|
||||
#endregion
|
||||
|
||||
#region Planets
|
||||
|
||||
var _selected_planet: ControlPlanet
|
||||
var _pointed_planet: ControlPlanet
|
||||
var _dragging_from_planet: bool
|
||||
|
||||
func _on_planet_selected(planet: ControlPlanet) -> void:
|
||||
if _selected_planet != null:
|
||||
_selected_planet.is_selected = false
|
||||
|
||||
_selected_planet = planet
|
||||
_selected_planet.is_selected = true
|
||||
|
||||
_dragging_from_planet = true
|
||||
_update_trail(0., true)
|
||||
|
||||
func _on_planet_pointer_entered(planet: ControlPlanet) -> void:
|
||||
_pointed_planet = planet
|
||||
|
||||
func _on_planet_pointer_exited(planet: ControlPlanet) -> void:
|
||||
if _pointed_planet == planet:
|
||||
_pointed_planet = null
|
||||
|
||||
#endregion
|
||||
|
||||
#region Trail
|
||||
|
||||
var _trail_opacity := 0.
|
||||
|
||||
func _update_trail(delta: float, snap_position: bool) -> void:
|
||||
var show_trail := _dragging_from_planet and _selected_planet != null and _selected_planet.player is LocalPlayer
|
||||
if show_trail or trail.visible:
|
||||
_trail_opacity = Utils.damp(_trail_opacity, 1. if show_trail else 0., 1e-4, delta)
|
||||
trail.color = Color(_selected_planet.player.color, _trail_opacity)
|
||||
trail.visible = _trail_opacity > .01
|
||||
|
||||
if show_trail:
|
||||
var target_position = _last_cursor_position if _pointed_planet == null else _pointed_planet.global_position
|
||||
trail.start_position = _selected_planet.global_position
|
||||
trail.end_position = target_position if snap_position else Utils.damp(trail.end_position, target_position, 1e-20, delta)
|
||||
|
||||
#endregion
|
|
@ -1,4 +1,4 @@
|
|||
class_name Util
|
||||
class_name Utils
|
||||
|
||||
## Time-independent damping with exponential-decay.
|
||||
##
|
88
ui.gd
88
ui.gd
|
@ -1,88 +0,0 @@
|
|||
extends Control
|
||||
class_name GameUI
|
||||
|
||||
@export var trail: Trail
|
||||
|
||||
var game: GameLogic
|
||||
|
||||
|
||||
func _on_game_started(game: GameLogic) -> void:
|
||||
self.game = game
|
||||
|
||||
for planet in game.planets:
|
||||
planet.selected.connect(_on_planet_selected)
|
||||
planet.pointer_entered.connect(_on_planet_pointer_entered)
|
||||
planet.pointer_exited.connect(_on_planet_pointer_exited)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
_update_trail(delta, false)
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouse:
|
||||
_handle_mouse_input(event)
|
||||
|
||||
#region Mouse input
|
||||
|
||||
var last_cursor_position: Vector2
|
||||
|
||||
func _handle_mouse_input(event: InputEventMouse) -> void:
|
||||
if event is InputEventMouseMotion:
|
||||
# The trail follows the cursor.
|
||||
last_cursor_position = event.global_position
|
||||
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_released():
|
||||
# The trail disappears when no longer dragging.
|
||||
dragging_from_planet = false
|
||||
|
||||
# Detect mouse released on a planet and spawn a fleet.
|
||||
if selected_planet != null and selected_planet.player is LocalPlayer and pointed_planet != null:
|
||||
var op := GameOperationSendFleet.new()
|
||||
op.from = selected_planet
|
||||
op.to = pointed_planet
|
||||
op.max_count = ceil(selected_planet.population / 2)
|
||||
selected_planet.player.pending_operations.push_front(op)
|
||||
|
||||
#endregion
|
||||
|
||||
#region Planets
|
||||
|
||||
var selected_planet: Planet
|
||||
var pointed_planet: Planet
|
||||
var dragging_from_planet: bool
|
||||
|
||||
func _on_planet_selected(planet: Planet) -> void:
|
||||
if selected_planet != null:
|
||||
selected_planet.is_selected = false
|
||||
|
||||
selected_planet = planet
|
||||
selected_planet.is_selected = true
|
||||
|
||||
dragging_from_planet = true
|
||||
_update_trail(0., true)
|
||||
|
||||
func _on_planet_pointer_entered(planet: Planet) -> void:
|
||||
pointed_planet = planet
|
||||
|
||||
func _on_planet_pointer_exited(planet: Planet) -> void:
|
||||
if pointed_planet == planet:
|
||||
pointed_planet = null
|
||||
|
||||
#endregion
|
||||
|
||||
#region Trail
|
||||
|
||||
var trail_opacity := 0.
|
||||
|
||||
func _update_trail(delta: float, snap_position: bool) -> void:
|
||||
var show_trail := dragging_from_planet and selected_planet != null and selected_planet.player is LocalPlayer
|
||||
if show_trail or trail.visible:
|
||||
trail_opacity = Util.damp(trail_opacity, 1. if show_trail else 0., 1e-4, delta)
|
||||
trail.color = Color(selected_planet.player.color, trail_opacity)
|
||||
trail.visible = trail_opacity > .01
|
||||
|
||||
if show_trail:
|
||||
var target_position = last_cursor_position if pointed_planet == null else pointed_planet.global_position
|
||||
trail.start_position = selected_planet.global_position
|
||||
trail.end_position = target_position if snap_position else Util.damp(trail.end_position, target_position, 1e-20, delta)
|
||||
|
||||
#endregion
|
Loading…
Reference in a new issue