moving old AndroidTetris directory into this new one.
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="de.android.androidtetris"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="13" />
+
+ <application android:label="My AndroidTetris">
+ <activity android:name=".AndroidTetrisActivity"
+ android:theme="@android:style/Theme.NoTitleBar" android:configChanges="keyboard" android:screenOrientation="portrait">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+</manifest>
\ No newline at end of file
--- /dev/null
+/* AUTO-GENERATED FILE. DO NOT MODIFY.
+ *
+ * This class was automatically generated by the
+ * aapt tool from the resource data it found. It
+ * should not be modified by hand.
+ */
+
+package de.android.androidtetris;
+
+public final class R {
+ public static final class attr {
+ }
+ public static final class drawable {
+ public static final int greenstar=0x7f020000;
+ public static final int icon=0x7f020001;
+ public static final int redstar=0x7f020002;
+ public static final int yellowstar=0x7f020003;
+ }
+ public static final class layout {
+ public static final int main=0x7f030000;
+ }
+ public static final class string {
+ public static final int app_name=0x7f040001;
+ public static final int hello=0x7f040000;
+ }
+}
--- /dev/null
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+ native <methods>;
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+ public void *(android.view.View);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
--- /dev/null
+# 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,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-14
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+</LinearLayout>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="hello">Hello World, AndroidTetrisActivity!</string>
+ <string name="app_name">AndroidTetris</string>
+</resources>
--- /dev/null
+package de.android.androidtetris;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+
+public class AndroidTetrisActivity extends Activity {
+ DrawView drawView;
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ DisplayMetrics displayMetrics = new DisplayMetrics();
+ this.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
+
+ setContentView(R.layout.main);
+ drawView = new DrawView(this);
+ //drawView.setDimensions(displayMetrics.widthPixels, displayMetrics.heightPixels);
+ this.setContentView(drawView);
+ drawView.requestFocus();
+ }
+}
\ No newline at end of file
--- /dev/null
+/**
+ *
+ */
+package de.android.androidtetris;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This enum stores every piece and the square related to that piece.
+ *
+ * @author gusarapo
+ *
+ */
+public enum CurrentPiece {
+ /*The tower piece*/
+ I(0) {
+ @Override
+ void fill() {
+ size[1][0]=Tile.RED;
+ size[1][1]=Tile.RED;
+ size[1][2]=Tile.RED;
+ size[1][3]=Tile.RED;
+ }
+ },
+ /*The box piece*/
+ O(1) {
+ @Override
+ void fill() {
+ size[1][1]=Tile.BLUE;
+ size[1][2]=Tile.BLUE;
+ size[2][1]=Tile.BLUE;
+ size[2][2]=Tile.BLUE;
+ }
+ },
+ /*The pyramid piece*/
+ T(2) {
+ @Override
+ void fill() {
+ size[1][1]=Tile.YELLOW;
+ size[0][2]=Tile.YELLOW;
+ size[1][2]=Tile.YELLOW;
+ size[2][2]=Tile.YELLOW;
+ }
+ },
+ /*The left leaner piece*/
+ Z(3) {
+ @Override
+ void fill() {
+ size[0][1]=Tile.CYAN;
+ size[1][1]=Tile.CYAN;
+ size[1][2]=Tile.CYAN;
+ size[2][2]=Tile.CYAN;
+ }
+ },
+ /*The right leaner piece*/
+ S(4) {
+ @Override
+ void fill() {
+ size[2][1]=Tile.GREEN;
+ size[1][1]=Tile.GREEN;
+ size[1][2]=Tile.GREEN;
+ size[0][2]=Tile.GREEN;
+ }
+ },
+ /*The left knight piece*/
+ L(5) {
+ @Override
+ void fill() {
+ size[1][1]=Tile.MAGENTA;
+ size[2][1]=Tile.MAGENTA;
+ size[2][2]=Tile.MAGENTA;
+ size[2][3]=Tile.MAGENTA;
+ }
+ },
+ /*The right knight piece*/
+ J(6) {
+ @Override
+ void fill() {
+ size[2][1]=Tile.WHITE;
+ size[1][1]=Tile.WHITE;
+ size[1][2]=Tile.WHITE;
+ size[1][3]=Tile.WHITE;
+ }
+ };
+
+
+ //Every piece is contained in a square. This is the square's width.
+ public static final int WIDTH = 4;
+ //Every piece is contained in a square. This is the square's height.
+ public static final int HEIGHT = 4;
+ //Stores the x coordinate (the position of this piece on the grid)
+ public int x;
+ //Stores the y coordinate (the position of this piece on the grid)
+ public int y;
+ //Every piece is contained in a square.
+ public final Tile[][] size = new Tile[WIDTH][HEIGHT];
+ //Stores the argument of the enum constant (passed to the constructor) JLS§8.9.1
+ public final int pieceNumber;
+ //Map with every enum constant. Class variable initializer. JLS§12.4.2 Executed in textual order.
+ private static final Map<Integer, CurrentPiece> pieceMap = new HashMap<Integer, CurrentPiece>();
+
+
+ //Static initializer. JLS§12.4.2 Executed in textual order.
+ static {
+ for (CurrentPiece piece : CurrentPiece.values())
+ {
+ pieceMap.put(piece.pieceNumber, piece);
+ }
+ }
+
+
+ /**
+ * Because we have enum constants with arguments we have to create this constructor.
+ * It initializes the piece with the right values.
+ *
+ * @param pieceNumber It is the argument of the enum constant
+ */
+ private CurrentPiece (final int pieceNumber)
+ {
+ this.pieceNumber = pieceNumber;
+
+ //Pre-Initialization of matrix size
+ for (int i=0; i< WIDTH; i++)
+ for (int j=0; j< HEIGHT; j++)
+ size[i][j]= Tile.NOCOLOR;
+
+ this.x = 0;
+ this.y = 0;
+ //It depends on what kind of piece, we have to fill the square in the right way.
+ this.fill();
+ }
+
+
+ /**
+ * This method is used to retrieve the enum piece related to its number
+ *
+ * @param pieceNumber The piece number is associated to the argument of the enum constant.
+ * @return the enum whose argument of the enum constant matches the pieceNumber.
+ */
+ public static final CurrentPiece getPiece (final int pieceNumber)
+ {
+ return pieceMap.get(pieceNumber);
+ }
+
+
+ /**
+ * This method is intended to be overridden by every piece to fill the square which contains the piece's shape.
+ */
+ abstract void fill();
+
+}
--- /dev/null
+/**
+ *
+ */
+package de.android.androidtetris;
+
+import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.view.KeyEvent;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+/**
+ * @author gusarapo
+ *
+ */
+public class DrawView extends SurfaceView {
+ private SurfaceHolder holder;
+ private final MainLoop mainLoop;
+ private static final int TILESIZE=16;
+ private static final int MAPWIDTH=10;
+ private static final int MAPHEIGHT=20;
+ private static final int GREY=8;
+ private Bitmap[] tileArray;
+ private Tile[][] mapMatrix;
+ private PrePiece prePiece;
+ private CurrentPiece currentPiece;
+ private final ExecutorService exec;
+
+ private class MainLoop implements Runnable
+ {
+ private final DrawView view;
+
+ public MainLoop(final DrawView view) {
+ this.view = view;
+ }
+
+
+ @Override
+ public void run()
+ {
+ while (true)
+ {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ synchronized (view.getHolder())
+ {
+ Canvas c = view.getHolder().lockCanvas();
+ view.move(0, 1);
+ view.drawMap(c);
+ //view.onDraw(c);
+ view.getHolder().unlockCanvasAndPost(c);
+ }
+ }
+ }
+ }
+
+
+ public DrawView(final Context context)
+ {
+ super(context);
+
+ //I have so much to learn...
+ //The OnKeyListener for a specific View will only be called if the key is pressed
+ //while that View has focus. For a generic SurfaceView to be focused it first needs to be focusable
+ //http://stackoverflow.com/questions/975918/processing-events-in-surfaceview
+ setFocusableInTouchMode(true);
+ setFocusable(true);
+
+
+ this.newGame();
+
+ //Our main loop.
+ mainLoop = new MainLoop(this);
+ exec = Executors.newSingleThreadExecutor();
+
+ holder = getHolder();
+ holder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceDestroyed(final SurfaceHolder holder) {
+ exec.shutdown();
+ try {
+ exec.awaitTermination(20L, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void surfaceCreated(final SurfaceHolder holder) {
+ exec.execute(mainLoop);
+ }
+
+ @Override
+ public void surfaceChanged(final SurfaceHolder holder, final int format, final int width, final int height) {
+
+ }
+ });
+ }
+
+
+ private void resetTiles(int tilecount) {
+ tileArray = new Bitmap[tilecount];
+ }
+
+
+ private void loadTile(int key, int color)
+ {
+
+ final Bitmap bitmap = Bitmap.createBitmap(TILESIZE, TILESIZE, Bitmap.Config.ARGB_8888);
+ for (int x = 0; x < TILESIZE; x++) {
+ for (int y=0; y< TILESIZE; y++) {
+ bitmap.setPixel(x, y, color);
+ }
+ }
+ tileArray[key] = bitmap;
+ }
+
+
+ private void newGame()
+ {
+ this.resetTiles(10);
+ for (Tile color : Tile.values() )
+ {
+ this.loadTile(color.getColor(), color.getColorRGBA());
+ }
+ mapMatrix = new Tile[MAPWIDTH][MAPHEIGHT+1];
+
+ //Start Map
+ this.startMap();
+ }
+
+ private CurrentPiece newCurrentBlock()
+ {
+ final Random random = new Random();
+
+ return CurrentPiece.getPiece(random.nextInt(7)%7);
+ }
+
+
+ private PrePiece newPreBlock()
+ {
+ final Random random = new Random();
+
+ return PrePiece.getPiece(random.nextInt(7)%7);
+ }
+
+ private void drawTile(Canvas canvas, int color, int x, int y)
+ {
+ canvas.drawBitmap(tileArray[color], x*TILESIZE, y*TILESIZE, null);
+ }
+
+ private void drawMap(Canvas canvas)
+ {
+ canvas.drawColor(Color.WHITE);
+ //We have to center the grid in the middle of our canvas.
+ //canvas.getWidth() <----------------- retrieve the screen width
+ //canvas.getWidth()/TILESIZE <-------- the tile size is 16, so we have to count on it when finding the center
+ //((canvas.getWidth()/TILESIZE))/2 <-- this is the middle of our screen, it depends on the tile size.
+ final int initX = (((canvas.getWidth()/TILESIZE)/2) - MAPWIDTH);
+
+
+ //draw the left bar (with scores, and next pieces
+ for(int x=MAPWIDTH; x< MAPWIDTH + GREY; x++)
+ for(int y=0; y< MAPHEIGHT; y++)
+ drawTile(canvas, Tile.GRAY.getColor(), x + initX, y);
+
+ //draw the pre-piece
+ for(int x=0; x < PrePiece.WIDTH; x++)
+ for(int y=0; y< PrePiece.HEIGHT; y++)
+ if(prePiece.size[x][y] != Tile.NOCOLOR)
+ drawTile(canvas, prePiece.size[x][y].getColor(), prePiece.x + x + initX, prePiece.y +y);
+
+ //draw grid
+ for(int x=0; x < MAPWIDTH; x++)
+ for(int y=0; y < MAPHEIGHT; y++)
+ drawTile(canvas, mapMatrix[x][y].getColor(), x + initX, y);
+
+ //draw the current block
+ for(int x=0; x < CurrentPiece.WIDTH; x++)
+ for(int y=0; y < CurrentPiece.HEIGHT; y++)
+ if(currentPiece.size[x][y] != Tile.NOCOLOR)
+ drawTile(canvas, currentPiece.size[x][y].getColor(), currentPiece.x + x + initX, currentPiece.y +y);
+ }
+
+
+ private void startMap() {
+ for(int x=0;x< MAPWIDTH;x++)
+ {
+ for(int y=0; y<= MAPHEIGHT;y++)
+ {
+ mapMatrix[x][y]=Tile.BLACK;
+ }
+ }
+ currentPiece = newCurrentBlock();
+ currentPiece.x = MAPWIDTH/2-2;
+ currentPiece.y = -1;
+ prePiece = newPreBlock();
+ prePiece.x = MAPWIDTH+2;
+ prePiece.y = GREY/4;
+ }
+
+
+ private void move (int x, int y)
+ {
+ if (this.collisionTest(x, y))
+ {
+ if (y == 1)
+ {
+ if (currentPiece.y == -1)
+ {
+ //GAMEOVER
+ startMap();
+ }
+ else
+ {
+ //Adding block to Grid
+ for(int i=0; i<CurrentPiece.WIDTH; i++)
+ for(int j=0; j<CurrentPiece.HEIGHT; j++)
+ if(currentPiece.size[i][j] != Tile.NOCOLOR)
+ mapMatrix[currentPiece.x+i][currentPiece.y+j] = currentPiece.size[i][j];
+
+
+ //Check row. Is it cleared?
+ for(int j=0; j< MAPHEIGHT; j++)
+ {
+ boolean filled=true;
+ for(int i=0; i< MAPWIDTH; i++)
+ if(mapMatrix[i][j] == Tile.BLACK)
+ filled=false;
+
+ if(filled)
+ {
+ removeRow(j);
+ }
+ }
+
+ currentPiece = CurrentPiece.getPiece(prePiece.pieceNumber);
+ currentPiece.x = MAPWIDTH/2-2;
+ currentPiece.y = -1;
+ prePiece = newPreBlock();
+ prePiece.x = MAPWIDTH+2;
+ prePiece.y = GREY/4;
+ }
+ }
+ }
+ else
+ {
+ currentPiece.x += x;
+ currentPiece.y += y;
+ }
+ }
+
+
+ private void removeRow(int row) {
+
+ for(int x=0; x< MAPWIDTH; x++)
+ for(int y=row; y>0; y--)
+ mapMatrix[x][y]=mapMatrix[x][y-1];
+ }
+
+
+ private boolean collisionTest(int cx, int cy)
+ {
+ int newx = currentPiece.x + cx;
+ int newy = currentPiece.y + cy;
+
+ return this.checkCollision(currentPiece.size, newx, newy);
+ }
+
+
+ private boolean checkCollision(Tile[][] tiles, int xposition, int yposition) {
+ //Check grid boundaries
+ for(int x=0; x<CurrentPiece.WIDTH; x++)
+ for(int y=0; y<CurrentPiece.HEIGHT; y++)
+ if(tiles[x][y] != Tile.NOCOLOR)
+ if ((yposition + y >= MAPHEIGHT) || (yposition + y < 0) || (xposition + x >= MAPWIDTH) || (xposition + x < 0))
+ return true;
+
+ //Check collisions with other blocks
+ for(int x=0; x< MAPWIDTH; x++)
+ for(int y=0; y< MAPHEIGHT; y++)
+ if(x >= xposition && x < xposition + CurrentPiece.WIDTH)
+ if(y >= yposition && y < yposition + CurrentPiece.HEIGHT)
+ if(mapMatrix[x][y] != Tile.BLACK)
+ if(tiles[x - xposition][y - yposition] != Tile.NOCOLOR)
+ return true;
+ return false;
+ }
+
+
+ private void rotateBlock() {
+ Tile[][] temporal = new Tile[CurrentPiece.WIDTH][CurrentPiece.HEIGHT];
+
+ //Copy and rotate current piece to the temporary array
+ for(int x=0; x<CurrentPiece.WIDTH; x++)
+ for(int y=0; y<CurrentPiece.HEIGHT; y++)
+ temporal[3-y][ x ]=currentPiece.size[ x ][y];
+
+ if (this.checkCollision(temporal, currentPiece.x, currentPiece.y))
+ {
+ //If there are collisions, rotate is forbidden.
+ return;
+ }
+
+ //Rotate is allowed
+ for(int x=0; x<CurrentPiece.WIDTH; x++)
+ for(int y=0; y<CurrentPiece.HEIGHT; y++)
+ currentPiece.size[x][y]=temporal[x][y];
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent msg) {
+ super.onKeyDown(keyCode, msg);
+
+ if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
+ synchronized (this.getHolder())
+ {
+ Canvas c = this.getHolder().lockCanvas();
+ this.move(-1, 0);
+ this.drawMap(c);
+ //view.onDraw(c);
+ this.getHolder().unlockCanvasAndPost(c);
+ }
+ return true;
+ }
+ if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
+ synchronized (this.getHolder())
+ {
+ Canvas c = this.getHolder().lockCanvas();
+ this.move(1, 0);
+ this.drawMap(c);
+ //view.onDraw(c);
+ this.getHolder().unlockCanvasAndPost(c);
+ }
+ return true;
+ }
+ if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
+ synchronized (this.getHolder())
+ {
+ Canvas c = this.getHolder().lockCanvas();
+ this.move(0,1);
+ this.drawMap(c);
+ //view.onDraw(c);
+ this.getHolder().unlockCanvasAndPost(c);
+ }
+ return true;
+ }
+ if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
+ synchronized (this.getHolder())
+ {
+ Canvas c = this.getHolder().lockCanvas();
+ this.rotateBlock();
+ this.drawMap(c);
+ //view.onDraw(c);
+ this.getHolder().unlockCanvasAndPost(c);
+ }
+ return true;
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
--- /dev/null
+/**
+ *
+ */
+package de.android.androidtetris;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This enum stores every piece and the square related to that piece.
+ *
+ * @author gusarapo
+ *
+ */
+public enum PrePiece {
+ /*The tower piece*/
+ I(0) {
+ @Override
+ void fill() {
+ size[1][0]=Tile.RED;
+ size[1][1]=Tile.RED;
+ size[1][2]=Tile.RED;
+ size[1][3]=Tile.RED;
+ }
+ },
+ /*The box piece*/
+ O(1) {
+ @Override
+ void fill() {
+ size[1][1]=Tile.BLUE;
+ size[1][2]=Tile.BLUE;
+ size[2][1]=Tile.BLUE;
+ size[2][2]=Tile.BLUE;
+ }
+ },
+ /*The pyramid piece*/
+ T(2) {
+ @Override
+ void fill() {
+ size[1][1]=Tile.YELLOW;
+ size[0][2]=Tile.YELLOW;
+ size[1][2]=Tile.YELLOW;
+ size[2][2]=Tile.YELLOW;
+ }
+ },
+ /*The left leaner piece*/
+ Z(3) {
+ @Override
+ void fill() {
+ size[0][1]=Tile.CYAN;
+ size[1][1]=Tile.CYAN;
+ size[1][2]=Tile.CYAN;
+ size[2][2]=Tile.CYAN;
+ }
+ },
+ /*The right leaner piece*/
+ S(4) {
+ @Override
+ void fill() {
+ size[2][1]=Tile.GREEN;
+ size[1][1]=Tile.GREEN;
+ size[1][2]=Tile.GREEN;
+ size[0][2]=Tile.GREEN;
+ }
+ },
+ /*The left knight piece*/
+ L(5) {
+ @Override
+ void fill() {
+ size[1][1]=Tile.MAGENTA;
+ size[2][1]=Tile.MAGENTA;
+ size[2][2]=Tile.MAGENTA;
+ size[2][3]=Tile.MAGENTA;
+ }
+ },
+ /*The right knight piece*/
+ J(6) {
+ @Override
+ void fill() {
+ size[2][1]=Tile.WHITE;
+ size[1][1]=Tile.WHITE;
+ size[1][2]=Tile.WHITE;
+ size[1][3]=Tile.WHITE;
+ }
+ };
+
+
+ //Every piece is contained in a square. This is the square's width.
+ public static final int WIDTH = 4;
+ //Every piece is contained in a square. This is the square's height.
+ public static final int HEIGHT = 4;
+ //Stores the x coordinate (the position of this piece on the grid)
+ public int x;
+ //Stores the y coordinate (the position of this piece on the grid)
+ public int y;
+ //Every piece is contained in a square.
+ public final Tile[][] size = new Tile[WIDTH][HEIGHT];
+ //Stores the argument of the enum constant (passed to the constructor) JLS§8.9.1
+ public final int pieceNumber;
+ //Map with every enum constant. Class variable initializer. JLS§12.4.2 Executed in textual order.
+ private static final Map<Integer, PrePiece> pieceMap = new HashMap<Integer, PrePiece>();
+
+
+ //Static initializer. JLS§12.4.2 Executed in textual order.
+ static {
+ for (PrePiece piece : PrePiece.values())
+ {
+ pieceMap.put(piece.pieceNumber, piece);
+ }
+ }
+
+
+ /**
+ * Because we have enum constants with arguments we have to create this constructor.
+ * It initializes the piece with the right values.
+ *
+ * @param pieceNumber It is the argument of the enum constant
+ */
+ private PrePiece (final int pieceNumber)
+ {
+ this.pieceNumber = pieceNumber;
+
+ //Pre-Initialization of matrix size
+ for (int i=0; i< WIDTH; i++)
+ for (int j=0; j< HEIGHT; j++)
+ size[i][j]= Tile.NOCOLOR;
+
+ this.x = 0;
+ this.y = 0;
+ //It depends on what kind of piece, we have to fill the square in the right way.
+ this.fill();
+ }
+
+
+ /**
+ * This method is used to retrieve the enum piece related to its number
+ *
+ * @param pieceNumber The piece number is associated to the argument of the enum constant.
+ * @return the enum whose argument of the enum constant matches the pieceNumber.
+ */
+ public static final PrePiece getPiece (final int pieceNumber)
+ {
+ return pieceMap.get(pieceNumber);
+ }
+
+
+ /**
+ * This method is intended to be overridden by every piece to fill the square which contains the piece's shape.
+ */
+ abstract void fill();
+
+}
--- /dev/null
+package de.android.androidtetris;
+
+import android.graphics.Color;
+
+/**
+ * This enum stores every tile and its associated RGBA color.
+ *
+ * @author gusarapo
+ *
+ */
+public enum Tile {
+ /*The red color*/
+ RED(0) {
+ @Override
+ int getColorRGBA() {
+ return Color.RED;
+ }
+ },
+ /*The blue color*/
+ BLUE(1) {
+ @Override
+ int getColorRGBA() {
+ return Color.BLUE;
+ }
+ },
+ /*The cyan color*/
+ CYAN(2) {
+ @Override
+ int getColorRGBA() {
+ return Color.CYAN;
+ }
+ },
+ /*The green color*/
+ GREEN(3) {
+ @Override
+ int getColorRGBA() {
+ return Color.GREEN;
+ }
+ },
+ /*The yellow color*/
+ YELLOW(4) {
+ @Override
+ int getColorRGBA() {
+ return Color.YELLOW;
+ }
+ },
+ /*The white color*/
+ WHITE(5) {
+ @Override
+ int getColorRGBA() {
+ return Color.WHITE;
+ }
+ },
+ /*The magenta color*/
+ MAGENTA(6) {
+ @Override
+ int getColorRGBA() {
+ return Color.MAGENTA;
+ }
+ },
+ /*The gray color*/
+ GRAY(7) {
+ @Override
+ int getColorRGBA() {
+ return Color.GRAY;
+ }
+ },
+ /*The black color*/
+ BLACK(8) {
+ @Override
+ int getColorRGBA() {
+ return Color.BLACK;
+ }
+ },
+ /*No color. It is used in pieces in order to create the piece's shape filling squares with color and no color*/
+ NOCOLOR(9) {
+ @Override
+ int getColorRGBA() {
+ return Color.TRANSPARENT;
+ }
+ };
+
+
+ //Stores the argument of the enum constant (passed to the constructor) JLS§8.9.1
+ private final int color;
+
+
+ /**
+ * Because we have enum constants with arguments we have to create this constructor.
+ * It initializes the tile with the right values.
+ *
+ * @param color It is the argument of the enum constant
+ */
+ Tile (final int color)
+ {
+ this.color = color;
+ }
+
+
+ /**
+ * This method retrieves the argument associated to the enum constant.
+ *
+ * @return integer value associated to the enum constant.
+ */
+ public int getColor()
+ {
+ return color;
+ }
+
+
+ /**
+ * This method is intended to be overridden by every tile to retrieve the
+ * RGBA color associated to that tile.
+ *
+ * @return RGBA color
+ */
+ abstract int getColorRGBA();
+}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="de.android.androidtetris"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="13" />
-
- <application android:label="My AndroidTetris">
- <activity android:name=".AndroidTetrisActivity"
- android:theme="@android:style/Theme.NoTitleBar" android:configChanges="keyboard" android:screenOrientation="portrait">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
-
- </application>
-</manifest>
\ No newline at end of file
+++ /dev/null
-/* AUTO-GENERATED FILE. DO NOT MODIFY.
- *
- * This class was automatically generated by the
- * aapt tool from the resource data it found. It
- * should not be modified by hand.
- */
-
-package de.android.androidtetris;
-
-public final class R {
- public static final class attr {
- }
- public static final class drawable {
- public static final int greenstar=0x7f020000;
- public static final int icon=0x7f020001;
- public static final int redstar=0x7f020002;
- public static final int yellowstar=0x7f020003;
- }
- public static final class layout {
- public static final int main=0x7f030000;
- }
- public static final class string {
- public static final int app_name=0x7f040001;
- public static final int hello=0x7f040000;
- }
-}
+++ /dev/null
--optimizationpasses 5
--dontusemixedcaseclassnames
--dontskipnonpubliclibraryclasses
--dontpreverify
--verbose
--optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-
--keep public class * extends android.app.Activity
--keep public class * extends android.app.Application
--keep public class * extends android.app.Service
--keep public class * extends android.content.BroadcastReceiver
--keep public class * extends android.content.ContentProvider
--keep public class * extends android.app.backup.BackupAgentHelper
--keep public class * extends android.preference.Preference
--keep public class com.android.vending.licensing.ILicensingService
-
--keepclasseswithmembernames class * {
- native <methods>;
-}
-
--keepclasseswithmembers class * {
- public <init>(android.content.Context, android.util.AttributeSet);
-}
-
--keepclasseswithmembers class * {
- public <init>(android.content.Context, android.util.AttributeSet, int);
-}
-
--keepclassmembers class * extends android.app.Activity {
- public void *(android.view.View);
-}
-
--keepclassmembers enum * {
- public static **[] values();
- public static ** valueOf(java.lang.String);
-}
-
--keep class * implements android.os.Parcelable {
- public static final android.os.Parcelable$Creator *;
-}
+++ /dev/null
-# 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,
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-
-# Project target.
-target=android-14
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="hello">Hello World, AndroidTetrisActivity!</string>
- <string name="app_name">AndroidTetris</string>
-</resources>
+++ /dev/null
-package de.android.androidtetris;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.util.DisplayMetrics;
-
-public class AndroidTetrisActivity extends Activity {
- DrawView drawView;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- DisplayMetrics displayMetrics = new DisplayMetrics();
- this.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
-
- setContentView(R.layout.main);
- drawView = new DrawView(this);
- //drawView.setDimensions(displayMetrics.widthPixels, displayMetrics.heightPixels);
- this.setContentView(drawView);
- drawView.requestFocus();
- }
-}
\ No newline at end of file
+++ /dev/null
-/**
- *
- */
-package de.android.androidtetris;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * This enum stores every piece and the square related to that piece.
- *
- * @author gusarapo
- *
- */
-public enum CurrentPiece {
- /*The tower piece*/
- I(0) {
- @Override
- void fill() {
- size[1][0]=Tile.RED;
- size[1][1]=Tile.RED;
- size[1][2]=Tile.RED;
- size[1][3]=Tile.RED;
- }
- },
- /*The box piece*/
- O(1) {
- @Override
- void fill() {
- size[1][1]=Tile.BLUE;
- size[1][2]=Tile.BLUE;
- size[2][1]=Tile.BLUE;
- size[2][2]=Tile.BLUE;
- }
- },
- /*The pyramid piece*/
- T(2) {
- @Override
- void fill() {
- size[1][1]=Tile.YELLOW;
- size[0][2]=Tile.YELLOW;
- size[1][2]=Tile.YELLOW;
- size[2][2]=Tile.YELLOW;
- }
- },
- /*The left leaner piece*/
- Z(3) {
- @Override
- void fill() {
- size[0][1]=Tile.CYAN;
- size[1][1]=Tile.CYAN;
- size[1][2]=Tile.CYAN;
- size[2][2]=Tile.CYAN;
- }
- },
- /*The right leaner piece*/
- S(4) {
- @Override
- void fill() {
- size[2][1]=Tile.GREEN;
- size[1][1]=Tile.GREEN;
- size[1][2]=Tile.GREEN;
- size[0][2]=Tile.GREEN;
- }
- },
- /*The left knight piece*/
- L(5) {
- @Override
- void fill() {
- size[1][1]=Tile.MAGENTA;
- size[2][1]=Tile.MAGENTA;
- size[2][2]=Tile.MAGENTA;
- size[2][3]=Tile.MAGENTA;
- }
- },
- /*The right knight piece*/
- J(6) {
- @Override
- void fill() {
- size[2][1]=Tile.WHITE;
- size[1][1]=Tile.WHITE;
- size[1][2]=Tile.WHITE;
- size[1][3]=Tile.WHITE;
- }
- };
-
-
- //Every piece is contained in a square. This is the square's width.
- public static final int WIDTH = 4;
- //Every piece is contained in a square. This is the square's height.
- public static final int HEIGHT = 4;
- //Stores the x coordinate (the position of this piece on the grid)
- public int x;
- //Stores the y coordinate (the position of this piece on the grid)
- public int y;
- //Every piece is contained in a square.
- public final Tile[][] size = new Tile[WIDTH][HEIGHT];
- //Stores the argument of the enum constant (passed to the constructor) JLS§8.9.1
- public final int pieceNumber;
- //Map with every enum constant. Class variable initializer. JLS§12.4.2 Executed in textual order.
- private static final Map<Integer, CurrentPiece> pieceMap = new HashMap<Integer, CurrentPiece>();
-
-
- //Static initializer. JLS§12.4.2 Executed in textual order.
- static {
- for (CurrentPiece piece : CurrentPiece.values())
- {
- pieceMap.put(piece.pieceNumber, piece);
- }
- }
-
-
- /**
- * Because we have enum constants with arguments we have to create this constructor.
- * It initializes the piece with the right values.
- *
- * @param pieceNumber It is the argument of the enum constant
- */
- private CurrentPiece (final int pieceNumber)
- {
- this.pieceNumber = pieceNumber;
-
- //Pre-Initialization of matrix size
- for (int i=0; i< WIDTH; i++)
- for (int j=0; j< HEIGHT; j++)
- size[i][j]= Tile.NOCOLOR;
-
- this.x = 0;
- this.y = 0;
- //It depends on what kind of piece, we have to fill the square in the right way.
- this.fill();
- }
-
-
- /**
- * This method is used to retrieve the enum piece related to its number
- *
- * @param pieceNumber The piece number is associated to the argument of the enum constant.
- * @return the enum whose argument of the enum constant matches the pieceNumber.
- */
- public static final CurrentPiece getPiece (final int pieceNumber)
- {
- return pieceMap.get(pieceNumber);
- }
-
-
- /**
- * This method is intended to be overridden by every piece to fill the square which contains the piece's shape.
- */
- abstract void fill();
-
-}
+++ /dev/null
-/**
- *
- */
-package de.android.androidtetris;
-
-import java.util.Random;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.view.KeyEvent;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-
-/**
- * @author gusarapo
- *
- */
-public class DrawView extends SurfaceView {
- private SurfaceHolder holder;
- private final MainLoop mainLoop;
- private static final int TILESIZE=16;
- private static final int MAPWIDTH=10;
- private static final int MAPHEIGHT=20;
- private static final int GREY=8;
- private Bitmap[] tileArray;
- private Tile[][] mapMatrix;
- private PrePiece prePiece;
- private CurrentPiece currentPiece;
- private final ExecutorService exec;
-
- private class MainLoop implements Runnable
- {
- private final DrawView view;
-
- public MainLoop(final DrawView view) {
- this.view = view;
- }
-
-
- @Override
- public void run()
- {
- while (true)
- {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- synchronized (view.getHolder())
- {
- Canvas c = view.getHolder().lockCanvas();
- view.move(0, 1);
- view.drawMap(c);
- //view.onDraw(c);
- view.getHolder().unlockCanvasAndPost(c);
- }
- }
- }
- }
-
-
- public DrawView(final Context context)
- {
- super(context);
-
- //I have so much to learn...
- //The OnKeyListener for a specific View will only be called if the key is pressed
- //while that View has focus. For a generic SurfaceView to be focused it first needs to be focusable
- //http://stackoverflow.com/questions/975918/processing-events-in-surfaceview
- setFocusableInTouchMode(true);
- setFocusable(true);
-
-
- this.newGame();
-
- //Our main loop.
- mainLoop = new MainLoop(this);
- exec = Executors.newSingleThreadExecutor();
-
- holder = getHolder();
- holder.addCallback(new SurfaceHolder.Callback() {
- @Override
- public void surfaceDestroyed(final SurfaceHolder holder) {
- exec.shutdown();
- try {
- exec.awaitTermination(20L, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- @Override
- public void surfaceCreated(final SurfaceHolder holder) {
- exec.execute(mainLoop);
- }
-
- @Override
- public void surfaceChanged(final SurfaceHolder holder, final int format, final int width, final int height) {
-
- }
- });
- }
-
-
- private void resetTiles(int tilecount) {
- tileArray = new Bitmap[tilecount];
- }
-
-
- private void loadTile(int key, int color)
- {
-
- final Bitmap bitmap = Bitmap.createBitmap(TILESIZE, TILESIZE, Bitmap.Config.ARGB_8888);
- for (int x = 0; x < TILESIZE; x++) {
- for (int y=0; y< TILESIZE; y++) {
- bitmap.setPixel(x, y, color);
- }
- }
- tileArray[key] = bitmap;
- }
-
-
- private void newGame()
- {
- this.resetTiles(10);
- for (Tile color : Tile.values() )
- {
- this.loadTile(color.getColor(), color.getColorRGBA());
- }
- mapMatrix = new Tile[MAPWIDTH][MAPHEIGHT+1];
-
- //Start Map
- this.startMap();
- }
-
- private CurrentPiece newCurrentBlock()
- {
- final Random random = new Random();
-
- return CurrentPiece.getPiece(random.nextInt(7)%7);
- }
-
-
- private PrePiece newPreBlock()
- {
- final Random random = new Random();
-
- return PrePiece.getPiece(random.nextInt(7)%7);
- }
-
- private void drawTile(Canvas canvas, int color, int x, int y)
- {
- canvas.drawBitmap(tileArray[color], x*TILESIZE, y*TILESIZE, null);
- }
-
- private void drawMap(Canvas canvas)
- {
- canvas.drawColor(Color.WHITE);
- //We have to center the grid in the middle of our canvas.
- //canvas.getWidth() <----------------- retrieve the screen width
- //canvas.getWidth()/TILESIZE <-------- the tile size is 16, so we have to count on it when finding the center
- //((canvas.getWidth()/TILESIZE))/2 <-- this is the middle of our screen, it depends on the tile size.
- final int initX = (((canvas.getWidth()/TILESIZE)/2) - MAPWIDTH);
-
-
- //draw the left bar (with scores, and next pieces
- for(int x=MAPWIDTH; x< MAPWIDTH + GREY; x++)
- for(int y=0; y< MAPHEIGHT; y++)
- drawTile(canvas, Tile.GRAY.getColor(), x + initX, y);
-
- //draw the pre-piece
- for(int x=0; x < PrePiece.WIDTH; x++)
- for(int y=0; y< PrePiece.HEIGHT; y++)
- if(prePiece.size[x][y] != Tile.NOCOLOR)
- drawTile(canvas, prePiece.size[x][y].getColor(), prePiece.x + x + initX, prePiece.y +y);
-
- //draw grid
- for(int x=0; x < MAPWIDTH; x++)
- for(int y=0; y < MAPHEIGHT; y++)
- drawTile(canvas, mapMatrix[x][y].getColor(), x + initX, y);
-
- //draw the current block
- for(int x=0; x < CurrentPiece.WIDTH; x++)
- for(int y=0; y < CurrentPiece.HEIGHT; y++)
- if(currentPiece.size[x][y] != Tile.NOCOLOR)
- drawTile(canvas, currentPiece.size[x][y].getColor(), currentPiece.x + x + initX, currentPiece.y +y);
- }
-
-
- private void startMap() {
- for(int x=0;x< MAPWIDTH;x++)
- {
- for(int y=0; y<= MAPHEIGHT;y++)
- {
- mapMatrix[x][y]=Tile.BLACK;
- }
- }
- currentPiece = newCurrentBlock();
- currentPiece.x = MAPWIDTH/2-2;
- currentPiece.y = -1;
- prePiece = newPreBlock();
- prePiece.x = MAPWIDTH+2;
- prePiece.y = GREY/4;
- }
-
-
- private void move (int x, int y)
- {
- if (this.collisionTest(x, y))
- {
- if (y == 1)
- {
- if (currentPiece.y == -1)
- {
- //GAMEOVER
- startMap();
- }
- else
- {
- //Adding block to Grid
- for(int i=0; i<CurrentPiece.WIDTH; i++)
- for(int j=0; j<CurrentPiece.HEIGHT; j++)
- if(currentPiece.size[i][j] != Tile.NOCOLOR)
- mapMatrix[currentPiece.x+i][currentPiece.y+j] = currentPiece.size[i][j];
-
-
- //Check row. Is it cleared?
- for(int j=0; j< MAPHEIGHT; j++)
- {
- boolean filled=true;
- for(int i=0; i< MAPWIDTH; i++)
- if(mapMatrix[i][j] == Tile.BLACK)
- filled=false;
-
- if(filled)
- {
- removeRow(j);
- }
- }
-
- currentPiece = CurrentPiece.getPiece(prePiece.pieceNumber);
- currentPiece.x = MAPWIDTH/2-2;
- currentPiece.y = -1;
- prePiece = newPreBlock();
- prePiece.x = MAPWIDTH+2;
- prePiece.y = GREY/4;
- }
- }
- }
- else
- {
- currentPiece.x += x;
- currentPiece.y += y;
- }
- }
-
-
- private void removeRow(int row) {
-
- for(int x=0; x< MAPWIDTH; x++)
- for(int y=row; y>0; y--)
- mapMatrix[x][y]=mapMatrix[x][y-1];
- }
-
-
- private boolean collisionTest(int cx, int cy)
- {
- int newx = currentPiece.x + cx;
- int newy = currentPiece.y + cy;
-
- return this.checkCollision(currentPiece.size, newx, newy);
- }
-
-
- private boolean checkCollision(Tile[][] tiles, int xposition, int yposition) {
- //Check grid boundaries
- for(int x=0; x<CurrentPiece.WIDTH; x++)
- for(int y=0; y<CurrentPiece.HEIGHT; y++)
- if(tiles[x][y] != Tile.NOCOLOR)
- if ((yposition + y >= MAPHEIGHT) || (yposition + y < 0) || (xposition + x >= MAPWIDTH) || (xposition + x < 0))
- return true;
-
- //Check collisions with other blocks
- for(int x=0; x< MAPWIDTH; x++)
- for(int y=0; y< MAPHEIGHT; y++)
- if(x >= xposition && x < xposition + CurrentPiece.WIDTH)
- if(y >= yposition && y < yposition + CurrentPiece.HEIGHT)
- if(mapMatrix[x][y] != Tile.BLACK)
- if(tiles[x - xposition][y - yposition] != Tile.NOCOLOR)
- return true;
- return false;
- }
-
-
- private void rotateBlock() {
- Tile[][] temporal = new Tile[CurrentPiece.WIDTH][CurrentPiece.HEIGHT];
-
- //Copy and rotate current piece to the temporary array
- for(int x=0; x<CurrentPiece.WIDTH; x++)
- for(int y=0; y<CurrentPiece.HEIGHT; y++)
- temporal[3-y][ x ]=currentPiece.size[ x ][y];
-
- if (this.checkCollision(temporal, currentPiece.x, currentPiece.y))
- {
- //If there are collisions, rotate is forbidden.
- return;
- }
-
- //Rotate is allowed
- for(int x=0; x<CurrentPiece.WIDTH; x++)
- for(int y=0; y<CurrentPiece.HEIGHT; y++)
- currentPiece.size[x][y]=temporal[x][y];
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent msg) {
- super.onKeyDown(keyCode, msg);
-
- if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
- synchronized (this.getHolder())
- {
- Canvas c = this.getHolder().lockCanvas();
- this.move(-1, 0);
- this.drawMap(c);
- //view.onDraw(c);
- this.getHolder().unlockCanvasAndPost(c);
- }
- return true;
- }
- if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
- synchronized (this.getHolder())
- {
- Canvas c = this.getHolder().lockCanvas();
- this.move(1, 0);
- this.drawMap(c);
- //view.onDraw(c);
- this.getHolder().unlockCanvasAndPost(c);
- }
- return true;
- }
- if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
- synchronized (this.getHolder())
- {
- Canvas c = this.getHolder().lockCanvas();
- this.move(0,1);
- this.drawMap(c);
- //view.onDraw(c);
- this.getHolder().unlockCanvasAndPost(c);
- }
- return true;
- }
- if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
- synchronized (this.getHolder())
- {
- Canvas c = this.getHolder().lockCanvas();
- this.rotateBlock();
- this.drawMap(c);
- //view.onDraw(c);
- this.getHolder().unlockCanvasAndPost(c);
- }
- return true;
- }
-
- return false;
- }
-}
\ No newline at end of file
+++ /dev/null
-/**
- *
- */
-package de.android.androidtetris;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * This enum stores every piece and the square related to that piece.
- *
- * @author gusarapo
- *
- */
-public enum PrePiece {
- /*The tower piece*/
- I(0) {
- @Override
- void fill() {
- size[1][0]=Tile.RED;
- size[1][1]=Tile.RED;
- size[1][2]=Tile.RED;
- size[1][3]=Tile.RED;
- }
- },
- /*The box piece*/
- O(1) {
- @Override
- void fill() {
- size[1][1]=Tile.BLUE;
- size[1][2]=Tile.BLUE;
- size[2][1]=Tile.BLUE;
- size[2][2]=Tile.BLUE;
- }
- },
- /*The pyramid piece*/
- T(2) {
- @Override
- void fill() {
- size[1][1]=Tile.YELLOW;
- size[0][2]=Tile.YELLOW;
- size[1][2]=Tile.YELLOW;
- size[2][2]=Tile.YELLOW;
- }
- },
- /*The left leaner piece*/
- Z(3) {
- @Override
- void fill() {
- size[0][1]=Tile.CYAN;
- size[1][1]=Tile.CYAN;
- size[1][2]=Tile.CYAN;
- size[2][2]=Tile.CYAN;
- }
- },
- /*The right leaner piece*/
- S(4) {
- @Override
- void fill() {
- size[2][1]=Tile.GREEN;
- size[1][1]=Tile.GREEN;
- size[1][2]=Tile.GREEN;
- size[0][2]=Tile.GREEN;
- }
- },
- /*The left knight piece*/
- L(5) {
- @Override
- void fill() {
- size[1][1]=Tile.MAGENTA;
- size[2][1]=Tile.MAGENTA;
- size[2][2]=Tile.MAGENTA;
- size[2][3]=Tile.MAGENTA;
- }
- },
- /*The right knight piece*/
- J(6) {
- @Override
- void fill() {
- size[2][1]=Tile.WHITE;
- size[1][1]=Tile.WHITE;
- size[1][2]=Tile.WHITE;
- size[1][3]=Tile.WHITE;
- }
- };
-
-
- //Every piece is contained in a square. This is the square's width.
- public static final int WIDTH = 4;
- //Every piece is contained in a square. This is the square's height.
- public static final int HEIGHT = 4;
- //Stores the x coordinate (the position of this piece on the grid)
- public int x;
- //Stores the y coordinate (the position of this piece on the grid)
- public int y;
- //Every piece is contained in a square.
- public final Tile[][] size = new Tile[WIDTH][HEIGHT];
- //Stores the argument of the enum constant (passed to the constructor) JLS§8.9.1
- public final int pieceNumber;
- //Map with every enum constant. Class variable initializer. JLS§12.4.2 Executed in textual order.
- private static final Map<Integer, PrePiece> pieceMap = new HashMap<Integer, PrePiece>();
-
-
- //Static initializer. JLS§12.4.2 Executed in textual order.
- static {
- for (PrePiece piece : PrePiece.values())
- {
- pieceMap.put(piece.pieceNumber, piece);
- }
- }
-
-
- /**
- * Because we have enum constants with arguments we have to create this constructor.
- * It initializes the piece with the right values.
- *
- * @param pieceNumber It is the argument of the enum constant
- */
- private PrePiece (final int pieceNumber)
- {
- this.pieceNumber = pieceNumber;
-
- //Pre-Initialization of matrix size
- for (int i=0; i< WIDTH; i++)
- for (int j=0; j< HEIGHT; j++)
- size[i][j]= Tile.NOCOLOR;
-
- this.x = 0;
- this.y = 0;
- //It depends on what kind of piece, we have to fill the square in the right way.
- this.fill();
- }
-
-
- /**
- * This method is used to retrieve the enum piece related to its number
- *
- * @param pieceNumber The piece number is associated to the argument of the enum constant.
- * @return the enum whose argument of the enum constant matches the pieceNumber.
- */
- public static final PrePiece getPiece (final int pieceNumber)
- {
- return pieceMap.get(pieceNumber);
- }
-
-
- /**
- * This method is intended to be overridden by every piece to fill the square which contains the piece's shape.
- */
- abstract void fill();
-
-}
+++ /dev/null
-package de.android.androidtetris;
-
-import android.graphics.Color;
-
-/**
- * This enum stores every tile and its associated RGBA color.
- *
- * @author gusarapo
- *
- */
-public enum Tile {
- /*The red color*/
- RED(0) {
- @Override
- int getColorRGBA() {
- return Color.RED;
- }
- },
- /*The blue color*/
- BLUE(1) {
- @Override
- int getColorRGBA() {
- return Color.BLUE;
- }
- },
- /*The cyan color*/
- CYAN(2) {
- @Override
- int getColorRGBA() {
- return Color.CYAN;
- }
- },
- /*The green color*/
- GREEN(3) {
- @Override
- int getColorRGBA() {
- return Color.GREEN;
- }
- },
- /*The yellow color*/
- YELLOW(4) {
- @Override
- int getColorRGBA() {
- return Color.YELLOW;
- }
- },
- /*The white color*/
- WHITE(5) {
- @Override
- int getColorRGBA() {
- return Color.WHITE;
- }
- },
- /*The magenta color*/
- MAGENTA(6) {
- @Override
- int getColorRGBA() {
- return Color.MAGENTA;
- }
- },
- /*The gray color*/
- GRAY(7) {
- @Override
- int getColorRGBA() {
- return Color.GRAY;
- }
- },
- /*The black color*/
- BLACK(8) {
- @Override
- int getColorRGBA() {
- return Color.BLACK;
- }
- },
- /*No color. It is used in pieces in order to create the piece's shape filling squares with color and no color*/
- NOCOLOR(9) {
- @Override
- int getColorRGBA() {
- return Color.TRANSPARENT;
- }
- };
-
-
- //Stores the argument of the enum constant (passed to the constructor) JLS§8.9.1
- private final int color;
-
-
- /**
- * Because we have enum constants with arguments we have to create this constructor.
- * It initializes the tile with the right values.
- *
- * @param color It is the argument of the enum constant
- */
- Tile (final int color)
- {
- this.color = color;
- }
-
-
- /**
- * This method retrieves the argument associated to the enum constant.
- *
- * @return integer value associated to the enum constant.
- */
- public int getColor()
- {
- return color;
- }
-
-
- /**
- * This method is intended to be overridden by every tile to retrieve the
- * RGBA color associated to that tile.
- *
- * @return RGBA color
- */
- abstract int getColorRGBA();
-}
\ No newline at end of file