mirror of
https://github.com/carp-lang/Carp.git
synced 2024-09-19 01:18:40 +03:00
6ddf0e8f2b
checker. In Concretize.hs, 'manageMemory' visits all args BEFORE managing their variables, making it possible to apply functions to args "at the same time" as passing them to the function. Example: (let [n (Array.unsafe-nth &b idx) new-b (Bucket.shrink @n k)] (Array.aset b idx new-b)))))) becomes (let [n (Array.unsafe-nth &b idx)] (Array.aset b idx (Bucket.shrink @n k)))))))
187 lines
5.7 KiB
Plaintext
187 lines
5.7 KiB
Plaintext
(use Int)
|
|
(use Double)
|
|
(use Array)
|
|
|
|
(load "SDL.carp")
|
|
(load "SDL_image.carp")
|
|
|
|
(load "Vector.carp")
|
|
(use Vector2)
|
|
|
|
(Project.config "title" "Reptile")
|
|
|
|
(deftype Snake
|
|
[body (Array (Vector2 Double))
|
|
dir SDL_Keycode
|
|
freeze Int
|
|
])
|
|
|
|
(use Snake)
|
|
|
|
(deftype World
|
|
[snake Snake
|
|
human (Vector2 Double)
|
|
dead Bool])
|
|
|
|
(use World)
|
|
|
|
(def bg-col 120)
|
|
(def grid-size 32)
|
|
|
|
(defn draw-snake [rend snake]
|
|
(let [body-length (length (body snake))]
|
|
(for [i 0 body-length]
|
|
(let [part (unsafe-nth (body snake) i)
|
|
x (* grid-size (to-int @(Vector2.x part)))
|
|
y (* grid-size (to-int @(Vector2.y part)))]
|
|
(if (= i 0)
|
|
(do
|
|
(SDL.set-render-draw-color rend 200 255 (+ 100 (* body-length 10)) 255)
|
|
(SDL.render-fill-rect rend (address (SDL.rect x y grid-size grid-size))))
|
|
(do
|
|
(SDL.set-render-draw-color rend 200 (+ 50 (* i (/ 200 body-length))) 100 255)
|
|
(SDL.render-fill-rect rend (address (SDL.rect x y grid-size grid-size)))))))))
|
|
|
|
(defn draw-human [rend human]
|
|
(do
|
|
(SDL.set-render-draw-color rend 100 100 250 255)
|
|
(let [x (* grid-size (to-int @(Vector2.x human)))
|
|
y (* grid-size (to-int @(Vector2.y human)))]
|
|
(SDL.render-fill-rect rend (address (SDL.rect x y grid-size grid-size))))))
|
|
|
|
(defn draw [rend world]
|
|
(do
|
|
(SDL.set-render-draw-blend-mode rend SDL.blend-mode-add)
|
|
(SDL.set-render-draw-color rend (- bg-col @(Snake.freeze (World.snake world))) bg-col bg-col 255)
|
|
(SDL.render-clear rend)
|
|
(draw-snake rend (snake world))
|
|
(draw-human rend (World.human world))
|
|
(SDL.render-present rend)
|
|
))
|
|
|
|
(def input-dir SDL.Keycode.down)
|
|
(def reset false)
|
|
|
|
(defn handle-events [app rend world]
|
|
(let [event (SDL.Event.init)]
|
|
(while (SDL.Event.poll (address event))
|
|
(let [et (SDL.Event.type &event)]
|
|
(cond (= et SDL.Event.quit) (SDLApp.stop app)
|
|
(= et SDL.Event.key-down) (let [key (SDL.Event.keycode &event)]
|
|
(cond
|
|
(or (= key SDL.Keycode.right)
|
|
(or (= key SDL.Keycode.up)
|
|
(or (= key SDL.Keycode.left) (= key SDL.Keycode.down))))
|
|
(set! input-dir key)
|
|
(= key SDL.Keycode.return) (set! reset true)
|
|
(= key SDL.Keycode.escape) (SDLApp.stop app)
|
|
()))
|
|
()
|
|
)))))
|
|
|
|
(defn move [vec dir]
|
|
(cond
|
|
(= SDL.Keycode.right dir) (add &vec &(Vector2.init 1.0 0.0))
|
|
(= SDL.Keycode.up dir) (add &vec &(Vector2.init 0.0 -1.0))
|
|
(= SDL.Keycode.left dir) (add &vec &(Vector2.init -1.0 0.0))
|
|
(= SDL.Keycode.down dir) (add &vec &(Vector2.init 0.0 1.0))
|
|
vec))
|
|
|
|
(defn shift-body [body]
|
|
(do
|
|
(let [i (- (length body) 2)]
|
|
(while (> i -1)
|
|
(do
|
|
(aset! body (inc i) @(unsafe-nth body i))
|
|
(set! i (dec i)))))
|
|
@body))
|
|
|
|
(defn create-human []
|
|
(Vector2.init (from-int (random-between 0 26))
|
|
(from-int (random-between 0 20))))
|
|
|
|
(defn kill-human [world]
|
|
(let [new-human (create-human)]
|
|
(World.set-human world new-human)))
|
|
|
|
(defn inc2 [i]
|
|
(+ i 2))
|
|
|
|
(defn grow [snake]
|
|
(let [new-snake (Snake.update-freeze snake &inc2)
|
|
b (Snake.body &new-snake)]
|
|
(Snake.set-body new-snake (push-back @b (unsafe-last b)))))
|
|
|
|
(defn update-after-kill [world]
|
|
(let [s (World.snake &world)
|
|
new-s (grow @s)
|
|
new-world (kill-human world)]
|
|
(World.set-snake new-world new-s)))
|
|
|
|
(defn check-for-kill [world]
|
|
(let [s (World.snake world)
|
|
h (World.human world)
|
|
b (Snake.body s)
|
|
head &(unsafe-first b)]
|
|
(if (= head h)
|
|
(update-after-kill @world)
|
|
@world)))
|
|
|
|
(defn check-world [world]
|
|
(let [snake (World.snake world)
|
|
b (Snake.body snake)
|
|
head &(unsafe-first b)
|
|
x @(Vector2.x head)
|
|
y @(Vector2.y head)]
|
|
(World.set-dead @world (or (< x 0.0)
|
|
(or (> x 26.0)
|
|
(or (< y 0.0) (> y 24.0)))))))
|
|
|
|
(defn tick [world]
|
|
(let [s (Snake.set-dir @(World.snake world) input-dir)
|
|
b (Snake.body &s)
|
|
new-head (move @(unsafe-nth b 0) @(dir &s))
|
|
new-body (aset (shift-body b) 0 new-head)
|
|
new-snake (Snake.set-body s new-body)
|
|
world-after-snake-move (World.set-snake @world new-snake)
|
|
world-checked (check-world &world-after-snake-move)]
|
|
(check-for-kill &world-checked)))
|
|
|
|
(defn create-world []
|
|
(World.init (Snake.init [(Vector2.init 10.0 10.0)
|
|
(Vector2.init 9.0 10.0)
|
|
(Vector2.init 8.0 10.0)
|
|
(Vector2.init 7.0 10.0)]
|
|
SDL.Keycode.down
|
|
0)
|
|
(create-human)
|
|
false))
|
|
|
|
(defn render-dead [rend]
|
|
(do
|
|
(SDL.set-render-draw-blend-mode rend SDL.blend-mode-add)
|
|
(SDL.set-render-draw-color rend 200 90 90 255)
|
|
(SDL.render-clear rend)
|
|
(SDL.render-present rend)
|
|
(SDL.delay 2000)
|
|
))
|
|
|
|
(defn main []
|
|
(let [app (SDLApp.create "R E P T I L E" 832 640)
|
|
rend @(SDLApp.renderer &app)
|
|
world (create-world)]
|
|
(do
|
|
(while (not @(World.dead &world))
|
|
(if reset
|
|
(do
|
|
(set! input-dir SDL.Keycode.right)
|
|
(set! world (create-world))
|
|
(set! reset false))
|
|
(do
|
|
(let [new-world (tick &world)]
|
|
(set! world new-world))
|
|
(handle-events &app rend &world)
|
|
(draw rend &world)
|
|
(SDL.delay 50))))
|
|
(render-dead rend))))
|