Created
April 3, 2021 05:05
-
-
Save oeloeloel/974e05cf112aff3ae49383131917059b to your computer and use it in GitHub Desktop.
Breakout made quickly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$gtk.reset | |
def tick args | |
defaults args | |
handle_input args | |
calc args | |
render args | |
end | |
def handle_input args | |
args.state.bat_x = args.mouse.x - (args.state.bat_w / 2) | |
args.state.ball_active = true if args.mouse.click | |
if args.inputs.keyboard.key_down.space | |
$gtk.reset | |
end | |
end | |
def defaults args | |
args.state.num_cols ||= 16 | |
args.state.num_rows ||= 8 | |
args.state.brick_width ||= 80 | |
args.state.brick_height ||= 40 | |
args.state.bricks ||= make_bricks args | |
args.state.ball_size ||= 20 | |
args.state.ball_x ||= (args.grid.w - args.state.ball_size) / 2 | |
args.state.ball_y ||= 60 | |
args.state.ball_active ||= false | |
args.state.ball_speed_x ||= 4 | |
args.state.ball_speed_y ||= 4 | |
args.state.bat_x ||= -1000 | |
args.state.bat_y ||= 40 | |
args.state.bat_w ||= 100 | |
args.state.bat_h ||= 20 | |
end | |
def calc args | |
return unless args.state.ball_active | |
next_x = args.state.ball_x + args.state.ball_speed_x | |
next_y = args.state.ball_y + args.state.ball_speed_y | |
next_ball_rect = [next_x, next_y, args.state.ball_size, args.state.ball_size] | |
bat_rect = [args.state.bat_x, args.state.bat_y, args.state.bat_w, args.state.bat_h] | |
# bounce on walls | |
args.state.ball_speed_x = 0 - args.state.ball_speed_x unless (0..1260) === next_x | |
# args.state.ball_speed_y = 0 - args.state.ball_speed_y unless (0..700) === next_y | |
args.state.ball_speed_x = 0 - args.state.ball_speed_x if 720 < next_y | |
if next_y < 0 | |
$gtk.reset | |
return | |
end | |
# HIT DETECTOR | |
hit_brick = false | |
top_bottom_hits = 0 | |
left_right_hits = 0 | |
args.state.bricks.map_2d do |col, row, brick| | |
next if brick == [] | |
if brick.intersect_rect? next_ball_rect | |
args.state.bricks[col][row] = [] | |
hit_brick = true | |
# check the last position of the ball | |
# keep track of the numbers of horizontal or vertical sides the ball crossed | |
# if the ball's top or bottom is outside of the brick, it crossed a horizontal | |
top_bottom_hits += 1 if args.state.ball_y + args.state.ball_size <= brick[1] || | |
args.state.ball_y >= brick[1] + brick[3] | |
# if the ball's left or right is outside of the brick, it crossed a vertical | |
left_right_hits += 1 if args.state.ball_x + args.state.ball_size <= brick[0] || | |
args.state.ball_x >= brick[0] + brick[2] | |
end | |
end | |
if hit_brick | |
# puts [left_right_hits, top_bottom_hits] | |
# bounce x | |
# if the ball crossed 1 horizontal, no vertical (it hit one brick) | |
# or the ball crossed 2 horizontals, 0-1 vertical (it hit two bricks side by side) | |
if left_right_hits > top_bottom_hits | |
ball_bounce(args, true, false) | |
# bounce y | |
# if the ball crossed 1 vertical, no hotizontal (it hit one brick) | |
# or the ball crossed 2 verticals, 0-1 horizontal (it hit two bricks, one on top of the other) | |
elsif top_bottom_hits > left_right_hits | |
ball_bounce(args, false, true) | |
# bounce x and y | |
# if the ball crossed 1 vertical and 1 horizontal | |
# (it hit the corner of 1 brick, or the corner between 2 bricks) | |
else | |
ball_bounce(args, true, true) | |
end | |
end | |
# hit bat | |
if bat_rect.intersect_rect? next_ball_rect | |
top_bottom_hits = 0 | |
left_right_hits = 0 | |
bounce_y = args.state.ball_y + args.state.ball_size <= bat_rect[1] || | |
args.state.ball_y >= bat_rect[1] + bat_rect[3] | |
bounce_x = args.state.ball_x + args.state.ball_size <= bat_rect[0] || | |
args.state.ball_x >= bat_rect[0] + bat_rect[2] | |
# do something if the ball hits near the end of the bat | |
bat_strike_point = next_x - bat_rect[0] | |
if bat_strike_point < 20 | |
args.state.ball_speed_x -= 0.5 | |
end | |
if bat_strike_point > bat_rect[2] - args.state.ball_size | |
args.state.ball_speed_x += 0.5 | |
end | |
ball_bounce(args, bounce_x, bounce_y) | |
end | |
args.state.ball_x = next_x | |
args.state.ball_y = next_y | |
end | |
def ball_bounce(args, bounce_x, bounce_y) | |
args.state.ball_speed_x = 0 - args.state.ball_speed_x if bounce_x | |
args.state.ball_speed_y = 0 - args.state.ball_speed_y if bounce_y | |
end | |
def make_bricks args | |
args.state.bricks = args.state.num_cols.times.map do |c| | |
args.state.num_rows.times.map do |r| | |
[ | |
c * args.state.brick_width, | |
720 - (r + 1) * args.state.brick_height, | |
args.state.brick_width, | |
args.state.brick_height, | |
'sprites/square/green.png' | |
] | |
end | |
end | |
end | |
def render args | |
args.outputs.sprites << [ | |
args.state.ball_x, | |
args.state.ball_y, | |
args.state.ball_size, | |
args.state.ball_size, | |
'sprites/square/red.png' | |
] | |
args.outputs.sprites << [ | |
args.state.bat_x, | |
args.state.bat_y, | |
args.state.bat_w, | |
args.state.bat_h, | |
'sprites/square/blue.png' | |
] | |
args.outputs.sprites << args.state.bricks | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment