Pastey Bouncing balls
- Posted by irv Aug 17, 2019
include GtkEngine.e include GtkCairo.e constant fps = 60 integer frameCounter = 0 enum X,Y,RAD,XSPD,YSPD,COLOR object balls = {{10,20,20,6,4,"red"},{30,30,20,5,4,"green"}} constant rad360 = 6.283185307179586 -- full circle in radians; constant disp = create(GdkDisplay), scrn = get(disp,"default screen"), win = create(GtkWindow,"title=Bouncing Ball,size=800x450,border=10,$destroy=Quit"), pan = create(GtkBox,"orientation=vertical,spacing=10"), screen = create(GtkDrawingArea,"background=white"), lbl = create(GtkLabel), box = create(GtkButtonBox), btn1 = create(GtkButton,"gtk-quit","Quit"), btn2 = create(GtkToggleButton,"Pause","Update"), tic = create(GTimeout,1000/fps,call_back(routine_id("Update"))), tok = create(GTimeout,1000,call_back(routine_id("ResetCounter"))) add(win,pan) pack(pan,screen,1,1) add(box,{btn1,lbl,btn2}) pack(pan,-box) show_all(win) integer screen_width, screen_height {screen_width,screen_height} = get(win,"size") -- allow for window borders; for i = 1 to length(balls) do balls[i][X] = rand(screen_width) / 2 balls[i][Y] = rand(screen_height) / 2 end for main() --------------------------------- global function ResetCounter() -- reset value for fps display; ------------------------------- set(lbl,"text",sprintf("%d fps",frameCounter)) frameCounter = 0 return 1 end function ---------------------------------------------- function CollideCircles(object A, object B) -- ---------------------------------------------- atom x = A[X] - B[X] atom y = A[Y] - B[Y] atom centerDistanceSq = x * x + y * y -- squared distance atom radius = A[RAD] + B[RAD] atom radiusSq = radius * radius return centerDistanceSq <= radiusSq end function ------------------------------------------- global function Update(atom ctl, atom data) -- ---------------------------------------------- if get(btn2,"active") then -- pause button is depressed; return 1 end if {screen_width,screen_height} = get(win,"size") - {20,60} -- in case changed; for i = 1 to length(balls) do balls[i][X] += balls[i][XSPD] balls[i][Y] += balls[i][YSPD] if (balls[i][X] <= balls[i][RAD]) or (balls[i][X] >= screen_width - balls[i][RAD]) then balls[i][XSPD] *= -1 end if if (balls[i][Y] <= balls[i][RAD]) or (balls[i][Y] >= screen_height - balls[i][RAD]) then balls[i][YSPD] *= -1 end if end for if CollideCircles(balls[1],balls[2]) then balls[1][XSPD] *= -1 balls[1][YSPD] *= -1 balls[2][XSPD] *= -1 balls[2][YSPD] *= -1 end if frameCounter += 1 atom cr = create(GdkCairo_t,get(screen,"window")) set(cr,{ -- clear screen; {"source rgba",255,255,255,255}, {"operator",CAIRO_OPERATOR_SOURCE}, {"paint"}}) for i = 1 to length(balls) do set(cr,{ -- draw ball A {"color",balls[i][COLOR]}, {"arc", balls[i][X], balls[i][Y], balls[i][RAD], 0, rad360}, -- full circle; {"fill"}}) end for set(cr,"destroy") return 1 end function


