Implement Game logic
TODO: Game UI with settings and start button, Gamepad input, visuals
This commit is contained in:
parent
92fc52a8ba
commit
8b21cdcc6a
6 changed files with 181 additions and 60 deletions
|
@ -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="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="Node2D" type="Node2D"]
|
||||||
|
|
||||||
[node name="GameManager" type="Node" parent="."]
|
[node name="GameManager" type="Node" parent="."]
|
||||||
|
|
||||||
[node name="Map" type="Node2D" parent="."]
|
[node name="Map" type="Node2D" parent="."]
|
||||||
script = ExtResource("1_dyj4p")
|
script = ExtResource("1_lps27")
|
||||||
texture = ExtResource("2_wiemx")
|
texture = ExtResource("2_wiemx")
|
||||||
|
tile_color = SubResource("Resource_22g0s")
|
||||||
|
|
||||||
[node name="Camera2D" type="Camera2D" parent="."]
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
|
|
||||||
|
|
118
Scripts/GameManager.gd
Normal file
118
Scripts/GameManager.gd
Normal file
|
@ -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
|
|
@ -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
|
|
|
@ -9,12 +9,23 @@ enum States {
|
||||||
}
|
}
|
||||||
|
|
||||||
@export var state : 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():
|
func _init():
|
||||||
state = States.EMPTY
|
state = States.EMPTY
|
||||||
|
|
||||||
func get_state() -> States:
|
func update_color():
|
||||||
return state
|
match state:
|
||||||
|
States.EMPTY:
|
||||||
func set_state(_state : States):
|
self.modulate = tile_color.empty
|
||||||
state = _state
|
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
|
||||||
|
|
8
Scripts/TileColors.gd
Normal file
8
Scripts/TileColors.gd
Normal file
|
@ -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
|
|
@ -15,6 +15,33 @@ run/main_scene="res://Scene/Game.tscn"
|
||||||
config/features=PackedStringArray("4.0", "GL Compatibility")
|
config/features=PackedStringArray("4.0", "GL Compatibility")
|
||||||
config/icon="res://icon.svg"
|
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]
|
[rendering]
|
||||||
|
|
||||||
renderer/rendering_method="gl_compatibility"
|
renderer/rendering_method="gl_compatibility"
|
||||||
|
|
Loading…
Reference in a new issue