-
Notifications
You must be signed in to change notification settings - Fork 0
/
game-field.lisp
147 lines (133 loc) · 5.57 KB
/
game-field.lisp
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
(defgeneric draw-init (game-field)
(:documentation "テトリミノのサイズにあわせ, 画面をリサイズする"))
(defgeneric draw-array (xmax ymax margin mino-size)
(:documentation "ゲームフィールドを描画する"))
(defgeneric draw-status-box (game-field)
(:documentation "ステータスボックスを描画する"))
(defgeneric draw-tetrimino (game-field)
(:documentation "テトリミノを描画する"))
(defgeneric draw-mino-stack (game-field)
(:documentation "テトリミノスタックを描画する"))
(defgeneric update-field (game-field)
(:documentation "画面を更新する"))
(defclass game-field ()
((margin
:reader get-field-margin
:initarg :margin
:initform 10
:documentation "ゲーム画面のマージン")
(mino-array
:reader game-field-array
:initarg :mino-array
:initform (make-array '(10 20))
:documentation "テトリミノ格納用配列")
(mino-size
:reader tetrimino-size
:initarg :mino-size
:initform 20
:documentation "テトリミノ格納用配列の描画サイズ")
(mino
:reader falling-tetrimino
:initarg :mino
:initform nil
:documentation "落下中のテトリミノ")
(mino-stack
:reader mino-stack
:initarg :mino-stack
:initform nil
:documentation "テトリミノスタック")
(status
:reader get-status-box
:initarg :status
:initform nil
:documentation "ステータスボックス")
))
;; 描画初期化
(defmethod draw-init ((game-field game-field))
(let ((margin (get-field-margin game-field))
(array-width (array-dimension (game-field-array game-field) 0))
(array-height (array-dimension (game-field-array game-field) 1))
(mino-size (tetrimino-size game-field))
(status (get-status-box game-field)))
(let ((status-width (get-status-box-w status)))
(sdl:resize-window (+ (* mino-size array-width) (* margin 3) status-width)
(+ (* mino-size array-height) (* margin 2))))))
;; ゲームフィールドを描画する
(defmethod draw-array (xmax ymax margin mino-size)
(dotimes (x xmax)
(dotimes (y ymax)
;; 四角形描画
(sdl:draw-box-* (+ margin (* x mino-size)) ; 左上頂点のX座標
(+ margin (* y mino-size)) ; 左上頂点のY座標
mino-size ; 幅
mino-size ; 高さ
:color sdl:*black* ; 中の色
:stroke-color sdl:*white*)))) ; 辺の色
;; ステータスボックスを描画する
(defmethod draw-status-box ((game-field game-field))
(let ((xmax (array-dimension (game-field-array game-field) 0))
(margin (get-field-margin game-field))
(mino-size (tetrimino-size game-field))
(status-box (get-status-box game-field)))
(let ((width (get-status-box-w status-box))
(height (get-status-box-h status-box))
(time (get-status-time status-box))
(score (get-status-score status-box)))
;; 四角形描画
(sdl:draw-box-* (+ (* margin 2) (* xmax mino-size)) ; 左上頂点のX座標
margin ; 左上頂点のY座標
width ; 幅
height ; 高さ
:color sdl:*black* ; 中の色
:stroke-color sdl:*white*) ; 辺の色
(sdl:draw-string-solid-* (format nil "time : ~D" time) (+ (+ (* margin 2) (* xmax mino-size)) 10) (+ margin 10))
(sdl:draw-string-solid-* (format nil "score : ~D" score) (+ (+ (* margin 2) (* xmax mino-size)) 10) (+ margin (* 10 3))))))
;; テトリミノを描画する
(defmethod draw-tetrimino ((game-field game-field))
(let ((tetrimino (falling-tetrimino game-field))
(margin (get-field-margin game-field))
(mino-size (tetrimino-size game-field)))
(let ((x (mino-x-array tetrimino))
(y (mino-y-array tetrimino))
(form (mino-form tetrimino))
(form-x (array-dimension (mino-form tetrimino) 0))
(form-y (array-dimension (mino-form tetrimino) 1)))
(dotimes (i form-x)
(dotimes (j form-y)
(when (< 0 (aref form i j))
;; 四角形描画
(sdl:draw-box-* (+ margin (* (+ i x) mino-size)) ; 左上頂点のX座標
(+ margin (* (+ j y) mino-size)) ; 左上頂点のY座標
mino-size ; 幅
mino-size ; 高さ
:color sdl:*blue* ; 中の色
:stroke-color sdl:*white*))))))) ; 辺の色
;; テトリミノスタックを描画する
(defmethod draw-mino-stack ((game-field game-field))
(let ((margin (get-field-margin game-field))
(mino-size (tetrimino-size game-field))
(mino-stack (mino-stack game-field)))
(let ((elems-x (array-dimension (get-mino-stack mino-stack) 0))
(elems-y (array-dimension (get-mino-stack mino-stack) 1))
(stack (get-mino-stack mino-stack)))
(dotimes (i elems-x)
(dotimes (j elems-y)
(when (< 0 (aref stack i j))
;; 四角形描画
(sdl:draw-box-* (+ margin (* i mino-size)) ; 左上頂点のX座標
(+ margin (* j mino-size)) ; 左上頂点のY座標
mino-size ; 幅
mino-size ; 高さ
:color sdl:*blue* ; 中の色
:stroke-color sdl:*white*))))))) ; 辺の色
;; 画面を更新する
;; テトリミノ, ステータスボックス, ゲームフィールドを描画する
(defmethod update-field ((game-field game-field))
(let ((margin (get-field-margin game-field))
(array-width (array-dimension (game-field-array game-field) 0))
(array-height (array-dimension (game-field-array game-field) 1))
(mino-size (tetrimino-size game-field)))
(draw-array array-width array-height margin mino-size)
(draw-status-box game-field)
(draw-tetrimino game-field)
(draw-mino-stack game-field)))