root/trunk/Tetris4Android/src/com/androidside/demo/tetris/BoardView.java

리비전 24, 10.7 kB (mefour에 의해 체크인됨, 15 년 전)

우태경

Line 
1 package com.androidside.demo.tetris;
2
3 import android.content.Context;
4 import android.graphics.Canvas;
5 import android.graphics.Paint;
6 import android.graphics.Rect;
7 import android.graphics.RectF;
8 import android.os.Bundle;
9 import android.util.AttributeSet;
10 import android.util.Log;
11 import android.view.View;
12
13 public class BoardView extends View {
14
15         static int squareLength; // square ���ш린 (in pixel)
16
17         static int COLS = Tetris4Android.COLS;  // columns
18         static int ROWS = Tetris4Android.ROWS;  // rows
19
20         int colors[];
21
22         Rect rectClient = new Rect();                   // �ъ� 媛������㈃ ��      Rect rectBoard = new Rect();                    // ������ ���由ъ� �����
23
24         // ��� �댁�
25         byte boardPrev[][];                                     // 吏�� ��� �댁�
26         byte boardCurr[][];                                     // ��� (蹂�꼍 �� ��� �댁�
27
28         Square pieceCurr[] = new Square[4];     // �����釉��
29
30         private byte mode = READY;                              // ��� 寃�������
31
32         public static final byte PAUSE = 0;             // �쇱� 以��
33         public static final byte READY = 1;     // 寃�� ��� ��以�� ���
34         public static final byte RUNNING = 2;   // 寃�� 吏�� 以�   public static final byte END = 3;               // 寃�� 醫����
35         public BoardView(Context context) {
36                 super(context);
37                 init();
38         }
39
40         public BoardView(Context context, AttributeSet attrs, int defStyle) {
41                 super(context, attrs, defStyle);
42                 init();
43         }
44
45         public BoardView(Context context, AttributeSet attrs) {
46                 super(context, attrs);
47                 init();
48         }
49
50         /**
51          * �대���� �ъ���� 媛�� �댁������ 珥�린 �ㅼ�
52          */
53         void init() {
54
55                 colors = new int[8]; // �대���� �ъ���� ����ㅼ� 吏�����.
56
57                 colors[0] = 0xff000060; // 諛곌꼍��
58                 // 釉����� �ъ���� ���
59                 colors[1] = 0xffff0000; // red
60                 colors[2] = 0xff00c800; // green
61                 colors[3] = 0xff00c8ff; // light blue
62                 colors[4] = 0xffffff00; // yellow
63                 colors[5] = 0xffff9600; // orange
64                 colors[6] = 0xffd200f0; // purple
65                 colors[7] = 0xff2800f0; // dark bluer
66
67                 // ��� ������ 怨듦���������.
68                 boardPrev = new byte[Tetris4Android.COLS][Tetris4Android.ROWS + 4];
69                 boardCurr = new byte[Tetris4Android.COLS][Tetris4Android.ROWS + 4];
70
71                 // fillBoard();
72                 showAllBlocks();
73                 // cleanBoard();
74         }
75
76         /* ��������媛������吏������린 ��� ����몄� */
77         private void fillBoard() {
78                 for (int r = 0; r < ROWS; r++) {
79                         for (int c = 0; c < COLS; c++) {
80                                 boardCurr[c][r] = (byte) (((r + c) % (colors.length - 1)) + 1);
81                         }
82                 }
83         }
84
85         public byte getMode() {
86                 return mode;
87         }
88
89         public void setMode(byte mode) {
90                 this.mode = mode;
91         }
92        
93         /* 紐⑤� 釉���������� ��㈃��異����以�� */
94         private void showAllBlocks() {
95                 for (int i = 0; i <= 6; i++) {
96                         newBlock(i);
97                         moveCurrentPiece(0, (6 - i) * 3, false);
98                 }
99         }
100
101         /* ��� 紐⑤� �댁���吏��怨������釉����珥�린����� 寃�� ��� ��以�� �④��대�. */
102         void cleanBoard() {
103                 for (int c = 0; c < COLS; c++) {
104                         for (int r = 0; r < ROWS; r++) {
105                                 boardPrev[c][r] = -1;
106                                 boardCurr[c][r] =  0;
107                         }
108                 }
109
110                 pieceCurr = new Square[4];
111         }
112
113         @Override
114         protected void onSizeChanged(int w, int h, int oldw, int oldh) {
115                 super.onSizeChanged(w, h, oldw, oldh);
116
117                 // 二쇱�吏���㈃ �����諛���쇰� �ㅼ� �ъ��������怨�����.
118                 int width = w / COLS;
119                 int height = h / ROWS;
120
121                 squareLength = Math.min(width, height);
122
123                 rectClient = new Rect(0, 0, w, h);
124
125                 int xoffset = (w - squareLength * COLS) / 2;
126                 int yoffset = (h - squareLength * ROWS) / 2;
127
128                 rectBoard = new Rect(
129                                         xoffset, yoffset,
130                                         xoffset + squareLength * COLS, yoffset + squareLength * ROWS);
131
132                 Log.v(Tetris4Android.TAG, " SQUARE LEN = " + squareLength);
133                 Log.v(Tetris4Android.TAG, "CLIENT RECT (" + rectClient.left + "," + rectClient.top + ")-(" + rectClient.right + ","     + rectClient.bottom + ")");
134                 Log.v(Tetris4Android.TAG, " BOARD RECT (" + rectBoard.left + ","  + rectBoard.top + ")-(" + rectBoard.right + ","       + rectBoard.bottom + ")");
135         }
136
137         /*
138          * 蹂�꼍 �������� 蹂�꼍 �����濡���릿�� ���� ��꺼吏������吏��щ���������.
139          */
140         private boolean moveBlocks(Square from[], Square to[]) {
141
142                 outerlabel:
143
144                 for (int i = 0; i < to.length; i++) {
145
146                         if (!to[i].isInBounds()) {
147                                 return false;
148                         }
149
150                         if (boardCurr[to[i].getX()][to[i].getY()] != 0) {
151
152                                 for (int j = 0; j < from.length; j++)
153                                 {
154                                         if (to[i].isEqual(from[j])) {
155                                                 continue outerlabel;
156                                         }
157                                 }
158                                 return false;
159                         }
160                 }
161
162                 // blank old piece
163                 for (int i = 0; i < from.length; i++)
164                 {
165                         if (from[i].isInBounds()) {
166                                 boardCurr[from[i].getX()][from[i].getY()] =  0;
167                                 boardPrev[from[i].getX()][from[i].getY()] = -1;
168                         }
169                 }
170
171                 for (int i = 0; i < to.length; i++)
172                 {
173                         boardCurr[to[i].getX()][to[i].getY()] = to[i].getColor();
174                 }
175
176                 return true;
177         }
178
179         /*
180          * �����釉����������. 留��, �����釉��������������硫�         * (怨듦���苑�李�寃쎌�) false 瑜�諛�����.
181          */
182         protected boolean newBlock() {
183
184                 // �����釉���대�濡� 湲곗〈���������諛�� ����쇰� 吏�����.
185                 Square old[] = new Square[4];
186                 old[0] = old[1] = old[2] = old[3] = new Square(-1, -1, (byte) 0);
187
188                 // �����紐⑥���媛���ㅻ�濡����.
189                 int blockType = (int) (Math.random() * 7);
190
191                 // 釉����������.
192                 newBlock(blockType);
193
194                 // �����釉�����대����.
195                 // 留��, �대����ㅽ����硫���㈃ 以�� ����������釉���������� �����                // �대� �ㅻⅨ 釉����議댁���� 寃쎌�) false 瑜�諛�����.
196                 return moveBlocks(old, pieceCurr);
197
198         }
199
200         /*
201          * ��㈃ 以�� �����吏��������������釉����������. �����釉���������釉���쇰� 吏�����.
202          */
203         private void newBlock(int type) {
204
205                 int m = COLS / 2;
206
207                 switch (type) {
208                 case 0:
209                         // ####
210                         pieceCurr[0] = new Square(m - 1, 0, (byte) 1);
211                         pieceCurr[1] = new Square(m - 2, 0, (byte) 1);
212                         pieceCurr[2] = new Square(m, 0, (byte) 1);
213                         pieceCurr[3] = new Square(m + 1, 0, (byte) 1);
214                         break;
215
216                 case 1:
217                         // ###
218                         // #
219                         pieceCurr[0] = new Square(m, 0, (byte) 5);
220                         pieceCurr[1] = new Square(m, 1, (byte) 5);
221                         pieceCurr[2] = new Square(m - 1, 0, (byte) 5);
222                         pieceCurr[3] = new Square(m + 1, 0, (byte) 5);
223                         break;
224
225                 case 2:
226                         // ##
227                         // ##
228                         pieceCurr[0] = new Square(m, 0, (byte) 2);
229                         pieceCurr[1] = new Square(m - 1, 1, (byte) 2);
230                         pieceCurr[2] = new Square(m, 1, (byte) 2);
231                         pieceCurr[3] = new Square(m + 1, 0, (byte) 2);
232                         break;
233
234                 case 3:
235                         // ##
236                         // ##
237                         pieceCurr[0] = new Square(m, 0, (byte) 7);
238                         pieceCurr[1] = new Square(m + 1, 1, (byte) 7);
239                         pieceCurr[2] = new Square(m, 1, (byte) 7);
240                         pieceCurr[3] = new Square(m - 1, 0, (byte) 7);
241                         break;
242
243                 case 4:
244                         // ##
245                         // ##
246                         pieceCurr[0] = new Square(m - 1, 1, (byte) 3);
247                         pieceCurr[1] = new Square(m, 1, (byte) 3);
248                         pieceCurr[2] = new Square(m - 1, 0, (byte) 3);
249                         pieceCurr[3] = new Square(m, 0, (byte) 3);
250
251                         break;
252
253                 case 5:
254                         // #
255                         // ###
256                         pieceCurr[0] = new Square(m, 1, (byte) 6);
257                         pieceCurr[1] = new Square(m - 1, 1, (byte) 6);
258                         pieceCurr[2] = new Square(m + 1, 1, (byte) 6);
259                         pieceCurr[3] = new Square(m + 1, 0, (byte) 6);
260                         break;
261
262                 case 6:
263                         // #
264                         // ###
265                         pieceCurr[0] = new Square(m, 1, (byte) 4);
266                         pieceCurr[1] = new Square(m + 1, 1, (byte) 4);
267                         pieceCurr[2] = new Square(m - 1, 1, (byte) 4);
268                         pieceCurr[3] = new Square(m - 1, 0, (byte) 4);
269                         break;
270                 }
271         }
272
273         /**
274          * �����釉�����대����.
275          *
276          * @param byx
277          *            ��� �대� 蹂��
278          * @param byy
279          *            ��� �대� 蹂��
280          * @param rotate
281          *            ��� �щ�
282          *
283          * @return �대� 媛����寃쎌� true, 洹몃�吏�紐삵� 寃쎌� false
284          */
285         synchronized boolean moveCurrentPiece(int byx, int byy, boolean rotate) {
286
287                 Square newpos[] = new Square[4];
288
289                 for (int i = 0; i < 4; i++) {
290                         if (rotate) {
291                                 int dx = pieceCurr[i].getX() - pieceCurr[0].getX();
292                                 int dy = pieceCurr[i].getY() - pieceCurr[0].getY();
293
294                                 newpos[i] = new Square(pieceCurr[0].getX() + dy, pieceCurr[0].getY() - dx, pieceCurr[i].getColor());
295
296                         } else {
297                                 newpos[i] = new Square(pieceCurr[i].getX() + byx, pieceCurr[i].getY() + byy, pieceCurr[i].getColor());
298                         }
299                 }
300
301                 if (!moveBlocks(pieceCurr, newpos))
302                         return false;
303
304                 pieceCurr = newpos;
305
306                 return true;
307         }
308
309         /**
310          * ��㈃��洹몃━��遺���대�.
311          */
312         @Override
313         protected void onDraw(Canvas canvas) {
314                 super.onDraw(canvas);
315
316                 Log.v(Tetris4Android.TAG, "DRAWING BOARD");
317
318                 Paint p = new Paint();
319
320                 p.setColor(0xffffffff);
321                 canvas.drawRect(rectClient, p);
322
323                 p.setColor(colors[0] & 0xe0ffffff);
324                 canvas.drawRect(rectBoard, p);
325
326                 for (int c = 0; c < COLS; c++) {
327                         for (int r = 0; r < ROWS; r++) {
328                                 {
329                                         p.setColor(colors[boardCurr[c][r]]);
330
331                                         // Log.v(Tetris4Android.TAG4LOG,
332                                         // "("+rectSquare.left+","+rectSquare.top+")-("+rectSquare.right+","+rectSquare.bottom+") COLOR = "
333                                         // + colors[boardCurr[c][r]]);
334
335                                         // RoundRect
336                                         {
337                                                 RectF rectSquare = new RectF(
338                                                                   rectBoard.left + squareLength * c, rectBoard.top + squareLength * r
339                                                                 , rectBoard.left + squareLength * (c + 1) - 1, rectBoard.top + squareLength * (r + 1) - 1
340                                                 );
341                                                 canvas.drawRoundRect(rectSquare, 4F, 4F, p);
342                                         }
343 //                                      // BasicRect
344 //                                      {
345 //                                              Rect rectSquare = new Rect(
346 //                                                                rectBoard.left + squareLength * c, rectBoard.top + squareLength * r
347 //                                                                      , rectBoard.left + squareLength * (c + 1) - 1, rectBoard.top + squareLength * (r + 1) - 1
348 //                                              );
349 //                                              canvas.drawRect(rectSquare, p);
350 //                                      }
351                                         boardPrev[c][r] = boardCurr[c][r];
352                                 }
353                         }
354                 }
355         }
356
357         /* 梨��吏��쇱������硫�吏���� */
358         void removeCompleteLines() {
359
360                 for (int r = ROWS - 1; r >= 0; r--) {
361                         int c;
362                         for (c = 0; c < COLS; c++) {
363                                 if (boardCurr[c][r] <= 0)       // 鍮�怨듦������硫� ���댄�蹂����媛����.
364                                         break;
365                         }
366
367                         // 梨��議��硫�..
368                         if (c == COLS) {
369                                 for (int k = r; k > 0; k--) {
370                                         for (int l = 0; l < COLS; l++) {
371                                                 boardCurr[l][k] = boardCurr[l][k - 1];
372                                         }
373                                 }
374                                 // ��� ��以�� �щ�媛��誘��, �ㅼ� �����以�� 寃�����.
375                                 r++;
376                         }
377                 }
378         }
379
380         /* ��������瑜�����������濡����. �닿���restoreState() ����� �대(�댁� ���. */
381         public Bundle saveState() {
382
383                 Bundle map = new Bundle();
384
385                 byte board[] = new byte[COLS * ROWS];
386                 for (int c = 0; c < COLS; c++) {
387                         for (int r = 0; r < ROWS; r++) {
388                                 board[r * COLS + c] = boardCurr[c][r];
389                         }
390                 }
391
392                 map.putByte("mode", mode);
393                 map.putByteArray("boardCurr", board);
394
395                 return map;
396         }
397
398         /* ��������瑜�蹂듭����. �닿���saveState() ����� �대(�댁� ���. */
399         public void restoreState(Bundle map) {
400
401                 setMode(PAUSE);
402
403                 byte board[];
404                 board = map.getByteArray("boardCurr");
405
406                 for (int c = 0; c < COLS; c++) {
407                         for (int r = 0; r < ROWS; r++) {
408                                 boardCurr[c][r] = board[r * COLS + c];
409                         }
410                 }
411
412                 setMode(map.getByte("mode"));
413         }
414 }
참고: 소스 브라우저를 사용하면서 도움이 필요하다면, TracBrowser를 참고하십시오.