snake.nv
· 5.0 KiB · Text
Raw
Playground
| 'INSTRUCTIONS' | ~~
you can move using the WASD keys !
|| '@include' (
https://gist.casuallyblue.dev/autumn/056799f483464c668e0a6a2d9db099df/raw/HEAD/game.nv
https://gist.casuallyblue.dev/autumn/e1c6774f800249be87a94240042135db/raw/HEAD/reduce.nv
)
'DOM' (<query h2 <style text-align = center > >)
'snake' . head 5 11 . body 4 11 . body 3 11
'direction' right
'speed' 1.7
'timer' 0
'food' 19 11
'score' 0
'cell size' 16
'grid size' 23
'' start game
'' set score text
| '' start game 'cell size' $cell? 'grid size' $grid?
| '' (@reduce @main =
start a { $cell $grid * } by { $cell $grid * } game .)
| '' game loop $dt
| '' check keys 'controls' ( w a s d r )
'' update movement timer $dt
'' check if snake can eat food
'' draw background
'' draw snake
'' draw food
'' check if snake died
'' next frame
| '' check keys? 'controls' $key | '' check if $key is pressed
| '' check keys |
| 'key pressed' w 'direction' down? |
| 'key pressed' a 'direction' right? |
| 'key pressed' s 'direction' up? |
| 'key pressed' d 'direction' left? |
| 'key pressed' w | 'new direction' up
| 'key pressed' a | 'new direction' left
| 'key pressed' s | 'new direction' down
| 'key pressed' d | 'new direction' right
| '' move? 'direction' $_ 'new direction' $direction |
'direction' $direction
| '' move 'direction' up? | '' move snake 'vector' + 0 - 1
| '' move 'direction' left? | '' move snake 'vector' - 1 + 0
| '' move 'direction' down? | '' move snake 'vector' + 0 + 1
| '' move 'direction' right? | '' move snake 'vector' + 1 + 0
| '' move snake? 'vector' $1 $2 $3 $4 'snake' head $x $y 'grid size' $size?
| 'new body position' $x $y
'' (@reduce seen = head { $x $2 $1 0 $size 1 - wrap }
{ $y $4 $3 0 $size 1 - wrap } .)
| '' move snake? 'snake' body $x $y 'new body position' $nx $ny
| 'new body position' $x $y
'seen' body $nx $ny
| '' move snake 'new body position' $x $y | '' reset snake
| '' update movement timer $dt 'paused'? |
| '' update movement timer $dt 'timer' $time
| '' (@reduce timer = { $dt 60 / $time + } .)
'' move if timer is done
| '' move if timer is done 'timer' $time 'speed' $speed?
| '@js' if ($time > $speed) {
f("", "move");
f("timer", 0);
} else {
f("timer", $time);
}
| '' check if snake can eat food 'snake' head $x $y? 'food' $x $y?
| '' move food to random location
'' extend snake
'' increase score
'' set score text
| '' check if snake can eat food |
| '' move food to random location 'food' $x $y 'grid size' $max?
| '' (@reduce food = { 0 $max random } { 0 $max random } .)
| '' increase score 'score' $score
| '' (@reduce score = { $score 1 + } .)
| '' set score text 'score' $score?
| 'DOM' (<query h2 @clear @append [Score: ] @append $score >)
| '' extend snake? 'snake' $segment $x $y | 'seen' $segment $x $y
| '' extend snake | '' duplicate tail segment
| '' duplicate tail segment 'seen' $segment $x $y?
| 'snake' $segment $x $y '' reset snake
| '' check if snake died? 'snake' head $x $y | 'head' $x $y
| '' check if snake died 'snake' body $x $y 'head' $x $y? |
'' . reset snake . replace head . snake died
| '' check if snake died? 'snake' body $x $y | 'seen' body $x $y
| '' check if snake died | '' reset snake '' replace head
| '' replace head 'head' $x $y | 'snake' head $x $y
| '' snake died 'score' $score?
| 'paused'
'DOM' (<query h2 @clear @append
[Game over! Press R to restart. Score: ]
@append $score
>)
| 'key pressed' r 'paused' | '' restart game
| 'key pressed' r |
| '' restart game? 'seen' $segment $x $y |
| '' restart game? 'snake' $segment $x $y |
| '' restart game 'direction' $direction 'food' $x $y 'score' $score
| 'snake' . head 5 11 . body 4 11 . body 3 11
'direction' right
'food' 19 11
'score' 0 '' set score text
| '' draw background
| '@graphics' clear #000c0f
| '' draw snake? 'snake' head $x $y 'pixel_position' $px $py 'cell size' $size?
| '@graphics' draw square $px $py $size #5af7ff
'seen' head $x $y
| '' draw snake? 'snake' body $x $y 'pixel_position' $px $py 'cell size' $size?
| '' (@reduce @graphics = draw square
{ $px 1 + } { $py 1 + } { $size 2 - } #10b0b0 .)
'seen' body $x $y
| '' draw snake? 'snake' $segment $x $y?
| '' convert $x $y to pixel position
| '' draw snake | '' reset snake
| '' draw food 'pixel_position' $x $y 'cell size' $size?
| '@graphics' draw circle $x $y $size #f0b050
| '' draw food? 'food' $x $y?
| '' convert $x $y to pixel position
| '@graphics' draw square $x $y $size $color '@@canvas context' $c?
| '@js' $c.fillStyle = $color;
$c.fillRect($x, $y, $size, $size);
| '@graphics' draw circle $x $y $width $color '@@canvas context' $c?
| '@js' $c.beginPath();
const r = $width / 2;
$c.arc(Number($x) + r, Number($y) + r, r, 0, 2 * Math.PI);
$c.fillStyle = $color;
$c.fill();
| '' convert $x $y to pixel position 'cell size' $scalar?
| '' (@reduce pixel_position = { $x $scalar * } { $y $scalar * } .)
| '' reset snake? 'seen' $segment $x $y | 'snake' $segment $x $y
| '' reset snake |
| 1 | | 'INSTRUCTIONS' | ~~ |
| 2 | you can move using the WASD keys ! |
| 3 | |
| 4 | || '@include' ( |
| 5 | https://gist.casuallyblue.dev/autumn/056799f483464c668e0a6a2d9db099df/raw/HEAD/game.nv |
| 6 | https://gist.casuallyblue.dev/autumn/e1c6774f800249be87a94240042135db/raw/HEAD/reduce.nv |
| 7 | ) |
| 8 | |
| 9 | 'DOM' (<query h2 <style text-align = center > >) |
| 10 | |
| 11 | 'snake' . head 5 11 . body 4 11 . body 3 11 |
| 12 | 'direction' right |
| 13 | 'speed' 1.7 |
| 14 | 'timer' 0 |
| 15 | 'food' 19 11 |
| 16 | 'score' 0 |
| 17 | 'cell size' 16 |
| 18 | 'grid size' 23 |
| 19 | |
| 20 | '' start game |
| 21 | '' set score text |
| 22 | |
| 23 | | '' start game 'cell size' $cell? 'grid size' $grid? |
| 24 | | '' (@reduce @main = |
| 25 | start a { $cell $grid * } by { $cell $grid * } game .) |
| 26 | |
| 27 | | '' game loop $dt |
| 28 | | '' check keys 'controls' ( w a s d r ) |
| 29 | '' update movement timer $dt |
| 30 | '' check if snake can eat food |
| 31 | '' draw background |
| 32 | '' draw snake |
| 33 | '' draw food |
| 34 | '' check if snake died |
| 35 | '' next frame |
| 36 | |
| 37 | | '' check keys? 'controls' $key | '' check if $key is pressed |
| 38 | | '' check keys | |
| 39 | |
| 40 | | 'key pressed' w 'direction' down? | |
| 41 | | 'key pressed' a 'direction' right? | |
| 42 | | 'key pressed' s 'direction' up? | |
| 43 | | 'key pressed' d 'direction' left? | |
| 44 | | 'key pressed' w | 'new direction' up |
| 45 | | 'key pressed' a | 'new direction' left |
| 46 | | 'key pressed' s | 'new direction' down |
| 47 | | 'key pressed' d | 'new direction' right |
| 48 | |
| 49 | | '' move? 'direction' $_ 'new direction' $direction | |
| 50 | 'direction' $direction |
| 51 | |
| 52 | | '' move 'direction' up? | '' move snake 'vector' + 0 - 1 |
| 53 | | '' move 'direction' left? | '' move snake 'vector' - 1 + 0 |
| 54 | | '' move 'direction' down? | '' move snake 'vector' + 0 + 1 |
| 55 | | '' move 'direction' right? | '' move snake 'vector' + 1 + 0 |
| 56 | |
| 57 | | '' move snake? 'vector' $1 $2 $3 $4 'snake' head $x $y 'grid size' $size? |
| 58 | | 'new body position' $x $y |
| 59 | '' (@reduce seen = head { $x $2 $1 0 $size 1 - wrap } |
| 60 | { $y $4 $3 0 $size 1 - wrap } .) |
| 61 | |
| 62 | | '' move snake? 'snake' body $x $y 'new body position' $nx $ny |
| 63 | | 'new body position' $x $y |
| 64 | 'seen' body $nx $ny |
| 65 | |
| 66 | | '' move snake 'new body position' $x $y | '' reset snake |
| 67 | |
| 68 | | '' update movement timer $dt 'paused'? | |
| 69 | | '' update movement timer $dt 'timer' $time |
| 70 | | '' (@reduce timer = { $dt 60 / $time + } .) |
| 71 | '' move if timer is done |
| 72 | |
| 73 | | '' move if timer is done 'timer' $time 'speed' $speed? |
| 74 | | '@js' if ($time > $speed) { |
| 75 | f("", "move"); |
| 76 | f("timer", 0); |
| 77 | } else { |
| 78 | f("timer", $time); |
| 79 | } |
| 80 | |
| 81 | | '' check if snake can eat food 'snake' head $x $y? 'food' $x $y? |
| 82 | | '' move food to random location |
| 83 | '' extend snake |
| 84 | '' increase score |
| 85 | '' set score text |
| 86 | | '' check if snake can eat food | |
| 87 | |
| 88 | | '' move food to random location 'food' $x $y 'grid size' $max? |
| 89 | | '' (@reduce food = { 0 $max random } { 0 $max random } .) |
| 90 | |
| 91 | | '' increase score 'score' $score |
| 92 | | '' (@reduce score = { $score 1 + } .) |
| 93 | |
| 94 | | '' set score text 'score' $score? |
| 95 | | 'DOM' (<query h2 @clear @append [Score: ] @append $score >) |
| 96 | |
| 97 | | '' extend snake? 'snake' $segment $x $y | 'seen' $segment $x $y |
| 98 | | '' extend snake | '' duplicate tail segment |
| 99 | | '' duplicate tail segment 'seen' $segment $x $y? |
| 100 | | 'snake' $segment $x $y '' reset snake |
| 101 | |
| 102 | | '' check if snake died? 'snake' head $x $y | 'head' $x $y |
| 103 | | '' check if snake died 'snake' body $x $y 'head' $x $y? | |
| 104 | '' . reset snake . replace head . snake died |
| 105 | | '' check if snake died? 'snake' body $x $y | 'seen' body $x $y |
| 106 | | '' check if snake died | '' reset snake '' replace head |
| 107 | | '' replace head 'head' $x $y | 'snake' head $x $y |
| 108 | |
| 109 | | '' snake died 'score' $score? |
| 110 | | 'paused' |
| 111 | 'DOM' (<query h2 @clear @append |
| 112 | [Game over! Press R to restart. Score: ] |
| 113 | @append $score |
| 114 | >) |
| 115 | |
| 116 | | 'key pressed' r 'paused' | '' restart game |
| 117 | | 'key pressed' r | |
| 118 | |
| 119 | | '' restart game? 'seen' $segment $x $y | |
| 120 | | '' restart game? 'snake' $segment $x $y | |
| 121 | | '' restart game 'direction' $direction 'food' $x $y 'score' $score |
| 122 | | 'snake' . head 5 11 . body 4 11 . body 3 11 |
| 123 | 'direction' right |
| 124 | 'food' 19 11 |
| 125 | 'score' 0 '' set score text |
| 126 | |
| 127 | | '' draw background |
| 128 | | '@graphics' clear #000c0f |
| 129 | |
| 130 | | '' draw snake? 'snake' head $x $y 'pixel_position' $px $py 'cell size' $size? |
| 131 | | '@graphics' draw square $px $py $size #5af7ff |
| 132 | 'seen' head $x $y |
| 133 | |
| 134 | | '' draw snake? 'snake' body $x $y 'pixel_position' $px $py 'cell size' $size? |
| 135 | | '' (@reduce @graphics = draw square |
| 136 | { $px 1 + } { $py 1 + } { $size 2 - } #10b0b0 .) |
| 137 | 'seen' body $x $y |
| 138 | |
| 139 | | '' draw snake? 'snake' $segment $x $y? |
| 140 | | '' convert $x $y to pixel position |
| 141 | |
| 142 | | '' draw snake | '' reset snake |
| 143 | |
| 144 | | '' draw food 'pixel_position' $x $y 'cell size' $size? |
| 145 | | '@graphics' draw circle $x $y $size #f0b050 |
| 146 | | '' draw food? 'food' $x $y? |
| 147 | | '' convert $x $y to pixel position |
| 148 | |
| 149 | | '@graphics' draw square $x $y $size $color '@@canvas context' $c? |
| 150 | | '@js' $c.fillStyle = $color; |
| 151 | $c.fillRect($x, $y, $size, $size); |
| 152 | |
| 153 | | '@graphics' draw circle $x $y $width $color '@@canvas context' $c? |
| 154 | | '@js' $c.beginPath(); |
| 155 | const r = $width / 2; |
| 156 | $c.arc(Number($x) + r, Number($y) + r, r, 0, 2 * Math.PI); |
| 157 | $c.fillStyle = $color; |
| 158 | $c.fill(); |
| 159 | |
| 160 | | '' convert $x $y to pixel position 'cell size' $scalar? |
| 161 | | '' (@reduce pixel_position = { $x $scalar * } { $y $scalar * } .) |
| 162 | |
| 163 | | '' reset snake? 'seen' $segment $x $y | 'snake' $segment $x $y |
| 164 | | '' reset snake | |
| 165 |