From 8b21cdcc6a23cfba0d32d0357f40162693b8ed9f Mon Sep 17 00:00:00 2001 From: snoweuph Date: Wed, 15 Feb 2023 18:11:37 +0100 Subject: [PATCH] Implement Game logic TODO: Game UI with settings and start button, Gamepad input, visuals --- Scene/Game.tscn | 15 ++++- Scripts/GameManager.gd | 118 ++++++++++++++++++++++++++++++++++++++++ Scripts/MapGenerator.gd | 52 ------------------ Scripts/Tile.gd | 21 +++++-- Scripts/TileColors.gd | 8 +++ project.godot | 27 +++++++++ 6 files changed, 181 insertions(+), 60 deletions(-) create mode 100644 Scripts/GameManager.gd delete mode 100644 Scripts/MapGenerator.gd create mode 100644 Scripts/TileColors.gd diff --git a/Scene/Game.tscn b/Scene/Game.tscn index 07e6562..d8daba0 100644 --- a/Scene/Game.tscn +++ b/Scene/Game.tscn @@ -1,15 +1,24 @@ -[gd_scene load_steps=3 format=3 uid="uid://clirt527jo4x2"] +[gd_scene load_steps=5 format=3 uid="uid://drs4bhpd3vrh2"] -[ext_resource type="Script" path="res://Scripts/MapGenerator.gd" id="1_dyj4p"] +[ext_resource type="Script" path="res://Scripts/GameManager.gd" id="1_lps27"] [ext_resource type="Texture2D" uid="uid://vv33w22kwgpc" path="res://Assets/tile.png" id="2_wiemx"] +[ext_resource type="Script" path="res://Scripts/TileColors.gd" id="3_gnesl"] + +[sub_resource type="Resource" id="Resource_22g0s"] +script = ExtResource("3_gnesl") +empty = Color(1, 1, 1, 1) +snake_head = Color(0, 1, 0, 1) +snake_body = Color(0.133333, 0.545098, 0.133333, 1) +apple = Color(1, 0, 0, 1) [node name="Node2D" type="Node2D"] [node name="GameManager" type="Node" parent="."] [node name="Map" type="Node2D" parent="."] -script = ExtResource("1_dyj4p") +script = ExtResource("1_lps27") texture = ExtResource("2_wiemx") +tile_color = SubResource("Resource_22g0s") [node name="Camera2D" type="Camera2D" parent="."] diff --git a/Scripts/GameManager.gd b/Scripts/GameManager.gd new file mode 100644 index 0000000..373eab9 --- /dev/null +++ b/Scripts/GameManager.gd @@ -0,0 +1,118 @@ +extends Node + +@export var map_size := 15 +@export var texture : Texture2D +@export var scale := 32.0 +@export var gaps := 4 +@export var speed := 0.25 + +@export var tile_color := TileColors.new() + +var tiles = [] +var snake_move_vector : Vector2 +var last_snake_move_vector : Vector2 +var snake_length : int + +var rng = RandomNumberGenerator.new() +var timer := 0.0 + +func generate_tiles(): + for x in range(map_size): + tiles.append([]) + tiles[x] = [] + for y in range(map_size): + var tile = Tile.new() + tile.texture = texture + tile.tile_color = tile_color + tile.scale = Vector2(scale, scale) + tile.position = Vector2(x * ( scale + gaps ) - map_size / 2 * (scale + gaps), y * (scale + gaps) - map_size / 2 * (scale + gaps)) + self.add_child(tile) + tiles[x].append([]) + tiles[x][y] = tile + pass + +func generate_apple(): + var foundViablePosition := false + var tile : Tile + while !foundViablePosition: + tile = tiles[rng.randi_range(0, map_size -1)][rng.randi_range(0, map_size -1)] as Tile + if(tile.state == Tile.States.EMPTY): + foundViablePosition = true + + tile.state = Tile.States.APPLE + pass + +func set_snake_to_start_position(): + #No need for float protection, godot automaticly converts floats to ints in this case + var tile = (tiles[map_size / 2][map_size / 2] as Tile) + tile.state = Tile.States.SNAKE + tile.snake_pos = 1 + pass + +func read_input() -> Vector2:# + # cant use Input.get_vector because it normalizes the vector + return Vector2(Input.get_axis("left", "right"), Input.get_axis("up", "down")) + + +func process_tiles(): + var new_snake_head : Tile + for x in range(map_size): + for y in range(map_size): + var tile = tiles[x][y] as Tile + if tile.state == Tile.States.SNAKE: + if tile.snake_pos == 1: + if x + snake_move_vector.x >= map_size || x + snake_move_vector.x < 0 || y + snake_move_vector.y >= map_size || y + snake_move_vector.y < 0: + game_stop() + return + new_snake_head = tiles[x + snake_move_vector.x][y + snake_move_vector.y] as Tile + tile.snake_pos += 1 + if(tile.snake_pos > snake_length): + tile.snake_pos = 0 + tile.state = Tile.States.EMPTY + + var was_apple = new_snake_head.state == Tile.States.APPLE + new_snake_head.snake_pos = 1 + new_snake_head.state = Tile.States.SNAKE + last_snake_move_vector = snake_move_vector + if was_apple: + snake_length += 1 + generate_apple() + pass + +func process_snake_rotation(): + var input = read_input() + print(input) + # Return if no Input or Input into multiple directions + if input.length() == 0 || input.length() > 1: + return + #return if input is the inverse of the moving direction + if input * -1 == last_snake_move_vector: + return + # set move direction into inpu direction + snake_move_vector = input.normalized() + +func _ready(): + game_start() + pass + +func game_start(): + snake_move_vector = Vector2.RIGHT + last_snake_move_vector = snake_move_vector + snake_length = 3 + tiles.clear() + generate_tiles() + set_snake_to_start_position() + generate_apple() + pass + +func game_stop(): + print("dead") + pass + +func _process(delta): + process_snake_rotation() + if(timer >= speed): + timer = 0 + process_tiles() + timer += delta + pass diff --git a/Scripts/MapGenerator.gd b/Scripts/MapGenerator.gd deleted file mode 100644 index a006eb9..0000000 --- a/Scripts/MapGenerator.gd +++ /dev/null @@ -1,52 +0,0 @@ -extends Node - -@export var map_size := 15 -@export var texture : Texture2D -@export var scale := 32.0 -@export var gaps := 4 - -@export_category("Colors") -@export var tile_color := Color.WHITE -@export var snake_color := Color.GREEN -@export var apple_color := Color.RED - -# Array of all Tiles of the Map -var tiles = [] - - -func generate_tiles(): - for x in range(map_size): - tiles.append([]) - tiles[x] = [] - for y in range(map_size): - var tile = Tile.new() - tile.texture = texture - tile.scale = Vector2(scale, scale) - tile.position = Vector2(x * ( scale + gaps ) - map_size / 2 * (scale + gaps), y * (scale + gaps) - map_size / 2 * (scale + gaps)) - self.add_child(tile) - tiles[x].append([]) - tiles[x][y] = tile - pass - -func _ready(): - generate_tiles() - pass - -func update_tile_colors(): - for x in range(map_size): - for y in range(map_size): - match tiles[x][y].get_state(): - - Tile.States.EMPTY: - tiles[x][y].modulate = tile_color - - Tile.States.SNAKE: - tiles[x][y].modulate = snake_color - - Tile.States.APPLE: - tiles[x][y].modulate = apple_color - pass - -func _process(delta): - update_tile_colors() - pass diff --git a/Scripts/Tile.gd b/Scripts/Tile.gd index 187383b..b4526bf 100644 --- a/Scripts/Tile.gd +++ b/Scripts/Tile.gd @@ -9,12 +9,23 @@ enum States { } @export var state : States +# 0 means no snake at all, 1 means head and the biger, the further it is from the head +@export var snake_pos := 0 +@export var tile_color : TileColors func _init(): state = States.EMPTY -func get_state() -> States: - return state - -func set_state(_state : States): - state = _state +func update_color(): + match state: + States.EMPTY: + self.modulate = tile_color.empty + States.SNAKE: + self.modulate = tile_color.snake_body if snake_pos > 1 else tile_color.snake_head + States.APPLE: + self.modulate = tile_color.apple + pass + +func _process(delta): + update_color() + pass diff --git a/Scripts/TileColors.gd b/Scripts/TileColors.gd new file mode 100644 index 0000000..5713fb9 --- /dev/null +++ b/Scripts/TileColors.gd @@ -0,0 +1,8 @@ +extends Resource + +class_name TileColors + +@export var empty := Color.WHITE +@export var snake_head := Color.GREEN +@export var snake_body := Color.FOREST_GREEN +@export var apple := Color.RED diff --git a/project.godot b/project.godot index 2a7ca0b..5979e6e 100644 --- a/project.godot +++ b/project.godot @@ -15,6 +15,33 @@ run/main_scene="res://Scene/Game.tscn" config/features=PackedStringArray("4.0", "GL Compatibility") config/icon="res://icon.svg" +[input] + +left={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"echo":false,"script":null) +] +} +right={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"echo":false,"script":null) +] +} +up={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"echo":false,"script":null) +] +} +down={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"echo":false,"script":null) +] +} + [rendering] renderer/rendering_method="gl_compatibility"