mirror of
https://github.com/carp-lang/Carp.git
synced 2024-10-11 20:49:05 +03:00
235 lines
6.8 KiB
Plaintext
235 lines
6.8 KiB
Plaintext
(use IO)
|
|
(use System)
|
|
(use Int)
|
|
(use Double)
|
|
(use Array)
|
|
|
|
(load "core/sdl.carp")
|
|
(load "core/sdl_image.carp")
|
|
(use Keycode)
|
|
(add-cflag "-fsanitize=address")
|
|
|
|
(deftype Vec2
|
|
[x Int
|
|
y Int])
|
|
|
|
(use Vec2)
|
|
|
|
(def RIGHT 0)
|
|
(def UP 1)
|
|
(def LEFT 2)
|
|
(def DOWN 3)
|
|
|
|
(deftype Snake
|
|
[body (Array Vec2)
|
|
dir Int
|
|
freeze Int
|
|
])
|
|
|
|
(use Snake)
|
|
|
|
(deftype Human
|
|
[pos Vec2])
|
|
|
|
(use Human)
|
|
|
|
(deftype World
|
|
[snake Snake
|
|
humans (Array Human)])
|
|
|
|
(use World)
|
|
|
|
(def bg-col 120)
|
|
(def grid-size 32)
|
|
|
|
(defn draw-snake [rend snake]
|
|
(let [body-count (count (body snake))]
|
|
(for [i 0 body-count]
|
|
(let [part (nth (body snake) i)
|
|
x (* grid-size (Vec2.x &part))
|
|
y (* grid-size (Vec2.y &part))]
|
|
(do
|
|
;; (if (= i 0)
|
|
;; (do
|
|
;; (SDL_SetRenderDrawColor rend 200 255 100 255)
|
|
;; (SDL_RenderFillRect rend (address (make-rect x y grid-size grid-size))))
|
|
;; ())
|
|
(SDL_SetRenderDrawColor rend 200 (+ 50 (* i (/ 200 body-count))) 100 255)
|
|
(SDL_RenderFillRect rend (address (make-rect x y grid-size grid-size))))))))
|
|
|
|
(defn draw-human [rend human]
|
|
(do
|
|
(SDL_SetRenderDrawColor rend 100 100 250 255)
|
|
(let [x (* grid-size (Vec2.x (pos &human)))
|
|
y (* grid-size (Vec2.y (pos &human)))]
|
|
(SDL_RenderFillRect rend (address (make-rect x y grid-size grid-size))))))
|
|
|
|
(defn draw [rend world]
|
|
(do
|
|
(SDL_SetRenderDrawBlendMode rend SDL_BLENDMODE_ADD)
|
|
(SDL_SetRenderDrawColor rend (- bg-col (* 2 (Snake.freeze (World.snake world)))) bg-col bg-col 255)
|
|
(SDL_RenderClear rend)
|
|
(draw-snake rend (snake world))
|
|
;; (let [hums (World.humans &world)]
|
|
;; (for [i 0 (count hums)]
|
|
;; (draw-human rend (nth hums i))))
|
|
(SDL_RenderPresent rend)
|
|
))
|
|
|
|
(def input-dir 1)
|
|
(def reset false)
|
|
|
|
(defn handle-events [app rend world]
|
|
(let [event (SDL_Event_init)]
|
|
(while (SDL_PollEvent (address event))
|
|
(let [et (event-type &event)]
|
|
(cond (= et SDL_QUIT) (quit app)
|
|
(= et SDL_KEYDOWN) (let [key (event-keycode &event)]
|
|
(cond
|
|
(= key SDLK_RIGHT) (set! input-dir RIGHT)
|
|
(= key SDLK_UP) (set! input-dir UP)
|
|
(= key SDLK_LEFT) (set! input-dir LEFT)
|
|
(= key SDLK_DOWN) (set! input-dir DOWN)
|
|
(= key SDLK_RETURN) (set! reset true)
|
|
(= key SDLK_ESCAPE) (quit app)
|
|
(println &"Unrecognized key.")))
|
|
()
|
|
;;(println "Some other event happened...")
|
|
)))))
|
|
|
|
(defn add-vec [a b]
|
|
(Vec2.init (+ (x &a) (x &b))
|
|
(+ (y &a) (y &b))))
|
|
|
|
(defn eq-vec [a b]
|
|
(and (= (x a) (x b))
|
|
(= (y a) (y b))))
|
|
|
|
(defn move [vec dir]
|
|
(cond
|
|
(= RIGHT dir) (add-vec vec (Vec2.init 1 0))
|
|
(= UP dir) (add-vec vec (Vec2.init 0 (- 0 1)))
|
|
(= LEFT dir) (add-vec vec (Vec2.init (- 0 1) 0))
|
|
(= DOWN dir) (add-vec vec (Vec2.init 0 1))
|
|
vec))
|
|
|
|
;; Replace this with Array.shift
|
|
(defn shift-body [body]
|
|
(do
|
|
;; (let [i (- (Array.count &body) 2)]
|
|
;; (while (> i (- 0 1))
|
|
;; (do
|
|
;; (aset! body (inc i) (copy (nth body i)))
|
|
;; (set! i (dec i)))))
|
|
body))
|
|
|
|
(defn create-human []
|
|
(Human.init (Vec2.init (random-between 8 26)
|
|
(random-between 4 20))))
|
|
|
|
;; (defn kill-human [world index]
|
|
;; (let [humans (World.humans world)
|
|
;; new-human (create-human)
|
|
;; humans2 (aset humans index new-human)]
|
|
;; (World.set-humans world humans2)))
|
|
|
|
(defn last [xs]
|
|
(Array.nth xs (dec (Array.count &xs))))
|
|
|
|
(defn grow [snake]
|
|
(let [new-snake (Snake.set-freeze snake 5)
|
|
b (Snake.body new-snake)]
|
|
(Snake.set-body new-snake (push-back b (last b)))))
|
|
|
|
(defn check-for-kill [world]
|
|
(let [s (World.snake world)
|
|
b (Snake.body s)
|
|
head (nth b 0)
|
|
humans (World.humans world)]
|
|
world
|
|
;; (do
|
|
;; (for [i 0 (count humans)]
|
|
;; (if (eq-vec head (pos (nth humans i)))
|
|
;; (do
|
|
;; ;;(set! world (World.set-snake world (grow s)))
|
|
;; (set! world (kill-human world i)))
|
|
;; ()))
|
|
;; world)
|
|
))
|
|
|
|
(defn shorten-snake [snake]
|
|
(Snake.set-body snake (Array.pop-back (Snake.body snake))))
|
|
|
|
;; (defn tick [w1]
|
|
;; (let [s1 (World.snake w1)
|
|
;; s5 (if (< (Snake.freeze s1) 1)
|
|
;; (let [s2 (if (or (= (Snake.dir s1) input-dir)
|
|
;; (= 1 (count (Snake.body s1))))
|
|
;; s1
|
|
;; (let [s1b (Snake.set-dir s1 input-dir)
|
|
;; s1c (shorten-snake s1b)]
|
|
;; s1c))
|
|
;; b1 (Snake.body s2)
|
|
;; head (nth b1 0)
|
|
;; new-head (move head (dir s2))
|
|
;; b2 (shift-body b1)
|
|
;; b3 (aset b2 0 new-head)
|
|
;; s3 (Snake.set-body s2 b3)]
|
|
;; s3)
|
|
;; (let [s2 (Snake.set-dir s1 input-dir)
|
|
;; s3 (Snake.set-freeze s2 (- (Snake.freeze s1) 1))]
|
|
;; s3))
|
|
;; w2 (World.set-snake w1 s5)]
|
|
;; (check-for-kill w2)))
|
|
|
|
(defn maybe-shorten [snake]
|
|
(if (or (= (Snake.dir snake) input-dir)
|
|
(= 1 (count (Snake.body snake))))
|
|
snake
|
|
snake))
|
|
|
|
;; (do
|
|
;; (println "Shorten!")
|
|
;; (shorten-snake snake))
|
|
|
|
(defn tick [world]
|
|
(let [s (Snake.set-dir (maybe-shorten (World.snake world)) input-dir)
|
|
b (Snake.body s)
|
|
new-head (move (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)]
|
|
(check-for-kill world-after-snake-move)))
|
|
|
|
(defn create-world []
|
|
(World.init (Snake.init [(Vec2.init 10 10)
|
|
(Vec2.init 9 10)
|
|
(Vec2.init 8 10)
|
|
(Vec2.init 7 10)
|
|
(Vec2.init 6 10)
|
|
(Vec2.init 5 10)
|
|
(Vec2.init 4 10)
|
|
(Vec2.init 3 10)
|
|
(Vec2.init 2 10)]
|
|
DOWN
|
|
0)
|
|
(repeat 30 create-human)))
|
|
|
|
(defn main []
|
|
(let [app (app-init &"R E P T I L E" 1024 768)
|
|
rend (app-renderer app)
|
|
world (create-world)]
|
|
(while true
|
|
(do
|
|
(if reset
|
|
(do
|
|
(set! input-dir RIGHT)
|
|
(set! world (create-world))
|
|
(set! reset false))
|
|
())
|
|
(let [new-world (tick world)]
|
|
(set! world new-world))
|
|
(handle-events app rend world)
|
|
(draw rend world)
|
|
(SDL_Delay 50)))))
|