Implement all Tetris basic functions.

master
sigonasr2 4 years ago
parent 880a56ddca
commit e533edac08
  1. 3
      Tetris/src/sig/game/Block.java
  2. 121
      Tetris/src/sig/game/Game.java
  3. 7
      Tetris/src/sig/game/GameState.java
  4. 12
      Tetris/src/sig/game/MoveDirection.java
  5. 93
      Tetris/src/sig/game/Player.java
  6. 12
      Tetris/src/sig/game/RotationDirection.java

@ -11,4 +11,7 @@ public class Block {
this.active=active;
this.color=col;
}
public String toString() {
return active?"O":"-";
}
}

@ -1,6 +1,7 @@
package sig.game;
import java.awt.Point;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;
@ -15,6 +16,11 @@ public class Game {
public static int tickDelay = 60;
public static int rotation = 0; //0-3
public static Grid gameGrid = new Grid();
public static int rotateDelay = 20;
public static int rotateTimer = rotateDelay;
public static GameState state = GameState.PLAYING;
public static void main(String[] args) {
@ -26,8 +32,8 @@ public class Game {
+ "XXXX"),
new Shape(
"XXXX"
+ "OOOO"
+ "OXXX"
+ "XOOO"
+ "XOXX"
+ "XXXX"),
new Shape(
"XOOX"
@ -36,8 +42,8 @@ public class Game {
+ "XXXX"),
new Shape(
"XXXX"
+ "XXXO"
+ "OOOO"
+ "XXOX"
+ "OOOX"
+ "XXXX")
,Color.ORANGE);
final Frame JPiece = new Frame(
@ -47,8 +53,8 @@ public class Game {
+ "XOOX"
+ "XXXX"),
new Shape(
"OXXX"
+ "OOOO"
"XOXX"
+ "XOOO"
+ "XXXX"
+ "XXXX"),
new Shape(
@ -57,8 +63,8 @@ public class Game {
+ "XOOX"
+ "XXXX"),
new Shape(
"OOOO"
+ "XXXO"
"OOOX"
+ "XXOX"
+ "XXXX"
+ "XXXX")
,Color.BLUE);
@ -193,12 +199,22 @@ public class Game {
static void step() {
tickDelay--;
rotateTimer--;
if (tickDelay<=0) {
moveBlock();
tickDelay=levelDelay[level];
}
if (rotateTimer<=0) {
//p.rotateCounterClockwise();
p.moveBlockLeft();
rotateTimer=rotateDelay;
}
DrawBoard();
}
private static void DrawBoard() {
ClearScreen();
Point[] checkPoints = p.GetPlayerBlocksInGrid();
Point[] checkPoints = p.GetPlayerBlocksInGrid(p.getCurrentShape());
for (int y=19;y>=0;y--) {
for (int x=0;x<10;x++) {
boolean plotted=false;
@ -210,7 +226,7 @@ public class Game {
}
}
if (!plotted) {
System.out.print((gameGrid.grid[x][y].active)?'O':'-');
System.out.print(gameGrid.grid[x][y]);
}
}
System.out.println();
@ -236,25 +252,88 @@ public class Game {
}
}*/
Point[] checkPoints = p.GetPlayerBlocksInGrid();
Point[] checkPoints = p.GetPlayerBlocksInGrid(p.getCurrentShape());
boolean isOccupied = isOccupied(checkPoints,new Point(0,-1));
if (isOccupied) {
SnapPieceThatCollided(checkPoints);
ClearLinesThatHaveFullRows();
} else {
MovePlayerBlockDownByOne();
}
}
private static void ClearLinesThatHaveFullRows() {
int deletionRows=0;
for (int y=0;y<gameGrid.grid[0].length;y++) {
//System.out.println("Called: "+y);
deletionRows = CheckAndClearFullRows(deletionRows, y);
}
}
private static int CheckAndClearFullRows(int deletionRows, int y) {
boolean isAllActive=true;
for (int x=0;x<gameGrid.grid.length;x++) {
//System.out.print(gameGrid.grid[x][y]);
if (!gameGrid.grid[x][y].active) {
isAllActive=false;
break;
}
}
//System.out.println();
if (isAllActive) {
//Take every block above this row, and shift it all down by one.
//x is the current row we are on.
//Move every row down, if we find a row that is also a match, increment the amount of rows we move down by 1.
deletionRows++;
} else {
for (int x=0;x<gameGrid.grid.length;x++) {
ShiftBlockDownByNumberOfDeletionRows(deletionRows, y, x);
}
}
return deletionRows;
}
private static void ShiftBlockDownByNumberOfDeletionRows(int deletionRows, int y, int x) {
if (deletionRows>0) {
gameGrid.grid[x][y-deletionRows].active=gameGrid.grid[x][y].active;
gameGrid.grid[x][y].active=false;
}
}
private static void MovePlayerBlockDownByOne() {
p.pos.translate(0, -1);
}
private static void SnapPieceThatCollided(Point[] checkPoints) {
for (Point point : checkPoints) {
//If any point in the grid is outside, this is our lose condition.
if (point.y>=gameGrid.grid[0].length) {
state = GameState.LOSE;
}
gameGrid.grid[point.x][point.y].active=true;
}
p.ShuffleNextPiece();
}
static boolean isOccupied(Point[] checkPoints) {
return isOccupied(checkPoints,new Point(0,0));
}
static boolean isOccupied(Point[] checkPoints,Point offset) {
boolean isOccupied = false;
for (int i=0;i<checkPoints.length;i++) {
Point point = checkPoints[i];
//point.translate(p.pos.x,p.pos.y);
if (point.y-1<0 || gameGrid.grid[point.x][point.y-1].active) {
if (point.y+offset.y<0 ||
point.y+offset.y>=gameGrid.grid[0].length||
point.x+offset.x>=gameGrid.grid.length||
point.x+offset.x<0
|| gameGrid.grid[point.x+offset.x][point.y+offset.y].active) {
isOccupied=true;
break;
}
}
if (isOccupied) {
for (Point point : checkPoints) {
gameGrid.grid[point.x][point.y].active=true;
}
p.ShuffleNextPiece();
} else {
p.pos.translate(0, -1);
}
return isOccupied;
}
}

@ -0,0 +1,7 @@
package sig.game;
public enum GameState {
PLAYING,
WIN,
LOSE;
}

@ -0,0 +1,12 @@
package sig.game;
public enum MoveDirection {
LEFT(-1),
RIGHT(1);
int value;
MoveDirection(int value) {
this.value=value;
}
}

@ -16,10 +16,6 @@ public class Player {
nextPiece = SelectRandomTetrimino();
pos = new Point(5,20);
}
private Frame SelectRandomTetrimino() {
return Game.piecePool[(int)(Math.random()*Game.piecePool.length)];
}
public void ShuffleNextPiece() {
piece = nextPiece.clone();
@ -27,9 +23,9 @@ public class Player {
pos = new Point(5,20);
}
public Point[] GetPlayerBlocksInGrid() {
public Point[] GetPlayerBlocksInGrid(Shape s) {
Point[] checkPoints = new Point[4];
Shape tetShape = piece.shape[Game.rotation];
Shape tetShape = s;
int pointsInserted=0;
for (int x=0;x<tetShape.shape.length;x++) {
for (int y=0;y<tetShape.shape[0].length;y++) {
@ -42,4 +38,89 @@ public class Player {
}
return checkPoints;
}
public Shape getCurrentShape() {
return piece.shape[Game.rotation];
}
public void rotateClockwise() {
//Get the new rotated piece.
//See if the current piece position with the new rotation shape overlaps any active squares.
//If they do, try to shift the piece one left, and compare again.
//If they still do, try to shift the piece one right, and compare again.
//If no piece position is free, we cannot rotate. Return.
//Otherwise, all conditions have been met, and we can rotate the piece.
Point[] checkPoints = GetPlayerBlocksInGrid(GetClockwiseRotatedCurrentPiece());
RotateIfSpaceIsFree(checkPoints,RotationDirection.CLOCKWISE);
}
public void rotateCounterClockwise() {
Point[] checkPoints = GetPlayerBlocksInGrid(GetCounterClockwiseRotatedCurrentPiece());
RotateIfSpaceIsFree(checkPoints,RotationDirection.COUNTERCLOCKWISE);
}
public void moveBlockRight() {
moveBlock(MoveDirection.RIGHT);
}
public void moveBlockLeft() {
moveBlock(MoveDirection.LEFT);
}
private void moveBlock(MoveDirection dir) {
Point[] checkPoints = GetPlayerBlocksInGrid(getCurrentShape());
boolean isFree = true;
for (Point p : checkPoints) {
if (Game.isOccupied(checkPoints,new Point(dir.value,0))) {
isFree=false;
break;
}
}
if (isFree) {
pos.translate(dir.value, 0);
}
}
private Frame SelectRandomTetrimino() {
return Game.piecePool[(int)(Math.random()*Game.piecePool.length)];
}
private void RotateIfSpaceIsFree(Point[] checkPoints,RotationDirection dir) {
int[] offset = new int[]{0,-1,1};
int freeOffset = -1;
for (int i=0;i<offset.length;i++) {
if (!Game.isOccupied(checkPoints,new Point(offset[i],0))) {
freeOffset = offset[i];
break;
}
}
if (freeOffset!=-1) {
pos.translate(freeOffset, 0);
Game.rotation=rotatePiece(Game.rotation,dir);
//System.out.println("rotation: "+Game.rotation);
}
}
private Shape GetClockwiseRotatedCurrentPiece() {
return piece.shape[rotatePiece(Game.rotation,RotationDirection.CLOCKWISE)];
}
private Shape GetCounterClockwiseRotatedCurrentPiece() {
return piece.shape[rotatePiece(Game.rotation,RotationDirection.COUNTERCLOCKWISE)];
}
private int rotatePiece(int currentRotation,RotationDirection direction) {
currentRotation+=direction.value;
if (currentRotation<0) {
currentRotation=3;
} else
if (currentRotation>3) {
currentRotation=0;
}
return currentRotation;
}
}

@ -0,0 +1,12 @@
package sig.game;
public enum RotationDirection {
CLOCKWISE(1),
COUNTERCLOCKWISE(-1);
int value;
RotationDirection(int value) {
this.value=value;
}
}
Loading…
Cancel
Save