eumandy/eugtk/examples/test188.ex

191 lines
5.2 KiB
Elixir
Raw Permalink Normal View History

2016-11-25 00:33:18 -07:00
---------------------------------------------------------------------------
--# 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