MAKE A ONE-BUTTON GAME USING PICO8 #7 – BLOCK WITH NO FLOOR
For making block support no floor. The steps that we need todo likely the same as the previous post.
– Add a variable to block data structure.
– Add condition for checking ground.
– Add condition for drawing block’s floor.
ADD A VARIABLE FOR BLOCK'S FLOOR
We need to modify a function for creating block data by adding “ground”.
function create_block(x,y,w,h,left_wall,right_wall, floor) return {x=x,y=y,w=w,h=h,obstacles={},left_wall=left_wall,right_wall=right_wall,floor=floor} end
CONDITION FOR CHECKING GROUND
This condition need to add to “player_apply_gravity()” function. Before we set value that the player’s character stands on the ground. It needs to check that the block has the floor to stand.
function player_apply_gravity() local next_py = player.y if player.ground == false then if player.jump_counter <= 0 then next_py += 1 if is_inside_block(player.x, player.y, current_block) == true and is_inside_block(player.x, next_py, current_block) == false and current_block.floor == true then next_py = player.y player.ground = true end end else if is_inside_block(player.x, player.y, current_block) == false then player.ground = false end end player.y = next_py end
MODIFY DRAWING BLOCK FUNCTION
For “draw_block()” function. we will add a condition for checking the “floor” variable for draw block’s floor and we need to remove code for draw block’s ceiling.
function draw_block(b,c)
if (b == nil) return if b.floor == true then line(b.x,b.y,b.x+b.w,b.y,c) end if b.left_wall == true then line(b.x,b.y,b.x,b.y-b.h,c) end if b.right_wall == true then line(b.x+b.w,b.y,b.x+b.w,b.y-b.h,c) end for obs in all(b.obstacles) do print("✽", b.x + (b.w*obs.value), b.y - 6, 8) end end
EDIT BLOCKS
We will edit codes in the “_init()” function that creates block’s data to show what we can achieve with the block with no floor.
function _init() add(block_list, create_block(16,64,96,8,true ,true , true)) add(block_list, create_block(16,56,96,8,true ,false, true)) add(block_list, create_block(16,48,96,8,false,false , true)) add(block_list, create_block(16,40,96,8,true,true , false)) player_reset() end
RESULT
player = {x=64,y=64,di=1,jump_counter=0,ground=true} current_block = nil block_list = {} function create_block(x,y,w,h,left_wall,right_wall, floor) return {x=x,y=y,w=w,h=h,obstacles={},left_wall=left_wall,right_wall=right_wall,floor=floor} end function draw_block(b,c) if (b == nil) return if b.floor == true then line(b.x,b.y,b.x+b.w,b.y,c) end if b.left_wall == true then line(b.x,b.y,b.x,b.y-b.h,c) end if b.right_wall == true then line(b.x+b.w,b.y,b.x+b.w,b.y-b.h,c) end for obs in all(b.obstacles) do print("✽", b.x + (b.w*obs.value), b.y - 6, 8) end end function distance(x1,y1,x2,y2) local dx = x1-x2 local dy = y1-y2 local distance = sqrt(dx*dx+dy*dy) return distance end function change_current_block(b) current_block = b local d = distance(camera_data.target_x + 64, camera_data.target_y + 64, current_block.x + current_block.w/2, current_block.y - current_block.h/2) _debug = d if d > 12 then set_camera_target(current_block) end end function add_obstacle(b,v) if (b == nil) return add(b.obstacles, {value=v}) end function is_inside_block(x,y,b) if (b == nil) return if x >= b.x and x < b.x + b.w then if y <= b.y and y > b.y - b.h then return true end end return false end function player_running() local next_px = player.x + player.di if is_inside_block(player.x, player.y, current_block) == true and is_inside_block(next_px, player.y, current_block) == false then if player.di == 1 and current_block.right_wall == false then elseif player.di == -1 and current_block.left_wall == false then else player.di = player.di * -1 next_px = player.x + player.di end end player.x = next_px end function player_jumping() if btnp(4) then if player.jump_counter == 0 and player.ground == true then player.jump_counter = 20 player.ground = false end end local next_py = player.y if player.jump_counter > 0 then player.jump_counter -= 1 if player.jump_counter > 10 then next_py = player.y - 1 else next_py = player.y end end player.y = next_py end function player_apply_gravity() local next_py = player.y if player.ground == false then if player.jump_counter <= 0 then next_py += 1 if is_inside_block(player.x, player.y, current_block) == true and is_inside_block(player.x, next_py, current_block) == false and current_block.floor == true then next_py = player.y player.ground = true end end else if is_inside_block(player.x, player.y, current_block) == false then player.ground = false end end player.y = next_py end function player_find_new_current_block() if player.ground == false and is_inside_block(player.x, player.y, current_block) == false then for b in all(block_list) do if is_inside_block(player.x, player.y, b) == true then change_current_block(b) break end end end end function player_hit_obstacle(b) if b == nil then return false end if is_inside_block(player.x, player.y, current_block) == false then return false end for o in all(b.obstacles) do local d = distance(player.x, player.y, (b.x + b.w * o.value), b.y) if d < 3 then return true end end end function player_reset() player = {x=64,y=64,di=1,jump_counter=0,ground=true} change_current_block(block_list[1]) end camera_data = {x=0,y=0,target_x=0,target_y=0} function set_camera_target(b) if b == nil then return end local block_center_x = b.x + b.w/2 local block_center_y = b.y - b.h/2 camera_data.target_x = block_center_x - 64 camera_data.target_y = block_center_y - 64 end function update_camera() if camera_data.x > camera_data.target_x then camera_data.x -= 1 elseif camera_data.x < camera_data.target_x then camera_data.x += 1 end if camera_data.y > camera_data.target_y then camera_data.y -= 1 elseif camera_data.y < camera_data.target_y then camera_data.y += 1 end camera(camera_data.x, camera_data.y) end function _init() add(block_list, create_block(16,64,96,8,true ,true , true)) add(block_list, create_block(16,56,96,8,true ,false, true)) add(block_list, create_block(16,48,96,8,false,false , true)) add(block_list, create_block(16,40,96,8,true,true , false)) player_reset() end function _update60() player_running() player_jumping() player_apply_gravity() player_find_new_current_block() local hit_result = player_hit_obstacle(current_block) if hit_result == true then player_reset() end update_camera() end function _draw() cls(0) print("웃", player.x-3, player.y - 5, 7) for b in all(block_list) do draw_block(b, 7) end end