Skip to content

Instantly share code, notes, and snippets.

@quad-damage
Last active December 25, 2022 14:54
Show Gist options
  • Save quad-damage/ab356bddafbe0b6bf2642a5838c00049 to your computer and use it in GitHub Desktop.
Save quad-damage/ab356bddafbe0b6bf2642a5838c00049 to your computer and use it in GitHub Desktop.
Flappy Bird style minigame for RIfk 7
------------------------------
-- FlappyRifk lua for Rifk7 --
-- by Quadruple --
-- ---------------------------
math.clamp = function(x, min, max)
if(x < min) then return min end
if(x > max) then return max end
return x
end
local function is_in_area(x, y, min_x, min_y, max_x, max_y)
return(
min_x < x and x < max_x and
min_y < y and y < max_y
)
end
local function collision_check(x, y, width, height, min_x, min_y, max_x, max_y)
return (
is_in_area(x + width, y + height, min_x, min_y, max_x, max_y) or
is_in_area(x , y + height, min_x, min_y, max_x, max_y) or
is_in_area(x + width, y , min_x, min_y, max_x, max_y) or
is_in_area(x , y , min_x, min_y, max_x, max_y)
)
end
-- WINDOW TABLE
-- Purpose: Initially, I wanted to write a full window framework
-- for Rifk7, however because I don't have access to some
-- important functions, I can't do it right now.
local window = {
x = menu.get(menu.add_slider("X position", 100, 0, renderer.get_screen_width())),
y = menu.get(menu.add_slider("Y position", 100, 0, renderer.get_screen_height())),
collision_debug = menu.get(menu.add_checkbox("Collision debug", false)),
jump_keybind = menu.get(menu.add_keybind("Jump key", 0x20, 0, 0)),
restart_keybind = menu.get(menu.add_keybind("Restart key", 82, 0, 0)),
width = 350,
height = 500
}
-- GAME RENDERER
-- Purpose: Since the game window can move around, this
-- table is in charge of automatically drawing game
-- elements without having to do stinky OBJECT_X / OBJECT_Y + WINDOW_X / WINDOW_Y math.
local game_renderer = {
x_modifier = 0,
y_modifier = 0,
update_global_modifiers = function(self, x, y)
self.x_modifier = x
self.y_modifier = y
end,
draw_rectangle = function(self,x,y,size_x,size_y,float_red,float_green,float_blue,float_alpha,rounding)
renderer.draw_rectangle(x + self.x_modifier,y + self.y_modifier,size_x,size_y,float_red,float_green,float_blue,float_alpha,rounding)
end,
draw_rectangle_filled = function(self,x,y,size_x,size_y,float_red,float_green,float_blue,float_alpha,rounding)
renderer.draw_rectangle_filled(x + self.x_modifier,y + self.y_modifier,size_x,size_y,float_red,float_green,float_blue,float_alpha,rounding)
end,
draw_rectangle_multicolored = function(self,x,y,size_x,size_y,float_red1,float_green1,float_blue1,float_alpha1,float_red2,float_green2,float_blue2,float_alpha2,horizontal)
renderer.draw_rectangle_multicolored(x + self.x_modifier,y + self.y_modifier,size_x,size_y,float_red1,float_green1,float_blue1,float_alpha1,float_red2,float_green2,float_blue2,float_alpha2,horizontal)
end,
-- Ditto as above, but clamped!
-- Used for pseudo-clipping on the pipes.
draw_rectangle_multicolored_and_clamped = function(self,x,y,size_x,size_y,float_red1,float_green1,float_blue1,float_alpha1,float_red2,float_green2,float_blue2,float_alpha2,horizontal, clamp_min_x, clamp_min_y, clamp_max_x, clamp_max_y)
if(x + size_x > clamp_max_x) then
size_x = math.clamp(clamp_max_x - x, 0, 1000)
end
if(x < clamp_min_x) then
size_x = size_x - math.abs(x)
x = clamp_min_x
end
self:draw_rectangle_multicolored(x,y,size_x,size_y,float_red1,float_green1,float_blue1,float_alpha1,float_red2,float_green2,float_blue2,float_alpha2,horizontal)
end,
draw_text = function(self,x,y,text,float_red,float_green,float_blue,float_alpha,flags)
renderer.draw_text(x + self.x_modifier,y + self.y_modifier,text,renderer.get_font(fonts.profont_15),float_red,float_green,float_blue,float_alpha,flags)
end,
draw_line_multicolored = function(self,x,y,end_x,end_y,float_red1,float_green1,float_blue1,float_alpha1,float_red2,float_green2,float_blue2,float_alpha2)
renderer.draw_line_multicolored(x + self.x_modifier,y + self.y_modifier,end_x + self.x_modifier,end_y + self.y_modifier,float_red1,float_green1,float_blue1,float_alpha1,float_red2,float_green2,float_blue2,float_alpha2)
end,
}
local player = {
score = 0,
is_dead = true,
y_position = 24,
y_velocity = 0,
update_player = function(self, in_jump)
-- Apply gravity
self.y_velocity = self.y_velocity - 0.75
-- Check if player is jumping
if(in_jump) then
self.y_velocity = self.y_velocity + 32
end
-- Clamp velocity and apply it.
self.y_velocity = math.clamp(self.y_velocity, -5.5, 8.5)
self.y_position = self.y_position + self.y_velocity
-- Kick player back down if they reach the top.
if(self.y_position >= 476) then
self.y_position = 470
self.y_velocity = 0
end
-- Kill if we hit the ground.
if(self.y_position <= 24) then
self.y_position = 24
self.is_dead = true
end
end,
reset_player = function(self)
self.score = 0
self.is_dead = false
self.jump_stamina = 0
self.y_position = 400
self.y_velocity = 0
end,
}
-- READERS BEWARE!
-- Since there's (apparently) no way to render images in Rifk, I had to make THIS!!!
-- The following is a function that renders Rifk at a given X and Y, with a SCALE.
-- The array stores 41 points in FLOAT(0 --> 1). On render, they get multiplied by
-- SCALE and then get drawn at X and Y.
local draw_rifk = {
rifk_points = {
[1] = {0.1953125, 0.1953125}, -- 25, 25
[2] = {0.484375, 0.1953125}, -- 62, 25
[3] = {0.484375, 0.078125}, -- 62, 10
[4] = {0.625, 0.0625}, -- 80, 8
[5] = {0.625, 0.328125}, -- 80, 42
[6] = {0.7421875, 0.328125}, -- 95, 42
[7] = {0.7421875, 0.7421875}, -- 95, 95
[8] = {0.1953125, 0.7421875}, -- 25, 95
[9] = {0.3125, 0.34375}, -- 40, 44
[10] = {0.390625, 0.453125}, -- 50, 58
[11] = {0.5600, 0.328100}, -- 72, 42
[12] = {0.46875, 0.453125}, -- 60, 58
[13] = {0.28125, 0.46875}, -- 36, 60
[14] = {0.28125, 0.546875}, -- 36, 70
[15] = {0.59375, 0.46875}, -- 76, 60
[16] = {0.59375, 0.546875}, -- 76, 70
[17] = {0.28125, 0.609375}, -- 36, 78
[18] = {0.5625, 0.609375}, -- 72, 78
[19] = {0.5625, 0.6870}, -- 72, 88
[20] = {0.28125, 0.6870}, -- 36, 88
[21] = {0.15625, 0.5}, -- 20, 64
[22] = {0.09375, 0.546875}, -- 12, 70
[23] = {0.09375, 0.640625}, -- 12, 82
[24] = {0.765625, 0.46875}, -- 98, 60
[25] = {0.859375, 0.4296875}, -- 110, 55
[26] = {0.890625, 0.3984375}, -- 114, 51
[27] = {0.890625, 0.1640625}, -- 114, 21
[28] = {0.8300000, 0.28125}, -- 107, 36
[29] = {0.953125, 0.28125}, -- 122, 36
[30] = {0.3359375, 0.765625}, -- 43, 98
[31] = {0.3359375, 0.8671875}, -- 43, 111
[32] = {0.2265625, 0.8671875}, -- 29, 111
[33] = {0.2265625, 0.9453125}, -- 29, 121
[34] = {0.40625, 0.9453125}, -- 52, 121
[35] = {0.40625, 0.765625}, -- 52, 98
[36] = {0.515625, 0.765625}, -- 66, 98
[37] = {0.515625, 0.9375}, -- 66, 120
[38] = {0.6953125, 0.9375}, -- 89, 120
[39] = {0.6953125, 0.8671875}, -- 89, 111
[40] = {0.5859375, 0.8671875}, -- 75, 111
[41] = {0.5859375, 0.765625} -- 75, 98
},
render = function(self, x, y, scale)
-- Draw body of Rifk
game_renderer:draw_line_multicolored(x + self.rifk_points[1][1] * scale, y + self.rifk_points[1][2] * scale, x + self.rifk_points[2][1] * scale, y + self.rifk_points[2][2] * scale, 153, 106, 157, 255, 206, 54, 200, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[2][1] * scale, y + self.rifk_points[2][2] * scale, x + self.rifk_points[3][1] * scale, y + self.rifk_points[3][2] * scale, 206, 54, 200, 255, 227, 34, 218, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[3][1] * scale, y + self.rifk_points[3][2] * scale, x + self.rifk_points[4][1] * scale, y + self.rifk_points[4][2] * scale, 227, 34, 218, 255, 254, 6, 240, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[4][1] * scale, y + self.rifk_points[4][2] * scale, x + self.rifk_points[5][1] * scale, y + self.rifk_points[5][2] * scale, 254, 6, 240, 255, 204, 54, 198, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[5][1] * scale, y + self.rifk_points[5][2] * scale, x + self.rifk_points[6][1] * scale, y + self.rifk_points[6][2] * scale, 204, 54, 198, 255, 222, 36, 213, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[6][1] * scale, y + self.rifk_points[6][2] * scale, x + self.rifk_points[7][1] * scale, y + self.rifk_points[7][2] * scale, 204, 54, 198, 255, 142, 116, 148, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[7][1] * scale, y + self.rifk_points[7][2] * scale, x + self.rifk_points[8][1] * scale, y + self.rifk_points[8][2] * scale, 142, 116, 148, 255, 48, 205, 69, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[8][1] * scale, y + self.rifk_points[8][2] * scale, x + self.rifk_points[1][1] * scale, y + self.rifk_points[1][2] * scale, 48, 205, 69, 255, 153, 106, 157, 255)
-- Left eyebrow of Rifk
game_renderer:draw_line_multicolored(x + self.rifk_points[9][1] * scale, y + self.rifk_points[9][2] * scale, x + self.rifk_points[10][1] * scale, y + self.rifk_points[10][2] * scale, 135, 102, 140, 255, 139, 114, 144, 255)
-- Right eyebrow of Rifk
game_renderer:draw_line_multicolored(x + self.rifk_points[11][1] * scale, y + self.rifk_points[11][2] * scale, x + self.rifk_points[12][1] * scale, y + self.rifk_points[12][2] * scale, 193, 67, 189, 255, 144, 98, 148, 255)
-- Left eye of Rifk
game_renderer:draw_line_multicolored(x + self.rifk_points[13][1] * scale, y + self.rifk_points[13][2] * scale, x + self.rifk_points[14][1] * scale, y + self.rifk_points[14][2] * scale, 117, 140, 126, 255, 86, 170, 101, 255)
-- Right eye of Rifk
game_renderer:draw_line_multicolored(x + self.rifk_points[15][1] * scale, y + self.rifk_points[15][2] * scale, x + self.rifk_points[16][1] * scale, y + self.rifk_points[16][2] * scale, 168, 91, 168, 255, 176, 72, 175, 255)
-- Mouth of Rifk
game_renderer:draw_line_multicolored(x + self.rifk_points[17][1] * scale, y + self.rifk_points[17][2] * scale, x + self.rifk_points[18][1] * scale, y + self.rifk_points[18][2] * scale, 89, 165, 103, 255, 136, 123, 141, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[18][1] * scale, y + self.rifk_points[18][2] * scale, x + self.rifk_points[19][1] * scale, y + self.rifk_points[19][2] * scale, 136, 123, 141, 255, 124, 133, 133, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[19][1] * scale, y + self.rifk_points[19][2] * scale, x + self.rifk_points[20][1] * scale, y + self.rifk_points[20][2] * scale, 124, 133, 133, 255, 78, 174, 93, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[20][1] * scale, y + self.rifk_points[20][2] * scale, x + self.rifk_points[17][1] * scale, y + self.rifk_points[17][2] * scale, 78, 174, 93, 255, 176, 72, 175, 255)
-- Left hand of Rifk
game_renderer:draw_line_multicolored(x + self.rifk_points[21][1] * scale, y + self.rifk_points[21][2] * scale, x + self.rifk_points[22][1] * scale, y + self.rifk_points[22][2] * scale, 86, 169, 101, 255, 73, 182, 91, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[22][1] * scale, y + self.rifk_points[22][2] * scale, x + self.rifk_points[23][1] * scale, y + self.rifk_points[23][2] * scale, 73, 182, 91, 255, 54, 185, 75, 255)
-- Right hand of Rifk
game_renderer:draw_line_multicolored(x + self.rifk_points[24][1] * scale, y + self.rifk_points[24][2] * scale, x + self.rifk_points[25][1] * scale, y + self.rifk_points[25][2] * scale, 201, 53, 196, 255, 225, 32, 216, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[25][1] * scale, y + self.rifk_points[25][2] * scale, x + self.rifk_points[26][1] * scale, y + self.rifk_points[26][2] * scale, 225, 32, 216, 255, 240, 21, 227, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[26][1] * scale, y + self.rifk_points[26][2] * scale, x + self.rifk_points[27][1] * scale, y + self.rifk_points[27][2] * scale, 240, 21, 227, 255, 238, 5, 228, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[28][1] * scale, y + self.rifk_points[28][2] * scale, x + self.rifk_points[29][1] * scale, y + self.rifk_points[29][2] * scale, 246, 12, 234, 255, 244, 5, 231, 255)
-- Left leg of Rifk
game_renderer:draw_line_multicolored(x + self.rifk_points[30][1] * scale, y + self.rifk_points[30][2] * scale, x + self.rifk_points[31][1] * scale, y + self.rifk_points[31][2] * scale, 69, 186, 86, 255, 51, 206, 72, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[31][1] * scale, y + self.rifk_points[31][2] * scale, x + self.rifk_points[32][1] * scale, y + self.rifk_points[32][2] * scale, 51, 206, 72, 255, 31, 217, 55, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[32][1] * scale, y + self.rifk_points[32][2] * scale, x + self.rifk_points[33][1] * scale, y + self.rifk_points[33][2] * scale, 31, 217, 55, 255, 22, 227, 48, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[33][1] * scale, y + self.rifk_points[33][2] * scale, x + self.rifk_points[34][1] * scale, y + self.rifk_points[34][2] * scale, 22, 227, 48, 255, 51, 204, 72, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[34][1] * scale, y + self.rifk_points[34][2] * scale, x + self.rifk_points[35][1] * scale, y + self.rifk_points[35][2] * scale, 22, 227, 48, 255, 51, 204, 72, 255)
-- Right leg of Rifk
game_renderer:draw_line_multicolored(x + self.rifk_points[36][1] * scale, y + self.rifk_points[36][2] * scale, x + self.rifk_points[37][1] * scale, y + self.rifk_points[37][2] * scale, 105, 156, 117, 255, 69, 185, 86, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[37][1] * scale, y + self.rifk_points[37][2] * scale, x + self.rifk_points[38][1] * scale, y + self.rifk_points[38][2] * scale, 69, 185, 86, 255, 102, 153, 114, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[38][1] * scale, y + self.rifk_points[38][2] * scale, x + self.rifk_points[39][1] * scale, y + self.rifk_points[39][2] * scale, 102, 153, 114, 255, 114, 142, 124, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[39][1] * scale, y + self.rifk_points[39][2] * scale, x + self.rifk_points[40][1] * scale, y + self.rifk_points[40][2] * scale, 114, 142, 124, 255, 96, 159, 109, 255)
game_renderer:draw_line_multicolored(x + self.rifk_points[40][1] * scale, y + self.rifk_points[40][2] * scale, x + self.rifk_points[41][1] * scale, y + self.rifk_points[41][2] * scale, 96, 159, 109, 255, 118, 141, 127, 255)
end
}
-- Not proud of the pipes system
-- TODO: Rework this
local pipes = {
pipe_list = { },
new_pipe = function(self, index, x_pos)
local p = {
y_safepoint = math.random(128, 500 - 128),
x_position = x_pos,
scored_pipe = false
}
self.pipe_list[index] = p
end,
reset_pipes = function(self)
for _, pipe in pairs(self.pipe_list) do
self:new_pipe(_, 600 + (300 * (_ - 1)))
end
end,
update_pipes = function(self)
for _, pipe in pairs(self.pipe_list) do
pipe.x_position = pipe.x_position - 1.50
if(pipe.x_position <= -24) then
pipe.x_position = 600
pipe.y_safepoint = math.random(128, 500 - 128)
pipe.scored_pipe = false
end
if(window.collision_debug:get_bool()) then
game_renderer:draw_rectangle_filled(pipe.x_position - 24, 0, 48, pipe.y_safepoint - 80, 255, 0, 0, 128, 0)
game_renderer:draw_rectangle_filled(pipe.x_position - 24, pipe.y_safepoint + 80, 48, (500 - pipe.y_safepoint - 80), 255, 0, 0, 128, 0)
game_renderer:draw_rectangle_filled(pipe.x_position - 24, pipe.y_safepoint - 80, 48, 160, 0, 0, 255, 128, 0)
game_renderer:draw_rectangle_filled(24 , 500 - player.y_position - 24, 48, 48, 0, 255, 0, 128, 0)
end
if(collision_check(24 , 500 - player.y_position - 24, 48, 48, pipe.x_position - 24, 0, pipe.x_position + 24, pipe.y_safepoint - 80) or
collision_check(24 , 500 - player.y_position - 24, 48, 48, pipe.x_position - 24, pipe.y_safepoint + 80, pipe.x_position + 24, 500)) then
player.is_dead = true
end
if(pipe.scored_pipe == false and
collision_check(24 , 500 - player.y_position - 24, 48, 48, pipe.x_position - 24, pipe.y_safepoint - 80, pipe.x_position + 24, pipe.y_safepoint + 80)) then
player.score = player.score + 1
pipe.scored_pipe = true
engine.execute_console_command("playvol common\\beep 0.2")
end
end
end
}
pipes:new_pipe(1, 400)
pipes:new_pipe(2, 600)
local game_vars = {
old_in_jump = false,
last_game_update = global_vars.get_real_time(),
update_tick_delay = (1 / 64) -- 64 ticks per second bay-bee!
-- Don't change this btw, the physx
-- are made for 64 tps.
}
local function update_game()
local delta = global_vars.get_real_time() - game_vars.last_game_update
if(delta >= game_vars.update_tick_delay) then
local in_jump_raw = window.jump_keybind:is_keybind_active()
local in_jump = false
-- ZILLION DOLLAR HOLD DETECTION --
if(in_jump_raw == true and game_vars.old_in_jump == false) then
in_jump = true
game_vars.old_in_jump = true
elseif(in_jump_raw == true and game_vars.old_in_jump == true) then
in_jump = false
end
if(in_jump_raw == false and game_vars.old_in_jump == true) then
game_vars.old_in_jump = false
end
-- ZILLION DOLLAR HOLD DETECTION --
-- Finally, game logic here
if(player.is_dead) then
-- Make player fall down when player dies.
if(player.y_position > 24) then
player.y_position = player.y_position - 5.5
end
-- Reset to y 24 if below.
if(player.y_position < 24) then
player.y_position = 24
end
-- Reset player if user presses the jump key.
if(window.restart_keybind:is_keybind_active()) then
player:reset_player()
pipes:reset_pipes()
end
else
pipes:update_pipes()
player:update_player(in_jump)
end
game_vars.last_game_update = global_vars.get_real_time()
end
end
local function render_game_window()
local x = window.x:get_float()
local y = window.y:get_float()
renderer.draw_rectangle_filled(x, y, window.width, window.height, 32, 32, 32, 220, 0)
game_renderer:update_global_modifiers(x, y)
-- Draw pipes
for _, pipe in pairs(pipes.pipe_list) do
-- Top pipe
game_renderer:draw_rectangle_multicolored_and_clamped(pipe.x_position - 24, 0, 48, pipe.y_safepoint - 80, 208, 22, 195, 255, 29, 143, 67, 255, true, 0, 0, 350, 500)
game_renderer:draw_rectangle_multicolored_and_clamped(pipe.x_position - 24 + 1, 1, 46, pipe.y_safepoint - 81 - 2, 32, 32, 32, 255, 64, 64, 64, 255, false, 0, 0, 350, 500)
-- Bottom pipe
game_renderer:draw_rectangle_multicolored_and_clamped(pipe.x_position - 24, pipe.y_safepoint + 80, 48, (500 - pipe.y_safepoint - 80), 208, 22, 195, 255, 29, 143, 67, 255, true, 0, 0, 350, 500)
game_renderer:draw_rectangle_multicolored_and_clamped(pipe.x_position - 23, pipe.y_safepoint + 81, 46, (500 - pipe.y_safepoint - 80) - 2, 64, 64, 64, 255, 32, 32, 32, 255, false, 0, 0, 350, 500)
end
-- Draw player
--game_renderer:draw_rectangle_filled(24 , 500 - player.y_position - 24, 48, 48, 0, 255, 0, 255, 0)
draw_rifk:render(24, 500 - player.y_position - 24, 48)
-- Draw HUD last
if(player.is_dead) then
game_renderer:draw_text(175, 225, "GAME OVER!", 0, 255, 0, 255, font_flags.centered_x)
game_renderer:draw_text(175, 241, string.format("Score: %s", player.score), 0, 255, 0, 255, font_flags.centered_x)
game_renderer:draw_text(175, 257, "Press [RESTART] to restart", 0, 255, 0, 255, font_flags.centered_x)
else
game_renderer:draw_text(175, 32, string.format("Score: %s", player.score), 0, 255, 0, 255, font_flags.centered_x)
end
-- Window border to hide some stinky-ness
renderer.draw_rectangle(x, y, window.width, window.height, 0, 255, 0, 220, 0)
end
local function onDraw()
update_game()
render_game_window()
end
hooks.add_callback("on_draw", onDraw)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment