## MAKE A ONE-BUTTON GAME USING PICO8 #4 – OBSTACLES

In this port, we will add obstacles into the block and the game will reset the player’s character position into starting position when the player’s character touch obstacles.

###### ADD VARIABLE AND FUNCTION FOR SUPPORT OBSTACLES IN THE BLOCK

First, we need to modify the function for creating a block by adding a variable for keeping obstacles data.

```function create_block(x,y,w,h)
return {x=x,y=y,w=w,h=h,obstacles={}}
end```

Second, we add a new function to create obstacle data into the block data. currently, It only data for obstacle’s position inside the block. The value between 0 to 1. 0 = left, 1 = right

```function add_obstacle(b,v)
if (b == nil) return
end```
```And the last one, we need to modify the function for drawing block to support obstacle.

function draw_block(b,c)
if (b == nil) return
rect(b.x,b.y,b.x+b.w,b.y-b.h,c)

for obs in all(b.obstacles) do
print("✽", b.x + (b.w*obs.value), b.y - 6, 8)
end
end

```
###### ADD FUNCTIONS FOR THE PLAYER'S CHARACTER

We need to make the player’s character interact with obstacles. We will add 2 new functions for collision detect and reset the player’s character to start position.

function player_hit_obstacle(b)

```   if b == nil then return false end

for o in all(b.obstacles) do
local dx = player.x - (b.x + b.w * o.value)
local dy = player.y - b.y
local distance = sqrt(dx*dx+dy*dy)

if distance < 3 then
return true
end
end
end
```
```function player_reset()
player = {x=64,y=64,di=1,jump_counter=0,ground=true}
current_block = block_list
end```
###### PUT EVERYTHING TOGETHER

We will add obstacles into a second and third block and make _update60() call function to detect collision between the player’s character and obstacles in the current block.

```function _init()
current_block = block_list

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
end```
###### SOURCE CODE
```player = {x=64,y=64,di=1,jump_counter=0,ground=true}
current_block = nil

block_list = {}
function create_block(x,y,w,h)
return {x=x,y=y,w=w,h=h,obstacles={}}
end

function draw_block(b,c)
if (b == nil) return
rect(b.x,b.y,b.x+b.w,b.y-b.h,c)

for obs in all(b.obstacles) do
print("✽", b.x + (b.w*obs.value), b.y - 6, 8)
end
end

if (b == nil) return
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

player.di = player.di * -1
next_px = player.x + player.di
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 then

next_py = player.y
player.ground = true
end
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
current_block = b
break
end
end
end
end

function player_hit_obstacle(b)
if b == nil then return false end

for o in all(b.obstacles) do
local dx = player.x - (b.x + b.w * o.value)
local dy = player.y - b.y
local distance = sqrt(dx*dx+dy*dy)

if distance < 3 then
return true
end
end
end

function player_reset()
player = {x=64,y=64,di=1,jump_counter=0,ground=true}
current_block = block_list
end

function _init()
current_block = block_list

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
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

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```