From a8b26c113d42c8be3167e3cb47c16c2863924381 Mon Sep 17 00:00:00 2001 From: Anna Wiggins Date: Sat, 7 Dec 2019 15:36:32 -0500 Subject: [PATCH] Implement infinite scrolling. --- infimap.p8 | 2 +- main.lua | 27 ++++++++++--- movement.lua | 74 ----------------------------------- player.lua | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 81 deletions(-) delete mode 100644 movement.lua create mode 100644 player.lua diff --git a/infimap.p8 b/infimap.p8 index 7c888d2..521e283 100644 --- a/infimap.p8 +++ b/infimap.p8 @@ -2,7 +2,7 @@ pico-8 cartridge // http://www.pico-8.com version 18 __lua__ #include mapgen.lua -#include movement.lua +#include player.lua #include main.lua __gfx__ 000000000000000033333333335555333344443338333333333333e3383333830000000000000000000000000000000000000000000000000000000000000000 diff --git a/main.lua b/main.lua index 09ed32c..3e11d62 100644 --- a/main.lua +++ b/main.lua @@ -1,6 +1,6 @@ function _init() init_mapgen() - init_movement({block_size/2, block_size/2}) + init_player({block_size/2, block_size/2}) generate_map({0, 0}) debug = false end @@ -8,6 +8,7 @@ end function _update() handle_input() + handle_map_update() if (btn(5) and btn(4) and btnp(3)) debug = not debug end @@ -21,14 +22,28 @@ function _draw() end end +-- decide whether we need to regenerate the map. +-- if so, call generate_map appropriately and reset coordinates. +function handle_map_update() + if out_of_bounds(camera_pos) then -- out_of_bounds() checks all screen bounds + -- we need to regenerate the map, so we generate a map chunk that + -- places the player in the middle of it. + generate_map({player_pos[1]-block_size/2, player_pos[2]-block_size/2}) + camera_pos = {block_size/2 - 8, block_size/2 - 8} + end +end + +function out_of_bounds(pos) + return pos[1] < 0 or pos[1] > block_size-16 or pos[2] < 0 or pos[2] > block_size-16 +end + function render_debug_info() - clip(0, 0, 32, 32) - rectfill(0, 0, 32, 32, 0) + clip(0, 0, 32, 24) + rectfill(0, 0, 32, 24, 0) print(stat(0), 0, 0, 15) print(camera_pos[1], 0, 8, 15) print(camera_pos[2], 16, 8, 15) - print(facing[1], 0, 16, 15) - print(facing[2], 16, 16, 15) - print(fget(mget(camera_pos[1]+8, camera_pos[2]+8)), 0, 24, 15) + print(player_pos[1], 0, 16, 15) + print(player_pos[2], 16, 16, 15) clip() end diff --git a/movement.lua b/movement.lua deleted file mode 100644 index cdf08fe..0000000 --- a/movement.lua +++ /dev/null @@ -1,74 +0,0 @@ -function init_movement(start_pos) - camera_pos = start_pos - - -- [1] is vertical facing, [2] is horizontal, -1 is up/left, 0 is neutral, - -- and 1 is down/right - facing = {1, 0} - - -- this is a constant for looking up player sprites by facing - player_lookup = { - [0] = { - [0] = -1, -- error state - [-1] = 122, -- left - [1] = 123, -- right - }, - [-1] = { - [0] = 120, -- up - [-1] = 124, -- up-left - [1] = 125, -- up-right - }, - [1] = { - [0] = 121, -- down - [-1] = 126, -- down-left - [1] = 127, -- down-right - }, - } -end - - -function handle_input() - local new_pos = {camera_pos[1], camera_pos[2]} - - if btnp(0) or btnp(1) or btnp(2) or btnp(3) then - if btnp(0) then - new_pos[1] -= 1 -- move left - facing[2] = -1 - end - if btnp(1) then - new_pos[1] += 1 -- move right - facing[2] = 1 - end - if not (btnp(0) or btnp(1)) then - facing[2] = 0 - end - - if btnp(2) then - new_pos[2] -= 1 -- move up - facing[1] = -1 - end - if btnp(3) then - new_pos[2] += 1 -- move down - facing[1] = 1 - end - if not (btnp(2) or btnp(3)) then - facing[1] = 0 - end - end - - if legal_move(new_pos) then - camera_pos = new_pos - end - - -- todo: determine whether we need to regen map and what that means -end - -function draw_player() - spr(player_lookup[facing[1]][facing[2]], 64, 64) - -- todo: animate the character on move -end - --- pos is camera position, meaning the player position is --- pos + {8, 8}. -function legal_move(pos) - return not fget(mget(pos[1]+8, pos[2]+8), 0) -end diff --git a/player.lua b/player.lua new file mode 100644 index 0000000..1f93fc5 --- /dev/null +++ b/player.lua @@ -0,0 +1,106 @@ +-- this module assumes all objects and the player are +-- 1x1 sprite in size. larger sprites are not currently supported +-- +-- exported variables: +-- player_pos # integer tuple {x,y}. absolute position of the player on the +-- # 'world map' +-- camera_pos # integer tuple {x,y}. Represents top-left position of the +-- # pico-8 camera on the pico-8 map +-- facing # integer tuple {v,h}. Current facing of the player. Values of +-- # each element can be -1 (up or left), 0 (neutral), +-- # or 1 (down or right) +-- +-- exported constants: +-- player_lookup # used internally to look up the sprite to render for a +-- # given facing +-- +-- functions: +-- init_player({x,y}) # call this in _init(). Sets player starting position, +-- # assumes the top-left of the pico-8 map is currently +-- # world position 0,0 +-- handle_input() # call in _update() to handle movement key presses. +-- # Assumes any sprite with flag 0 set is an obstacle. +-- draw_player() # call in _draw(). Draws the player sprite. + +function init_player(start_pos) + -- camera_pos is the relative coordinate of the camera + -- on the currently generated map chunk. player_pos is + -- the *absolute* world coordinates of the player. + player_pos = start_pos + camera_pos = {start_pos[1]-8, start_pos[2]-8} + + -- [1] is vertical facing, [2] is horizontal, -1 is up/left, 0 is neutral, + -- and 1 is down/right + facing = {1, 0} + + -- this is a constant for looking up player sprites by facing + player_lookup = { + [0] = { + [0] = -1, -- error state + [-1] = 122, -- left + [1] = 123, -- right + }, + [-1] = { + [0] = 120, -- up + [-1] = 124, -- up-left + [1] = 125, -- up-right + }, + [1] = { + [0] = 121, -- down + [-1] = 126, -- down-left + [1] = 127, -- down-right + }, + } +end + + +function handle_input() + local new_pos = {camera_pos[1], camera_pos[2]} + local new_ppos = {player_pos[1], player_pos[2]} + + if btnp(0) or btnp(1) or btnp(2) or btnp(3) then + if btnp(0) then + new_pos[1] -= 1 -- move left + new_ppos[1] -= 1 + facing[2] = -1 + end + if btnp(1) then + new_pos[1] += 1 -- move right + new_ppos[1] += 1 -- move right + facing[2] = 1 + end + if not (btnp(0) or btnp(1)) then + facing[2] = 0 + end + + if btnp(2) then + new_pos[2] -= 1 -- move up + new_ppos[2] -= 1 -- move up + facing[1] = -1 + end + if btnp(3) then + new_pos[2] += 1 -- move down + new_ppos[2] += 1 -- move down + facing[1] = 1 + end + if not (btnp(2) or btnp(3)) then + facing[1] = 0 + end + end + + if _legal_move(new_pos) then + camera_pos = new_pos + player_pos = new_ppos + end +end + +function draw_player() + spr(player_lookup[facing[1]][facing[2]], 64, 64) + -- todo: animate the character on move +end + +-- pos is camera position, meaning the map-relative player +-- position is pos + {8, 8}. +function _legal_move(pos) + return not fget(mget(pos[1]+8, pos[2]+8), 0) +end