-- This module assumes all objects and the player are 1x1 sprite in size. -- Larger sprites will probably work for objects, but not for the player. -- -- exported variables: -- player_[xy] # position of the player on the 'world map' -- facing_[vh] # Current facing of the player. Values of -- # each element can be -1 (up or left), 0 (neutral), -- # or 1 (down or right) -- -- functions: -- init_player() # call this in _init(). -- 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() player_x, player_y = 0, 0 facing_v = 1 facing_h = 0 -- this is a constant for looking up player sprites by facing player_lookup = { [0] = { [0] = 0xffff, -- error state [0xffff] = 122, -- left [1] = 123, -- right }, [0xffff] = { [0] = 120, -- up [0xffff] = 124, -- up-left [1] = 125, -- up-right }, [1] = { [0] = 121, -- down [0xffff] = 126, -- down-left [1] = 127, -- down-right }, } end -- NB: references menu_mode from main.lua function player_input() local new_x, new_y = player_x, player_y if btnp"4" then interact() end if btnp"5" then menu_mode = true -- pass control to menu end if btnp"0" or btnp"1" or btnp"2" or btnp"3" then if btnp"0" then new_x -= 1 -- move left facing_h = 0xffff end if btnp"1" then new_x += 1 -- move right facing_h = 1 end if not (btnp"0" or btnp"1") then facing_h = 0 end if btnp"2" then new_y -= 1 -- move up facing_v = 0xffff end if btnp"3" then new_y += 1 -- move down facing_v = 1 end if not (btnp"2" or btnp"3") then facing_v = 0 end end -- note that facing always changes, even if we can't move to the new location if legal_move(new_x, new_y) then player_x, player_y = new_x, new_y end end function draw_player() spr(player_lookup[facing_v][facing_h], 60, 60) -- todo: animate the character on move -- draw the player's HUD local interact_x, interact_y = can_interact() if interact_x and interact_y then spr(119, 0, 120) end -- todo: introduce the concept of an inventory here end -- returns x,y as the coordinates of the interactable object -- nil,nil if nothing to interact with -- NB: this function calls get_tile() from world.lua function can_interact() -- flag 1 represents an interactable (read: destructible) sprite. -- check the tile the player is standing on if fget(get_tile(player_x, player_y), 1) then return player_x, player_y end -- check the tile the player is facing faced_tile_x, faced_tile_y = get_position_facing() if fget(get_tile(faced_tile_x, faced_tile_y), 1) then return faced_tile_x, faced_tile_y end return nil, nil end -- NB: this function calls get_tile() and references the -- object_interaction_map from world.lua function interact() -- get the position to interact with local x, y = can_interact() if (x == nil or y == nil) return local sprite = get_tile(x, y) local data = object_interaction_map[sprite] -- todo: figure out playing sound effects, animation? -- modify the tile by writing the change to the mod_buffer -- (the rendered image will be updated by draw_world() write_map_change(data.replacement, x, y) end -- returns x,y representing the map-local position the player is facing. function get_position_facing() return player_x+facing_h, player_y+facing_v end -- NB: this function calls get_tile() from world.lua function legal_move(pos_x, pos_y) return not fget(get_tile(pos_x, pos_y), 0) end