Index: /trunk/Tetris4Android/default.properties =================================================================== --- /trunk/Tetris4Android/default.properties (revision 24) +++ /trunk/Tetris4Android/default.properties (revision 24) @@ -0,0 +1,13 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Indicates whether an apk should be generated for each density. +split.density=false +# Project target. +target=android-5 Index: /trunk/Tetris4Android/.classpath =================================================================== --- /trunk/Tetris4Android/.classpath (revision 24) +++ /trunk/Tetris4Android/.classpath (revision 24) @@ -0,0 +1,7 @@ + + + + + + + Index: /trunk/Tetris4Android/.project =================================================================== --- /trunk/Tetris4Android/.project (revision 24) +++ /trunk/Tetris4Android/.project (revision 24) @@ -0,0 +1,33 @@ + + + Tetris4Android + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + Index: /trunk/Tetris4Android/AndroidManifest.xml =================================================================== --- /trunk/Tetris4Android/AndroidManifest.xml (revision 24) +++ /trunk/Tetris4Android/AndroidManifest.xml (revision 24) @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + Index: /trunk/Tetris4Android/src/com/androidside/demo/tetris/Tetris4Android.java =================================================================== --- /trunk/Tetris4Android/src/com/androidside/demo/tetris/Tetris4Android.java (revision 24) +++ /trunk/Tetris4Android/src/com/androidside/demo/tetris/Tetris4Android.java (revision 24) @@ -0,0 +1,22 @@ +package com.androidside.demo.tetris; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; + +public class Tetris4Android extends Activity { + + public static final String TAG = "Tetris"; // for Logging + + // ��껜 ��� �ш린 (移멸낵 以��� + public final static int COLS = 10; // ��� 移��� public final static int ROWS = 20; // ��� 以��� + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Log.v(TAG, "onCreate()"); + + setContentView(R.layout.main); + } +} Index: /trunk/Tetris4Android/src/com/androidside/demo/tetris/Square.java =================================================================== --- /trunk/Tetris4Android/src/com/androidside/demo/tetris/Square.java (revision 24) +++ /trunk/Tetris4Android/src/com/androidside/demo/tetris/Square.java (revision 24) @@ -0,0 +1,36 @@ +package com.androidside.demo.tetris; + +public class Square { + + int x, y; // X 醫��, Y 醫�� + byte color; // ��� + + Square(int x, int y, byte color) { + + this.x = x; + this.y = y; + this.color = color; + } + + int getX() { + return x; + } + + int getY() { + return y; + } + + byte getColor() { + return color; + } + + // ������ш���� ����� 議댁���� 寃��吏���� + boolean isInBounds() { + return (x >= 0 && x < Tetris4Android.COLS && y >= 0 && y < Tetris4Android.ROWS); + } + + boolean isEqual(Square s) { + + return x == s.x && y == s.y && color == s.color; + } +} Index: /trunk/Tetris4Android/src/com/androidside/demo/tetris/BoardView.java =================================================================== --- /trunk/Tetris4Android/src/com/androidside/demo/tetris/BoardView.java (revision 24) +++ /trunk/Tetris4Android/src/com/androidside/demo/tetris/BoardView.java (revision 24) @@ -0,0 +1,414 @@ +package com.androidside.demo.tetris; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.RectF; +import android.os.Bundle; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; + +public class BoardView extends View { + + static int squareLength; // square ���ш린 (in pixel) + + static int COLS = Tetris4Android.COLS; // columns + static int ROWS = Tetris4Android.ROWS; // rows + + int colors[]; + + Rect rectClient = new Rect(); // �ъ� 媛������㈃ �� Rect rectBoard = new Rect(); // ������ ���由ъ� ����� + + // ��� �댁� + byte boardPrev[][]; // 吏�� ��� �댁� + byte boardCurr[][]; // ��� (蹂�꼍 �� ��� �댁� + + Square pieceCurr[] = new Square[4]; // �����釉�� + + private byte mode = READY; // ��� 寃������� + + public static final byte PAUSE = 0; // �쇱� 以�� + public static final byte READY = 1; // 寃�� ��� ��以�� ��� + public static final byte RUNNING = 2; // 寃�� 吏�� 以� public static final byte END = 3; // 寃�� 醫���� + public BoardView(Context context) { + super(context); + init(); + } + + public BoardView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + public BoardView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + /** + * �대���� �ъ���� 媛�� �댁������ 珥�린 �ㅼ� + */ + void init() { + + colors = new int[8]; // �대���� �ъ���� ����ㅼ� 吏�����. + + colors[0] = 0xff000060; // 諛곌꼍�� + // 釉����� �ъ���� ��� + colors[1] = 0xffff0000; // red + colors[2] = 0xff00c800; // green + colors[3] = 0xff00c8ff; // light blue + colors[4] = 0xffffff00; // yellow + colors[5] = 0xffff9600; // orange + colors[6] = 0xffd200f0; // purple + colors[7] = 0xff2800f0; // dark bluer + + // ��� ������ 怨듦���������. + boardPrev = new byte[Tetris4Android.COLS][Tetris4Android.ROWS + 4]; + boardCurr = new byte[Tetris4Android.COLS][Tetris4Android.ROWS + 4]; + + // fillBoard(); + showAllBlocks(); + // cleanBoard(); + } + + /* ��������媛������吏������린 ��� ����몄� */ + private void fillBoard() { + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + boardCurr[c][r] = (byte) (((r + c) % (colors.length - 1)) + 1); + } + } + } + + public byte getMode() { + return mode; + } + + public void setMode(byte mode) { + this.mode = mode; + } + + /* 紐⑤� 釉���������� ��㈃��異����以�� */ + private void showAllBlocks() { + for (int i = 0; i <= 6; i++) { + newBlock(i); + moveCurrentPiece(0, (6 - i) * 3, false); + } + } + + /* ��� 紐⑤� �댁���吏��怨������釉����珥�린����� 寃�� ��� ��以�� �④��대�. */ + void cleanBoard() { + for (int c = 0; c < COLS; c++) { + for (int r = 0; r < ROWS; r++) { + boardPrev[c][r] = -1; + boardCurr[c][r] = 0; + } + } + + pieceCurr = new Square[4]; + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + + // 二쇱�吏���㈃ �����諛���쇰� �ㅼ� �ъ��������怨�����. + int width = w / COLS; + int height = h / ROWS; + + squareLength = Math.min(width, height); + + rectClient = new Rect(0, 0, w, h); + + int xoffset = (w - squareLength * COLS) / 2; + int yoffset = (h - squareLength * ROWS) / 2; + + rectBoard = new Rect( + xoffset, yoffset, + xoffset + squareLength * COLS, yoffset + squareLength * ROWS); + + Log.v(Tetris4Android.TAG, " SQUARE LEN = " + squareLength); + Log.v(Tetris4Android.TAG, "CLIENT RECT (" + rectClient.left + "," + rectClient.top + ")-(" + rectClient.right + "," + rectClient.bottom + ")"); + Log.v(Tetris4Android.TAG, " BOARD RECT (" + rectBoard.left + "," + rectBoard.top + ")-(" + rectBoard.right + "," + rectBoard.bottom + ")"); + } + + /* + * 蹂�꼍 �������� 蹂�꼍 �����濡���릿�� ���� ��꺼吏������吏��щ���������. + */ + private boolean moveBlocks(Square from[], Square to[]) { + + outerlabel: + + for (int i = 0; i < to.length; i++) { + + if (!to[i].isInBounds()) { + return false; + } + + if (boardCurr[to[i].getX()][to[i].getY()] != 0) { + + for (int j = 0; j < from.length; j++) + { + if (to[i].isEqual(from[j])) { + continue outerlabel; + } + } + return false; + } + } + + // blank old piece + for (int i = 0; i < from.length; i++) + { + if (from[i].isInBounds()) { + boardCurr[from[i].getX()][from[i].getY()] = 0; + boardPrev[from[i].getX()][from[i].getY()] = -1; + } + } + + for (int i = 0; i < to.length; i++) + { + boardCurr[to[i].getX()][to[i].getY()] = to[i].getColor(); + } + + return true; + } + + /* + * �����釉����������. 留��, �����釉��������������硫� * (怨듦���苑�李�寃쎌�) false 瑜�諛�����. + */ + protected boolean newBlock() { + + // �����釉���대�濡� 湲곗〈���������諛�� ����쇰� 吏�����. + Square old[] = new Square[4]; + old[0] = old[1] = old[2] = old[3] = new Square(-1, -1, (byte) 0); + + // �����紐⑥���媛���ㅻ�濡����. + int blockType = (int) (Math.random() * 7); + + // 釉����������. + newBlock(blockType); + + // �����釉�����대����. + // 留��, �대����ㅽ����硫���㈃ 以�� ����������釉���������� ����� // �대� �ㅻⅨ 釉����議댁���� 寃쎌�) false 瑜�諛�����. + return moveBlocks(old, pieceCurr); + + } + + /* + * ��㈃ 以�� �����吏��������������釉����������. �����釉���������釉���쇰� 吏�����. + */ + private void newBlock(int type) { + + int m = COLS / 2; + + switch (type) { + case 0: + // #### + pieceCurr[0] = new Square(m - 1, 0, (byte) 1); + pieceCurr[1] = new Square(m - 2, 0, (byte) 1); + pieceCurr[2] = new Square(m, 0, (byte) 1); + pieceCurr[3] = new Square(m + 1, 0, (byte) 1); + break; + + case 1: + // ### + // # + pieceCurr[0] = new Square(m, 0, (byte) 5); + pieceCurr[1] = new Square(m, 1, (byte) 5); + pieceCurr[2] = new Square(m - 1, 0, (byte) 5); + pieceCurr[3] = new Square(m + 1, 0, (byte) 5); + break; + + case 2: + // ## + // ## + pieceCurr[0] = new Square(m, 0, (byte) 2); + pieceCurr[1] = new Square(m - 1, 1, (byte) 2); + pieceCurr[2] = new Square(m, 1, (byte) 2); + pieceCurr[3] = new Square(m + 1, 0, (byte) 2); + break; + + case 3: + // ## + // ## + pieceCurr[0] = new Square(m, 0, (byte) 7); + pieceCurr[1] = new Square(m + 1, 1, (byte) 7); + pieceCurr[2] = new Square(m, 1, (byte) 7); + pieceCurr[3] = new Square(m - 1, 0, (byte) 7); + break; + + case 4: + // ## + // ## + pieceCurr[0] = new Square(m - 1, 1, (byte) 3); + pieceCurr[1] = new Square(m, 1, (byte) 3); + pieceCurr[2] = new Square(m - 1, 0, (byte) 3); + pieceCurr[3] = new Square(m, 0, (byte) 3); + + break; + + case 5: + // # + // ### + pieceCurr[0] = new Square(m, 1, (byte) 6); + pieceCurr[1] = new Square(m - 1, 1, (byte) 6); + pieceCurr[2] = new Square(m + 1, 1, (byte) 6); + pieceCurr[3] = new Square(m + 1, 0, (byte) 6); + break; + + case 6: + // # + // ### + pieceCurr[0] = new Square(m, 1, (byte) 4); + pieceCurr[1] = new Square(m + 1, 1, (byte) 4); + pieceCurr[2] = new Square(m - 1, 1, (byte) 4); + pieceCurr[3] = new Square(m - 1, 0, (byte) 4); + break; + } + } + + /** + * �����釉�����대����. + * + * @param byx + * ��� �대� 蹂�� + * @param byy + * ��� �대� 蹂�� + * @param rotate + * ��� �щ� + * + * @return �대� 媛����寃쎌� true, 洹몃�吏�紐삵� 寃쎌� false + */ + synchronized boolean moveCurrentPiece(int byx, int byy, boolean rotate) { + + Square newpos[] = new Square[4]; + + for (int i = 0; i < 4; i++) { + if (rotate) { + int dx = pieceCurr[i].getX() - pieceCurr[0].getX(); + int dy = pieceCurr[i].getY() - pieceCurr[0].getY(); + + newpos[i] = new Square(pieceCurr[0].getX() + dy, pieceCurr[0].getY() - dx, pieceCurr[i].getColor()); + + } else { + newpos[i] = new Square(pieceCurr[i].getX() + byx, pieceCurr[i].getY() + byy, pieceCurr[i].getColor()); + } + } + + if (!moveBlocks(pieceCurr, newpos)) + return false; + + pieceCurr = newpos; + + return true; + } + + /** + * ��㈃��洹몃━��遺���대�. + */ + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + Log.v(Tetris4Android.TAG, "DRAWING BOARD"); + + Paint p = new Paint(); + + p.setColor(0xffffffff); + canvas.drawRect(rectClient, p); + + p.setColor(colors[0] & 0xe0ffffff); + canvas.drawRect(rectBoard, p); + + for (int c = 0; c < COLS; c++) { + for (int r = 0; r < ROWS; r++) { + { + p.setColor(colors[boardCurr[c][r]]); + + // Log.v(Tetris4Android.TAG4LOG, + // "("+rectSquare.left+","+rectSquare.top+")-("+rectSquare.right+","+rectSquare.bottom+") COLOR = " + // + colors[boardCurr[c][r]]); + + // RoundRect + { + RectF rectSquare = new RectF( + rectBoard.left + squareLength * c, rectBoard.top + squareLength * r + , rectBoard.left + squareLength * (c + 1) - 1, rectBoard.top + squareLength * (r + 1) - 1 + ); + canvas.drawRoundRect(rectSquare, 4F, 4F, p); + } +// // BasicRect +// { +// Rect rectSquare = new Rect( +// rectBoard.left + squareLength * c, rectBoard.top + squareLength * r +// , rectBoard.left + squareLength * (c + 1) - 1, rectBoard.top + squareLength * (r + 1) - 1 +// ); +// canvas.drawRect(rectSquare, p); +// } + boardPrev[c][r] = boardCurr[c][r]; + } + } + } + } + + /* 梨��吏��쇱������硫�吏���� */ + void removeCompleteLines() { + + for (int r = ROWS - 1; r >= 0; r--) { + int c; + for (c = 0; c < COLS; c++) { + if (boardCurr[c][r] <= 0) // 鍮�怨듦������硫� ���댄�蹂����媛����. + break; + } + + // 梨��議��硫�.. + if (c == COLS) { + for (int k = r; k > 0; k--) { + for (int l = 0; l < COLS; l++) { + boardCurr[l][k] = boardCurr[l][k - 1]; + } + } + // ��� ��以�� �щ�媛��誘��, �ㅼ� �����以�� 寃�����. + r++; + } + } + } + + /* ��������瑜�����������濡����. �닿���restoreState() ����� �대(�댁� ���. */ + public Bundle saveState() { + + Bundle map = new Bundle(); + + byte board[] = new byte[COLS * ROWS]; + for (int c = 0; c < COLS; c++) { + for (int r = 0; r < ROWS; r++) { + board[r * COLS + c] = boardCurr[c][r]; + } + } + + map.putByte("mode", mode); + map.putByteArray("boardCurr", board); + + return map; + } + + /* ��������瑜�蹂듭����. �닿���saveState() ����� �대(�댁� ���. */ + public void restoreState(Bundle map) { + + setMode(PAUSE); + + byte board[]; + board = map.getByteArray("boardCurr"); + + for (int c = 0; c < COLS; c++) { + for (int r = 0; r < ROWS; r++) { + boardCurr[c][r] = board[r * COLS + c]; + } + } + + setMode(map.getByte("mode")); + } +} Index: /trunk/Tetris4Android/res/values/strings.xml =================================================================== --- /trunk/Tetris4Android/res/values/strings.xml (revision 24) +++ /trunk/Tetris4Android/res/values/strings.xml (revision 24) @@ -0,0 +1,7 @@ + + + Hello World, Tetris4Android! + Tetris4Android + Tetris4Android + 寃�� ��/string> + Index: /trunk/Tetris4Android/res/layout/main.xml =================================================================== --- /trunk/Tetris4Android/res/layout/main.xml (revision 24) +++ /trunk/Tetris4Android/res/layout/main.xml (revision 24) @@ -0,0 +1,26 @@ + + + + + + + + + +