(Siirretty kilpailun keskustelusta.)
Tein yksinkertaisen kirjaston pelin ajoitusta ja pelitilan hallintaa varten 8th ohjelmointikielelle. Käytän kiinteätä aika-askelta pelin päivitystä varten ja tarvittaessa jätän piirtämättä. Jokaisella pelitilalla on update ja draw sanat, mitkä on tallennettu taulukkoihin pelitilaa vastaavan indeksin kohdalle. Ohjelma ajaa tapahtuma looppia ja se taas ajaa peliä, eli koko hoito toimii yksinkertaisena tilakoneena.
Tein esimerkkipelin kirjaston käytöstä. Räjähdykset pitäisi varmaan tuohon kyllä lisätä!
\
\ Minimal game timing and state manager library for the 8th programmimg language.
\
ns: game
0.01 var, dt
0 var, game-state
var frame-time
var accumulator
var new-time
var current-time
var update-events
var draw-events
: secs
d:ticks d:ticks/sec n:/ ;
: dt@ \ -- n
dt @ ;
: dt! \ n --
dt ! ;
: state@ \ -- n
game-state @ ;
: state! \ n --
game-state ! ;
: update@
update-events @ ;
: update! \ a --
update-events ! ;
: draw@
draw-events @ ;
: draw! \ a --
draw-events ! ;
: vsync \ T --
nk:vsync ;
: init \ vsync dt game-state update-events draw-events --
draw-events !
update-events !
game-state !
dt !
nk:vsync
accumulator off
secs current-time ! ;
\ Delta timing routine.
\ Uses fixed time step for update.
\ Skips render frames if needed to keep up with the pace.
: event-loop
secs new-time !
new-time @ current-time @ n:- frame-time !
new-time @ current-time !
frame-time @ accumulator n:+!
repeat
accumulator @ dt @ n:> not if
break
else
update-events @ game-state @
caseof
accumulator @ dt @ n:- accumulator !
then
again
draw-events @ game-state @
caseof ;Alla simppeli esimerkkiohjelma.
needs nk/gui
needs math/trigd
needs games/state
"data/fly.png" app:asset img:new var, fly-img
var fly-sprite
var fly-width
var fly-height
var blood-sprite
var flydead-sprite
800 constant WIDTH
600 constant HEIGHT
7 constant BLOOD-IMAGES
6 constant FLY-DEAD-IMAGES
10 constant START-FLIES
5 constant MORE-FLIES
5 constant MORE-FLIES-DELAY
0.01 constant DT
true constant VWAIT
\ Game states
0 constant MAIN
a:new var, fly-list
a:new var, blood-list
var delay
: FLY-SPRITE-WIDTH
0.125 nk:win-wide n:* n:int ;
: FLY-SPRITE-HEIGHT
0.055 nk:win-high n:* n:int ;
: BLOOD-SPRITE-WIDTH
0.1 nk:win-wide n:* n:int ;
: BLOOD-SPRITE-HEIGHT
0.1 nk:win-high n:* n:int ;
: rand \ x -- rand(x-1)
>r rand-pcg n:abs r> n:mod ;
: circleptx \ x r deg -- x
n:cosd n:* n:+ ;
: circlepty \ y r deg -- y
n:sind n:* n:- ;
: scale-speed \ speed -- scaled-speed
nk:win-wide nk:win-high n:max n:* WIDTH n:/ ;
: add-fly-init \ -- [ x, y, dx, dy, frame, killed ]
fly-list @
WIDTH rand \ x
HEIGHT rand \ y
360 rand \ angle
4 rand \ speed
12 rand \ frame
false \ killed
0 \ anim-delay
0 \ move-delay
8 a:close
a:push drop ;
: add-fly \ -- [ x, y, dx, dy, frame, killed ]
fly-list @
nk:win-wide rand \ x
30 rand \ y
360 rand \ angle
4 rand \ speed
12 rand \ frame
false \ killed
0 \ anim-delay
0 \ move-delay
8 a:close
a:push drop ;
: add-blood \ [ x, y ] -- [ x, y, frame1, frame2 ]
blood-list @
swap
a:open
6 rand
7 rand
4 a:close
a:push drop ;
: draw
blood-list @
( \ Draw dead fly
0 a:@ FLY-SPRITE-WIDTH 2 n:/ n:- \ x
swap
1 a:@ FLY-SPRITE-HEIGHT 2 n:/ n:- \ y
swap >r
FLY-SPRITE-WIDTH FLY-SPRITE-HEIGHT 4 a:close \ [ x, y, w, h ]
flydead-sprite @ r> 2 a:@ swap >r a:@ nip
"white" nk:draw-image
\ Draw blood splatter
r>
0 a:@ FLY-SPRITE-WIDTH 2 n:/ n:- \ x
swap
1 a:@ FLY-SPRITE-HEIGHT 2 n:/ n:- \ y
swap >r
BLOOD-SPRITE-WIDTH BLOOD-SPRITE-HEIGHT 4 a:close \ [ x, y, w, h ]
blood-sprite @ r> 2 a:@ nip a:@ nip
"white" nk:draw-image
) a:each! drop
\ Draw alive flies
fly-list @
( 0 a:@ FLY-SPRITE-WIDTH 2 n:/ n:- \ x
swap
1 a:@ FLY-SPRITE-HEIGHT 2 n:/ n:- \ y
swap >r
FLY-SPRITE-WIDTH FLY-SPRITE-HEIGHT 4 a:close \ [ x, y, w, h ]
fly-sprite @ r> 4 a:@ nip a:@ nip
"white" nk:draw-image
) a:each! drop ;
: move-flies
fly-list @
(
0 a:@ swap 3 a:@ scale-speed swap 2 a:@ swap 0 >r >r circleptx \ x
r> r> rot a:!
1 a:@ swap 3 a:@ scale-speed swap 2 a:@ swap 1 >r >r circlepty \ y
r> r> rot a:!
\ wrap
0 a:@ nk:win-wide n:mod 0 swap a:! \ x
1 a:@ nk:win-high n:mod 1 swap a:! \ y
\ anim delay
6 a:@ game:secs n:< if
4 a:@ n:1+ 12 n:mod 4 swap a:!
6 game:secs 0.1 n:+ a:!
then
\ move delay
7 a:@ game:secs n:< if
2 360 rand 640 n:- a:!
3 5 rand a:!
7 game:secs 0.05 n:+ a:!
then
\ Check mouse clicks for flies
0 a:@ FLY-SPRITE-WIDTH 2 n:/ n:- swap 1 a:@ FLY-SPRITE-HEIGHT 2 n:/ n:- swap >r FLY-SPRITE-WIDTH FLY-SPRITE-HEIGHT 4 a:close dup nk:BUTTON_LEFT swap true nk:clicked? if
r@ 5 true a:! drop
nk:rect-center nip add-blood
else
drop
then
rdrop
) a:each!
\ Remove dead flies
( 5 a:@ not nip ) a:filter fly-list !
\ Time to add more flies?
game:secs delay @ n:> if
fly-list @ a:len nip START-FLIES n:< if
' add-fly MORE-FLIES times
then
game:secs MORE-FLIES-DELAY n:+ delay !
then ;
: init
fly-img @ img:size
fly-height ! 12 n:/ n:int fly-width !
drop
a:new
( fly-img @ swap fly-width @ n:* n:int 0 fly-width @ fly-height @ img:crop a:push ) 0 11 loop
fly-sprite !
a:new
( "data/b%d.png" s:strfmt app:asset img:new a:push ) 0 BLOOD-IMAGES n:1- loop
blood-sprite !
a:new
( "data/fd%d.png" s:strfmt app:asset img:new a:push ) 0 FLY-DEAD-IMAGES n:1- loop
flydead-sprite !
' add-fly-init START-FLIES times
game:secs MORE-FLIES-DELAY n:+ delay ! ;
: new-win
{
name: "main",
wide: @WIDTH,
high: @HEIGHT,
bg: "palegreen",
fonts: {
font1: ` 24 font:system ` ,
font2: ["tahoma:24", "arial:24", "ubuntu:24"]
},
font: "font1",
title: "8th Bug Elimination Tool!"
}
\ invoke nk:win to create the outermost window from the JSON definition:
nk:win ;
: main-render
{
bg: "white",
font: "font2",
padding: [0,0],
flags: [ @nk:WINDOW_NO_SCROLLBAR ]
}
nk:begin
game:event-loop
nk:end ;
: app:main
init
new-win
VWAIT DT MAIN [ ' move-flies ] [ ' draw ] game:init
' main-render 0 nk:render-loop ;Aihe on jo aika vanha, joten et voi enää vastata siihen.