Challenge:
Winner?:
No
Code Snippet:
set display mode 320,240,32 sync on sync rate 40 backdrop on color backdrop 0 hide mouse randomize timer() paddle_X = screen width()/2 : `X position of paddle (start centered of screen) paddle_Width = 20 : `paddle's half width (if set to 20, total paddle width would be 40) paddle_thickness = 5 : `thickness of paddle #constant INTERFACE_BORDER = 276 : `x-intercept boundary marking off interface from game area #constant MAX_ANGLE = 80 : `max angle that paddle can reflect ball off type vector2d x as float y as float endtype type toy position as vector2d oldPosition as vector2d direction as vector2d velocity as float radius as float endtype ball as toy ball.position.x = 50 ball.position.y = 200 ball.direction.x = 0.5 ball.direction.y = -0.5 ball.velocity = 4 ball.radius = 3 type triangle x1 as float y1 as float x2 as float y2 as float x3 as float y3 as float alive as integer endtype type brick a as triangle b as triangle endtype dim map(11,5) as brick for x = 0 to 10 for y = 1 to 5 map(x,y).a.x1 = x*25 map(x,y).a.y1 = y*15 map(x,y).a.x2 = x*25 map(x,y).a.y2 = (y+1)*15 map(x,y).a.x3 = (x+1)*25 map(x,y).a.y3 = (y+1)*15 map(x,y).a.alive = 1 map(x,y).b.x1 = x*25 map(x,y).b.y1 = y*15 map(x,y).b.x2 = (x+1)*25 map(x,y).b.y2 = y*15 map(x,y).b.x3 = (x+1)*25 map(x,y).b.y3 = (y+1)*15 map(x,y).b.alive = 1 next y next x rem temp variable tri as triangle null = make vector2(1) : `ball direction vector and reflection vector(after calculation) null = make vector2(2) : `line normal REPEAT rem record previous position ball.oldPosition.x = ball.position.x ball.oldPosition.y = ball.position.y gosub _handle_controls for x = 0 to 10 for y = 1 to 5 if map(x,y).a.alive = 1 tri = map(x,y).a draw_triangle(tri.x1,tri.y1,tri.x2,tri.y2,tri.x3,tri.y3) endif if map(x,y).b.alive = 1 tri = map(x,y).b draw_triangle(tri.x1,tri.y1,tri.x2,tri.y2,tri.x3,tri.y3) endif next y next x ball.position.x = ball.position.x + ball.direction.x*ball.velocity ball.position.y = ball.position.y + ball.direction.y*ball.velocity gosub _handle_ball_collisions circle ball.position.x, ball.position.y,ball.radius draw_paddle(paddle_X,paddle_Width) draw_interface() text 1,1,str$(screen fps()) sync UNTIL SPACEKEY() rem handle paddle movement with mouse and handle paddle's boundaries _handle_controls: paddle_X = paddle_x + mousemovex()/3 if paddle_X-paddle_Width < 0 then paddle_X = paddle_Width if paddle_X+paddle_Width > interface_border then paddle_X = interface_border-paddle_Width return rem handles ball collision with paddle, play area boundaries, and brick objects _handle_ball_collisions: rem if ball hits paddle if ball.position.y >= screen height()-(paddle_thickness + ball.radius) if ball.position.x >= paddle_X - paddle_Width AND ball.position.x <= paddle_X + paddle_Width angle# = 270 + ((ball.position.x-paddle_X) * MAX_ANGLE)/paddle_Width ball.direction.x = cos(angle#) ball.direction.y = sin(angle#) endif endif rem walls if ball.position.x <= ball.radius ball.position.x = ball.radius ball.direction.x = ball.direction.x*-1 endif if ball.position.x >= INTERFACE_BORDER-ball.radius ball.position.x = INTERFACE_BORDER-ball.radius ball.direction.x = ball.direction.x*-1 endif rem ceiling if ball.position.y <= ball.radius ball.position.y = ball.radius ball.direction.y = ball.direction.y*-1 endif rem if ball drops below paddle if ball.position.y > screen height() ball.position.y = screen height()-1 ball.direction.y = ball.direction.y*-1 endif rem brick collision for x = 0 to 10 for y = 1 to 5 if map(x,y).a.alive = 1 tri = map(x,y).a if triangle_collide#(ball,tri) > 0 map(x,y).a.alive = 0 calculate_reflection() endif endif if map(x,y).b.alive = 1 tri = map(x,y).b if triangle_collide#(ball,tri) > 0 map(x,y).b.alive = 0 calculate_reflection() endif endif next y next x return rem calculates ball's reflection from brick(triangle) rem assumes reflection surface vector was set and normalized (vector 2) function calculate_reflection() set vector2 1, ball.direction.x, ball.direction.y dp# = dot product vector2(1,2)*2 multiply vector2 2,dp# subtract vector2 1, 1, 2 normalize vector2 1, 1 ball.direction.x = x vector2(1) ball.direction.y = y vector2(1) endfunction rem returns a time value of set [0,1] of closest intersection between ball's velocity vector and triangle's sides rem if intersection happens, calculates normal of reflection surface and stores in vector 2 rem returns -1 if no sides were hit function triangle_collide#(b as toy, t as triangle) a# = _line_intersect(b.oldPosition.x,b.oldPosition.y,b.position.x,b.position.y,t.x1,t.y1,t.x2,t.y2) b# = _line_intersect(b.oldPosition.x,b.oldPosition.y,b.position.x,b.position.y,t.x1,t.y1,t.x3,t.y3) c# = _line_intersect(b.oldPosition.x,b.oldPosition.y,b.position.x,b.position.y,t.x2,t.y2,t.x3,t.y3) rem if a# is first intersection if a# < 1 if a# < b# and a# < c# rem set normal of reflection surface set vector2 2, t.y2-t.y1,-(t.x2-t.x1) normalize vector2 2,2 exitfunction a# endif else rem if b# is first intersection if b# < 1 if b# < a# and b# < c# rem set normal of reflection surface set vector2 2, t.y1-t.y3,-(t.x1-t.x3) normalize vector2 2,2 exitfunction b# endif else rem if c# is first intersection if c# < 1 if c# < a# and c# < b# rem set normal of reflection surface set vector2 2, t.y3-t.y2,-(t.x3-t.x2) normalize vector2 2,2 exitfunction c# endif endif endif endif endfunction -1.0 rem draw the paddle at 'X' with a half-length of 'midLength' function draw_paddle(x,midLength) box x-midLength,screen height()-5,x+midLength,screen height() endfunction rem draws the interface on the right side of screen function draw_interface() line INTERFACE_BORDER,0,INTERFACE_BORDER,screen height() endfunction rem draws a triangle function draw_triangle(ax,ay,bx,by,cx,cy) line ax,ay,bx,by line ax,ay,cx,cy line bx,by,cx,cy endfunction REM returns 2 if the two line segments dont intersect, between [0,1] if they do function _line_intersect(ax#,ay#,bx#,by#,cx#,cy#,dx#,dy#) d# = (dy# - cy#)*(bx# - ax#) - (dx# - cx#)*(by# - ay#) Ua# = ((dx# - cx#)*(ay# - cy#) - (dy# - cy#)*(ax# - cx#)) / d# Ub# = ((bx# - ax#)*(ay# - cy#) - (by# - ay#)*(ax# - cx#)) / d# _intersect# = 2 if Ua# > 0 and Ua# < 1 and Ub# > 0 and Ub# < 1 then _intersect# = Ua# endfunction _intersect#