From f922fe4669080d1633e0a345a3f8981867c9e841 Mon Sep 17 00:00:00 2001 From: David Luevano Alvarado Date: Fri, 3 Jun 2022 21:13:19 -0600 Subject: add working world gen, fixed food placing, minor refactoring --- src/Main.tscn | 10 +-- src/entities/actors/snake/scenes/Body.tscn | 4 +- src/entities/actors/snake/scenes/Head.tscn | 5 +- src/entities/actors/snake/scenes/Snake.tscn | 9 +- src/entities/actors/snake/scenes/Tail.tscn | 3 +- src/entities/actors/snake/scripts/camera.gd | 9 ++ .../actors/snake/scripts/generic_segment.gd | 7 ++ src/entities/actors/snake/scripts/head.gd | 2 + src/entities/actors/snake/scripts/snake.gd | 22 +++-- src/entities/actors/snake/sprites/body.png | Bin 168 -> 136 bytes src/entities/actors/snake/sprites/head.png | Bin 188 -> 174 bytes src/entities/actors/snake/sprites/tail.png | Bin 174 -> 133 bytes src/entities/food/scenes/Food.tscn | 2 +- src/entities/food/scripts/food.gd | 3 +- src/entities/food/scripts/food_manager.gd | 43 ++++++--- src/entities/food/sprites/apple.png | Bin 148 -> 135 bytes src/event.gd | 13 ++- src/fonts/MonogramExtended.tres | 6 ++ src/fonts/monogram_extended.ttf | Bin 0 -> 41508 bytes src/global.gd | 9 +- src/main.gd | 21 ++++- src/project.godot | 5 ++ src/tools/ScreenRecorder.tscn | 25 ------ src/tools/screen_recorder.gd | 13 --- src/tools/screen_recorder/ScreenRecorder.tscn | 26 ++++++ src/tools/screen_recorder/screen_recorder.gd | 13 +++ src/tools/world_generator/scenes/WalkerHead.tscn | 6 ++ src/tools/world_generator/scenes/WalkerUnit.tscn | 6 ++ .../world_generator/scenes/WorldGenerator.tscn | 65 ++++++++++++++ src/tools/world_generator/scripts/walker_head.gd | 70 +++++++++++++++ src/tools/world_generator/scripts/walker_unit.gd | 98 +++++++++++++++++++++ .../world_generator/scripts/world_generator.gd | 12 +++ src/tools/world_generator/sprites/black.png | Bin 0 -> 99 bytes src/tools/world_generator/sprites/black.png.import | 35 ++++++++ src/tools/world_generator/sprites/white.png | Bin 0 -> 99 bytes src/tools/world_generator/sprites/white.png.import | 35 ++++++++ src/ui/UI.tscn | 32 +++++-- src/ui/ui.gd | 9 ++ 38 files changed, 531 insertions(+), 87 deletions(-) create mode 100644 src/entities/actors/snake/scripts/camera.gd create mode 100644 src/fonts/MonogramExtended.tres create mode 100644 src/fonts/monogram_extended.ttf delete mode 100644 src/tools/ScreenRecorder.tscn delete mode 100644 src/tools/screen_recorder.gd create mode 100644 src/tools/screen_recorder/ScreenRecorder.tscn create mode 100644 src/tools/screen_recorder/screen_recorder.gd create mode 100644 src/tools/world_generator/scenes/WalkerHead.tscn create mode 100644 src/tools/world_generator/scenes/WalkerUnit.tscn create mode 100644 src/tools/world_generator/scenes/WorldGenerator.tscn create mode 100644 src/tools/world_generator/scripts/walker_head.gd create mode 100644 src/tools/world_generator/scripts/walker_unit.gd create mode 100644 src/tools/world_generator/scripts/world_generator.gd create mode 100644 src/tools/world_generator/sprites/black.png create mode 100644 src/tools/world_generator/sprites/black.png.import create mode 100644 src/tools/world_generator/sprites/white.png create mode 100644 src/tools/world_generator/sprites/white.png.import (limited to 'src') 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 Binary files a/src/entities/actors/snake/sprites/body.png and b/src/entities/actors/snake/sprites/body.png differ diff --git a/src/entities/actors/snake/sprites/head.png b/src/entities/actors/snake/sprites/head.png index 525de45..0bca146 100644 Binary files a/src/entities/actors/snake/sprites/head.png and b/src/entities/actors/snake/sprites/head.png differ diff --git a/src/entities/actors/snake/sprites/tail.png b/src/entities/actors/snake/sprites/tail.png index ff78e1b..05abc6e 100644 Binary files a/src/entities/actors/snake/sprites/tail.png and b/src/entities/actors/snake/sprites/tail.png 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 Binary files a/src/entities/food/sprites/apple.png and b/src/entities/food/sprites/apple.png 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 Binary files /dev/null and b/src/fonts/monogram_extended.ttf 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/ScreenRecorder.tscn deleted file mode 100644 index 96d6dff..0000000 --- a/src/tools/ScreenRecorder.tscn +++ /dev/null @@ -1,25 +0,0 @@ -[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://addons/GifMaker/GifRecorder.gd" type="Script" id=3] - -[node name="ScreenRecorder" type="CanvasLayer"] -script = ExtResource( 2 ) - -[node name="Control" type="Control" parent="."] -anchor_right = 1.0 -anchor_bottom = 1.0 - -[node name="GifRectangle" type="ReferenceRect" parent="Control"] -anchor_right = 1.0 -anchor_bottom = 1.0 -script = ExtResource( 1 ) - -[node name="GifRecorder" type="Viewport" parent="Control"] -size = Vector2( 2, 2 ) -script = ExtResource( 3 ) -render_type = 1 -seconds = 4.0 -autostart = true -capture_node_path = NodePath("../GifRectangle") diff --git a/src/tools/screen_recorder.gd b/src/tools/screen_recorder.gd deleted file mode 100644 index 2ab77e5..0000000 --- a/src/tools/screen_recorder.gd +++ /dev/null @@ -1,13 +0,0 @@ -extends CanvasLayer - -onready var gif_recorder: GifRecorder = $Control/GifRecorder - - -func _input(event: InputEvent) -> void: - if event is InputEventKey and event.scancode == KEY_G and event.pressed: - print("Encoding GIF.") - gif_recorder.render_to_file("res://test.gif") - yield(gif_recorder, "done_encoding") - print("Done encoding GIF.") - gif_recorder.clear() - gif_recorder.start() diff --git a/src/tools/screen_recorder/ScreenRecorder.tscn b/src/tools/screen_recorder/ScreenRecorder.tscn new file mode 100644 index 0000000..c5ddcd2 --- /dev/null +++ b/src/tools/screen_recorder/ScreenRecorder.tscn @@ -0,0 +1,26 @@ +[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/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="."] +anchor_right = 1.0 +anchor_bottom = 1.0 + +[node name="GifRectangle" type="ReferenceRect" parent="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 1 ) + +[node name="GifRecorder" type="Viewport" parent="Control"] +size = Vector2( 2, 2 ) +script = ExtResource( 3 ) +render_type = 1 +seconds = 4.0 +autostart = true +capture_node_path = NodePath("../GifRectangle") diff --git a/src/tools/screen_recorder/screen_recorder.gd b/src/tools/screen_recorder/screen_recorder.gd new file mode 100644 index 0000000..2ab77e5 --- /dev/null +++ b/src/tools/screen_recorder/screen_recorder.gd @@ -0,0 +1,13 @@ +extends CanvasLayer + +onready var gif_recorder: GifRecorder = $Control/GifRecorder + + +func _input(event: InputEvent) -> void: + if event is InputEventKey and event.scancode == KEY_G and event.pressed: + print("Encoding GIF.") + gif_recorder.render_to_file("res://test.gif") + yield(gif_recorder, "done_encoding") + print("Done encoding GIF.") + gif_recorder.clear() + gif_recorder.start() 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 Binary files /dev/null and b/src/tools/world_generator/sprites/black.png 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 Binary files /dev/null and b/src/tools/world_generator/sprites/white.png 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 -- cgit v1.2.3