summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Luevano Alvarado <david@luevano.xyz>2022-06-03 21:13:19 -0600
committerDavid Luevano Alvarado <david@luevano.xyz>2022-06-03 21:13:19 -0600
commitf922fe4669080d1633e0a345a3f8981867c9e841 (patch)
tree7c2c98bfca20fda37fe34ba99e2d3caa9a39ca02 /src
parent898877f09808691a5e5d45850d27ae85f270db16 (diff)
add working world gen, fixed food placing, minor refactoring
Diffstat (limited to 'src')
-rw-r--r--src/Main.tscn10
-rw-r--r--src/entities/actors/snake/scenes/Body.tscn4
-rw-r--r--src/entities/actors/snake/scenes/Head.tscn5
-rw-r--r--src/entities/actors/snake/scenes/Snake.tscn9
-rw-r--r--src/entities/actors/snake/scenes/Tail.tscn3
-rw-r--r--src/entities/actors/snake/scripts/camera.gd9
-rw-r--r--src/entities/actors/snake/scripts/generic_segment.gd7
-rw-r--r--src/entities/actors/snake/scripts/head.gd2
-rw-r--r--src/entities/actors/snake/scripts/snake.gd22
-rw-r--r--src/entities/actors/snake/sprites/body.pngbin168 -> 136 bytes
-rw-r--r--src/entities/actors/snake/sprites/head.pngbin188 -> 174 bytes
-rw-r--r--src/entities/actors/snake/sprites/tail.pngbin174 -> 133 bytes
-rw-r--r--src/entities/food/scenes/Food.tscn2
-rw-r--r--src/entities/food/scripts/food.gd3
-rw-r--r--src/entities/food/scripts/food_manager.gd43
-rw-r--r--src/entities/food/sprites/apple.pngbin148 -> 135 bytes
-rw-r--r--src/event.gd13
-rw-r--r--src/fonts/MonogramExtended.tres6
-rw-r--r--src/fonts/monogram_extended.ttfbin0 -> 41508 bytes
-rw-r--r--src/global.gd9
-rw-r--r--src/main.gd21
-rw-r--r--src/project.godot5
-rw-r--r--src/tools/screen_recorder/ScreenRecorder.tscn (renamed from src/tools/ScreenRecorder.tscn)3
-rw-r--r--src/tools/screen_recorder/screen_recorder.gd (renamed from src/tools/screen_recorder.gd)0
-rw-r--r--src/tools/world_generator/scenes/WalkerHead.tscn6
-rw-r--r--src/tools/world_generator/scenes/WalkerUnit.tscn6
-rw-r--r--src/tools/world_generator/scenes/WorldGenerator.tscn65
-rw-r--r--src/tools/world_generator/scripts/walker_head.gd70
-rw-r--r--src/tools/world_generator/scripts/walker_unit.gd98
-rw-r--r--src/tools/world_generator/scripts/world_generator.gd12
-rw-r--r--src/tools/world_generator/sprites/black.pngbin0 -> 99 bytes
-rw-r--r--src/tools/world_generator/sprites/black.png.import35
-rw-r--r--src/tools/world_generator/sprites/white.pngbin0 -> 99 bytes
-rw-r--r--src/tools/world_generator/sprites/white.png.import35
-rw-r--r--src/ui/UI.tscn32
-rw-r--r--src/ui/ui.gd9
36 files changed, 494 insertions, 50 deletions
diff --git a/src/Main.tscn b/src/Main.tscn
index 1442e36..d633409 100644
--- a/src/Main.tscn
+++ b/src/Main.tscn
@@ -1,21 +1,19 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://entities/actors/snake/scenes/Snake.tscn" type="PackedScene" id=1]
-[ext_resource path="res://tools/ScreenRecorder.tscn" type="PackedScene" id=2]
[ext_resource path="res://ui/UI.tscn" type="PackedScene" id=3]
[ext_resource path="res://main.gd" type="Script" id=4]
[ext_resource path="res://entities/food/scenes/FoodManager.tscn" type="PackedScene" id=5]
+[ext_resource path="res://tools/world_generator/scenes/WorldGenerator.tscn" type="PackedScene" id=6]
[node name="Main" type="Node2D"]
script = ExtResource( 4 )
+[node name="WorldGenerator" parent="." instance=ExtResource( 6 )]
+
[node name="FoodManager" parent="." instance=ExtResource( 5 )]
+WORLD_GENERATOR_NP = NodePath("../WorldGenerator")
[node name="Snake" parent="." instance=ExtResource( 1 )]
-[node name="Camera" type="Camera2D" parent="."]
-current = true
-
[node name="UI" parent="." instance=ExtResource( 3 )]
-
-[node name="ScreenRecorder" parent="." instance=ExtResource( 2 )]
diff --git a/src/entities/actors/snake/scenes/Body.tscn b/src/entities/actors/snake/scenes/Body.tscn
index 49694c0..7b5de58 100644
--- a/src/entities/actors/snake/scenes/Body.tscn
+++ b/src/entities/actors/snake/scenes/Body.tscn
@@ -4,8 +4,8 @@
[ext_resource path="res://entities/actors/snake/scripts/generic_segment.gd" type="Script" id=2]
[sub_resource type="CapsuleShape2D" id=1]
-radius = 4.99999
-height = 4.00002
+radius = 1.99999
+height = 2.00001
[node name="BodyPathFollow" type="PathFollow2D"]
loop = false
diff --git a/src/entities/actors/snake/scenes/Head.tscn b/src/entities/actors/snake/scenes/Head.tscn
index d118fbf..336265b 100644
--- a/src/entities/actors/snake/scenes/Head.tscn
+++ b/src/entities/actors/snake/scenes/Head.tscn
@@ -3,8 +3,8 @@
[ext_resource path="res://entities/actors/snake/sprites/head.png" type="Texture" id=1]
[ext_resource path="res://entities/actors/snake/scripts/head.gd" type="Script" id=2]
-[sub_resource type="ConvexPolygonShape2D" id=1]
-points = PoolVector2Array( -5, 0, 5, 0, 5, -3, 3, -4, 1, -5, -1, -5, -3, -4, -5, -3 )
+[sub_resource type="CircleShape2D" id=1]
+radius = 2.0
[node name="Head" type="KinematicBody2D"]
collision_mask = 262
@@ -14,4 +14,5 @@ script = ExtResource( 2 )
texture = ExtResource( 1 )
[node name="Collision" type="CollisionShape2D" parent="."]
+position = Vector2( 0, -2 )
shape = SubResource( 1 )
diff --git a/src/entities/actors/snake/scenes/Snake.tscn b/src/entities/actors/snake/scenes/Snake.tscn
index cb1eb2a..ea234c4 100644
--- a/src/entities/actors/snake/scenes/Snake.tscn
+++ b/src/entities/actors/snake/scenes/Snake.tscn
@@ -1,9 +1,10 @@
-[gd_scene load_steps=6 format=2]
+[gd_scene load_steps=7 format=2]
[ext_resource path="res://entities/actors/snake/scenes/Head.tscn" type="PackedScene" id=1]
[ext_resource path="res://entities/actors/snake/scenes/Body.tscn" type="PackedScene" id=2]
[ext_resource path="res://entities/actors/snake/scripts/snake.gd" type="Script" id=3]
[ext_resource path="res://entities/actors/snake/scenes/Tail.tscn" type="PackedScene" id=4]
+[ext_resource path="res://entities/actors/snake/scripts/camera.gd" type="Script" id=5]
[sub_resource type="Curve2D" id=1]
_data = {
@@ -15,7 +16,11 @@ script = ExtResource( 3 )
BODY_SEGMENT_NP = ExtResource( 2 )
TAIL_SEGMENT_NP = ExtResource( 4 )
+[node name="Head" parent="." instance=ExtResource( 1 )]
+
[node name="Path" type="Path2D" parent="."]
curve = SubResource( 1 )
-[node name="Head" parent="." instance=ExtResource( 1 )]
+[node name="Camera" type="Camera2D" parent="."]
+current = true
+script = ExtResource( 5 )
diff --git a/src/entities/actors/snake/scenes/Tail.tscn b/src/entities/actors/snake/scenes/Tail.tscn
index 17e8ec5..adfe422 100644
--- a/src/entities/actors/snake/scenes/Tail.tscn
+++ b/src/entities/actors/snake/scenes/Tail.tscn
@@ -4,7 +4,7 @@
[ext_resource path="res://entities/actors/snake/scripts/generic_segment.gd" type="Script" id=2]
[sub_resource type="CircleShape2D" id=1]
-radius = 4.12311
+radius = 2.0
[node name="TailPathFollow" type="PathFollow2D"]
loop = false
@@ -20,4 +20,5 @@ collision_mask = 0
texture = ExtResource( 1 )
[node name="Collision" type="CollisionShape2D" parent="Tail"]
+position = Vector2( 7.23998e-06, 2 )
shape = SubResource( 1 )
diff --git a/src/entities/actors/snake/scripts/camera.gd b/src/entities/actors/snake/scripts/camera.gd
new file mode 100644
index 0000000..c230dad
--- /dev/null
+++ b/src/entities/actors/snake/scripts/camera.gd
@@ -0,0 +1,9 @@
+extends Camera2D
+
+onready var _snake_head: KinematicBody2D = get_parent().get_node("Head")
+var _snake_position: Vector2
+
+
+func _physics_process(delta: float) -> void:
+ _snake_position = _snake_head.global_position
+ global_position = global_position.linear_interpolate(_snake_position, delta)
diff --git a/src/entities/actors/snake/scripts/generic_segment.gd b/src/entities/actors/snake/scripts/generic_segment.gd
index e2db91d..d0bb944 100644
--- a/src/entities/actors/snake/scripts/generic_segment.gd
+++ b/src/entities/actors/snake/scripts/generic_segment.gd
@@ -6,6 +6,7 @@ onready var _segment: Area2D = get_child(0)
func _ready() -> void:
+ Event.connect("snake_rotated", self, "_on_snake_rotated")
_segment.connect("body_entered", self, "_on_body_entered")
@@ -15,3 +16,9 @@ func _physics_process(delta: float) -> void:
func _on_body_entered(body: Node) -> void:
Event.emit_signal("snake_segment_body_entered", body)
+
+
+func _on_snake_rotated() -> void:
+ # this is just random, i need to offset a tiny bit whenever the snake rotates
+ # so that the first body segmetn doesn't catch up with the head
+ offset -= Global.SNAKE_SPEED * pow(get_physics_process_delta_time(), 2) \ No newline at end of file
diff --git a/src/entities/actors/snake/scripts/head.gd b/src/entities/actors/snake/scripts/head.gd
index 448802e..117f461 100644
--- a/src/entities/actors/snake/scripts/head.gd
+++ b/src/entities/actors/snake/scripts/head.gd
@@ -5,6 +5,7 @@ enum {
RIGHT=1
}
+var _initial_speed: float = Global.SNAKE_SPEED
var velocity: Vector2 = Vector2.ZERO
var _direction: Vector2 = Vector2.UP
var _time_elapsed: float = 0.0
@@ -26,6 +27,7 @@ func _physics_process(delta: float) -> void:
func _rotate_to(direction: int) -> void:
rotate(deg2rad(direction * Global.SNAKE_ROT_SPEED * get_physics_process_delta_time()))
_direction = _direction.rotated(deg2rad(direction * Global.SNAKE_ROT_SPEED * get_physics_process_delta_time()))
+ Event.emit_signal("snake_rotated")
# using a timer is not recommended for < 0.01
diff --git a/src/entities/actors/snake/scripts/snake.gd b/src/entities/actors/snake/scripts/snake.gd
index ead6254..01e09da 100644
--- a/src/entities/actors/snake/scripts/snake.gd
+++ b/src/entities/actors/snake/scripts/snake.gd
@@ -13,6 +13,7 @@ var tail_segment: PathFollow2D
# didn't konw how to name this, basically holds the current path lenght
# whenever the add body segment, and we use this stack to add body parts
var body_segment_queue: Array
+# var distance_to_first_segment: float
func _ready():
@@ -23,21 +24,28 @@ func _ready():
Event.connect("snake_added_initial_segments", self, "_on_snake_added_initial_segments")
Event.connect("food_eaten", self, "_on_food_eaten")
+ # need to always set a new curve when ready, so when restarting it's af resh curve
+ path.curve = Curve2D.new()
func _physics_process(delta: float) -> void:
- if body_segment_queue.size() != 0:
+ if body_segment_queue.size() != 0 and current_body_segments > max_body_initial_segments:
_add_new_segment()
+ # if body_segment_stack.size() > 0:
+ # distance_to_first_segment = path.curve.get_baked_length() - body_segment_stack.front().offset
+ # if distance_to_first_segment >= Global.SNAKE_SEGMENT_SIZE:
+ # print(distance_to_first_segment)
+
func _input(event: InputEvent) -> void:
if event.is_action_pressed("add_body_part"):
_add_segment_to_queue()
-func _draw() -> void:
- if path.curve.get_baked_points().size() >= 2:
- draw_polyline(path.curve.get_baked_points(), Color.aquamarine, 1, true)
+# func _draw() -> void:
+# if path.curve.get_baked_points().size() >= 2:
+# draw_polyline(path.curve.get_baked_points(), Color.aquamarine, 1, true)
func _add_new_segment() -> void:
@@ -83,7 +91,7 @@ func _add_segment_to_queue() -> void:
func _on_snake_path_new_point(coordinates: Vector2) -> void:
path.curve.add_point(coordinates)
# update call is to draw curve as there are new points to the path's curve
- update()
+ # update()
if current_body_segments < max_body_initial_segments:
_add_initial_segment(BODY_SEGMENT_NP)
@@ -101,5 +109,5 @@ func _on_snake_added_initial_segments() -> void:
set_process_input(true)
-func _on_food_eaten(type: int) -> void:
- _add_segment_to_queue() \ No newline at end of file
+func _on_food_eaten(type: int, location: Vector2) -> void:
+ _add_segment_to_queue()
diff --git a/src/entities/actors/snake/sprites/body.png b/src/entities/actors/snake/sprites/body.png
index ebef3b4..d94ff94 100644
--- a/src/entities/actors/snake/sprites/body.png
+++ b/src/entities/actors/snake/sprites/body.png
Binary files differ
diff --git a/src/entities/actors/snake/sprites/head.png b/src/entities/actors/snake/sprites/head.png
index 525de45..0bca146 100644
--- a/src/entities/actors/snake/sprites/head.png
+++ b/src/entities/actors/snake/sprites/head.png
Binary files differ
diff --git a/src/entities/actors/snake/sprites/tail.png b/src/entities/actors/snake/sprites/tail.png
index ff78e1b..05abc6e 100644
--- a/src/entities/actors/snake/sprites/tail.png
+++ b/src/entities/actors/snake/sprites/tail.png
Binary files differ
diff --git a/src/entities/food/scenes/Food.tscn b/src/entities/food/scenes/Food.tscn
index bc330e2..7accbc6 100644
--- a/src/entities/food/scenes/Food.tscn
+++ b/src/entities/food/scenes/Food.tscn
@@ -3,7 +3,7 @@
[ext_resource path="res://entities/food/scripts/food.gd" type="Script" id=2]
[sub_resource type="CircleShape2D" id=1]
-radius = 7.0
+radius = 4.0
[node name="Food" type="Area2D"]
collision_layer = 256
diff --git a/src/entities/food/scripts/food.gd b/src/entities/food/scripts/food.gd
index 1689837..e8b0261 100644
--- a/src/entities/food/scripts/food.gd
+++ b/src/entities/food/scripts/food.gd
@@ -11,6 +11,7 @@ var _type_texture: Dictionary = {
export(Type) var TYPE
onready var _sprite: Sprite = $Sprite
+var location: Vector2
func _ready():
@@ -19,5 +20,5 @@ func _ready():
func _on_body_entered(body: Node) -> void:
- Event.emit_signal("food_eaten", TYPE)
+ Event.emit_signal("food_eaten", TYPE, location)
queue_free() \ No newline at end of file
diff --git a/src/entities/food/scripts/food_manager.gd b/src/entities/food/scripts/food_manager.gd
index 20772db..426677c 100644
--- a/src/entities/food/scripts/food_manager.gd
+++ b/src/entities/food/scripts/food_manager.gd
@@ -2,38 +2,53 @@ class_name FoodManager
extends Node2D
export(PackedScene) var FOOD: PackedScene
+export(NodePath) var WORLD_GENERATOR_NP: NodePath
+onready var world_generator: Node2D = get_node(WORLD_GENERATOR_NP)
+onready var possible_food_locations: Array = world_generator.get_valid_map_coords()
var max_apples: int = 10
-var current_apples: int = 0
+var current_food: Array = []
func _ready():
- Event.connect("food_eaten", self, "_on_food_eaten")
randomize()
+ Event.connect("food_eaten", self, "_on_food_eaten")
func _process(delta) -> void:
- if current_apples < max_apples:
+ if current_food.size() < max_apples:
_place_new_food()
- current_apples += 1
func _place_new_food() -> void:
var food: Area2D = FOOD.instance()
Event.emit_signal("food_placing_new_food", food.TYPE)
- var position: Vector2 = _get_random_pos()
- food.global_position = position
+ var pos_loc: Array = _get_random_pos()
+ var pos: Vector2 = pos_loc[0]
+ var loc: Vector2 = pos_loc[1]
+
+ food.global_position = pos
+ food.location = loc
add_child(food)
- Event.emit_signal("food_placed_new_food", food.TYPE)
+ current_food.append(loc)
+ Event.emit_signal("food_placed_new_food", food.TYPE, loc)
+
+func _get_random_pos() -> Array:
+ var found_valid_loc: bool = false
+ var index: int
+ var location: Vector2
-func _get_random_pos() -> Vector2:
- var screen_size: Vector2 = get_viewport().get_visible_rect().size
- var temp_x: float = randf() * screen_size.x - screen_size.x / 2.0
- var temp_y: float = randf() * screen_size.y - screen_size.y / 2.0
+ while not found_valid_loc:
+ print("trying")
+ index = randi() % possible_food_locations.size()
+ location = possible_food_locations[index]
+ if current_food.find(location) == -1:
+ found_valid_loc = true
- return Vector2(temp_x, temp_y)
+ return [world_generator.get_centered_world_position(location), location]
-func _on_food_eaten(type: int) -> void:
- current_apples -= 1 \ No newline at end of file
+func _on_food_eaten(type: int, location: Vector2) -> void:
+ var index: int = current_food.find(location)
+ current_food.remove(index)
diff --git a/src/entities/food/sprites/apple.png b/src/entities/food/sprites/apple.png
index d4fd6ad..7111450 100644
--- a/src/entities/food/sprites/apple.png
+++ b/src/entities/food/sprites/apple.png
Binary files differ
diff --git a/src/event.gd b/src/event.gd
index 7e72aca..054781f 100644
--- a/src/event.gd
+++ b/src/event.gd
@@ -1,11 +1,20 @@
extends Node
+signal game_start
+signal game_over
+
signal snake_path_new_point(coordinates)
signal snake_adding_new_segment(type)
signal snake_added_new_segment(type)
signal snake_added_initial_segments
signal snake_segment_body_entered(body)
+signal snake_rotated
signal food_placing_new_food(type)
-signal food_placed_new_food(type)
-signal food_eaten(type) \ No newline at end of file
+signal food_placed_new_food(type, location)
+signal food_eaten(type, location)
+
+signal world_gen_walker_started(id)
+signal world_gen_walker_finished(id)
+signal world_gen_walker_died(id)
+signal world_gen_spawn_walker_unit(location) \ No newline at end of file
diff --git a/src/fonts/MonogramExtended.tres b/src/fonts/MonogramExtended.tres
new file mode 100644
index 0000000..0f50f72
--- /dev/null
+++ b/src/fonts/MonogramExtended.tres
@@ -0,0 +1,6 @@
+[gd_resource type="DynamicFont" load_steps=2 format=2]
+
+[ext_resource path="res://fonts/monogram_extended.ttf" type="DynamicFontData" id=1]
+
+[resource]
+font_data = ExtResource( 1 )
diff --git a/src/fonts/monogram_extended.ttf b/src/fonts/monogram_extended.ttf
new file mode 100644
index 0000000..4d4a390
--- /dev/null
+++ b/src/fonts/monogram_extended.ttf
Binary files differ
diff --git a/src/global.gd b/src/global.gd
index 2885443..72cb294 100644
--- a/src/global.gd
+++ b/src/global.gd
@@ -1,9 +1,12 @@
extends Node
var GAME_SCALE: float = 2.0
+var TILE_SIZE: int = 16
+var WORLD_TILE_PATH: int = 0
+var WORLD_TILE_WALL: int = 1
var SNAKE_SPEED: float = 50.0
-var SNAKE_ROT_SPEED: float = 200.0
-var SNAKE_POSITION_UPDATE_INTERVAL: float = 0.01
+var SNAKE_ROT_SPEED: float = 300.0
+var SNAKE_POSITION_UPDATE_INTERVAL: float = 0.001
# this usually corresponds to the sprite size
-var SNAKE_SEGMENT_SIZE: float = 14.0
+var SNAKE_SEGMENT_SIZE: float = 6.0
diff --git a/src/main.gd b/src/main.gd
index cdfbbf1..38a0341 100644
--- a/src/main.gd
+++ b/src/main.gd
@@ -5,13 +5,22 @@ onready var _snake: Node2D = $Snake
func _ready() -> void:
+ Event.connect("game_start", self, "_on_game_start")
+ Event.connect("game_over", self, "_on_game_over")
Event.connect("snake_segment_body_entered", self, "_on_snake_segment_body_entered")
+
+ _snake_disabled(false)
# OS.window_size = Global.GAME_SCALE * OS.window_size
+func _input(event: InputEvent) -> void:
+ if event.is_action_pressed("restart"):
+ get_tree().reload_current_scene()
+
+
func _on_snake_segment_body_entered(body: Node) -> void:
if body is KinematicBody2D:
- _snake_disabled(false)
+ Event.emit_signal("game_over")
func _snake_disabled(on_off: bool) -> void:
@@ -20,3 +29,13 @@ func _snake_disabled(on_off: bool) -> void:
_snake.propagate_call("set_physics_process", [on_off])
_snake.propagate_call("set_physics_process_internal", [on_off])
_snake.propagate_call("set_process_input", [on_off])
+
+
+func _on_game_start() -> void:
+ print("game start")
+ _snake_disabled(true)
+
+
+func _on_game_over() -> void:
+ print("game over")
+ _snake_disabled(false)
diff --git a/src/project.godot b/src/project.godot
index bf55ea9..9319699 100644
--- a/src/project.godot
+++ b/src/project.godot
@@ -117,6 +117,11 @@ add_body_part={
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":32,"unicode":0,"echo":false,"script":null)
]
}
+restart={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":82,"unicode":0,"echo":false,"script":null)
+ ]
+}
[layer_names]
diff --git a/src/tools/ScreenRecorder.tscn b/src/tools/screen_recorder/ScreenRecorder.tscn
index 96d6dff..c5ddcd2 100644
--- a/src/tools/ScreenRecorder.tscn
+++ b/src/tools/screen_recorder/ScreenRecorder.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://addons/GifMaker/GifRectangle.gd" type="Script" id=1]
-[ext_resource path="res://tools/screen_recorder.gd" type="Script" id=2]
+[ext_resource path="res://tools/screen_recorder/screen_recorder.gd" type="Script" id=2]
[ext_resource path="res://addons/GifMaker/GifRecorder.gd" type="Script" id=3]
[node name="ScreenRecorder" type="CanvasLayer"]
+layer = 0
script = ExtResource( 2 )
[node name="Control" type="Control" parent="."]
diff --git a/src/tools/screen_recorder.gd b/src/tools/screen_recorder/screen_recorder.gd
index 2ab77e5..2ab77e5 100644
--- a/src/tools/screen_recorder.gd
+++ b/src/tools/screen_recorder/screen_recorder.gd
diff --git a/src/tools/world_generator/scenes/WalkerHead.tscn b/src/tools/world_generator/scenes/WalkerHead.tscn
new file mode 100644
index 0000000..a62b9ed
--- /dev/null
+++ b/src/tools/world_generator/scenes/WalkerHead.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=2]
+
+[ext_resource path="res://tools/world_generator/scripts/walker_head.gd" type="Script" id=1]
+
+[node name="WalkerHead" type="Node2D"]
+script = ExtResource( 1 )
diff --git a/src/tools/world_generator/scenes/WalkerUnit.tscn b/src/tools/world_generator/scenes/WalkerUnit.tscn
new file mode 100644
index 0000000..bf10698
--- /dev/null
+++ b/src/tools/world_generator/scenes/WalkerUnit.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=2]
+
+[ext_resource path="res://tools/world_generator/scripts/walker_unit.gd" type="Script" id=1]
+
+[node name="WalkerUnit" type="Node2D"]
+script = ExtResource( 1 )
diff --git a/src/tools/world_generator/scenes/WorldGenerator.tscn b/src/tools/world_generator/scenes/WorldGenerator.tscn
new file mode 100644
index 0000000..32ed939
--- /dev/null
+++ b/src/tools/world_generator/scenes/WorldGenerator.tscn
@@ -0,0 +1,65 @@
+[gd_scene load_steps=8 format=2]
+
+[ext_resource path="res://tools/world_generator/sprites/white.png" type="Texture" id=1]
+[ext_resource path="res://tools/world_generator/sprites/black.png" type="Texture" id=2]
+[ext_resource path="res://tools/world_generator/scenes/WalkerUnit.tscn" type="PackedScene" id=3]
+[ext_resource path="res://tools/world_generator/scenes/WalkerHead.tscn" type="PackedScene" id=4]
+[ext_resource path="res://tools/world_generator/scripts/world_generator.gd" type="Script" id=5]
+
+[sub_resource type="ConvexPolygonShape2D" id=2]
+points = PoolVector2Array( 16, 16, 0, 16, 0, 0, 16, 0 )
+
+[sub_resource type="TileSet" id=1]
+0/name = "white.png 0"
+0/texture = ExtResource( 1 )
+0/tex_offset = Vector2( 0, 0 )
+0/modulate = Color( 1, 1, 1, 1 )
+0/region = Rect2( 0, 0, 16, 16 )
+0/tile_mode = 0
+0/occluder_offset = Vector2( 0, 0 )
+0/navigation_offset = Vector2( 0, 0 )
+0/shape_offset = Vector2( 0, 0 )
+0/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
+0/shape_one_way = false
+0/shape_one_way_margin = 0.0
+0/shapes = [ ]
+0/z_index = 0
+1/name = "black.png 1"
+1/texture = ExtResource( 2 )
+1/tex_offset = Vector2( 0, 0 )
+1/modulate = Color( 1, 1, 1, 1 )
+1/region = Rect2( 0, 0, 16, 16 )
+1/tile_mode = 0
+1/occluder_offset = Vector2( 0, 0 )
+1/navigation_offset = Vector2( 0, 0 )
+1/shape_offset = Vector2( 0, 0 )
+1/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
+1/shape = SubResource( 2 )
+1/shape_one_way = false
+1/shape_one_way_margin = 1.0
+1/shapes = [ {
+"autotile_coord": Vector2( 0, 0 ),
+"one_way": false,
+"one_way_margin": 1.0,
+"shape": SubResource( 2 ),
+"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
+} ]
+1/z_index = 0
+
+[node name="WorldGenerator" type="Node2D"]
+script = ExtResource( 5 )
+TILEMAP_NP = NodePath("TileMap")
+
+[node name="TileMap" type="TileMap" parent="."]
+tile_set = SubResource( 1 )
+cell_size = Vector2( 16, 16 )
+cell_quadrant_size = 4
+format = 1
+
+[node name="WalkerHead" parent="." instance=ExtResource( 4 )]
+TILEMAP_NP = NodePath("../TileMap")
+WALKER_UNIT_NP = ExtResource( 3 )
+
+[node name="Camera" type="Camera2D" parent="."]
+current = true
+zoom = Vector2( 5, 5 )
diff --git a/src/tools/world_generator/scripts/walker_head.gd b/src/tools/world_generator/scripts/walker_head.gd
new file mode 100644
index 0000000..3bf7e3a
--- /dev/null
+++ b/src/tools/world_generator/scripts/walker_head.gd
@@ -0,0 +1,70 @@
+extends Node2D
+
+export(NodePath) var TILEMAP_NP: NodePath
+export(PackedScene) var WALKER_UNIT_NP: PackedScene
+export(int, 5, 100, 1) var starting_unit_count: int = 5
+export(int, 5, 10, 1) var initial_safe_zone_size: int = 5
+
+onready var tilemap: TileMap = get_node(TILEMAP_NP)
+
+var max_x: int = 0
+var max_y: int = 0
+var map_margin: int = 10
+var units: int = 0
+
+
+func _ready() -> void:
+ Event.connect("world_gen_walker_started", self, "_on_world_gen_walker_started")
+ Event.connect("world_gen_walker_finished", self, "_on_world_gen_walker_finished")
+ Event.connect("world_gen_walker_died", self, "_on_world_gen_walker_died")
+ Event.connect("world_gen_spawn_walker_unit", self, "_on_world_gen_spawn_walker_unit")
+ _place_safe_zone()
+ _spawn_walker_units()
+ _fill_empty_space()
+
+
+func _place_safe_zone() -> void:
+ for i in initial_safe_zone_size:
+ for j in initial_safe_zone_size:
+ tilemap.set_cell(i, j, Global.WORLD_TILE_PATH)
+ tilemap.set_cell(-i, -j, Global.WORLD_TILE_PATH)
+
+
+func _spawn_walker_units() -> void:
+ for i in starting_unit_count:
+ _spawn_walker_unit(Vector2.ZERO)
+
+
+func _spawn_walker_unit(spawn_position: Vector2) -> void:
+ var walker_unit: Node2D = WALKER_UNIT_NP.instance()
+ add_child(walker_unit)
+ units += 1
+ walker_unit.position = spawn_position
+ walker_unit.start(units)
+
+
+func _fill_empty_space() -> void:
+ var rect: Rect2 = tilemap.get_used_rect()
+ var margin: int = map_margin
+ for x in range(-margin, rect.size.x + margin):
+ for y in range (-margin, rect.size.y + margin ):
+ var poses: Vector2= Vector2(rect.position.x + x, rect.position.y + y)
+ if tilemap.get_cell(int(poses.x), int(poses.y)) == TileMap.INVALID_CELL:
+ tilemap.set_cellv(poses, Global.WORLD_TILE_WALL)
+
+
+func _on_world_gen_walker_started(id: int) -> void:
+ print("Walker unit %s started." % id)
+
+
+func _on_world_gen_walker_finished(id: int) -> void:
+ print("Walker unit %s finished." % id)
+
+
+func _on_world_gen_walker_died(id: int) -> void:
+ print("Walker unit %s died." % id)
+
+
+func _on_world_gen_spawn_walker_unit(location: Vector2) -> void:
+ print("Spawning new walking unit.")
+ _spawn_walker_unit(location)
diff --git a/src/tools/world_generator/scripts/walker_unit.gd b/src/tools/world_generator/scripts/walker_unit.gd
new file mode 100644
index 0000000..cfa8f91
--- /dev/null
+++ b/src/tools/world_generator/scripts/walker_unit.gd
@@ -0,0 +1,98 @@
+extends Node2D
+
+enum Direction {
+ LEFT,
+ RIGHT,
+ UP,
+ DOWN
+}
+
+var direction: Dictionary = {
+ Direction.LEFT: Vector2.LEFT,
+ Direction.RIGHT: Vector2.RIGHT,
+ Direction.UP: Vector2.UP,
+ Direction.DOWN: Vector2.DOWN
+}
+
+var _walker_head: Node2D
+var _tilemap: TileMap
+
+var given_birth: bool = false
+var walked_straight: bool = false
+
+var path_length: int
+var birth_chance: float
+var death_chance: float
+var walk_straight_chance: float
+var walk_straight_length: float
+
+
+func start(id: int) -> void:
+ Event.emit_signal("world_gen_walker_started", id)
+ _walker_head = get_parent()
+ _tilemap = _walker_head.tilemap
+ _randomize_stats()
+
+ var path_steps: Array = _get_path_steps()
+ var walker_died: bool = _set_path_tiles(path_steps)
+
+ if walker_died:
+ Event.emit_signal("world_gen_walker_died", id)
+ else:
+ Event.emit_signal("world_gen_walker_finished", id)
+ queue_free()
+
+
+func _randomize_stats() -> void:
+ randomize()
+ path_length = int(rand_range(50, 200))
+ birth_chance = rand_range(0.001, 0.01)
+ death_chance = rand_range(0.0, 0.005) / 2.0
+ walk_straight_chance = rand_range(0.001, 0.025)
+ walk_straight_length = rand_range(4, 20)
+
+
+func _get_path_steps() -> Array:
+ var path_steps: Array = []
+ var step: int
+ for _i in path_length:
+ step = randi() % Direction.size()
+ path_steps.append(step)
+
+ if randf() < walk_straight_chance and not walked_straight:
+ for j in walk_straight_length:
+ path_steps.append(step)
+ walked_straight = true
+ return path_steps
+
+
+func _set_path_tiles(path_steps: Array) -> bool:
+ # get initial tile location
+ var location: Vector2 = get_parent().global_position * Global.TILE_SIZE
+ var move_direction: Vector2
+ _set_tile(location, 0)
+ for step in path_steps:
+ move_direction = direction[step]
+ location += move_direction * Global.TILE_SIZE
+ _set_tile(location, Global.WORLD_TILE_PATH)
+
+ if randf() < birth_chance and not given_birth:
+ Event.emit_signal("world_gen_spawn_walker_unit", location)
+ given_birth = true
+
+ if randf() < death_chance:
+ return true
+ return false
+
+
+func _set_tile(location: Vector2, tile: int) -> void:
+ var coordinates: Vector2 = _tilemap.world_to_map(location)
+ _update_map_size(coordinates)
+ _tilemap.set_cellv(coordinates, tile)
+
+
+func _update_map_size(coordinates: Vector2) -> void:
+ if coordinates.x > _walker_head.max_x:
+ _walker_head.max_x = coordinates.x
+ if coordinates.y > _walker_head.max_y:
+ _walker_head.max_y = coordinates.y
diff --git a/src/tools/world_generator/scripts/world_generator.gd b/src/tools/world_generator/scripts/world_generator.gd
new file mode 100644
index 0000000..5e8626b
--- /dev/null
+++ b/src/tools/world_generator/scripts/world_generator.gd
@@ -0,0 +1,12 @@
+extends Node2D
+
+export(NodePath) var TILEMAP_NP: NodePath
+onready var tilemap: TileMap = get_node(TILEMAP_NP)
+
+
+func get_valid_map_coords() -> Array:
+ return tilemap.get_used_cells_by_id(Global.WORLD_TILE_PATH)
+
+
+func get_centered_world_position(location: Vector2) -> Vector2:
+ return tilemap.map_to_world(location) + Vector2.ONE * Global.TILE_SIZE / 2.0
diff --git a/src/tools/world_generator/sprites/black.png b/src/tools/world_generator/sprites/black.png
new file mode 100644
index 0000000..d59329c
--- /dev/null
+++ b/src/tools/world_generator/sprites/black.png
Binary files differ
diff --git a/src/tools/world_generator/sprites/black.png.import b/src/tools/world_generator/sprites/black.png.import
new file mode 100644
index 0000000..baaf7e2
--- /dev/null
+++ b/src/tools/world_generator/sprites/black.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/black.png-c132963832bee437653237bacfeb5776.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://tools/world_generator/sprites/black.png"
+dest_files=[ "res://.import/black.png-c132963832bee437653237bacfeb5776.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=false
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=false
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+process/normal_map_invert_y=false
+stream=false
+size_limit=0
+detect_3d=false
+svg/scale=1.0
diff --git a/src/tools/world_generator/sprites/white.png b/src/tools/world_generator/sprites/white.png
new file mode 100644
index 0000000..a449dec
--- /dev/null
+++ b/src/tools/world_generator/sprites/white.png
Binary files differ
diff --git a/src/tools/world_generator/sprites/white.png.import b/src/tools/world_generator/sprites/white.png.import
new file mode 100644
index 0000000..434e753
--- /dev/null
+++ b/src/tools/world_generator/sprites/white.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/white.png-a9cc063b7d400d5bbfefc663f8a2b60f.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://tools/world_generator/sprites/white.png"
+dest_files=[ "res://.import/white.png-a9cc063b7d400d5bbfefc663f8a2b60f.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=false
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=false
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+process/normal_map_invert_y=false
+stream=false
+size_limit=0
+detect_3d=false
+svg/scale=1.0
diff --git a/src/ui/UI.tscn b/src/ui/UI.tscn
index f5b0ac3..207a5fa 100644
--- a/src/ui/UI.tscn
+++ b/src/ui/UI.tscn
@@ -1,6 +1,7 @@
-[gd_scene load_steps=2 format=2]
+[gd_scene load_steps=3 format=2]
[ext_resource path="res://ui/ui.gd" type="Script" id=1]
+[ext_resource path="res://fonts/MonogramExtended.tres" type="DynamicFont" id=2]
[node name="UI" type="CanvasLayer"]
script = ExtResource( 1 )
@@ -12,13 +13,30 @@ anchor_bottom = 1.0
[node name="StatsHUD" type="MarginContainer" parent="Root"]
margin_left = 10.0
margin_top = 10.0
-margin_right = 310.0
-margin_bottom = 110.0
+margin_right = 130.0
+margin_bottom = 50.0
[node name="VBox" type="VBoxContainer" parent="Root/StatsHUD"]
-margin_right = 300.0
-margin_bottom = 100.0
+margin_right = 120.0
+margin_bottom = 40.0
[node name="SnakeSize" type="Label" parent="Root/StatsHUD/VBox"]
-margin_right = 300.0
-margin_bottom = 14.0
+margin_right = 120.0
+margin_bottom = 13.0
+custom_fonts/font = ExtResource( 2 )
+
+[node name="MarginContainer" type="MarginContainer" parent="Root"]
+anchor_top = 1.0
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_top = -20.0
+
+[node name="CenterContainer" type="CenterContainer" parent="Root/MarginContainer"]
+margin_right = 320.0
+margin_bottom = 20.0
+
+[node name="Start" type="Button" parent="Root/MarginContainer/CenterContainer"]
+margin_left = 139.0
+margin_right = 180.0
+margin_bottom = 20.0
+text = "Start"
diff --git a/src/ui/ui.gd b/src/ui/ui.gd
index cb7353e..8132d52 100644
--- a/src/ui/ui.gd
+++ b/src/ui/ui.gd
@@ -2,6 +2,7 @@ class_name UI
extends CanvasLayer
onready var _snake_size_label: Label = $Root/StatsHUD/VBox/SnakeSize
+onready var _start_button: Button = $Root/MarginContainer/CenterContainer/Start
var snake_size: int = 0
var _snake_size_fmt: String = "Snake size: %s"
@@ -11,7 +12,15 @@ func _ready():
Event.connect("snake_added_new_segment", self, "_on_Snake_added_new_segment")
_snake_size_label.text =_snake_size_fmt % snake_size
+ _start_button.connect("pressed", self, "_on_start_button_pressed")
+
func _on_Snake_added_new_segment(type: String) -> void:
snake_size += 1
_snake_size_label.text =_snake_size_fmt % snake_size
+
+
+func _on_start_button_pressed() -> void:
+ _start_button.disabled = true
+ _start_button.visible = false
+ Event.emit_signal("game_start") \ No newline at end of file