2017-09-06 11:05:19 +03:00
|
|
|
(use Int)
|
|
|
|
(use Double)
|
|
|
|
(use Array)
|
2017-06-27 15:57:16 +03:00
|
|
|
|
2018-03-20 18:05:52 +03:00
|
|
|
(load "SDL.carp")
|
|
|
|
(load "SDL_image.carp")
|
2017-06-27 15:57:16 +03:00
|
|
|
|
2017-12-18 19:37:56 +03:00
|
|
|
(load "Vector.carp")
|
|
|
|
(use Vector2)
|
2017-06-27 15:57:16 +03:00
|
|
|
|
2018-03-14 22:48:23 +03:00
|
|
|
(Project.config "title" "Reptile")
|
|
|
|
|
2017-06-27 15:57:16 +03:00
|
|
|
(deftype Snake
|
2017-12-18 19:37:56 +03:00
|
|
|
[body (Array V2)
|
|
|
|
dir SDL_Keycode
|
2017-06-27 15:57:16 +03:00
|
|
|
freeze Int
|
2017-12-18 19:37:56 +03:00
|
|
|
])
|
2017-06-27 15:57:16 +03:00
|
|
|
|
2017-09-06 11:05:19 +03:00
|
|
|
(use Snake)
|
2017-06-27 15:57:16 +03:00
|
|
|
|
|
|
|
(deftype World
|
|
|
|
[snake Snake
|
2017-12-18 19:37:56 +03:00
|
|
|
human V2
|
|
|
|
dead Bool])
|
2017-06-27 15:57:16 +03:00
|
|
|
|
2017-09-06 11:05:19 +03:00
|
|
|
(use World)
|
2017-06-27 15:57:16 +03:00
|
|
|
|
|
|
|
(def bg-col 120)
|
|
|
|
(def grid-size 32)
|
|
|
|
|
|
|
|
(defn draw-snake [rend snake]
|
2018-05-20 10:57:51 +03:00
|
|
|
(let [body-length (length (body snake))]
|
|
|
|
(for [i 0 body-length]
|
2017-06-27 15:57:16 +03:00
|
|
|
(let [part (nth (body snake) i)
|
2018-02-05 12:19:03 +03:00
|
|
|
x (* grid-size (to-int @(Vector2.V2.x part)))
|
|
|
|
y (* grid-size (to-int @(Vector2.V2.y part)))]
|
2017-12-18 19:37:56 +03:00
|
|
|
(if (= i 0)
|
|
|
|
(do
|
2018-05-20 10:57:51 +03:00
|
|
|
(SDL.set-render-draw-color rend 200 255 (+ 100 (* body-length 10)) 255)
|
2018-03-20 16:34:49 +03:00
|
|
|
(SDL.render-fill-rect rend (address (SDL.rect x y grid-size grid-size))))
|
2017-12-18 19:37:56 +03:00
|
|
|
(do
|
2018-05-20 10:57:51 +03:00
|
|
|
(SDL.set-render-draw-color rend 200 (+ 50 (* i (/ 200 body-length))) 100 255)
|
2018-03-20 16:34:49 +03:00
|
|
|
(SDL.render-fill-rect rend (address (SDL.rect x y grid-size grid-size)))))))))
|
2017-06-27 15:57:16 +03:00
|
|
|
|
|
|
|
(defn draw-human [rend human]
|
|
|
|
(do
|
2018-03-20 16:34:49 +03:00
|
|
|
(SDL.set-render-draw-color rend 100 100 250 255)
|
2018-02-05 12:19:03 +03:00
|
|
|
(let [x (* grid-size (to-int @(Vector2.V2.x human)))
|
|
|
|
y (* grid-size (to-int @(Vector2.V2.y human)))]
|
2018-03-20 16:34:49 +03:00
|
|
|
(SDL.render-fill-rect rend (address (SDL.rect x y grid-size grid-size))))))
|
2017-06-27 15:57:16 +03:00
|
|
|
|
|
|
|
(defn draw [rend world]
|
|
|
|
(do
|
2018-03-20 16:34:49 +03:00
|
|
|
(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)
|
2017-06-27 15:57:16 +03:00
|
|
|
(draw-snake rend (snake world))
|
2017-12-18 19:37:56 +03:00
|
|
|
(draw-human rend (World.human world))
|
2018-03-20 16:34:49 +03:00
|
|
|
(SDL.render-present rend)
|
2017-06-27 15:57:16 +03:00
|
|
|
))
|
|
|
|
|
2018-03-26 14:52:34 +03:00
|
|
|
(def input-dir SDL.Keycode.down)
|
2017-06-27 15:57:16 +03:00
|
|
|
(def reset false)
|
|
|
|
|
|
|
|
(defn handle-events [app rend world]
|
2018-03-20 18:05:52 +03:00
|
|
|
(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)]
|
2018-03-20 16:34:49 +03:00
|
|
|
(cond
|
2018-03-26 14:52:34 +03:00
|
|
|
(or (= key SDL.Keycode.right)
|
|
|
|
(or (= key SDL.Keycode.up)
|
|
|
|
(or (= key SDL.Keycode.left) (= key SDL.Keycode.down))))
|
2018-03-20 16:34:49 +03:00
|
|
|
(set! input-dir key)
|
2018-03-26 14:52:34 +03:00
|
|
|
(= key SDL.Keycode.return) (set! reset true)
|
|
|
|
(= key SDL.Keycode.escape) (SDLApp.stop app)
|
2018-03-20 16:34:49 +03:00
|
|
|
()))
|
2017-06-27 15:57:16 +03:00
|
|
|
()
|
|
|
|
)))))
|
|
|
|
|
|
|
|
(defn move [vec dir]
|
|
|
|
(cond
|
2018-03-26 14:52:34 +03:00
|
|
|
(= 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))
|
2017-06-27 15:57:16 +03:00
|
|
|
vec))
|
|
|
|
|
|
|
|
(defn shift-body [body]
|
|
|
|
(do
|
2018-05-20 10:57:51 +03:00
|
|
|
(let [i (- (Array.length body) 2)]
|
2017-12-18 19:37:56 +03:00
|
|
|
(while (> i -1)
|
|
|
|
(do
|
|
|
|
(aset! body (inc i) @(nth body i))
|
2018-02-02 09:19:10 +03:00
|
|
|
(set! i (dec i)))))
|
2017-12-18 19:37:56 +03:00
|
|
|
@body))
|
2017-06-27 15:57:16 +03:00
|
|
|
|
|
|
|
(defn create-human []
|
2017-12-18 19:37:56 +03:00
|
|
|
(Vector2.init (from-int (random-between 0 26))
|
|
|
|
(from-int (random-between 0 20))))
|
2017-06-27 15:57:16 +03:00
|
|
|
|
2017-12-18 19:37:56 +03:00
|
|
|
(defn kill-human [world]
|
|
|
|
(let [new-human (create-human)]
|
|
|
|
(World.set-human world new-human)))
|
2017-06-27 15:57:16 +03:00
|
|
|
|
2017-12-18 19:37:56 +03:00
|
|
|
(defn inc2 [i]
|
|
|
|
(+ i 2))
|
2017-06-27 15:57:16 +03:00
|
|
|
|
|
|
|
(defn grow [snake]
|
2017-12-18 19:37:56 +03:00
|
|
|
(let [new-snake (Snake.update-freeze snake inc2)
|
|
|
|
b (Snake.body &new-snake)]
|
|
|
|
(Snake.set-body new-snake (push-back @b (last b)))))
|
|
|
|
|
|
|
|
(defn update-after-kill [world]
|
|
|
|
(let [s (World.snake &world)
|
|
|
|
new-world (kill-human world)]
|
|
|
|
(World.set-snake new-world (grow @s))))
|
2017-06-27 15:57:16 +03:00
|
|
|
|
|
|
|
(defn check-for-kill [world]
|
|
|
|
(let [s (World.snake world)
|
2017-12-18 19:37:56 +03:00
|
|
|
h (World.human world)
|
2017-06-27 15:57:16 +03:00
|
|
|
b (Snake.body s)
|
2017-12-18 19:37:56 +03:00
|
|
|
head &(first b)]
|
|
|
|
(if (= head h)
|
|
|
|
(update-after-kill @world)
|
|
|
|
@world)))
|
|
|
|
|
|
|
|
(defn check-world [world]
|
|
|
|
(let [snake (World.snake world)
|
|
|
|
b (Snake.body snake)
|
|
|
|
head &(first b)
|
2018-02-05 12:19:03 +03:00
|
|
|
x @(Vector2.V2.x head)
|
|
|
|
y @(Vector2.V2.y head)]
|
2017-12-18 19:37:56 +03:00
|
|
|
(World.set-dead @world (or (< x 0.0)
|
|
|
|
(or (> x 26.0)
|
|
|
|
(or (< y 0.0) (> y 24.0)))))))
|
2017-06-27 15:57:16 +03:00
|
|
|
|
|
|
|
(defn tick [world]
|
2017-12-18 19:37:56 +03:00
|
|
|
(let [s (Snake.set-dir @(World.snake world) input-dir)
|
|
|
|
b (Snake.body &s)
|
2018-02-05 12:19:03 +03:00
|
|
|
new-head (move @(nth b 0) @(dir &s))
|
2017-06-27 15:57:16 +03:00
|
|
|
new-body (aset (shift-body b) 0 new-head)
|
|
|
|
new-snake (Snake.set-body s new-body)
|
2017-12-18 19:37:56 +03:00
|
|
|
world-after-snake-move (World.set-snake @world new-snake)
|
|
|
|
world-checked (check-world &world-after-snake-move)]
|
|
|
|
(check-for-kill &world-checked)))
|
2017-06-27 15:57:16 +03:00
|
|
|
|
|
|
|
(defn create-world []
|
2017-12-18 19:37:56 +03:00
|
|
|
(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)]
|
2018-03-26 14:52:34 +03:00
|
|
|
SDL.Keycode.down
|
2017-06-27 15:57:16 +03:00
|
|
|
0)
|
2017-12-18 19:37:56 +03:00
|
|
|
(create-human)
|
|
|
|
false))
|
|
|
|
|
|
|
|
(defn render-dead [rend]
|
|
|
|
(do
|
2018-03-20 16:34:49 +03:00
|
|
|
(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)
|
2017-12-18 19:37:56 +03:00
|
|
|
))
|
2017-06-27 15:57:16 +03:00
|
|
|
|
|
|
|
(defn main []
|
2018-03-20 18:38:50 +03:00
|
|
|
(let [app (SDLApp.create "R E P T I L E" 832 640)
|
2018-03-20 16:34:49 +03:00
|
|
|
rend @(SDLApp.renderer &app)
|
2017-06-27 15:57:16 +03:00
|
|
|
world (create-world)]
|
2017-12-18 19:37:56 +03:00
|
|
|
(do
|
2018-02-05 12:19:03 +03:00
|
|
|
(while (not @(World.dead &world))
|
2017-06-27 15:57:16 +03:00
|
|
|
(if reset
|
|
|
|
(do
|
2018-03-26 14:52:34 +03:00
|
|
|
(set! input-dir SDL.Keycode.right)
|
2018-02-02 09:19:10 +03:00
|
|
|
(set! world (create-world))
|
|
|
|
(set! reset false))
|
2017-12-18 19:37:56 +03:00
|
|
|
(do
|
|
|
|
(let [new-world (tick &world)]
|
2018-02-02 09:19:10 +03:00
|
|
|
(set! world new-world))
|
2017-12-18 19:37:56 +03:00
|
|
|
(handle-events &app rend &world)
|
|
|
|
(draw rend &world)
|
2018-03-20 16:34:49 +03:00
|
|
|
(SDL.delay 50))))
|
2017-12-18 19:37:56 +03:00
|
|
|
(render-dead rend))))
|