/* Tetris.java * Two-player Tetris * Released under the Ricky license: * You are free to do whatever you * want with this source, AS LONG AS * you learn something from it. * Author: Ricky C. * Last modified: 4/19/07 * School: [removed] * IDE used: Eclipse JDK v3.2.2 / Java SDK v1.6.0_01 * Purpose: To allow two players to play a game of Tetris. */ import java.awt.*; import java.awt.event.*; import java.awt.geom.Rectangle2D; import java.util.Random; public class Tetris extends Frame implements Runnable,WindowListener,KeyListener { private static final long serialVersionUID = -6773388040204011141L; // GAME SETTINGS // public static final int FPS = 30; public static final int GAMEAREAWIDTH = 10; public static final int GAMEAREAHEIGHT = 20; public static final int GAMEAREABGCOLOR = 0xFFFFFF; public static final int GAMEAREABORDERCOLOR = 0xFFFFFF; public static final int BLOCKSIZE = 16; // STATE CONSTANTS // public static final int STATE_PRESSAKEY = 0; public static final int STATE_READY = 1; public static final int STATE_NORMAL = 2; public static final int STATE_PAUSE_ELIMINATINGLINES = 3; public static final int STATE_PAUSE_USER = 4; public static final int STATE_GAMEOVER = 5; // BLOCK IDS // public static final int BLOCK_I = 0; public static final int BLOCK_J = 1; public static final int BLOCK_L = 2; public static final int BLOCK_O = 3; public static final int BLOCK_S = 4; public static final int BLOCK_T = 5; public static final int BLOCK_Z = 6; Player player1; Player player2; int globalState; // BACK BUFFERED DRAWING VARIABLES // Thread drawThread; Graphics bbGraphics; Image bbImage; long lastUpdate; public static final Random randGen = new Random(System.currentTimeMillis()); // KEYPRESS BUFFER // // Notice type "Boolean[]", not "boolean[]" // This is done intentionally so that I can utilize the // null state that only exists in Boolean. Boolean[] keys; public static void main(String[] args) { new Tetris(); System.exit(0); } public Tetris() { this.setVisible(false); setUpWindow(); resetGame(); // START DRAWING drawThread.start(); try { drawThread.join(); } catch(Exception e) {} } /* sets up the Frame */ private void setUpWindow() { this.setTitle("Tetris"); this.setResizable(false); this.setBackground(Color.white); this.setForeground(Color.black); this.addWindowListener(this); this.addKeyListener(this); this.setVisible(true); this.setSize(getInsets().left+getInsets().right+GAMEAREAWIDTH*BLOCKSIZE*2+90,getInsets().top+getInsets().bottom+GAMEAREAHEIGHT*BLOCKSIZE); Dimension dim = getToolkit().getScreenSize(); Rectangle abounds = getBounds(); this.setLocation((dim.width - abounds.width) / 2, (dim.height - abounds.height) / 2); } /* clears the key buffer */ private void clearKeys() { if(keys==null) return; synchronized(keys) { for(int i=0;i-1) { for(int y=emptyLine;y>=topLine;y--) { for(int x=0;xgAC.length-1 || x+xloc>gAC[0].length-1 || gAC[y+yloc][x+xloc]!=GAMEAREABGCOLOR) return true; } } return false; } /* try to move the block (relx, rely) relative units * relx and rely are in screen coordinates; positive Y is downward */ public synchronized boolean translate(int relx, int rely) { //if(xloc+relx<0 || xloc+relx+localSpace[0].length>inst.gameAreaColors[0].length || yloc+rely<0 || yloc+rely+localSpace.length>inst.gameAreaColors.length) // return false; if(owner==null) return true; for(int y=0;yowner.gameAreaColors.length-1 || x+xloc+relx<0 || x+xloc+relx>owner.gameAreaColors[0].length-1 || owner.gameAreaColors[y+yloc+rely][x+xloc+relx]!=GAMEAREABGCOLOR) return false; } } xloc+=relx; yloc+=rely; return true; } /* draw the block onto gameAreaColors, and then return the result */ public synchronized int[][] draw(int[][] gameAreaColors) { int[][] temp = new int[gameAreaColors.length][gameAreaColors[0].length]; for(int i=0;i