191 lines
5.2 KiB
Elixir
191 lines
5.2 KiB
Elixir
|
|
||
|
---------------------------------------------------------------------------
|
||
|
--# 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
|
||
|
|