Merge pull request 'Interactable Items' (#4) from Interacable-Items into main

Reviewed-on: #4
pull/6/head
Yan Wittmann 2025-01-08 18:48:55 +01:00
commit b49d3a6d27
23 changed files with 303 additions and 177 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
project/.godot
.idea
.vscode

3
.vscode/settings.json vendored 100644
View File

@ -0,0 +1,3 @@
{
"godotTools.editorPath.godot4": "g:\\Godot\\Godot_v4.3-stable_win64_console.exe"
}

View File

@ -1,33 +1,34 @@
## Todo
- Sprites (Dome)
- camp (multiple textures)
- boat
- see DC
- Design a tilemap for the game (Dome)
- Navigation v3 (Yan)
- Player: function to walk up to a tile, not onto the tile (trees, etc.)
- Visualization: Current navigation path
- Interactive and Non-Interactive Items
- Add all the items needed to build the game (bushes, trees, etc.)
- Add logic regarding the objects, like taking branches, etc.
- Camp, chest (inventory slots, array of items, Interactions)
- Implement Behaviours
- Implement all kinds of Behaviours, see document
- UI, Visualization, make the simulation understandable (Luca, Colin)
- GraphEdit
- GraphEdit toggle (key)
- Inventory
- Player Stats
- Temperature layer toggle (key)
- etc.
## Done
- Sprites (Dome)
- Ground
- Berry bush (filled, empty)
- Tree (filled, empty)
- Ship parts
- camp (multiple textures)
- Design a tilemap for the game (Dome, Colin, Luca)
- Navigation v3 (Yan)
- Player: function to walk up to a tile, not onto the tile (trees, etc.)
- Player v2 (Colin)
- TBD
- Check player pickup function and inventory system (if inventory already full, etc.)
- Check player walking capability
- Interactions with camp, etc.
- Interactive and Non-Interactive Items (Luca)
- Add all the items needed to build the game (bushes, trees, etc.)
- Add logic regarding the objects, like picking up berries or taking branches, etc.
- Camp, chest (inventory slots, array of items)
- Implement Behaviours
- Implement all kinds of Behaviours, see document
- Visualization, make the simulation understandable
- GraphEdit
- Distances
- Current navigation path
- etc.
## Done
- Initialize Tilemap (Yan)
- Script --> World (manages access to tilemap)
- Player is on tilemap

View File

@ -1 +1 @@
{"frames":[{"duration":0.1}],"layers":[{"name":"ground","cels":[{"image":"tilemaps\\tilemap_ground.png","frame":0}]},{"name":"objects","cels":[{"image":"tilemaps\\tilemap_objects.png","frame":0}]},{"name":"temperature","cels":[{"image":"tilemaps\\tilemap_temperature.png","frame":0}]},{"name":"player","cels":[{"image":"tilemaps\\tilemap_player.png","frame":0}]}],"height":320,"filename":"tilemaps.aseprite","width":320}
{"filename":"tilemaps.aseprite","width":320,"layers":[{"cels":[{"frame":0,"image":"tilemaps/tilemap_ground.png"}],"name":"ground"},{"cels":[{"frame":0,"image":"tilemaps/tilemap_objects.png"}],"name":"objects"},{"cels":[{"frame":0,"image":"tilemaps/tilemap_temperature.png"}],"name":"temperature"},{"cels":[{"frame":0,"image":"tilemaps/tilemap_player.png"}],"name":"player"}],"height":320,"frames":[{"duration":0.1}]}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -2,7 +2,7 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dy0gpc2vgr3o5"
uid="uid://diwoxcyj13q7v"
path="res://.godot/imported/tilemap_ground.png-cb404afe66e487b3999901e2d621baa7.ctex"
metadata={
"vram_texture": false
@ -31,4 +31,4 @@ process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
detect_3d/compress_to=0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -2,7 +2,7 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://cvb8hqljk0rv3"
uid="uid://dkvyu6a2bqans"
path="res://.godot/imported/tilemap_objects.png-36dc04b2c5c4ea8db297745921fe10e8.ctex"
metadata={
"vram_texture": false

View File

@ -2,7 +2,7 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bam5su5j62mof"
uid="uid://bwkvdumh22cmh"
path="res://.godot/imported/tilemap_player.png-ea1fa2aedf5bb220961e9080aa573e32.ctex"
metadata={
"vram_texture": false

View File

@ -2,7 +2,7 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://d1sdhqjtrt1ng"
uid="uid://dtoy4tdohey8t"
path="res://.godot/imported/tilemap_temperature.png-df4acfda23c8781105475512aa320086.ctex"
metadata={
"vram_texture": false

View File

@ -1,9 +1,9 @@
[gd_resource type="TileSet" load_steps=9 format=3 uid="uid://bi836ygcmyvhb"]
[ext_resource type="Texture2D" uid="uid://dy0gpc2vgr3o5" path="res://assets/tilemap/tilemaps/tilemap_ground.png" id="1_ukrsa"]
[ext_resource type="Texture2D" uid="uid://cvb8hqljk0rv3" path="res://assets/tilemap/tilemaps/tilemap_objects.png" id="2_o4fdg"]
[ext_resource type="Texture2D" uid="uid://d1sdhqjtrt1ng" path="res://assets/tilemap/tilemaps/tilemap_temperature.png" id="3_xap0v"]
[ext_resource type="Texture2D" uid="uid://bam5su5j62mof" path="res://assets/tilemap/tilemaps/tilemap_player.png" id="4_f38wc"]
[ext_resource type="Texture2D" uid="uid://diwoxcyj13q7v" path="res://assets/tilemap/tilemaps/tilemap_ground.png" id="1_ukrsa"]
[ext_resource type="Texture2D" uid="uid://dkvyu6a2bqans" path="res://assets/tilemap/tilemaps/tilemap_objects.png" id="2_15xge"]
[ext_resource type="Texture2D" uid="uid://dtoy4tdohey8t" path="res://assets/tilemap/tilemaps/tilemap_temperature.png" id="3_xap0v"]
[ext_resource type="Texture2D" uid="uid://bwkvdumh22cmh" path="res://assets/tilemap/tilemaps/tilemap_player.png" id="4_f38wc"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_114re"]
texture = ExtResource("1_ukrsa")
@ -17,12 +17,35 @@ texture = ExtResource("1_ukrsa")
3:0/0 = 0
3:0/0/custom_data_0 = true
3:0/0/custom_data_2 = 1
0:2/0 = 0
1:2/0 = 0
3:2/0 = 0
3:3/0 = 0
3:4/0 = 0
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_7jeam"]
texture = ExtResource("2_o4fdg")
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_x77e4"]
texture = ExtResource("2_15xge")
0:0/0 = 0
1:0/0 = 0
2:0/0 = 0
0:1/0 = 0
0:2/0 = 0
0:3/0 = 0
1:3/0 = 0
0:4/0 = 0
0:5/0 = 0
0:6/0 = 0
0:7/0 = 0
3:0/0 = 0
1:1/0 = 0
2:1/0 = 0
3:1/0 = 0
1:2/0 = 0
2:2/0 = 0
3:2/0 = 0
4:2/0 = 0
4:0/size_in_atlas = Vector2i(1, 2)
4:0/0 = 0
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_1og8x"]
texture = ExtResource("3_xap0v")
@ -34,6 +57,9 @@ texture = ExtResource("3_xap0v")
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_i41cv"]
texture = ExtResource("4_f38wc")
0:0/0 = 0
1:0/0 = 0
2:0/0 = 0
3:0/0 = 0
[resource]
custom_data_layer_0/name = "walkable"
@ -43,6 +69,6 @@ custom_data_layer_1/type = 2
custom_data_layer_2/name = "cost"
custom_data_layer_2/type = 2
sources/0 = SubResource("TileSetAtlasSource_114re")
sources/1 = SubResource("TileSetAtlasSource_7jeam")
sources/2 = SubResource("TileSetAtlasSource_1og8x")
sources/3 = SubResource("TileSetAtlasSource_i41cv")
sources/1 = SubResource("TileSetAtlasSource_x77e4")

File diff suppressed because one or more lines are too long

View File

@ -81,6 +81,26 @@ force_game_tick={
"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":70,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null)
]
}
key_4={
"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":52,"key_label":0,"unicode":52,"location":0,"echo":false,"script":null)
]
}
key_7={
"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":55,"key_label":0,"unicode":55,"location":0,"echo":false,"script":null)
]
}
key_5={
"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":53,"key_label":0,"unicode":53,"location":0,"echo":false,"script":null)
]
}
key_6={
"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":54,"key_label":0,"unicode":54,"location":0,"echo":false,"script":null)
]
}
[rendering]

View File

@ -1,7 +1,7 @@
class_name Camera
extends Camera2D
@export var border_acceleration: float = 2000.0
@export var border_acceleration: float = 0#2000.0
@export var max_speed: float = 500.0
@export var inner_border_threshold: float = 60.0
@export var outer_border_threshold: float = 40.0

View File

@ -9,7 +9,6 @@ extends Node
func _ready() -> void:
player.game_manager = self
game_ticker.start()
func _process(delta: float) -> void:

View File

@ -1,9 +1,12 @@
class_name PlayerManager
extends Node
@onready var inventory_label: Label = %InventoryLabel
@export var food_damage: int = 1
@export var temperature_damage: int = 1
@export var temperature_endure: int = 50
@export var view_distance: int = 50
var tilemap_types: TileMapTileTypes = TileMapTileTypes.new()
#
@ -29,10 +32,18 @@ func defer_ready() -> void:
update_board()
func _process(delta: float) -> void:
if Input.is_action_just_pressed("key_3"):
game_manager.camera.go_to_zooming(game_manager.world.tilemap_player.cell_to_local(board_position), 2)
if Input.is_action_just_pressed("key_5"):
pick_up_item(Vector2i(5, 8))
pick_up_item(Vector2i(9, 9))
update_board()
if Input.is_action_just_pressed("key_4"):
var nearest: Vector2i = find_nearest_object([game_manager.world.tilemap_types.OBJECT_I_TREE_1])
# nearest.x = nearest.x - 1
walk_towards(nearest)
update_board()
# SECTION: board access/mangement
@ -40,6 +51,10 @@ func _process(delta: float) -> void:
func update_board() -> void:
game_manager.world.tilemap_player.clear_cells()
game_manager.world.tilemap_player.set_cell(board_position, tilemap_types.PLAYER)
if inventory_slot and inventory_slot != tilemap_types.EMPTY:
inventory_label.text = str(inventory_slot)
else:
inventory_label.text = "empty"
# SECTION: inventory system
@ -52,23 +67,51 @@ func pick_up_item(tilemap_pos: Vector2i) -> void:
var pick_up_item_type: Vector2i = game_manager.world.tilemap_interactive.tilemap.get_cell_atlas_coords(tilemap_pos)
if inventory_slot != tilemap_types.EMPTY:
# set the type of the item on the tilemap to the one in the inventory, switching them
game_manager.world.tilemap_interactive.set_cell(tilemap_pos, inventory_slot)
# check if tile will transform into another tile upon pickup
var tile_after_pickup_transform = null
var tile_drop_item: Vector2i = inventory_slot
if tilemap_types.OBJECT_I_FILLED_BUSH == pick_up_item_type:
tile_after_pickup_transform = tilemap_types.OBJECT_I_EMPTY_BUSH
pick_up_item_type = tilemap_types.OBJECT_I_BERRY
tile_drop_item = tilemap_types.OBJECT_I_BERRY
# check if the inventory slot is empty
if inventory_slot == tilemap_types.EMPTY:
inventory_slot = pick_up_item_type
if tile_after_pickup_transform:
game_manager.world.tilemap_interactive.set_cell(tilemap_pos, tile_after_pickup_transform)
else:
game_manager.world.tilemap_interactive.clear_cell(tilemap_pos)
print("Picked up item: ", pick_up_item_type)
else:
# inventory is full, swap the item
print("Inventory is full. Swapping item: ", inventory_slot, " with item: ", pick_up_item_type)
if tile_after_pickup_transform:
game_manager.world.tilemap_interactive.set_cell(tilemap_pos, tile_after_pickup_transform)
var drop_location: Vector2i = game_manager.world.find_item_drop_location(tilemap_pos)
if drop_location != tilemap_types.EMPTY:
game_manager.world.tilemap_interactive.set_cell(drop_location, tile_drop_item)
else:
push_warning("Could not find valid drop position for ", inventory_slot)
else:
game_manager.world.tilemap_interactive.set_cell(tilemap_pos, tile_drop_item)
inventory_slot = pick_up_item_type
# SECTION: player movement
func walk_towards(position: Vector2i) -> void:
walk_along(game_manager.world.find_path(board_position, position))
var path: Array[Vector2i] = game_manager.world.find_path(board_position, position)
walk_along(path)
func walk_along(path: Array[Vector2i]) -> void:
if len(path) > 1:
var next_position: Vector2i = path[1]
var direction: Vector2i = find_direction(board_position, next_position)
move_player(direction)
else:
push_warning("walk_along path is empty")
func move_player(direction: Vector2i) -> void:
@ -79,6 +122,29 @@ func move_player(direction: Vector2i) -> void:
push_warning("Player trying to move to non-walkable position, prevented ", new_position)
func find_nearest_object(object_collection: Array[Vector2i]) -> Vector2i:
var object_positions: Array[Vector2i] = []
for obj in object_collection:
object_positions.append_array(game_manager.world.tilemap_interactive.get_cells_by_type(obj))
if object_positions.size() == 0:
push_warning("No " + str(object_collection) + " found!")
return tilemap_types.NO_TILE_FOUND
var closest_object: Vector2i = tilemap_types.NO_TILE_FOUND
var shortest_distance: float = 99999999
for position in object_positions:
var distance: float = game_manager.world.manhattan_distance(board_position, position)
if closest_object == tilemap_types.NO_TILE_FOUND or distance < shortest_distance:
closest_object = position
shortest_distance = distance
print("Find nearest " + str(object_collection) + " at:", closest_object)
return closest_object
func find_direction(pos_a: Vector2i, pos_b: Vector2i) -> Vector2i:
var direction: Vector2i = Vector2i(0, 0)
if pos_a.x < pos_b.x:

View File

@ -26,7 +26,7 @@ func internal_run(p_blackboard: Dictionary) -> void:
run(p_blackboard)
else:
run(p_blackboard)
print(" - ", name, " ", status)
func find_running_child() -> Task:

View File

@ -2,6 +2,7 @@ class_name TileMapTileTypes
# global values
const EMPTY: Vector2i = Vector2i(-1, -1)
const NO_TILE_FOUND: Vector2i = Vector2i(-999999, -999999)
#
# ground, sid = 0
const GROUND_GRASS: Vector2i = Vector2i(0, 0)
@ -11,22 +12,25 @@ const GROUND_SAND: Vector2i = Vector2i(3, 0)
#
# objects, sid = 1
# NI = not interactive
const OBJECT_NI_RANDOM_1: Vector2i = Vector2i(0, 0) # testing only, to be removed
const OBJECT_NI_RANDOM_2: Vector2i = Vector2i(1, 0) # testing only, to be removed
const OBJECT_NI_ROCK_1: Vector2i = Vector2i(2, 0)
# I = interactive
const OBJECT_BOAT_ENGINE :Vector2i = Vector2i(0,1)
const OBJECT_FUEL : Vectro2i = Vector2i(1,1)
const OBJECT_ANCHOR: Vector2i = Vector2(2,1)
const OBJECT_EMPTY_BUSH: Vector2i = Vector2(3,0)
const OBJECT_BERRY_BUSH: Vector2i = Vector2(3,1)
const OBJECT_TREE: Vector2i = Vector2(3,0)
const OBJECT_CHEST: Vector2i = Vector(0,2)
const OBJECT_GEARS: Vector2i = Vector(1,2)
const OBJECT_MEDIKIT: Vector2i = Vector(2,2)
const OBJECT_PADDLE: Vector2i = Vector(3,2)
const OBJECT_GAS_STOVE: Vector2i = Vector(4,2)
const OBJECT_I_BOAT_ENGINE: Vector2i = Vector2i(0, 1)
const OBJECT_I_FUEL: Vector2i = Vector2i(1, 1)
const OBJECT_I_ANCHOR: Vector2i = Vector2i(2, 1)
const OBJECT_I_EMPTY_BUSH: Vector2i = Vector2i(3, 0)
const OBJECT_I_FILLED_BUSH: Vector2i = Vector2i(3, 1)
const OBJECT_I_BERRY: Vector2i = Vector2i(0, 5)
const OBJECT_I_TREE_1: Vector2i = Vector2i(4, 0)
const OBJECT_I_CHEST: Vector2i = Vector2i(0, 2)
const OBJECT_I_GEARS: Vector2i = Vector2i(1, 2)
const OBJECT_I_MEDIKIT: Vector2i = Vector2i(2, 2)
const OBJECT_I_PADDLE: Vector2i = Vector2i(3, 2)
const OBJECT_I_GAS_STOVE: Vector2i = Vector2i(4, 2)
# collections
const OBJECT_COLLECTION_BERRY_SOURCE: Array[Vector2i] = [OBJECT_I_FILLED_BUSH, OBJECT_I_BERRY]
#
# temperature, sid = 2
const TEMPERATURE_NORMAL: Vector2i = Vector2i(-1, -1)
const TEMPERATURE_COLD_1: Vector2i = Vector2i(0, 0)

View File

@ -37,12 +37,13 @@ func _ready() -> void:
# tilemap_ground.set_cell(Vector2i(0, 0), tilemap_types.GROUND_GRASS)
# print(tilemap_ground.local_to_cell(get_local_mouse_position()))
func local_mouse_position() -> Vector2:
return get_local_mouse_position()
func tilemap_mouse_position() -> Vector2i:
return tilemap_ground.local_to_cell(get_local_mouse_position())
func find_item_drop_location(center_pos: Vector2i) -> Vector2i:
for x in range(center_pos.x - 2, center_pos.x + 2):
for y in range(center_pos.y - 2, center_pos.y + 2):
var check_pos: Vector2i = Vector2i(x, y)
if not tilemap_interactive.get_cell(check_pos) and is_walkable(check_pos):
return check_pos
return Vector2i(-1, -1)
func is_walkable(position: Vector2i) -> bool: