summaryrefslogtreecommitdiffstats
path: root/snek.scm
blob: d92d43f5e7603089ad46d94c0896b1b36ff8e155 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
(define-syntax with-drawing
  (syntax-rules ()
    ((with-drawing body ...)
     (dynamic-wind
       raylib#begin-drawing
       (lambda () (begin body ...))
       raylib#end-drawing))))

(define BLACK (raylib#make-color 0 0 0 255))
(define WHITE (raylib#make-color 255 255 255 255))
(define RED   (raylib#make-color 255 0 0 255))

(define KEY_ESC 256)
(define KEY_RIGHT 262)
(define KEY_LEFT 263)
(define KEY_DOWN 264)
(define KEY_UP 265)

(define VP_WIDTH 560)
(define VP_HEIGHT 320)
(define GRID_SIZE 16)
(define GRID_WIDTH (fixnum->flonum (/ VP_WIDTH GRID_SIZE)))
(define GRID_HEIGHT (fixnum->flonum (/ VP_HEIGHT GRID_SIZE)))

(define VP_WIDTH_F (fixnum->flonum VP_WIDTH))
(define VP_HEIGHT_F (fixnum->flonum VP_HEIGHT))
(define GRID_SIZE_F (fixnum->flonum GRID_SIZE))

(define FC 0)
(define game-running #f)

(define (check-pos pos snake-limbs)
	(if (null? snake-limbs) #t
		(and (not (and (= (raylib#vec2-x pos)
						  (raylib#vec2-x (car snake-limbs)))
					   (= (raylib#vec2-y pos)
						  (raylib#vec2-y (car snake-limbs)))))
			 (check-pos pos (cdr snake-limbs)))))

(define (place-apple! state)
  (let ((candidate
		 (raylib#make-vec2 (* GRID_SIZE_F
							  (flfloor (* GRID_WIDTH (random-real))))
                           (* GRID_SIZE_F
							  (flfloor (* GRID_HEIGHT (random-real)))))))
	(if (check-pos candidate (vector->list (state-snake-limbs state)))
		(state-apple-pos-set! state candidate)
		(place-apple! state))))

(define-structure state
  snake-limbs
  apple-pos
  square-dims
  score
  direction)

(define (wrap pos)
  (cond ((> (raylib#vec2-x pos) VP_WIDTH_F)
		 (raylib#vec2-x-set! pos 0.0))
		((< (raylib#vec2-x pos) 0.0)
		 (raylib#vec2-x-set! pos (+ (raylib#vec2-x pos) VP_WIDTH_F)))
		((> (raylib#vec2-y pos) VP_HEIGHT_F)
		 (raylib#vec2-y-set! pos 0.0))
		((< (raylib#vec2-y pos) 0.0)
		 (raylib#vec2-y-set! pos (+ (raylib#vec2-y pos) VP_HEIGHT_F)))))

(define (update state)
  (cond ((raylib#key-pressed? KEY_RIGHT)
		 (state-direction-set! state 'right))
		((raylib#key-pressed? KEY_LEFT)
		 (state-direction-set! state 'left))
		((raylib#key-pressed? KEY_UP)
		 (state-direction-set! state 'down))
		((raylib#key-pressed? KEY_DOWN)
		 (state-direction-set! state 'up)))
  (when (and game-running (= FC 10))
	(set! FC 0)
	(let* ((last-limb (vector-ref (state-snake-limbs state) 0))
		   (new-limb (cond ((eq? 'right (state-direction state))
							(raylib#make-vec2 (+ (raylib#vec2-x last-limb)
												 GRID_SIZE_F)
											  (raylib#vec2-y last-limb)))
						   ((eq? 'left (state-direction state))
							(raylib#make-vec2 (- (raylib#vec2-x last-limb)
												 GRID_SIZE_F)
											  (raylib#vec2-y last-limb)))
						   ((eq? 'up (state-direction state))
							(raylib#make-vec2 (raylib#vec2-x last-limb)
											  (+ (raylib#vec2-y last-limb)
												 GRID_SIZE_F)))
						   ((eq? 'down (state-direction state))
							(raylib#make-vec2 (raylib#vec2-x last-limb)
											  (- (raylib#vec2-y last-limb)
												 GRID_SIZE_F))))))
	  (wrap new-limb)
	  (if (not (check-pos new-limb
					 (cdr (vector->list (state-snake-limbs state)))))
		  (set! game-running #f))
	  (if (and (= (raylib#vec2-x (state-apple-pos state))
				  (raylib#vec2-x new-limb))
			   (= (raylib#vec2-y (state-apple-pos state))
				  (raylib#vec2-y new-limb)))
		  (begin
			(state-snake-limbs-set! state
									(vector-append (make-vector 1 new-limb)
												   (state-snake-limbs state)))
			(place-apple! state))
		  (begin
			(vector-copy! (state-snake-limbs state) 1
						  (state-snake-limbs state) 0
						  (- (vector-length (state-snake-limbs state)) 1))
			(vector-set! (state-snake-limbs state) 0 new-limb)))))
  state)

(define (draw-snake limbs sq_sz)
  (unless (null? limbs)
	(raylib#draw-rectangle-V (car limbs) sq_sz WHITE)
	(raylib#draw-rec-lines (raylib#make-rec (raylib#vec2-x (car limbs))
											(raylib#vec2-y (car limbs))
											GRID_SIZE_F GRID_SIZE_F)
						   1.0 BLACK)
	(draw-snake (cdr limbs) sq_sz)))

(define (draw state)
  (with-drawing
    (raylib#clear-background BLACK)
    ;; (raylib#draw-fps 5 5)

	;; draw snake
	(draw-snake (vector->list (state-snake-limbs state))
				(state-square-dims state))
	
    ;; draw apple
    (raylib#draw-rectangle-V (state-apple-pos state)
                             (state-square-dims state)
                             RED)))

(define (main-loop state)
  (unless (raylib#window-sould-close)
	(set! FC (+ FC 1))
	(update state)
	(draw state)
	(main-loop state)))
	  

(define (init)
  (make-state (vector (raylib#make-vec2 (* 6.0 GRID_SIZE_F) GRID_SIZE_F)
					  (raylib#make-vec2 (* 5.0 GRID_SIZE_F) GRID_SIZE_F)
					  (raylib#make-vec2 (* 4.0 GRID_SIZE_F) GRID_SIZE_F))
			  (raylib#make-vec2 0.0 0.0)
			  (raylib#make-vec2 GRID_SIZE_F GRID_SIZE_F)
			  0
			  'right))

(define (main arg)
  (raylib#set-target-fps 60)
  (raylib#init-window VP_WIDTH VP_HEIGHT "snek")
  (raylib#set-exit-key KEY_ESC)
  (set! game-running #t)
  (display "GAME ON!")
  (let ((state (init)))
	(place-apple! state)
	(main-loop state))
  (raylib#close-window))

(main '())