Update Worldmap

Add unoptimized desert palette animation
Make worldmap scrolling smooth
Also reduce minimum window size to 1x scaling
This commit is contained in:
Luke Hubmayer-Werner 2024-04-12 19:49:02 +09:30
parent 714a6ad123
commit 61ed503d58
3 changed files with 29 additions and 13 deletions

View File

@ -193,8 +193,8 @@ func shrink_to_integer():
get_tree().set_screen_stretch(SceneTree.STRETCH_MODE_VIEWPORT, SceneTree.STRETCH_ASPECT_KEEP, base_resolution*scale, scale) get_tree().set_screen_stretch(SceneTree.STRETCH_MODE_VIEWPORT, SceneTree.STRETCH_ASPECT_KEEP, base_resolution*scale, scale)
func update_window_scale(): func update_window_scale():
if OS.window_size < base_resolution*2: if OS.window_size < base_resolution:
OS.window_size = base_resolution*2 OS.window_size = base_resolution
var size := OS.get_window_size() var size := OS.get_window_size()
var scale_vec := size / base_resolution var scale_vec := size / base_resolution
var scale_f := max(min(scale_vec.x, scale_vec.y), 1) var scale_f := max(min(scale_vec.x, scale_vec.y), 1)

View File

@ -8,6 +8,9 @@ uniform float uv_scale = 512.0; // Require square tilemap for now
uniform bool enable_sea_scroll = true; // Disable on underwater maps (tileset 3) uniform bool enable_sea_scroll = true; // Disable on underwater maps (tileset 3)
uniform bool enable_waterfall_scroll = true; // Only enable on tileset 1 uniform bool enable_waterfall_scroll = true; // Only enable on tileset 1
uniform bool enable_tile_globbing = false; // hack for minimap uniform bool enable_tile_globbing = false; // hack for minimap
uniform float timescale_desert = 7.5;
uniform float timescale_sea = 0.234375; // 60.0/256.0
uniform float timescale_waterfall = 1.3;
// uniform vec2 subtile_offset = vec2(0.0); // uniform vec2 subtile_offset = vec2(0.0);
const float index_scale = 255.0 / 16.0; const float index_scale = 255.0 / 16.0;
const vec2 sea_tile_uv = vec2(2.0, 6.0)/16.0; const vec2 sea_tile_uv = vec2(2.0, 6.0)/16.0;
@ -19,6 +22,10 @@ const vec2 waterfall_tile_uv_end = vec2(9.0, 9.0)/16.0;
const vec2 waterfall_tile_uv_end_hack = vec2(9.0, 10.0)/16.0; // we hack a second row in the atlas const vec2 waterfall_tile_uv_end_hack = vec2(9.0, 10.0)/16.0; // we hack a second row in the atlas
const vec2 waterfall_tile_size = waterfall_tile_uv_end - waterfall_tile_uv; const vec2 waterfall_tile_size = waterfall_tile_uv_end - waterfall_tile_uv;
const vec2 waterfall_tile_size_inv = 1.0/waterfall_tile_size; const vec2 waterfall_tile_size_inv = 1.0/waterfall_tile_size;
const float desert_pal_row_int = 5.0;
const float desert_pal_col_start = 1.0/16.0;
const float desert_pal_col_end = 5.0/16.0;
const float desert_pal_col_range = desert_pal_col_end - desert_pal_col_start + 1.0/16.0;
// This shader maps from tileID texels to Tiles, and then applies palette. // This shader maps from tileID texels to Tiles, and then applies palette.
// tiles hardcoded to 16x16 tiles for now // tiles hardcoded to 16x16 tiles for now
@ -48,7 +55,7 @@ vec2 get_tile_atlas_uv(float tile_id, vec2 uv) {
// i.e. every 16 frames it will have scrolled all rows 1px // i.e. every 16 frames it will have scrolled all rows 1px
// every 256 frames it will have performed a full scroll // every 256 frames it will have performed a full scroll
// At 60fps this is one full scroll every 4.266... seconds // At 60fps this is one full scroll every 4.266... seconds
pos.x = fract(pos.x - TIME/4.267 + (pos.y * (9.0/16.0))); pos.x = fract(pos.x - TIME*timescale_sea + (pos.y * (9.0/16.0)));
out_uv = mix(sea_tile_uv, sea_tile_uv_end, pos); out_uv = mix(sea_tile_uv, sea_tile_uv_end, pos);
} }
// Waterfall VScroll UV modulation // Waterfall VScroll UV modulation
@ -60,7 +67,7 @@ vec2 get_tile_atlas_uv(float tile_id, vec2 uv) {
// Real animation seems to scroll in a cycle of shift col 1px, next frame, shift col 1px, next frame, increment by 4 rows twice, shift that one, repeat // Real animation seems to scroll in a cycle of shift col 1px, next frame, shift col 1px, next frame, increment by 4 rows twice, shift that one, repeat
// 1, 1, 5, 5, 3, 3, 7, 7, 2, 2, 6, 6, 4, 4, 8, 8 // 1, 1, 5, 5, 3, 3, 7, 7, 2, 2, 6, 6, 4, 4, 8, 8
// For now, don't bother about the double increment // For now, don't bother about the double increment
pos.y = fract((pos.y - TIME*1.3 + (pos.x * (4.5/32.0))) * 0.5); pos.y = fract((pos.y - TIME*timescale_waterfall + (pos.x * (4.5/32.0))) * 0.5);
out_uv = mix(waterfall_tile_uv, waterfall_tile_uv_end_hack, pos); out_uv = mix(waterfall_tile_uv, waterfall_tile_uv_end_hack, pos);
} }
@ -81,8 +88,14 @@ void fragment() {
vec2 lut_uv = get_tile_atlas_uv(tile_id, UV); vec2 lut_uv = get_tile_atlas_uv(tile_id, UV);
float color_id = texture(tile_atlas, lut_uv).r; float color_id = texture(tile_atlas, lut_uv).r;
float color_idx16 = color_id * index_scale; float color_idx16 = color_id * index_scale;
float pal_row = trunc(color_idx16) / palette_rows; float pal_row_int = trunc(color_idx16);
float pal_row = pal_row_int / palette_rows;
float pal_col = fract(color_idx16); float pal_col = fract(color_idx16);
// Scroll #1~#5 for moving desert every 8 frames at 60fps (7.5Hz)
if (enable_waterfall_scroll && pal_row_int == desert_pal_row_int && pal_col >= desert_pal_col_start && pal_col <= desert_pal_col_end) {
pal_col = mod(pal_col + trunc(TIME*timescale_desert), desert_pal_col_range) + desert_pal_col_start;
}
// World 1 also has row #6 cols #12 and #13 swap every 5 frames at 60fps (12Hz) (world 2 portal)
vec2 palette_uv = vec2(pal_col, pal_row); vec2 palette_uv = vec2(pal_col, pal_row);
COLOR = texture(palette, palette_uv); COLOR = texture(palette, palette_uv);

View File

@ -53,9 +53,20 @@ func _ready() -> void:
minimap.rect_position = Vector2(8, 168) minimap.rect_position = Vector2(8, 168)
_set_map(0) _set_map(0)
func handle_movement_input(delta: float, quantize:=8.0) -> void:
delta = round(delta*quantize)/quantize
if Input.is_physical_key_pressed(KEY_RIGHT):
self.pos.x += delta
if Input.is_physical_key_pressed(KEY_LEFT):
self.pos.x -= delta
if Input.is_physical_key_pressed(KEY_DOWN):
self.pos.y += delta
if Input.is_physical_key_pressed(KEY_UP):
self.pos.y -= delta
# Called every frame. 'delta' is the elapsed time since the previous frame. # Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void: func _process(delta: float) -> void:
self.handle_movement_input(delta*16)
self.pos = self.pos.posmod(256.0) self.pos = self.pos.posmod(256.0)
self.minimap_tween -= sign(minimap_tween - minimap_mode) * delta * 4 self.minimap_tween -= sign(minimap_tween - minimap_mode) * delta * 4
self.minimap_tween = clamp(minimap_tween, 0, 1) self.minimap_tween = clamp(minimap_tween, 0, 1)
@ -88,14 +99,6 @@ func _input(event: InputEvent) -> void:
if event is InputEventKey: if event is InputEventKey:
if event.pressed: if event.pressed:
match event.physical_scancode: match event.physical_scancode:
KEY_RIGHT:
pos.x += 1
KEY_LEFT:
pos.x -= 1
KEY_DOWN:
pos.y += 1
KEY_UP:
pos.y -= 1
KEY_1: KEY_1:
_set_map(0) _set_map(0)
KEY_2: KEY_2: