Finish implementation of Tetris! Download the jar if you want to play
it.
This commit is contained in:
parent
e533edac08
commit
489a043441
BIN
Tetris/Tetris.jar
Normal file
BIN
Tetris/Tetris.jar
Normal file
Binary file not shown.
@ -1,12 +1,22 @@
|
|||||||
package sig.game;
|
package sig.game;
|
||||||
|
|
||||||
public enum Color {
|
public enum Color {
|
||||||
BLUE,
|
BLUE(java.awt.Color.BLUE),
|
||||||
AQUA,
|
AQUA(new java.awt.Color(196,196,255)),
|
||||||
RED,
|
RED(java.awt.Color.RED),
|
||||||
GREEN,
|
GREEN(java.awt.Color.GREEN),
|
||||||
PURPLE,
|
PURPLE(java.awt.Color.MAGENTA),
|
||||||
YELLOW,
|
YELLOW(java.awt.Color.YELLOW),
|
||||||
ORANGE,
|
ORANGE(java.awt.Color.ORANGE),
|
||||||
BLACK
|
BLACK(java.awt.Color.BLACK);
|
||||||
|
|
||||||
|
java.awt.Color col;
|
||||||
|
|
||||||
|
Color(java.awt.Color col) {
|
||||||
|
this.col=col;
|
||||||
|
}
|
||||||
|
|
||||||
|
java.awt.Color getColor() {
|
||||||
|
return col;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ public class Frame {
|
|||||||
Shape s4,
|
Shape s4,
|
||||||
Color col) {
|
Color col) {
|
||||||
shape = new Shape[]{s1,s2,s3,s4};
|
shape = new Shape[]{s1,s2,s3,s4};
|
||||||
|
s1.col=s2.col=s3.col=s4.col=col;
|
||||||
this.col=col;
|
this.col=col;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
package sig.game;
|
package sig.game;
|
||||||
|
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.WindowConstants;
|
||||||
|
|
||||||
public class Game {
|
public class Game {
|
||||||
public static Frame[] piecePool;
|
public static Frame[] piecePool;
|
||||||
public static Player p;
|
public static Player p;
|
||||||
@ -12,177 +17,200 @@ public class Game {
|
|||||||
30,27,25,23,22,20,18,16,14,12,
|
30,27,25,23,22,20,18,16,14,12,
|
||||||
10,9,8,7,6,5,4,3,2,1
|
10,9,8,7,6,5,4,3,2,1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static int linesCleared = 0;
|
||||||
|
|
||||||
public static int level = 0;
|
public static int level = 0;
|
||||||
public static int tickDelay = 60;
|
public static int tickDelay = 60;
|
||||||
public static int rotation = 0; //0-3
|
public static int rotation = 0; //0-3
|
||||||
public static Grid gameGrid = new Grid();
|
public static Grid gameGrid = new Grid();
|
||||||
|
|
||||||
|
public static int keyDelay = 0;
|
||||||
|
public final static int defaultKeyDelay = 4;
|
||||||
|
|
||||||
public static int rotateDelay = 20;
|
public static int rotateDelay = 20;
|
||||||
public static int rotateTimer = rotateDelay;
|
public static int rotateTimer = rotateDelay;
|
||||||
|
|
||||||
public static GameState state = GameState.PLAYING;
|
public static GameState state = GameState.PLAYING;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static JFrame frame;
|
||||||
|
public static GameCanvas canvas;
|
||||||
|
|
||||||
final Frame LPiece = new Frame(
|
public static int lastKey = -1;
|
||||||
new Shape(
|
|
||||||
"XOXX"
|
public static HashMap<Integer,Key> keyMap = new HashMap<>();
|
||||||
+ "XOXX"
|
|
||||||
+ "XOOX"
|
final public static Frame LPiece = new Frame(
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XOXX"
|
||||||
"XXXX"
|
+ "XOXX"
|
||||||
+ "XOOO"
|
+ "XOOX"
|
||||||
+ "XOXX"
|
+ "XXXX"),
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XXXX"
|
||||||
"XOOX"
|
+ "XOOO"
|
||||||
+ "XXOX"
|
+ "XOXX"
|
||||||
+ "XXOX"
|
+ "XXXX"),
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XOOX"
|
||||||
"XXXX"
|
+ "XXOX"
|
||||||
+ "XXOX"
|
+ "XXOX"
|
||||||
+ "OOOX"
|
+ "XXXX"),
|
||||||
+ "XXXX")
|
new Shape(
|
||||||
,Color.ORANGE);
|
"XXXX"
|
||||||
final Frame JPiece = new Frame(
|
+ "XXOX"
|
||||||
new Shape(
|
+ "OOOX"
|
||||||
"XXOX"
|
+ "XXXX")
|
||||||
+ "XXOX"
|
,Color.ORANGE);
|
||||||
+ "XOOX"
|
final public static Frame JPiece = new Frame(
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XXOX"
|
||||||
"XOXX"
|
+ "XXOX"
|
||||||
+ "XOOO"
|
+ "XOOX"
|
||||||
+ "XXXX"
|
+ "XXXX"),
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XOXX"
|
||||||
"XXOX"
|
+ "XOOO"
|
||||||
+ "XXOX"
|
+ "XXXX"
|
||||||
+ "XOOX"
|
+ "XXXX"),
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XOOX"
|
||||||
"OOOX"
|
+ "XOXX"
|
||||||
+ "XXOX"
|
+ "XOXX"
|
||||||
+ "XXXX"
|
+ "XXXX"),
|
||||||
+ "XXXX")
|
new Shape(
|
||||||
,Color.BLUE);
|
"OOOX"
|
||||||
final Frame SPiece = new Frame(
|
+ "XXOX"
|
||||||
new Shape(
|
+ "XXXX"
|
||||||
"XOXX"
|
+ "XXXX")
|
||||||
+ "XOOX"
|
,Color.BLUE);
|
||||||
+ "XXOX"
|
final public static Frame SPiece = new Frame(
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XOXX"
|
||||||
"XOOX"
|
+ "XOOX"
|
||||||
+ "OOXX"
|
+ "XXOX"
|
||||||
+ "XXXX"
|
+ "XXXX"),
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XOOX"
|
||||||
"XOXX"
|
+ "OOXX"
|
||||||
+ "XOOX"
|
+ "XXXX"
|
||||||
+ "XXOX"
|
+ "XXXX"),
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XOXX"
|
||||||
"XOOX"
|
+ "XOOX"
|
||||||
+ "OOXX"
|
+ "XXOX"
|
||||||
+ "XXXX"
|
+ "XXXX"),
|
||||||
+ "XXXX")
|
new Shape(
|
||||||
,Color.RED);
|
"XOOX"
|
||||||
final Frame ZPiece = new Frame(
|
+ "OOXX"
|
||||||
new Shape(
|
+ "XXXX"
|
||||||
"XXOX"
|
+ "XXXX")
|
||||||
+ "XOOX"
|
,Color.RED);
|
||||||
+ "XOXX"
|
final public static Frame ZPiece = new Frame(
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XXOX"
|
||||||
"OOXX"
|
+ "XOOX"
|
||||||
+ "XOOX"
|
+ "XOXX"
|
||||||
+ "XXXX"
|
+ "XXXX"),
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"OOXX"
|
||||||
"XXOX"
|
+ "XOOX"
|
||||||
+ "XOOX"
|
+ "XXXX"
|
||||||
+ "XOXX"
|
+ "XXXX"),
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XXOX"
|
||||||
"OOXX"
|
+ "XOOX"
|
||||||
+ "XOOX"
|
+ "XOXX"
|
||||||
+ "XXXX"
|
+ "XXXX"),
|
||||||
+ "XXXX")
|
new Shape(
|
||||||
,Color.GREEN);
|
"OOXX"
|
||||||
final Frame TPiece = new Frame(
|
+ "XOOX"
|
||||||
new Shape(
|
+ "XXXX"
|
||||||
"OOOX"
|
+ "XXXX")
|
||||||
+ "XOXX"
|
,Color.GREEN);
|
||||||
+ "XXXX"
|
final public static Frame TPiece = new Frame(
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"OOOX"
|
||||||
"XOXX"
|
+ "XOXX"
|
||||||
+ "OOXX"
|
+ "XXXX"
|
||||||
+ "XOXX"
|
+ "XXXX"),
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XOXX"
|
||||||
"XOXX"
|
+ "OOXX"
|
||||||
+ "OOOX"
|
+ "XOXX"
|
||||||
+ "XXXX"
|
+ "XXXX"),
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XOXX"
|
||||||
"XOXX"
|
+ "OOOX"
|
||||||
+ "XOOX"
|
+ "XXXX"
|
||||||
+ "XOXX"
|
+ "XXXX"),
|
||||||
+ "XXXX")
|
new Shape(
|
||||||
,Color.PURPLE);
|
"XOXX"
|
||||||
final Frame OPiece = new Frame(
|
+ "XOOX"
|
||||||
new Shape(
|
+ "XOXX"
|
||||||
"XOOX"
|
+ "XXXX")
|
||||||
+ "XOOX"
|
,Color.PURPLE);
|
||||||
+ "XXXX"
|
final public static Frame OPiece = new Frame(
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XOOX"
|
||||||
"XOOX"
|
+ "XOOX"
|
||||||
+ "XOOX"
|
+ "XXXX"
|
||||||
+ "XXXX"
|
+ "XXXX"),
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XOOX"
|
||||||
"XOOX"
|
+ "XOOX"
|
||||||
+ "XOOX"
|
+ "XXXX"
|
||||||
+ "XXXX"
|
+ "XXXX"),
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"XOOX"
|
||||||
"XOOX"
|
+ "XOOX"
|
||||||
+ "XOOX"
|
+ "XXXX"
|
||||||
+ "XXXX"
|
+ "XXXX"),
|
||||||
+ "XXXX")
|
new Shape(
|
||||||
,Color.YELLOW);
|
"XOOX"
|
||||||
final Frame IPiece = new Frame(
|
+ "XOOX"
|
||||||
new Shape(
|
+ "XXXX"
|
||||||
"XXOX"
|
+ "XXXX")
|
||||||
+ "XXOX"
|
,Color.YELLOW);
|
||||||
+ "XXOX"
|
final public static Frame IPiece = new Frame(
|
||||||
+ "XXOX"),
|
new Shape(
|
||||||
new Shape(
|
"XXOX"
|
||||||
"OOOO"
|
+ "XXOX"
|
||||||
+ "XXXX"
|
+ "XXOX"
|
||||||
+ "XXXX"
|
+ "XXOX"),
|
||||||
+ "XXXX"),
|
new Shape(
|
||||||
new Shape(
|
"OOOO"
|
||||||
"XXOX"
|
+ "XXXX"
|
||||||
+ "XXOX"
|
+ "XXXX"
|
||||||
+ "XXOX"
|
+ "XXXX"),
|
||||||
+ "XXOX"),
|
new Shape(
|
||||||
new Shape(
|
"XXOX"
|
||||||
"OOOO"
|
+ "XXOX"
|
||||||
+ "XXXX"
|
+ "XXOX"
|
||||||
+ "XXXX"
|
+ "XXOX"),
|
||||||
+ "XXXX")
|
new Shape(
|
||||||
,Color.AQUA);
|
"OOOO"
|
||||||
|
+ "XXXX"
|
||||||
|
+ "XXXX"
|
||||||
|
+ "XXXX")
|
||||||
|
,Color.AQUA);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
piecePool = new Frame[] {LPiece,JPiece,SPiece,ZPiece,TPiece,OPiece,IPiece};
|
piecePool = new Frame[] {LPiece,JPiece,SPiece,ZPiece,TPiece,OPiece,IPiece};
|
||||||
|
|
||||||
p = new Player();
|
p = new Player();
|
||||||
|
|
||||||
|
frame = new JFrame();
|
||||||
|
canvas = new GameCanvas();
|
||||||
|
frame.addKeyListener(canvas);
|
||||||
|
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||||
|
frame.setSize(1024, 576);
|
||||||
|
frame.setTitle("My Tetris Game");
|
||||||
|
frame.add(canvas);
|
||||||
|
frame.setResizable(false);
|
||||||
|
frame.setVisible(true);
|
||||||
|
|
||||||
TimerTask stepTask = new TimerTask() {
|
TimerTask stepTask = new TimerTask() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -194,27 +222,71 @@ public class Game {
|
|||||||
Timer t = new Timer();
|
Timer t = new Timer();
|
||||||
|
|
||||||
t.schedule(stepTask, 0, (long)Math.floor(1000/60f));
|
t.schedule(stepTask, 0, (long)Math.floor(1000/60f));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void step() {
|
static void step() {
|
||||||
tickDelay--;
|
tickDelay--;
|
||||||
rotateTimer--;
|
//rotateTimer--;
|
||||||
if (tickDelay<=0) {
|
if (state!=GameState.LOSE) {
|
||||||
moveBlock();
|
if (tickDelay<=0) {
|
||||||
tickDelay=levelDelay[level];
|
moveBlock();
|
||||||
}
|
tickDelay=levelDelay[level];
|
||||||
if (rotateTimer<=0) {
|
}
|
||||||
//p.rotateCounterClockwise();
|
/*if (rotateTimer<=0) {
|
||||||
p.moveBlockLeft();
|
//p.rotateCounterClockwise();
|
||||||
rotateTimer=rotateDelay;
|
p.moveBlockLeft();
|
||||||
|
rotateTimer=rotateDelay;
|
||||||
|
}*/
|
||||||
|
HandleKeys();
|
||||||
}
|
}
|
||||||
DrawBoard();
|
DrawBoard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void HandleKeys() {
|
||||||
|
if (AreKeysHeldDown(KeyEvent.VK_LEFT,KeyEvent.VK_A)) {
|
||||||
|
Game.p.moveBlockLeft();
|
||||||
|
UpdateKeyDelay(KeyEvent.VK_LEFT,KeyEvent.VK_A);
|
||||||
|
}
|
||||||
|
if (AreKeysHeldDown(KeyEvent.VK_RIGHT,KeyEvent.VK_D)) {
|
||||||
|
Game.p.moveBlockRight();
|
||||||
|
UpdateKeyDelay(KeyEvent.VK_RIGHT,KeyEvent.VK_D);
|
||||||
|
}
|
||||||
|
if (AreKeysHeldDown(KeyEvent.VK_S,KeyEvent.VK_DOWN)) {
|
||||||
|
Game.tickDelay=1;
|
||||||
|
UpdateKeyDelay(KeyEvent.VK_S,KeyEvent.VK_DOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateKeyDelay(int...keys) {
|
||||||
|
for (int i=0;i<keys.length;i++) {
|
||||||
|
if (keyMap.containsKey(keys[i])) {
|
||||||
|
keyMap.get(keys[i]).setTimer(Game.defaultKeyDelay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean AreKeysHeldDown(Integer...keys) {
|
||||||
|
for (int i=0;i<keys.length;i++) {
|
||||||
|
if (keyMap.containsKey(keys[i])&&keyMap.get(keys[i]).pressed
|
||||||
|
&&keyMap.get(keys[i]).timer<=0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (keyMap.containsKey(keys[i])) {
|
||||||
|
keyMap.get(keys[i]).setTimer(keyMap.get(keys[i]).timer-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static void DrawBoard() {
|
private static void DrawBoard() {
|
||||||
|
canvas.repaint();
|
||||||
|
//DrawConsoleBoard();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DrawConsoleBoard() {
|
||||||
ClearScreen();
|
ClearScreen();
|
||||||
Point[] checkPoints = p.GetPlayerBlocksInGrid(p.getCurrentShape());
|
Point[] checkPoints = p.GetPlayerBlocksInGrid(p.getCurrentShape(),p.pos);
|
||||||
for (int y=19;y>=0;y--) {
|
for (int y=19;y>=0;y--) {
|
||||||
for (int x=0;x<10;x++) {
|
for (int x=0;x<10;x++) {
|
||||||
boolean plotted=false;
|
boolean plotted=false;
|
||||||
@ -252,7 +324,7 @@ public class Game {
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
Point[] checkPoints = p.GetPlayerBlocksInGrid(p.getCurrentShape());
|
Point[] checkPoints = p.GetPlayerBlocksInGrid(p.getCurrentShape(),p.pos);
|
||||||
|
|
||||||
boolean isOccupied = isOccupied(checkPoints,new Point(0,-1));
|
boolean isOccupied = isOccupied(checkPoints,new Point(0,-1));
|
||||||
|
|
||||||
@ -270,6 +342,10 @@ public class Game {
|
|||||||
//System.out.println("Called: "+y);
|
//System.out.println("Called: "+y);
|
||||||
deletionRows = CheckAndClearFullRows(deletionRows, y);
|
deletionRows = CheckAndClearFullRows(deletionRows, y);
|
||||||
}
|
}
|
||||||
|
linesCleared+=deletionRows;
|
||||||
|
if (linesCleared/10>level && level<19) {
|
||||||
|
level=linesCleared/10;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int CheckAndClearFullRows(int deletionRows, int y) {
|
private static int CheckAndClearFullRows(int deletionRows, int y) {
|
||||||
@ -298,7 +374,9 @@ public class Game {
|
|||||||
private static void ShiftBlockDownByNumberOfDeletionRows(int deletionRows, int y, int x) {
|
private static void ShiftBlockDownByNumberOfDeletionRows(int deletionRows, int y, int x) {
|
||||||
if (deletionRows>0) {
|
if (deletionRows>0) {
|
||||||
gameGrid.grid[x][y-deletionRows].active=gameGrid.grid[x][y].active;
|
gameGrid.grid[x][y-deletionRows].active=gameGrid.grid[x][y].active;
|
||||||
|
gameGrid.grid[x][y-deletionRows].color=gameGrid.grid[x][y].color;
|
||||||
gameGrid.grid[x][y].active=false;
|
gameGrid.grid[x][y].active=false;
|
||||||
|
gameGrid.grid[x][y].color=Color.BLACK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,10 +387,12 @@ public class Game {
|
|||||||
private static void SnapPieceThatCollided(Point[] checkPoints) {
|
private static void SnapPieceThatCollided(Point[] checkPoints) {
|
||||||
for (Point point : checkPoints) {
|
for (Point point : checkPoints) {
|
||||||
//If any point in the grid is outside, this is our lose condition.
|
//If any point in the grid is outside, this is our lose condition.
|
||||||
if (point.y>=gameGrid.grid[0].length) {
|
if (point.y>=20) {
|
||||||
state = GameState.LOSE;
|
state = GameState.LOSE;
|
||||||
|
} else {
|
||||||
|
gameGrid.grid[point.x][point.y].active=true;
|
||||||
|
gameGrid.grid[point.x][point.y].color=p.getCurrentShape().col;
|
||||||
}
|
}
|
||||||
gameGrid.grid[point.x][point.y].active=true;
|
|
||||||
}
|
}
|
||||||
p.ShuffleNextPiece();
|
p.ShuffleNextPiece();
|
||||||
}
|
}
|
||||||
@ -325,6 +405,7 @@ public class Game {
|
|||||||
for (int i=0;i<checkPoints.length;i++) {
|
for (int i=0;i<checkPoints.length;i++) {
|
||||||
Point point = checkPoints[i];
|
Point point = checkPoints[i];
|
||||||
//point.translate(p.pos.x,p.pos.y);
|
//point.translate(p.pos.x,p.pos.y);
|
||||||
|
//System.out.println((point.x+offset.x)+"/"+(point.y+offset.y));
|
||||||
if (point.y+offset.y<0 ||
|
if (point.y+offset.y<0 ||
|
||||||
point.y+offset.y>=gameGrid.grid[0].length||
|
point.y+offset.y>=gameGrid.grid[0].length||
|
||||||
point.x+offset.x>=gameGrid.grid.length||
|
point.x+offset.x>=gameGrid.grid.length||
|
||||||
@ -333,6 +414,7 @@ public class Game {
|
|||||||
isOccupied=true;
|
isOccupied=true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
//System.out.println("Pass");
|
||||||
}
|
}
|
||||||
return isOccupied;
|
return isOccupied;
|
||||||
}
|
}
|
||||||
|
132
Tetris/src/sig/game/GameCanvas.java
Normal file
132
Tetris/src/sig/game/GameCanvas.java
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
package sig.game;
|
||||||
|
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.KeyListener;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import sig.utils.DrawUtils;
|
||||||
|
|
||||||
|
public class GameCanvas extends JPanel implements KeyListener{
|
||||||
|
public final static Font displayText = new Font("Consolas",Font.BOLD,24);
|
||||||
|
|
||||||
|
public final static int WINDOW_WIDTH = 1024;
|
||||||
|
public final static int WINDOW_HEIGHT = 576;
|
||||||
|
|
||||||
|
public final static int BLOCK_SIZE = 24;
|
||||||
|
public final static int FIELD_WIDTH = BLOCK_SIZE*10;
|
||||||
|
public final static int FIELD_HEIGHT = BLOCK_SIZE*20;
|
||||||
|
|
||||||
|
public final static int FIELD_STARTX = WINDOW_WIDTH/2-FIELD_WIDTH/2;
|
||||||
|
public final static int FIELD_STARTY = WINDOW_HEIGHT/2+FIELD_HEIGHT/2;
|
||||||
|
|
||||||
|
public final static int LINES_CLEARED_DISPLAYX = WINDOW_WIDTH/2+180;
|
||||||
|
public final static int LINES_CLEARED_DISPLAYY = WINDOW_HEIGHT/2;
|
||||||
|
|
||||||
|
public final static int LEVEL_DISPLAYX = WINDOW_WIDTH/2+180;
|
||||||
|
public final static int LEVEL_DISPLAYY = LINES_CLEARED_DISPLAYY-64;
|
||||||
|
|
||||||
|
public final static int NEXTPIECE_DISPLAYX = WINDOW_WIDTH/2+180;
|
||||||
|
public final static int NEXTPIECE_DISPLAYY = LEVEL_DISPLAYY-128;
|
||||||
|
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
g.setColor(java.awt.Color.DARK_GRAY);
|
||||||
|
g.fillRect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
|
//System.out.println("Redrawn");
|
||||||
|
Point[] checkPoints = Game.p.GetPlayerBlocksInGrid(Game.p.getCurrentShape(),Game.p.pos);
|
||||||
|
for (int y=0;y<20;y++) {
|
||||||
|
for (int x=0;x<10;x++) {
|
||||||
|
boolean plotted=false;
|
||||||
|
for (Point point : checkPoints) {
|
||||||
|
if (point.x==x && point.y==y) {
|
||||||
|
plotted=true;
|
||||||
|
//System.out.print('P');
|
||||||
|
g.setColor((Game.state==GameState.LOSE)
|
||||||
|
?java.awt.Color.LIGHT_GRAY:
|
||||||
|
Game.p.getCurrentShape().col.getColor());
|
||||||
|
Point blockCoord=getBlockCoordinateToPixelCoordinate(point);
|
||||||
|
g.fill3DRect(blockCoord.x, blockCoord.y, BLOCK_SIZE, BLOCK_SIZE, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!plotted) {
|
||||||
|
g.setColor((Game.state==GameState.LOSE&&Game.gameGrid.grid[x][y].active)
|
||||||
|
?java.awt.Color.LIGHT_GRAY:Game.gameGrid.grid[x][y].color.getColor());
|
||||||
|
Point blockCoord=getBlockCoordinateToPixelCoordinate(new Point(x,y));
|
||||||
|
g.fill3DRect(blockCoord.x, blockCoord.y, BLOCK_SIZE, BLOCK_SIZE, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Point[] nextPoints = Game.p.GetPlayerBlocksInGrid(Game.p.getNextShape(),new Point(0,0));
|
||||||
|
|
||||||
|
g.setColor(java.awt.Color.BLACK);
|
||||||
|
g.fill3DRect(NEXTPIECE_DISPLAYX, NEXTPIECE_DISPLAYY, 104, 104, true);
|
||||||
|
for (Point p : nextPoints) {
|
||||||
|
g.setColor(Game.p.getNextShape().col.getColor());
|
||||||
|
g.fill3DRect(p.x*BLOCK_SIZE+NEXTPIECE_DISPLAYX+52, p.y*BLOCK_SIZE+NEXTPIECE_DISPLAYY+52, BLOCK_SIZE, BLOCK_SIZE, false);
|
||||||
|
}
|
||||||
|
g.setColor(java.awt.Color.WHITE);
|
||||||
|
g.setFont(displayText);
|
||||||
|
g.drawString("NEXT",NEXTPIECE_DISPLAYX,NEXTPIECE_DISPLAYY);
|
||||||
|
g.setColor(java.awt.Color.WHITE);
|
||||||
|
g.setFont(displayText);
|
||||||
|
g.drawString("LINES",LINES_CLEARED_DISPLAYX,LINES_CLEARED_DISPLAYY);
|
||||||
|
g.drawString(Integer.toString(Game.linesCleared),LINES_CLEARED_DISPLAYX+6,LINES_CLEARED_DISPLAYY+24);
|
||||||
|
g.drawString("LEVEL",LEVEL_DISPLAYX,LEVEL_DISPLAYY);
|
||||||
|
g.drawString(Integer.toString(Game.level+1),LEVEL_DISPLAYX+6,LEVEL_DISPLAYY+24);
|
||||||
|
if (Game.state==GameState.LOSE) {
|
||||||
|
DrawUtils.drawCenteredText(g, g.getFont(),this, WINDOW_WIDTH/2, WINDOW_HEIGHT/2, java.awt.Color.WHITE, "Press R to Restart!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point getBlockCoordinateToPixelCoordinate(Point blockLoc) {
|
||||||
|
return new Point(FIELD_STARTX+BLOCK_SIZE*blockLoc.x,FIELD_STARTY-BLOCK_SIZE*blockLoc.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
List<Integer> keys = Arrays.asList(
|
||||||
|
KeyEvent.VK_LEFT,KeyEvent.VK_A,
|
||||||
|
KeyEvent.VK_RIGHT,KeyEvent.VK_D,
|
||||||
|
KeyEvent.VK_S,KeyEvent.VK_DOWN
|
||||||
|
);
|
||||||
|
Game.lastKey=e.getKeyCode();
|
||||||
|
/*if ((Game.keyMap.containsKey(e.getKeyCode())&&!Game.keyMap.get(e.getKeyCode())&&keys.contains(e.getKeyCode())
|
||||||
|
)||!Game.keyMap.containsKey(e.getKeyCode())) {
|
||||||
|
System.out.println("Executing");
|
||||||
|
Game.keyDelay=20;
|
||||||
|
}*/
|
||||||
|
if (Game.keyMap.containsKey(e.getKeyCode())) {
|
||||||
|
Game.keyMap.put(e.getKeyCode(),Game.keyMap.get(e.getKeyCode()).updatePress(true));
|
||||||
|
} else {
|
||||||
|
Game.keyMap.put(e.getKeyCode(),new Key(true));
|
||||||
|
}
|
||||||
|
if (e.getKeyCode()==KeyEvent.VK_Z||e.getKeyCode()==KeyEvent.VK_COMMA) {
|
||||||
|
Game.p.rotateClockwise();
|
||||||
|
}
|
||||||
|
if (e.getKeyCode()==KeyEvent.VK_X||e.getKeyCode()==KeyEvent.VK_PERIOD) {
|
||||||
|
Game.p.rotateCounterClockwise();
|
||||||
|
}
|
||||||
|
if (e.getKeyCode()==KeyEvent.VK_R && Game.state==GameState.LOSE) {
|
||||||
|
Game.p = new Player();
|
||||||
|
Game.gameGrid = new Grid();
|
||||||
|
Game.level=0;
|
||||||
|
Game.linesCleared=0;
|
||||||
|
Game.state=GameState.PLAYING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
Game.keyMap.put(e.getKeyCode(),Game.keyMap.get(e.getKeyCode()).updatePress(false));
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@ import java.util.Arrays;
|
|||||||
public class Grid {
|
public class Grid {
|
||||||
|
|
||||||
final int GRID_WIDTH = 10;
|
final int GRID_WIDTH = 10;
|
||||||
final int GRID_HEIGHT = 20;
|
final int GRID_HEIGHT = 24;
|
||||||
|
|
||||||
Block[][] grid = new Block[GRID_WIDTH][GRID_HEIGHT];
|
Block[][] grid = new Block[GRID_WIDTH][GRID_HEIGHT];
|
||||||
|
|
||||||
|
18
Tetris/src/sig/game/Key.java
Normal file
18
Tetris/src/sig/game/Key.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package sig.game;
|
||||||
|
|
||||||
|
public class Key {
|
||||||
|
boolean pressed;
|
||||||
|
int timer;
|
||||||
|
public Key(boolean pressed) {
|
||||||
|
this.pressed=pressed;
|
||||||
|
this.timer=0;
|
||||||
|
}
|
||||||
|
public Key updatePress(boolean pressed) {
|
||||||
|
this.pressed=pressed;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public Key setTimer(int timer) {
|
||||||
|
this.timer=timer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -20,10 +20,10 @@ public class Player {
|
|||||||
public void ShuffleNextPiece() {
|
public void ShuffleNextPiece() {
|
||||||
piece = nextPiece.clone();
|
piece = nextPiece.clone();
|
||||||
nextPiece = SelectRandomTetrimino();
|
nextPiece = SelectRandomTetrimino();
|
||||||
pos = new Point(5,20);
|
pos = new Point(5,21);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Point[] GetPlayerBlocksInGrid(Shape s) {
|
public Point[] GetPlayerBlocksInGrid(Shape s,Point offset) {
|
||||||
Point[] checkPoints = new Point[4];
|
Point[] checkPoints = new Point[4];
|
||||||
Shape tetShape = s;
|
Shape tetShape = s;
|
||||||
int pointsInserted=0;
|
int pointsInserted=0;
|
||||||
@ -31,7 +31,7 @@ public class Player {
|
|||||||
for (int y=0;y<tetShape.shape[0].length;y++) {
|
for (int y=0;y<tetShape.shape[0].length;y++) {
|
||||||
if (tetShape.shape[x][y].active) {
|
if (tetShape.shape[x][y].active) {
|
||||||
Point point = new Point((x-2),-y);
|
Point point = new Point((x-2),-y);
|
||||||
point.translate(pos.x,pos.y);
|
point.translate(offset.x,offset.y);
|
||||||
checkPoints[pointsInserted++] = point;
|
checkPoints[pointsInserted++] = point;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,12 +50,12 @@ public class Player {
|
|||||||
//If they still do, try to shift the piece one right, 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.
|
//If no piece position is free, we cannot rotate. Return.
|
||||||
//Otherwise, all conditions have been met, and we can rotate the piece.
|
//Otherwise, all conditions have been met, and we can rotate the piece.
|
||||||
Point[] checkPoints = GetPlayerBlocksInGrid(GetClockwiseRotatedCurrentPiece());
|
Point[] checkPoints = GetPlayerBlocksInGrid(GetClockwiseRotatedCurrentPiece(),pos);
|
||||||
RotateIfSpaceIsFree(checkPoints,RotationDirection.CLOCKWISE);
|
RotateIfSpaceIsFree(checkPoints,RotationDirection.CLOCKWISE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rotateCounterClockwise() {
|
public void rotateCounterClockwise() {
|
||||||
Point[] checkPoints = GetPlayerBlocksInGrid(GetCounterClockwiseRotatedCurrentPiece());
|
Point[] checkPoints = GetPlayerBlocksInGrid(GetCounterClockwiseRotatedCurrentPiece(),pos);
|
||||||
RotateIfSpaceIsFree(checkPoints,RotationDirection.COUNTERCLOCKWISE);
|
RotateIfSpaceIsFree(checkPoints,RotationDirection.COUNTERCLOCKWISE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,10 +73,11 @@ public class Player {
|
|||||||
|
|
||||||
|
|
||||||
private void moveBlock(MoveDirection dir) {
|
private void moveBlock(MoveDirection dir) {
|
||||||
Point[] checkPoints = GetPlayerBlocksInGrid(getCurrentShape());
|
Point[] checkPoints = GetPlayerBlocksInGrid(getCurrentShape(),pos);
|
||||||
boolean isFree = true;
|
boolean isFree = true;
|
||||||
for (Point p : checkPoints) {
|
for (Point p : checkPoints) {
|
||||||
if (Game.isOccupied(checkPoints,new Point(dir.value,0))) {
|
if (Game.isOccupied(checkPoints,new Point(dir.value,0))&&p.y>=0) {
|
||||||
|
//System.out.println(p.x+","+p.y);
|
||||||
isFree=false;
|
isFree=false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -92,14 +93,19 @@ public class Player {
|
|||||||
|
|
||||||
private void RotateIfSpaceIsFree(Point[] checkPoints,RotationDirection dir) {
|
private void RotateIfSpaceIsFree(Point[] checkPoints,RotationDirection dir) {
|
||||||
int[] offset = new int[]{0,-1,1};
|
int[] offset = new int[]{0,-1,1};
|
||||||
int freeOffset = -1;
|
if (Game.p.getCurrentShape().equals(Game.IPiece.shape[Game.rotation])) {
|
||||||
|
//System.out.println("Is I Piece.");
|
||||||
|
offset = new int[] {0,-1,1,-2,2,-3};
|
||||||
|
}
|
||||||
|
int freeOffset = -99999;
|
||||||
for (int i=0;i<offset.length;i++) {
|
for (int i=0;i<offset.length;i++) {
|
||||||
if (!Game.isOccupied(checkPoints,new Point(offset[i],0))) {
|
if (!Game.isOccupied(checkPoints,new Point(offset[i],0))) {
|
||||||
|
//System.out.println("Found an offset: "+offset[i]);
|
||||||
freeOffset = offset[i];
|
freeOffset = offset[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (freeOffset!=-1) {
|
if (freeOffset!=-99999) {
|
||||||
pos.translate(freeOffset, 0);
|
pos.translate(freeOffset, 0);
|
||||||
Game.rotation=rotatePiece(Game.rotation,dir);
|
Game.rotation=rotatePiece(Game.rotation,dir);
|
||||||
//System.out.println("rotation: "+Game.rotation);
|
//System.out.println("rotation: "+Game.rotation);
|
||||||
@ -123,4 +129,8 @@ public class Player {
|
|||||||
}
|
}
|
||||||
return currentRotation;
|
return currentRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Shape getNextShape() {
|
||||||
|
return nextPiece.shape[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
5
Tetris/src/sig/game/PlayerBlock.java
Normal file
5
Tetris/src/sig/game/PlayerBlock.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package sig.game;
|
||||||
|
|
||||||
|
public class PlayerBlock {
|
||||||
|
|
||||||
|
}
|
@ -8,11 +8,13 @@ public class Shape {
|
|||||||
new Block[] {new Block(false),new Block(false),new Block(false),new Block(false),},
|
new Block[] {new Block(false),new Block(false),new Block(false),new Block(false),},
|
||||||
};*/
|
};*/
|
||||||
Block[][] shape;
|
Block[][] shape;
|
||||||
|
Color col;
|
||||||
Shape(String shapeStr) {
|
Shape(String shapeStr) {
|
||||||
Block[][] shapeArr = new Block[4][4];
|
Block[][] shapeArr = new Block[4][4];
|
||||||
for (int i=0;i<shapeStr.length();i++) {
|
for (int i=0;i<shapeStr.length();i++) {
|
||||||
shapeArr[i/4][i%4]= new Block(shapeStr.charAt(i)=='O');
|
shapeArr[i/4][i%4]= new Block(shapeStr.charAt(i)=='O');
|
||||||
}
|
}
|
||||||
shape = shapeArr;
|
shape = shapeArr;
|
||||||
|
col = shapeArr[0][0].color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,8 @@ import java.awt.image.BufferedImage;
|
|||||||
import java.awt.image.ImageObserver;
|
import java.awt.image.ImageObserver;
|
||||||
import java.text.AttributedString;
|
import java.text.AttributedString;
|
||||||
|
|
||||||
import sig.MyPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
|
||||||
public class DrawUtils {
|
public class DrawUtils {
|
||||||
public static void drawOutlineText(Graphics g, Font font, double x, double y, int outline_size, Color text_color, Color shadow_color, String message) {
|
public static void drawOutlineText(Graphics g, Font font, double x, double y, int outline_size, Color text_color, Color shadow_color, String message) {
|
||||||
@ -58,19 +59,19 @@ public class DrawUtils {
|
|||||||
g2.drawString(as.getIterator(),(int)(x+xoffset),(int)(y+yoffset));
|
g2.drawString(as.getIterator(),(int)(x+xoffset),(int)(y+yoffset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static void drawCenteredOutlineText(Graphics g, Font font, double x, double y, int font_size, int outline_size, Color text_color, Color shadow_color, String message) {
|
public static void drawCenteredOutlineText(Graphics g, Font font,JPanel panel, double x, double y, int font_size, int outline_size, Color text_color, Color shadow_color, String message) {
|
||||||
Rectangle2D textBounds = TextUtils.calculateStringBoundsFont(message, font);
|
Rectangle2D textBounds = TextUtils.calculateStringBoundsFont(panel,message, font);
|
||||||
drawOutlineText(g,font,x,y,-textBounds.getWidth()/2,-textBounds.getHeight()/2,font_size,outline_size,text_color,shadow_color,message);
|
drawOutlineText(g,font,x,y,-textBounds.getWidth()/2,-textBounds.getHeight()/2,font_size,outline_size,text_color,shadow_color,message);
|
||||||
}
|
}
|
||||||
public static void drawCenteredOutlineText(Graphics g, Font font, double x, double y, int outline_size, Color text_color, Color shadow_color, String message) {
|
public static void drawCenteredOutlineText(Graphics g, Font font,JPanel panel, double x, double y, int outline_size, Color text_color, Color shadow_color, String message) {
|
||||||
drawCenteredOutlineText(g,font,x,y,1,outline_size,text_color,shadow_color,message);
|
drawCenteredOutlineText(g,font,panel,x,y,1,outline_size,text_color,shadow_color,message);
|
||||||
}
|
}
|
||||||
public static void drawText(Graphics g, double x, double y, Color color, String message) {
|
public static void drawText(Graphics g, double x, double y, Color color, String message) {
|
||||||
if (message.length()>0) {
|
if (message.length()>0) {
|
||||||
AttributedString as = new AttributedString(message);
|
/*AttributedString as = new AttributedString(message);
|
||||||
as.addAttribute(TextAttribute.FONT, MyPanel.programFont);
|
as.addAttribute(TextAttribute.FONT, MyPanel.programFont);*/
|
||||||
g.setColor(color);
|
g.setColor(color);
|
||||||
g.drawString(as.getIterator(),(int)x,(int)y);
|
g.drawString(message,(int)x,(int)y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static void drawTextFont(Graphics g, Font font, double x, double y, Color color, String message) {
|
public static void drawTextFont(Graphics g, Font font, double x, double y, Color color, String message) {
|
||||||
@ -90,11 +91,11 @@ public class DrawUtils {
|
|||||||
/**
|
/**
|
||||||
* Centers the text along the X Axis.
|
* Centers the text along the X Axis.
|
||||||
*/
|
*/
|
||||||
public static void drawCenteredText(Graphics g, Font font, int x, int y, Color color, String text) {
|
public static void drawCenteredText(Graphics g, Font font,JPanel panel, int x, int y, Color color, String text) {
|
||||||
AttributedString as = new AttributedString(text);
|
AttributedString as = new AttributedString(text);
|
||||||
as.addAttribute(TextAttribute.FONT, font);
|
as.addAttribute(TextAttribute.FONT, font);
|
||||||
g.setColor(color);
|
g.setColor(color);
|
||||||
Rectangle2D textBounds = TextUtils.calculateStringBoundsFont(text, font);
|
Rectangle2D textBounds = TextUtils.calculateStringBoundsFont(panel,text, font);
|
||||||
g.drawString(as.getIterator(),(int)(x-textBounds.getWidth()/2),(int)(y+textBounds.getHeight()));
|
g.drawString(as.getIterator(),(int)(x-textBounds.getWidth()/2),(int)(y+textBounds.getHeight()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,12 +6,13 @@ import java.awt.font.FontRenderContext;
|
|||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import sig.MyRobot;
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
public class TextUtils {
|
public class TextUtils {
|
||||||
|
|
||||||
public static Rectangle2D calculateStringBoundsFont(String msg, Font font) {
|
public static Rectangle2D calculateStringBoundsFont(JPanel panel,String msg, Font font) {
|
||||||
FontRenderContext frc = MyRobot.p.getFontMetrics(font).getFontRenderContext();
|
FontRenderContext frc = panel.getFontMetrics(font).getFontRenderContext();
|
||||||
return font.getStringBounds(msg, frc);
|
return font.getStringBounds(msg, frc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user