Large refactor to avoid the need to use map() and camera() - the new approach just re-calculates the local world and allows us to scroll 'smoothly' forever.
This commit is contained in:
parent
2ca23a7b4e
commit
16bcbc8e00
|
@ -2,9 +2,8 @@ pico-8 cartridge // http://www.pico-8.com
|
||||||
version 18
|
version 18
|
||||||
__lua__
|
__lua__
|
||||||
#include debug.lua
|
#include debug.lua
|
||||||
#include data.lua
|
|
||||||
#include sound.lua
|
#include sound.lua
|
||||||
#include mapgen.lua
|
#include world.lua
|
||||||
#include player.lua
|
#include player.lua
|
||||||
#include main.lua
|
#include main.lua
|
||||||
__gfx__
|
__gfx__
|
||||||
|
|
84
data.lua
84
data.lua
|
@ -1,84 +0,0 @@
|
||||||
-- data shared between modules goes here, both constants and mutable data.
|
|
||||||
-- also contains some functions that act solely on the data
|
|
||||||
--
|
|
||||||
-- also has commented "fake constants" that are replaced by actual values, for
|
|
||||||
-- reference.
|
|
||||||
--
|
|
||||||
-- also see index_map.md for more "constant" values
|
|
||||||
|
|
||||||
function init_data()
|
|
||||||
-- block_size = 64
|
|
||||||
-- biome_size = 128
|
|
||||||
|
|
||||||
-- the indices here are sprite numbers.
|
|
||||||
object_interaction_map = {
|
|
||||||
-- bush
|
|
||||||
[3] = {
|
|
||||||
replacement = 17,
|
|
||||||
sfx = 13,
|
|
||||||
drop = 68
|
|
||||||
},
|
|
||||||
|
|
||||||
-- tree
|
|
||||||
[4] = {
|
|
||||||
replacement = 14,
|
|
||||||
sfx = 11,
|
|
||||||
drop = 64
|
|
||||||
},
|
|
||||||
|
|
||||||
-- big mushroom
|
|
||||||
[8] = {
|
|
||||||
replacement = 16,
|
|
||||||
sfx = 12,
|
|
||||||
drop = 65
|
|
||||||
},
|
|
||||||
|
|
||||||
-- cactus w/ flower
|
|
||||||
[10] = {
|
|
||||||
replacement = 15,
|
|
||||||
sfx = 12,
|
|
||||||
drop = 67
|
|
||||||
},
|
|
||||||
|
|
||||||
-- cactus
|
|
||||||
[13] = {
|
|
||||||
replacement = 15,
|
|
||||||
sfx = 12,
|
|
||||||
drop = 66
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-- initialize a ring buffer of changed positions. In use, this will be keyed
|
|
||||||
-- using strings of the form mod_buffer["x:y"], using absolute world
|
|
||||||
-- coordinates. this is to flatten the buffer so that #mod_cache is useful
|
|
||||||
-- for checking against max_mod_entries.
|
|
||||||
max_mod_entries = 4096
|
|
||||||
mod_buffer = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
-- x and y are global coords
|
|
||||||
function get_mod_key(x, y)
|
|
||||||
return tostr(x) .. ":" .. tostr(y)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- x and y are map-local coords
|
|
||||||
function write_map_change(new_sprite, x, y)
|
|
||||||
local global_x, global_y = calculate_world_pos(x, y)
|
|
||||||
if #mod_buffer >= max_mod_entries then
|
|
||||||
cull_mod_buffer()
|
|
||||||
end
|
|
||||||
|
|
||||||
mod_buffer[get_mod_key(global_x, global_y)] = new_sprite
|
|
||||||
end
|
|
||||||
|
|
||||||
function cull_mod_buffer()
|
|
||||||
-- we cull 10% of the mod buffer at a time
|
|
||||||
-- todo: implement this
|
|
||||||
end
|
|
||||||
|
|
||||||
function calculate_world_pos(x, y)
|
|
||||||
-- player_pos_[xy] is world absolute, so we can get the world pos of map 0,0,
|
|
||||||
-- then add x and y back in.
|
|
||||||
return player_pos_x - camera_pos_x - 8 + x,
|
|
||||||
player_pos_y - camera_pos_y - 8 + y
|
|
||||||
end
|
|
21
main.lua
21
main.lua
|
@ -1,24 +1,23 @@
|
||||||
function _init()
|
function _init()
|
||||||
init_data()
|
init_sound""
|
||||||
init_sound()
|
init_world""
|
||||||
init_mapgen()
|
|
||||||
init_player(32, 32)
|
init_player(32, 32)
|
||||||
generate_map(0, 0)
|
init_debug""
|
||||||
init_debug()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function _update()
|
function _update()
|
||||||
handle_input()
|
handle_input""
|
||||||
handle_map_update()
|
-- handle_map_update""
|
||||||
end
|
end
|
||||||
|
|
||||||
function _draw()
|
function _draw()
|
||||||
cls()
|
cls""
|
||||||
-- the screen is 128x128 pixels, so it fits 16x16 sprites
|
-- the screen is 128x128 pixels, so it fits 16x16 sprites
|
||||||
map(camera_pos_x, camera_pos_y, 0, 0, 16, 16)
|
-- map(camera_pos_x, camera_pos_y, 0, 0, 16, 16)
|
||||||
draw_player()
|
draw_world_segment(player_pos_x, player_pos_y)
|
||||||
debug_print()
|
draw_player""
|
||||||
|
debug_print""
|
||||||
end
|
end
|
||||||
|
|
||||||
-- decide whether we need to regenerate the map.
|
-- decide whether we need to regenerate the map.
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
--- Procedural generation methods
|
--- Procedural generation methods
|
||||||
|
|
||||||
function init_mapgen()
|
function init_world()
|
||||||
uid_seed = 2229 -- arbitrarily chosen number
|
|
||||||
|
|
||||||
-- Metadata for different biomes
|
-- Metadata for different biomes
|
||||||
-- tile_frequencies tuples are {frequency, sprite_index}, see index_map.md
|
-- tile_frequencies tuples are {frequency, sprite_index}, see index_map.md
|
||||||
-- frequencies by convention add up to 1000, but this is arbitrary, the
|
-- frequencies by convention add up to 1000, but this is arbitrary, the
|
||||||
|
@ -45,6 +43,62 @@ function init_mapgen()
|
||||||
|
|
||||||
build_biome(biome, biome_data[biome])
|
build_biome(biome, biome_data[biome])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- the indices here are sprite numbers.
|
||||||
|
object_interaction_map = {
|
||||||
|
-- bush
|
||||||
|
[3] = {
|
||||||
|
replacement = 17,
|
||||||
|
sfx = 13,
|
||||||
|
drop = 68
|
||||||
|
},
|
||||||
|
|
||||||
|
-- tree
|
||||||
|
[4] = {
|
||||||
|
replacement = 14,
|
||||||
|
sfx = 11,
|
||||||
|
drop = 64
|
||||||
|
},
|
||||||
|
|
||||||
|
-- big mushroom
|
||||||
|
[8] = {
|
||||||
|
replacement = 16,
|
||||||
|
sfx = 12,
|
||||||
|
drop = 65
|
||||||
|
},
|
||||||
|
|
||||||
|
-- cactus w/ flower
|
||||||
|
[10] = {
|
||||||
|
replacement = 15,
|
||||||
|
sfx = 12,
|
||||||
|
drop = 67
|
||||||
|
},
|
||||||
|
|
||||||
|
-- cactus
|
||||||
|
[13] = {
|
||||||
|
replacement = 15,
|
||||||
|
sfx = 12,
|
||||||
|
drop = 66
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- initialize a ring buffer of changed positions. In use, this will be keyed
|
||||||
|
-- using strings of the form mod_buffer["x:y"], using absolute world
|
||||||
|
-- coordinates. this is to flatten the buffer so that #mod_cache is useful
|
||||||
|
-- for checking against max_mod_entries.
|
||||||
|
max_mod_entries = 4096
|
||||||
|
mod_buffer = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- draw the sprites for this part of the world to the screen
|
||||||
|
-- this calculates everything about the world fresh every frame,
|
||||||
|
-- but pico-8 handles this just fine!
|
||||||
|
function draw_world_segment(start_x, start_y)
|
||||||
|
for x=0,15 do
|
||||||
|
for y=0,15 do
|
||||||
|
spr(get_tile(start_x-8+x, start_y-8+y), x*8, y*8)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- build the lookup table for a given biome, based on the biome_meta data for
|
-- build the lookup table for a given biome, based on the biome_meta data for
|
||||||
|
@ -100,15 +154,34 @@ function get_tile(pos_x, pos_y)
|
||||||
return biome.tile_lookup[(uid % #biome.tile_lookup) + 1]
|
return biome.tile_lookup[(uid % #biome.tile_lookup) + 1]
|
||||||
end
|
end
|
||||||
|
|
||||||
-- generate the map and writes to the map area from 0 - block_size,
|
|
||||||
-- assuming 'start' as the top-left corner of the map area to generate.
|
---
|
||||||
-- writes block_size x block_size tiles
|
--- mod buffer functions - these handle parts of the world map that have
|
||||||
-- after a call to generate_map you should always center the camera/player over the map, i.e.
|
--- changed from their 'default' position
|
||||||
-- camera at { (block_size / 2) - 8, (block_size / 2) - 8 }
|
---
|
||||||
function generate_map(start_x, start_y)
|
--- todo: the mod buffer eventually needs to be a bit more elaborate.
|
||||||
for x=0,63 do
|
--- we need to make it possible to cull only old and unimportant changes,
|
||||||
for y=0,63 do
|
--- so each entry needs a 'critical' flag and something to indicate order
|
||||||
mset(x, y, get_tile(start_x+x, start_y+y))
|
--- added. We could keep 2 buffers for the latter, one that's just keys
|
||||||
end
|
--- in an array... expensive though.
|
||||||
end
|
---
|
||||||
|
|
||||||
|
-- x and y are global coords
|
||||||
|
function get_mod_key(x, y)
|
||||||
|
return tostr(x) .. ":" .. tostr(y)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- x and y are map-local coords
|
||||||
|
function write_map_change(new_sprite, x, y)
|
||||||
|
local global_x, global_y = calculate_world_pos(x, y)
|
||||||
|
if #mod_buffer >= max_mod_entries then
|
||||||
|
cull_mod_buffer()
|
||||||
|
end
|
||||||
|
|
||||||
|
mod_buffer[get_mod_key(global_x, global_y)] = new_sprite
|
||||||
|
end
|
||||||
|
|
||||||
|
function cull_mod_buffer()
|
||||||
|
-- we cull 10% of the mod buffer at a time
|
||||||
|
-- todo: implement this
|
||||||
end
|
end
|
Loading…
Reference in New Issue
Block a user