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
|
||||
__lua__
|
||||
#include debug.lua
|
||||
#include data.lua
|
||||
#include sound.lua
|
||||
#include mapgen.lua
|
||||
#include world.lua
|
||||
#include player.lua
|
||||
#include main.lua
|
||||
__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()
|
||||
init_data()
|
||||
init_sound()
|
||||
init_mapgen()
|
||||
init_sound""
|
||||
init_world""
|
||||
init_player(32, 32)
|
||||
generate_map(0, 0)
|
||||
init_debug()
|
||||
init_debug""
|
||||
end
|
||||
|
||||
|
||||
function _update()
|
||||
handle_input()
|
||||
handle_map_update()
|
||||
handle_input""
|
||||
-- handle_map_update""
|
||||
end
|
||||
|
||||
function _draw()
|
||||
cls()
|
||||
cls""
|
||||
-- the screen is 128x128 pixels, so it fits 16x16 sprites
|
||||
map(camera_pos_x, camera_pos_y, 0, 0, 16, 16)
|
||||
draw_player()
|
||||
debug_print()
|
||||
-- map(camera_pos_x, camera_pos_y, 0, 0, 16, 16)
|
||||
draw_world_segment(player_pos_x, player_pos_y)
|
||||
draw_player""
|
||||
debug_print""
|
||||
end
|
||||
|
||||
-- decide whether we need to regenerate the map.
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
--- Procedural generation methods
|
||||
|
||||
function init_mapgen()
|
||||
uid_seed = 2229 -- arbitrarily chosen number
|
||||
|
||||
function init_world()
|
||||
-- Metadata for different biomes
|
||||
-- tile_frequencies tuples are {frequency, sprite_index}, see index_map.md
|
||||
-- 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])
|
||||
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
|
||||
|
||||
-- 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]
|
||||
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
|
||||
-- after a call to generate_map you should always center the camera/player over the map, i.e.
|
||||
-- camera at { (block_size / 2) - 8, (block_size / 2) - 8 }
|
||||
function generate_map(start_x, start_y)
|
||||
for x=0,63 do
|
||||
for y=0,63 do
|
||||
mset(x, y, get_tile(start_x+x, start_y+y))
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
--- mod buffer functions - these handle parts of the world map that have
|
||||
--- changed from their 'default' position
|
||||
---
|
||||
--- todo: the mod buffer eventually needs to be a bit more elaborate.
|
||||
--- we need to make it possible to cull only old and unimportant changes,
|
||||
--- so each entry needs a 'critical' flag and something to indicate order
|
||||
--- added. We could keep 2 buffers for the latter, one that's just keys
|
||||
--- in an array... expensive though.
|
||||
---
|
||||
|
||||
-- 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
|
Loading…
Reference in New Issue
Block a user