Base tilemap setup complete, added camera controls

pull/1/head
Yan Wittmann 2025-01-04 12:13:42 +01:00
parent baffb6f74a
commit ebe842edee
16 changed files with 312 additions and 19 deletions

View File

@ -1,13 +1,12 @@
- Sprites
- Sprites (dome)
- Initialize Tilemap (Yan)
- Script --> World (manages access to tilemap)
- Player is an object, not on tilemap
- Player is on tilemap
- Multiple layers
- Ground (Water, Ground) --> custom data (Walkable, Weight = 1)
- Obstacles (Stone, ...)
- Pickup (Berries, Trees, Boat parts) --> custom data (Type of collectable "tree", "berry", "boat")
- Temperature layer (toggleable, types: normal and warm, transparent solid color)
- Collect all "objects" from the tilemap on initialization in arrays/dictionaries for later access in the tree
- Temperature layer (normal and different levels of coldness, transparent solid color)
- Design a tilemap for the game
- Player (Dome)
- Stats (see document)

View File

@ -4,8 +4,8 @@
{
"cels": [
{
"frame": 0,
"image": "tilemaps\\tilemap_ground.png"
"image": "tilemaps\\tilemap_ground.png",
"frame": 0
}
],
"name": "ground"
@ -13,18 +13,36 @@
{
"cels": [
{
"frame": 0,
"image": "tilemaps\\tilemap_objects.png"
"image": "tilemaps\\tilemap_objects.png",
"frame": 0
}
],
"name": "objects"
},
{
"cels": [
{
"image": "tilemaps\\tilemap_temperature.png",
"frame": 0
}
],
"filename": "tilemaps.aseprite",
"name": "temperature"
},
{
"cels": [
{
"image": "tilemaps\\tilemap_player.png",
"frame": 0
}
],
"name": "player"
}
],
"width": 320,
"frames": [
{
"duration": 0.1
}
],
"width": 320
"filename": "tilemaps.aseprite"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bam5su5j62mof"
path="res://.godot/imported/tilemap_player.png-ea1fa2aedf5bb220961e9080aa573e32.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/tilemap/tilemaps/tilemap_player.png"
dest_files=["res://.godot/imported/tilemap_player.png-ea1fa2aedf5bb220961e9080aa573e32.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d1sdhqjtrt1ng"
path="res://.godot/imported/tilemap_temperature.png-df4acfda23c8781105475512aa320086.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/tilemap/tilemaps/tilemap_temperature.png"
dest_files=["res://.godot/imported/tilemap_temperature.png-df4acfda23c8781105475512aa320086.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
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

View File

@ -1,7 +1,9 @@
[gd_resource type="TileSet" load_steps=5 format=3 uid="uid://bi836ygcmyvhb"]
[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"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_114re"]
texture = ExtResource("1_ukrsa")
@ -17,8 +19,23 @@ texture = ExtResource("2_o4fdg")
0:0/0 = 0
1:0/0 = 0
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_1og8x"]
texture = ExtResource("3_xap0v")
0:0/0 = 0
0:0/0/custom_data_1 = 100
1:0/0 = 0
1:0/0/custom_data_1 = -200
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_i41cv"]
texture = ExtResource("4_f38wc")
0:0/0 = 0
[resource]
custom_data_layer_0/name = "walkable"
custom_data_layer_0/type = 1
custom_data_layer_1/name = "temperature"
custom_data_layer_1/type = 2
sources/0 = SubResource("TileSetAtlasSource_114re")
sources/1 = SubResource("TileSetAtlasSource_7jeam")
sources/2 = SubResource("TileSetAtlasSource_1og8x")
sources/3 = SubResource("TileSetAtlasSource_i41cv")

View File

@ -1,9 +1,17 @@
[gd_scene load_steps=3 format=4 uid="uid://b88asko1ugyd2"]
[gd_scene load_steps=6 format=4 uid="uid://b88asko1ugyd2"]
[ext_resource type="Script" path="res://scripts/global/GameManager.gd" id="1_eeg2d"]
[ext_resource type="Script" path="res://scripts/tilemap/World.gd" id="1_k0rw8"]
[ext_resource type="TileSet" uid="uid://bi836ygcmyvhb" path="res://assets/tilemap/tileset.tres" id="1_vlccq"]
[ext_resource type="Script" path="res://scripts/global/Camera.gd" id="2_1vbjl"]
[ext_resource type="Script" path="res://scripts/player/PlayerManager.gd" id="4_1xqo1"]
[node name="Island-scene" type="Node2D"]
script = ExtResource("1_eeg2d")
[node name="Camera2D" type="Camera2D" parent="."]
offset = Vector2(575.745, 325.09)
script = ExtResource("2_1vbjl")
[node name="Tileset" type="Node2D" parent="."]
script = ExtResource("1_k0rw8")
@ -23,3 +31,6 @@ tile_set = ExtResource("1_vlccq")
[node name="TemperatureLayer" type="TileMapLayer" parent="Tileset"]
tile_set = ExtResource("1_vlccq")
[node name="PlayerManager" type="Node" parent="."]
script = ExtResource("4_1xqo1")

View File

@ -15,6 +15,48 @@ run/main_scene="res://main-scenes/island.tscn"
config/features=PackedStringArray("4.3", "GL Compatibility")
config/icon="res://icon.svg"
[input]
camera_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":4194319,"key_label":0,"unicode":0,"location":0,"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":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
]
}
camera_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,"location":0,"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,"location":0,"echo":false,"script":null)
]
}
camera_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,"location":0,"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,"location":0,"echo":false,"script":null)
]
}
camera_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,"location":0,"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,"location":0,"echo":false,"script":null)
]
}
camera_zoom_in={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194446,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
camera_zoom_out={
"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":4194440,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
camera_drag={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":4,"position":Vector2(373, 18),"global_position":Vector2(382, 64),"factor":1.0,"button_index":3,"canceled":false,"pressed":true,"double_click":false,"script":null)
]
}
[rendering]
renderer/rendering_method="gl_compatibility"

View File

@ -0,0 +1,88 @@
class_name Camera
extends Camera2D
@export var border_acceleration: float = 800.0
@export var max_speed: float = 500.0
@export var inner_border_threshold: float = 60.0
@export var outer_border_threshold: float = 20.0
@export var min_position: Vector2 = Vector2(-1000, -1000)
@export var max_position: Vector2 = Vector2(4000, 4000)
var target_position: Vector2
var velocity: Vector2 = Vector2.ZERO
#
var drag_active: bool = false
var drag_start: Vector2
func _ready():
target_position = position
func _input(event):
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_WHEEL_UP:
zoom = zoom * 1.1
elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
zoom = zoom / 1.1
func _process(delta):
if Input.is_action_just_pressed("camera_drag"):
drag_active = true
drag_start = get_viewport().get_mouse_position()
if Input.is_action_just_released("camera_drag"):
drag_active = false
if drag_active:
var drag_end: Vector2 = get_viewport().get_mouse_position()
var drag_offset: Vector2 = drag_end - drag_start
drag_start = drag_end
position -= drag_offset / zoom
var is_zoom_in: bool = Input.is_action_pressed("camera_zoom_in")
var is_zoom_out: bool = Input.is_action_pressed("camera_zoom_out")
if is_zoom_in:
zoom = zoom * 1.1
elif is_zoom_out:
zoom = zoom / 1.1
var mouse_pos: Vector2 = get_viewport().get_mouse_position()
var screen_size: Vector2 = get_viewport().get_visible_rect().size
var acceleration: Vector2 = Vector2.ZERO
var is_up: bool = Input.is_action_pressed("camera_up") or mouse_pos.y < inner_border_threshold and mouse_pos.y > -outer_border_threshold
var is_down: bool = Input.is_action_pressed("camera_down") or mouse_pos.y > screen_size.y - inner_border_threshold and mouse_pos.y < screen_size.y + outer_border_threshold
var is_left: bool = Input.is_action_pressed("camera_left") or mouse_pos.x < inner_border_threshold and mouse_pos.x > -outer_border_threshold
var is_right: bool = Input.is_action_pressed("camera_right") or mouse_pos.x > screen_size.x - inner_border_threshold and mouse_pos.x < screen_size.x + outer_border_threshold
if is_left:
acceleration.x = -border_acceleration
elif is_right:
acceleration.x = border_acceleration
if is_up:
acceleration.y = -border_acceleration
elif is_down:
acceleration.y = border_acceleration
acceleration *= Vector2.ONE / zoom
if acceleration.length() > 0:
# if the acceleration is the opposite direction of the velocity, double the acceleration
if acceleration.dot(velocity) < 0:
acceleration = acceleration * 2
velocity = velocity + acceleration * delta
else:
velocity = velocity.move_toward(Vector2.ZERO, border_acceleration * delta)
if velocity.length() > max_speed:
velocity = velocity.normalized() * max_speed
var target_offset = velocity * delta
target_position = position + target_offset
target_position.x = clamp(target_position.x, min_position.x, max_position.x)
target_position.y = clamp(target_position.y, min_position.y, max_position.y)
var offset: Vector2 = target_position - position
position += offset

View File

@ -0,0 +1,6 @@
class_name GameManager
extends Node
@onready var world: World = $Tileset
@onready var player: PlayerManager = $PlayerManager
@onready var camera: Camera2D = $Camera2D

View File

@ -0,0 +1,2 @@
class_name PlayerManager
extends Node

View File

@ -57,3 +57,23 @@ func local_to_cell(global_position: Vector2) -> Vector2i:
func cell_to_local(cell_position: Vector2i) -> Vector2:
return tilemap.map_to_local(cell_position)
func fill_area(start: Vector2i, end: Vector2i, atlas_coords: Vector2i) -> void:
for x in range(start.x, end.x + 1):
for y in range(start.y, end.y + 1):
tilemap.set_cell(Vector2i(x, y), sid, atlas_coords)
func fill_circle(center: Vector2i, radius: int, atlas_coords: Vector2i) -> void:
for x in range(center.x - radius, center.x + radius + 1):
for y in range(center.y - radius, center.y + radius + 1):
if center.distance_to(Vector2i(x, y)) <= radius:
tilemap.set_cell(Vector2i(x, y), sid, atlas_coords)
func fill_ellipse(center: Vector2i, radius_x: int, radius_y: int, atlas_coords: Vector2i) -> void:
for x in range(center.x - radius_x, center.x + radius_x + 1):
for y in range(center.y - radius_y, center.y + radius_y + 1):
if (pow(x - center.x, 2) / pow(radius_x, 2) + pow(y - center.y, 2) / pow(radius_y, 2)) <= 1:
tilemap.set_cell(Vector2i(x, y), sid, atlas_coords)

View File

@ -1,7 +1,19 @@
class_name TileMapTileTypes
# ground layer
const GRASS: Vector2i = Vector2i(0, 0)
const WATER_SHALLOW: Vector2i = Vector2i(1, 0)
const WATER_DEEP: Vector2i = Vector2i(2, 0)
const SAND: Vector2i = Vector2i(3, 0)
# ground, sid = 0
const GROUND_GRASS: Vector2i = Vector2i(0, 0)
const GROUND_WATER_SHALLOW: Vector2i = Vector2i(1, 0)
const GROUND_WATER_DEEP: Vector2i = Vector2i(2, 0)
const GROUND_SAND: Vector2i = Vector2i(3, 0)
#
# objects, sid = 1
const OBJECT_RANDOM_1: Vector2i = Vector2i(0, 0) # testing only, to be removed
const OBJECT_RANDOM_2: Vector2i = Vector2i(1, 0) # testing only, to be removed
#
# temperature, sid = 2
const TEMPERATURE_NORMAL: Vector2i = Vector2i(-1, -1)
const TEMPERATURE_COLD_1: Vector2i = Vector2i(0, 0)
const TEMPERATURE_COLD_2: Vector2i = Vector2i(1, 0)
#
# player, sid = 3
const PLAYER: Vector2i = Vector2i(0, 0)

View File

@ -11,10 +11,15 @@ var tilemap_types: TileMapTileTypes = TileMapTileTypes.new()
func _ready() -> void:
tilemap_ground.sid = 0
tilemap_ground.tilemap = $GroundLayer
tilemap_non_interactive.sid = 1
tilemap_non_interactive.tilemap = $NonInteractiveObjectsLayer
tilemap_interactive.sid = 1
tilemap_interactive.tilemap = $InteractiveObjectsLayer
tilemap_player.sid = 3
tilemap_player.tilemap = $PlayerLayer
tilemap_temperature.sid = 2
tilemap_temperature.tilemap = $TemperatureLayer
tilemap_ground.setup()
@ -24,10 +29,15 @@ func _ready() -> void:
tilemap_temperature.setup()
# example usage
# tilemap_temperature.fill_area(Vector2i(0, 0), Vector2i(10, 10), tilemap_types.TEMPERATURE_COLD_1)
# tilemap_temperature.fill_area(Vector2i(4, 4), Vector2i(6, 6), tilemap_types.TEMPERATURE_NORMAL)
# print(tilemap_non_interactive.get_cells_by_custom_data("walkable", true))
# tilemap_ground.clear_cells()
# tilemap_ground.set_cell(Vector2i(0, 0), tilemap_types.GRASS)
# tilemap_ground.set_cell(Vector2i(0, 0), tilemap_types.GROUND_GRASS)
func _process(delta: float) -> void:
print(tilemap_ground.local_to_cell(get_local_mouse_position()))
pass
# print(tilemap_ground.local_to_cell(get_local_mouse_position()))