randomize timer() REM VARIABLES depth# = 498 screenwidth# = 800 screenheight# = 600 width# = (depth#/100)*160 height# = (depth#/100)*120 even# = screenwidth#/1.6 prop# = depth#/even# #constant obj_paddle = 1 #constant obj_ball = 2 paddle_X# = screenwidth#/2 : `X position of paddle (start centered of screen) paddle_Width = 40 : `paddle's half width (if set to 20, total paddle width would be 40) paddle_thickness = 5 : `thickness of paddle #constant INTERFACE_BORDER = 800 : `x-intercept boundary marking off interface from game area #constant MAX_ANGLE = 75 : `max angle that paddle can reflect ball off #constant BRICK_WIDTH = 60 #constant BRICK_HEIGHT = 40 death = 1 score = 0 lives = 4 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 = paddle_thickness + ball.radius ball.direction.x = 0 ball.direction.y = 1 ball.velocity = 4 ball.radius = 10 type fadeObject object as integer fade as integer endtype dim fadeObjectOut(0) as fadeObject fade_count = 0 dim killObject(0) 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 rem temp variable tri as triangle null = make vector2(1) : `ball direction vector and reflection vector(after calculation) null = make vector2(2) : `line normal REM SETUP set display mode screenwidth#,screenheight#,32 sync on sync rate 60 autocam off hide mouse REM CREATE IMAGE for x=1 to 20 for y=1 to 20 c = rnd(255) dot rnd(128), rnd(128), rgb(c,c,c) next y next x get image 1, 1,1,128,128 REM CREATE PADDLE make object plain obj_paddle,paddle_Width*2,paddle_thickness color object obj_paddle, rgb(255,0,0) REM CREATE BALL make object sphere obj_ball, ball.radius color object obj_ball, rgb(200,128,0) REM CREATE BACKGROUND make object plain 3, screenwidth#+4, screenheight#+4 position object 3, screenwidth#/2, screenheight#/2,500 texture object 3, 1 color as dword obj = 3 REM Create triangles for x = 1 to 11 for y = 1 to 5 color = rgb(rnd(255),rnd(255),rnd(255)) inc obj make object triangle obj,0,0,0,0,-BRICK_HEIGHT,0,BRICK_WIDTH,-BRICK_HEIGHT,0 position object obj, x*BRICK_WIDTH,screenheight#-y*BRICK_HEIGHT,depth# color object obj, color map(x,y).a.x1 = x*BRICK_WIDTH map(x,y).a.y1 = screenheight#-y*BRICK_HEIGHT map(x,y).a.x2 = x*BRICK_WIDTH map(x,y).a.y2 = screenheight#-(y+1)*BRICK_HEIGHT map(x,y).a.x3 = (x+1)*BRICK_WIDTH map(x,y).a.y3 = screenheight#-(y+1)*BRICK_HEIGHT map(x,y).a.alive = obj inc obj make object triangle obj,0,0,0,BRICK_WIDTH,0,0,BRICK_WIDTH,-BRICK_HEIGHT,0 position object obj, x*BRICK_WIDTH,screenheight#-y*BRICK_HEIGHT,depth# color object obj, color map(x,y).b.x1 = x*BRICK_WIDTH map(x,y).b.y1 = screenheight#-y*BRICK_HEIGHT map(x,y).b.x2 = (x+1)*BRICK_WIDTH map(x,y).b.y2 = screenheight#-y*BRICK_HEIGHT map(x,y).b.x3 = (x+1)*BRICK_WIDTH map(x,y).b.y3 = screenheight#-(y+1)*BRICK_HEIGHT map(x,y).b.alive = obj next y next x REM STUFF position camera width#/2,height#/2,0 speedup_stamp = timer() REM ============================== MAIN LOOP ================================= DO rem record previous position ball.oldPosition.x = ball.position.x ball.oldPosition.y = ball.position.y gosub _handle_controls if death = 0 rem get new position of ball 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 else ball.position.x = paddle_X if mouseclick() = 1 then death = 0 endif if speedup_stamp+2000 < timer() ball.velocity = ball.velocity + 0.2 speedup_stamp = timer() endif position object obj_ball, ball.position.x, ball.position.y,depth# position object obj_paddle, paddle_X,5,498 gosub _handle_fading_objects center text screenwidth#/2,1,"Score: "+str$(score) text screenwidth#-100,1,"Lives: "+str$(lives) text 1,1,"FPS: "+str$(screen fps()) text 1,10,"Speed: "+str$(ball.velocity) fastsync LOOP REM ========================= END MAIN LOOP =============================== 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 <= (paddle_thickness + ball.radius) if ball.position.x >= paddle_X - paddle_Width AND ball.position.x <= paddle_X + paddle_Width angle# = 90-((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 >= screenheight#-ball.radius ball.position.y = screenheight#-ball.radius ball.direction.y = ball.direction.y*-1 endif rem if ball drops below paddle if ball.position.y < 0 ball.position.y = paddle_thickness + ball.radius ball.direction.y = 1 ball.direction.x = 0 ball.velocity = 4 death = 1 dec lives, 1 endif rem brick collision for x = 1 to 11 for y = 1 to 5 if map(x,y).a.alive > 0 tri = map(x,y).a if triangle_collide#(ball,tri) > 0 `hide object map(x,y).a.alive array insert at top fadeObjectOut(0) fadeObjectOut(0).object = map(x,y).a.alive fadeObjectOut(0).fade = 100 inc fade_count, 1 inc score, 10 map(x,y).a.alive = 0 if map(x,y).a.alive = 0 and map(x,y).b.alive = 0 then inc score, 5 calculate_reflection() endif endif if map(x,y).b.alive > 0 tri = map(x,y).b if triangle_collide#(ball,tri) > 0 `hide object map(x,y).b.alive array insert at top fadeObjectOut(0) fadeObjectOut(0).object = map(x,y).b.alive fadeObjectOut(0).fade = 100 inc fade_count, 1 inc score, 10 map(x,y).b.alive = 0 if map(x,y).a.alive = 0 and map(x,y).b.alive = 0 then inc score, 5 calculate_reflection() endif endif next y next x return rem does some stuff, i don't feel like documenting right now _handle_fading_objects: for i = 0 to fade_count obj = fadeObjectOut(i).object fadeObjectOut(i).fade = fadeObjectOut(i).fade - 2 if fadeObjectOut(i).fade >= 0 fade object obj, fadeObjectOut(i).fade else array insert at top killObject() killObject(0) = obj `hide object obj `array delete element fadeObjectOut(i) `dec fade_count, 1 endif next i for j = 0 to array count(killObject()) for i = 0 to fade_count if fadeObjectOut(i).object = killObject(j) `hide object killObject(j) array delete element fadeObjectOut(i) dec fade_count, 1 endif next i next j empty array killObject() 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 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#