Kirjoittelin yhden pekkaspäivän aikana kirjaston, jonka avulla olisi tarkoitus kirjoitella tasohyppely. Tällä hetkellä isoin osa toiminnalisuutta on toteutettu, mutta en ole koodia vielä yrittänyt optimoida.
Olen testannut toimintaa Raspberry PI 4B:llä ja toimii kohtuullisen kivasti. Laitan kirjaston ja koodin saataville tasohyppely demon kanssa kun saan pari juttua vielä toteutettua.
Olisi kiva, jos joku uskaltautuisi kokeilemaan miten alla oleva testiohjelma toimii pöytäkoneella. Paketissa 64-bittiset binäärit useimmille käyttöjärjestelmille. Linux:in päällä toimii myös ilman X-ikkuna tukea ja itse ajaisin niin.
Onko mukana myös FPS rajoitin? Jos ei niin ei s ovellu lauta peleihin? :)
win64: siinä se vieritti ruutua mäpin reunasta reunaan. Näytti toimivan OK? Oletko hankkinut tasohyppelylisenssin viestintävirastolta?
vesikuusi kirjoitti:
win64: siinä se vieritti ruutua mäpin reunasta reunaan. Näytti toimivan OK? Oletko hankkinut tasohyppelylisenssin viestintävirastolta?
Viitsitkö vielä kokeilla tätä
Tuo on yksinkertainen kirjastolla tehty tasohyppelyn runko. Kiinnostaa miten pyörii oikealla raudalla.
Pitänee varmaan kysyä viestintäviraston kantakin asiaan... ;)
Alla esimerkkinä Super Mario tyylisen tasohyppelyn minimi toteutus. Tältä se siis näyttää.
needs nk/gui
needs nk/keyboard
needs games/state
needs games/tilemap
22 font:system font:new "font1" font:atlas! drop
800 constant SCREEN-WIDTH
600 constant SCREEN-HEIGHT
640 constant VIEWPORT-WIDTH
480 constant VIEWPORT-HEIGHT
SCREEN-WIDTH 2 n:/ VIEWPORT-WIDTH 2 n:/ n:- constant VIEWPORT-X
SCREEN-HEIGHT 2 n:/ VIEWPORT-HEIGHT 2 n:/ n:- constant VIEWPORT-Y
32 constant TILE-WIDTH
32 constant TILE-HEIGHT
64 constant SPRITE-WIDTH
64 constant SPRITE-HEIGHT
SPRITE-WIDTH 2 n:* constant 2X-SPRITE-WIDTH
true constant WAIT-VSYNC
1 60 n:/ constant DT
\ Game states.
0 constant MAIN
{
bg: "black",
padding: [0,0],
flags: [ @nk:WINDOW_NO_SCROLLBAR ]
} constant main-render
"data/mariol.png" img:new constant mariol-img
"data/marior.png" img:new constant marior-img
"data/tiles.png" img:new TILE-WIDTH TILE-HEIGHT "data/level.map" map:load constant level
"data/tiles.png" img:new TILE-WIDTH TILE-HEIGHT "data/collision.map" map:load constant collision
VIEWPORT-WIDTH VIEWPORT-HEIGHT VIEWPORT-X VIEWPORT-Y viewport:new constant vp
level map:rect@ nip 2 a:@ nip constant MAP-WIDTH
0.5 constant GRAVITY
var x
var y
var dx
var dy
var scrollx
var jumping
var scrolling
var flipx
var delay
var frame
[@marior-img, @mariol-img] var, image
var bottom
var top
var left
var right
var time
: init
\ Initial map position
0 0 2 a:close dup
level swap map:pos! drop
collision swap map:pos! drop
\ Init player
160 x !
224 y !
0 dx !
0 dy !
0 frame !
5 dup delay ! time !
false jumping !
0 scrollx !
false scrolling !
0 flipx !
21 63 2 a:close 42 63 2 a:close 2 a:close bottom !
21 0 2 a:close 42 0 2 a:close 2 a:close top !
1 17 2 a:close 7 21 2 a:close 2 a:close left !
56 21 2 a:close 63 21 2 a:close 2 a:close right ! ;
: animate-player
-1 time n:+!
time @ 0 n:> not if
jumping @ if
2 frame !
else
dx @ 0 n:= not scrolling @ or if
1 frame n:+!
frame @ 2 n:mod frame !
else
0 frame !
then
delay @ time !
then
then ;
: draw-player
x @ y @ SPRITE-WIDTH SPRITE-HEIGHT 4 a:close vp viewport:pos@ nip tilemap:rect-ofs+
image @ flipx @ a:@ nip
"white"
0 frame @ SPRITE-HEIGHT n:* SPRITE-WIDTH SPRITE-HEIGHT 4 a:close
nk:draw-sub-image ;
: tile-collision
\ Sprite top to the top of viewport
y @ 0 n:< if
0 y !
GRAVITY dy !
then
\ Platforms
dy @ 0 n:> if
collision vp viewport:pos@
x @ y @ 2 a:close
' n:+ a:2map
bottom @ flipx @ a:@ nip
' n:+ a:2map
tilemap:color
repeat
xff7f00ff n:= not if
break
else
-0.5 y n:+!
collision vp viewport:pos@
x @ y @ 2 a:close
' n:+ a:2map
bottom @ flipx @ a:@ nip
' n:+ a:2map
tilemap:color
then
again
collision vp viewport:pos@
x @ y @ 2 a:close
' n:+ a:2map
bottom @ flipx @ a:@ nip
' n:+ a:2map
1 a:@ n:1+ 1 swap a:!
tilemap:color xff7f00ff n:= if
0 dy !
false jumping !
then
then
\ Bottom of sprite
collision vp viewport:pos@
x @ y @ 2 a:close
' n:+ a:2map
bottom @ flipx @ a:@ nip
' n:+ a:2map
tilemap:color
repeat
xffff00ff n:= not if
break
else
-0.5 y n:+!
collision vp viewport:pos@
x @ y @ 2 a:close
' n:+ a:2map
bottom @ flipx @ a:@ nip
' n:+ a:2map
tilemap:color
then
again
collision vp viewport:pos@
x @ y @ 2 a:close
' n:+ a:2map
bottom @ flipx @ a:@ nip
' n:+ a:2map
1 a:@ n:1+ 1 swap a:!
tilemap:color xffff00ff n:= if
0 dy !
false jumping !
then
\ Right side of sprite
collision vp viewport:pos@
x @ y @ 2 a:close
' n:+ a:2map
right @ flipx @ a:@ nip
' n:+ a:2map
tilemap:color
repeat
xffff00ff n:= not if
break
else
-0.5 x n:+!
collision vp viewport:pos@
x @ y @ 2 a:close
' n:+ a:2map
right @ flipx @ a:@ nip
' n:+ a:2map
tilemap:color
then
again
\ Left side of sprite
collision vp viewport:pos@
x @ y @ 2 a:close
' n:+ a:2map
left @ flipx @ a:@ nip
' n:+ a:2map
tilemap:color
repeat
xffff00ff n:= not if
break
else
0.5 x n:+!
collision vp viewport:pos@
x @ y @ 2 a:close
' n:+ a:2map
left @ flipx @ a:@ nip
' n:+ a:2map
tilemap:color
then
again ;
: new-win
{
name: "main",
title: "Testing...",
wide: @SCREEN-WIDTH,
high: @SCREEN-HEIGHT,
resizable: false,
bg: "black"
}
nk:win ;
: draw
level vp tilemap:draw
draw-player ;
: update
scan:LEFT nk:scancode? if
-0.5 dx n:+!
dx @ -4 n:< if
-4 dx !
then
1 flipx !
x @ 2X-SPRITE-WIDTH n:< scrollx @ 0 n:> and if
true scrolling !
dx @ scrollx n:+!
scrollx @ 0 n:< if
0 scrollx !
then
level scrollx @ 0 map:move drop
else
false scrolling !
then
else
scan:RIGHT nk:scancode? if
0.5 dx n:+!
dx @ 4 n:> if
4 dx !
then
0 flipx !
x @ VIEWPORT-WIDTH 2X-SPRITE-WIDTH n:- SPRITE-WIDTH n:- n:> scrollx @ MAP-WIDTH VIEWPORT-WIDTH n:- n:< and if
true scrolling !
dx @ scrollx n:+!
scrollx @ MAP-WIDTH VIEWPORT-WIDTH n:- n:> if
MAP-WIDTH VIEWPORT-WIDTH n:- scrollx !
then
level scrollx @ 0 map:move drop
else
false scrolling !
then
else
0 dx !
false scrolling !
then
then
scan:UP nk:scancode? jumping @ not and if
-10.5 dy !
then
scrolling @ not if
dx @ x n:+!
then
\ Guard player keeps within allowed bounds
x @ 0 VIEWPORT-WIDTH SPRITE-WIDTH n:- n:clamp x !
GRAVITY dy n:+!
dy @ 0 n:= not if
true jumping !
then
dy @ y n:+!
tile-collision
animate-player
scan:ESCAPE nk:scancode? if
bye
then ;
: app:main
new-win
WAIT-VSYNC
DT
MAIN
[ ' update ]
[ ' draw ]
main-render
game:init
init
game:event-loop ;Aihe on jo aika vanha, joten et voi enää vastata siihen.