--------------------------------------------------------------------------- --# Friendly aliens drop cows from a ufo. -- Being friendly, the aliens provide cows with parachutes. -- Cows do what cows do, once they reach the ground. -- -- On my computer, I can get about 140 cows before the CPU load nears 100% -- It's interesting to run this and a system monitor program -- on a multi-processor pc, and note how well the load is shared. -- Ideally, this could be re-written to use tasks, one per cow. --------------------------------------------------------------------------- include GtkEngine.e include std/rand.e sequence cows = {} atom cowspeed = 150 integer state = 0 enum X,Y enum DirectionRight,DirectionLeft enum Ptr, Position, Direction, Facing, Eating constant Xrange = {2,310}, Yrange = {1,255} constant BORDER_LEFT = 2, BORDER_RIGHT = 300, BORDER_TOP = 75, BORDER_BOTTOM = 220 constant win = create(GtkWindow,{ {"resizable",FALSE}, {"position",GTK_WIN_POS_CENTER_ALWAYS}, {"connect","destroy",_("Bailout")}}) constant evbx = create(GtkEventBox,{ {"background","#ffeeee"}, {"connect","button-press-event",_("AddACow")}}) add(win,evbx) constant panel = create(GtkBox,VERTICAL) add(evbx,panel) constant layout = create(GtkLayout,{ {"tooltip markup","Click to add a cow"}}) pack(panel,layout,TRUE,TRUE) constant pix = create(GdkPixbuf,"thumbnails/nature_small.jpg") constant img = create(GtkImage,pix) set(layout,"put",img,-2,-2) sequence cow = repeat(0,10) -- fake animation, better to do it with gifs? cow[1] = create(GdkPixbuf,"thumbnails/cowbell.png",20,20) cow[2] = create(GdkPixbuf,"thumbnails/cowbell2.png",20,20) cow[3] = create(GdkPixbuf,"thumbnails/coweat.png",20,20) cow[4] = create(GdkPixbuf,"thumbnails/coweat2.png",20,20) cow[5] = create(GdkPixbuf,"thumbnails/coweat3.png",20,20) cow[6] = create(GdkPixbuf,"thumbnails/coweat4.png",20,20) cow[7] = create(GdkPixbuf,"thumbnails/coweat5.png",20,20) cow[8] = create(GdkPixbuf,"thumbnails/coweat6.png",20,20) cow[9] = create(GdkPixbuf,"thumbnails/coweat7.png",20,20) cow[10]= create(GdkPixbuf,"thumbnails/cowbell3.png",20,20) atom timer = 0 atom flasher = create(GTimeout,250,_("flash")) show_all(win) set(win,"size request",320,240) constant ufo1 = create(GdkPixbuf,"thumbnails/ufo1.png",40,0,1) constant ufo2 = create(GdkPixbuf,"thumbnails/ufo2.png",40,0,1) set(win,"cursor",ufo1) Info(win,, "Bovine Invaders \nfrom Outer Space", "Move the UFO around,\n click the left mouse button!") main() ---------------------------- function flash() ---------------------------- state = not(state) if state then set(win,"cursor",ufo1) else set(win,"cursor",ufo2) end if return 1 end function ---------------------------- function Bailout() ---------------------------- cows = {} timer = 0 Quit() return 1 end function ---------------------------- function AddACow() ---------------------------- object location = get(win,"pointer") location[X] = ensure_in_range(location[X],Xrange) location[Y] = ensure_in_range(location[Y],Yrange) +5 cows = append(cows,{Ptr,Position,Direction,Facing, Eating}) cows[$][Ptr] = create(GtkImage) cows[$][Position] = location cows[$][Direction] = {rand_range(-1,+1),rand_range(-1,+1)} cows[$][Facing] = rand(2) cows[$][Eating] = rand(2)=1 integer x = ensure_in_range((cows[$][Direction][X]+1) + cows[$][Facing]+cows[$][Eating],{1,4}) set(cows[$][Ptr],"from pixbuf",cow[x]) set(layout,"put",cows[$][Ptr],location[X],location[Y]) show(cows[$][Ptr]) set(win,"title",format("[] cows browsing",length(cows))) timer = 0 cowspeed -= 1 -- adjust timer to trigger faster the more cows; timer = create(GTimeout,cowspeed,call_back(routine_id("MoveACow"))) return 0 end function ------------------------------ function MoveACow() ------------------------------ integer n,r, eating, chance if length(cows) = 0 then -- no cows? forgettaboutit! return 1 end if n = rand(length(cows)) r = rand(20) switch r do -- add some random actions; case 2 then cows[n][Direction][X] = 1 case 3 then cows[n][Direction][Y] = 1 case 4 then cows[n][Direction][X] = -1 case 5 then cows[n][Direction][Y] = -1 case 6,8,12 then cows[n][Eating] = 2 case 9,10,11 then cows[n][Eating] = 0 end switch if cows[n][Position][Y] > 70 then -- cow is on ground; set(cows[n][Ptr],"from pixbuf",cow[cows[n][Facing]+cows[n][Eating]]) elsif cows[n][Position][Y] > 40 then -- cow nearing ground - deploy chute set(cows[n][Ptr],"from pixbuf",cow[10]) cows[n][Position][Y] += 2 else -- bailing out. set(cows[n][Ptr],"from pixbuf",cow[rand(3)+6]) cows[n][Position][Y] += 4 end if set(layout,"move",cows[n][Ptr],cows[n][Position][X],cows[n][Position][Y]) -- turn cow n when it reaches a border; if cows[n][Position][X] < BORDER_LEFT then cows[n][Direction][X] = +1 cows[n][Facing] = DirectionLeft end if if cows[n][Position][X] > BORDER_RIGHT then cows[n][Direction][X] = -1 cows[n][Facing] = DirectionRight end if if cows[n][Position][Y] < BORDER_TOP then cows[n][Direction][Y] = +1 cows[n][Eating] = 2 end if if cows[n][Position][Y] > BORDER_BOTTOM then cows[n][Direction][Y] = -1 cows[n][Eating] = 0 end if cows[n][Position] += cows[n][Direction] return 1 end function