MAKE A ONE(MAYBE TWO)-BUTTON(S) GAME USING PICO8 #8 – DROP FROM THE CURRENT BLOCK
After thinking for a while, I decided to add a new ability to the player’s character. It can drop from the current block to a lower one. Because I have planned for the player’s character to obtain new skills after winning each boss. This post will focus on the ability to drop from the current block to the lower one.
The game will change from one-button game to two-buttons game. 🙂
SUPPORT DROPPING WITH A NEW BUTTON
It required to add a variable to keep which block that it will ignore for checking the ground and a function for detecting pressing a button.
ignore_block = nil
In this function. If the player presses the button. It will set value for “ignore_block” with the “current_block”‘s value.
function player_drop_down() if btnp(5) and player.ground == true and current_block != nil and ignore_block == nil then ignore_block = current_block end end
ADD CONDITIONS FOR CHECKING "IGNORE_BLOCK" VALUE
In the “change_current_block()” function. we add condition to clear value in “ignore_block” variable when player change to the new block.
function change_current_block(b) current_block = b if current_block != ignore_block then ignore_block = nil end 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
In “player_apply_gravity()” function. we will add a condition to skip setting the ground value when the player’s character stays inside “ignore_block”.
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 if current_block != ignore_block then next_py = player.y player.ground = true end end end else if is_inside_block(player.x, player.y, current_block) == false or current_block == ignore_block then player.ground = false end end player.y = next_py end
RESULT
player = {x=64,y=64,di=1,jump_counter=0,ground=true} ignore_block = nil 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 if current_block != ignore_block then ignore_block = nil end 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_drop_down() if btnp(5) and player.ground == true and current_block != nil and ignore_block == nil then ignore_block = current_block end 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 if current_block != ignore_block then next_py = player.y player.ground = true end end end else if is_inside_block(player.x, player.y, current_block) == false or current_block == ignore_block 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_drop_down() 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