//JAKE HACKIM //NICK SUGGS //2013 import java.awt.*; import java.awt.event.*; import java.applet.Applet; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.KeyAdapter; import java.util.*; import java.util.TimerTask; import java.util.Timer; import java.lang.Object; import java.text.DecimalFormat; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseAdapter; import javax.swing.*; import java.io.*; public class Tetris extends Applet { //==================================================// // GLOBAL DECLARATIONS // //==================================================// String playerName = "Player"; int DIFF = 0; boolean lineWasFull = false; Font f; int RANDOM; int fontIndex = 0; RadioButton diff; String easyString = "Easy"; String normalString = "Normal"; String hardString = "Hard"; int[] cleared = {0, 0, 0, 0, 0, 0, 0}; int LINES = 0; int SCORE = 0; boolean gameLost = false; int delayIncrease = 1; Timer t = new Timer(); Rectangle playGame = new Rectangle(190, 192, 436, 100); Rectangle highScores = new Rectangle(190, 321, 436, 100); Rectangle options = new Rectangle(190, 450, 436, 100); Block[] icons = new Block[7]; Block nextBlock; int delay = 1000; int period = 500; int currentBlock = 0; Block thisBlock; int button = 2; boolean trigger = true; boolean first = true; final int SPAWNX = 5; final int SPAWNY = 3; Graphics g; Graphics gBuffer; Image vMem; Image mainScreen; Image paused; Image img1; Image img2; Image img3; Image img4; Image img5; Image img6; Image img7; Image board; int appletWidth = getWidth(); int appletHeight = getHeight(); int BLOCKSCALE; ArrayList blocks = new ArrayList(); //==================================================// // INIT METHOD // //==================================================// public void init() { diff = new RadioButton(); icons[0] = new Block(1, button, true); icons[1] = new Block(2, button, true); icons[2] = new Block(3, button, true); icons[3] = new Block(4, button, true); icons[4] = new Block(5, button, true); icons[5] = new Block(6, button, true); icons[6] = new Block(7, button, true); RANDOM = (int) (Math.random() * 7) + 1; img1 = getImage(getDocumentBase(), "L.png"); img2 = getImage(getDocumentBase(), "RL.png"); img3 = getImage(getDocumentBase(), "T.png"); img4 = getImage(getDocumentBase(), "O.png"); img5 = getImage(getDocumentBase(), "S.png"); img6 = getImage(getDocumentBase(), "RS.png"); img7 = getImage(getDocumentBase(), "Ln.png"); board = getImage(getDocumentBase(), "Board.png"); mainScreen = getImage(getDocumentBase(), "MwT.png"); appletWidth = getWidth(); appletHeight = getHeight(); if(appletWidth > appletHeight) appletWidth = appletHeight; else appletHeight = appletWidth; BLOCKSCALE = (int) appletWidth * appletHeight / 12500; super.init(); addKeyListener(new KeyListener()); addMouseListener(new MouseListener()); addBlock(); vMem = createImage(appletWidth,appletHeight); gBuffer = vMem.getGraphics(); gBuffer.setColor(Color.white); gBuffer.fillRect(0,0,appletWidth,appletHeight); mainScreen = getImage(getDocumentBase(), "MwT.png"); } //==================================================// // PAINT METHOD // //==================================================// public void paint(Graphics g) { switch(button) { //==================================================// // TETRIS GAME // //==================================================// case 1: //clear(gBuffer); clear(g); nextBlock = new Block(RANDOM, button, false); //g.drawImage(board, 0, 0, getWidth(), getHeight(), this); thisBlock = blocks.get(currentBlock); //drawGrid(gBuffer); if(trigger) { //clear(g); //drawGrid(gBuffer); //repaint(); trigger = false; eraseBlock(g, thisBlock); } for(Block b : blocks) { switch(b.getBlockType()) { case 1: b.drawBlock(g, img1, BLOCKSCALE); break; case 2: b.drawBlock(g, img2, BLOCKSCALE); break; case 3: b.drawBlock(g, img3, BLOCKSCALE); break; case 4: b.drawBlock(g, img4, BLOCKSCALE); break; case 5: b.drawBlock(g, img5, BLOCKSCALE); break; case 6: b.drawBlock(g, img6, BLOCKSCALE); break; case 7: b.drawBlock(g, img7, BLOCKSCALE); break; } } if(appletWidth != getWidth() || appletHeight != getHeight()) { clear(g); //drawGrid(g); appletWidth = getWidth(); appletHeight = getHeight(); repaint(); } blocks.get(currentBlock).turns = 0; lineIsFull(); if(lineWasFull) { lineWasFull = false; repaint(); } if(currentBlock >= 1) { if(gameLost()) { quitGame(g); } } if(trigger) { trigger = false; repaint(); } break; //==================================================// // MAIN MENU // //==================================================// case 2: outputMenu(g); g.setColor(Color.blue); g.fillRect(190, 192, 436, 100); g.setColor(Color.red); g.fillRect(190, 321, 436, 100); g.setColor(Color.magenta); g.fillRect(190, 450, 436, 100); f = new Font("Ariel", Font.BOLD, 62); g.setFont(f); g.setColor(Color.white); g.drawString("PLAY GAME", 225, 265); g.drawString("HIGH SCORES", 190, 394); g.drawString("CONTROLS", 230, 523); break; //==================================================// // PAUSED GAME // //==================================================// case 3: paused = createImage(getWidth(), getHeight()); f = new Font("Arial", Font.BOLD, 32); g.setFont(f); g.setColor(new Color(0, 0, 0, 75)); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(Color.white); g.drawString("PAUSED", 341, 215); if(gameLost) { g.setColor(Color.black); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(Color.white); g.drawString("GAME OVER", 330, 215); DecimalFormat form = new DecimalFormat("00000000"); g.drawString("Score: " + form.format(SCORE), 300, 245); g.drawString("Lines: " + form.format(LINES), 302, 275); } System.out.println("THE GAME IS PAUSED"); break; //==================================================// // LOST GAME // //==================================================// case 4: //Scanner input = new Scanner(System.in); System.out.println("BUTTON IS 4"); int x = 0; drawLostGame(g); gameLost = true; t.purge(); t.cancel(); button = 3; x = SCORE; createTable(playerName, x); repaint(); break; //==================================================// // HIGH SCORES // //==================================================// case 5: createTable("", 0); button = 2; break; //==================================================// // DIFFICULTY SELECTION // //==================================================// case 6: diff.show(playerName); button = 7; repaint(); break; case 7: DIFF = 1; if(diff.box2.isSelected()) { runTimer(); DIFF = 2; } if(diff.box1.isSelected() || diff.box2.isSelected()) { button = 1; diff.close(); } repaint(); break; //==================================================// // CONTROLS AND CREDITS // //==================================================// case 8: outputOptions(g); break; } } //==================================================// // TIMER METHODS // //==================================================// public void runTimer() { t.scheduleAtFixedRate(new TimerTask() { public void run() { trigger = true; if(!collide() && button != 3 && button != 2) { blocks.get(currentBlock).moveDown(); //repaint(); } if(collide() && button != 3 && button != 2) { //System.out.println("ACTIVE"); blocks.get(currentBlock).moveUp(button); //if(!blocks.get(currentBlock).isPlaced()) // blocks.get(currentBlock).placeBlock(); //addBlock(RANDOM); //currentBlock++; //RANDOM = (int) (Math.random() * 7) + 1; //while(!collide() && blocks.get(currentBlock).canMoveUp()); //{ // blocks.get(currentBlock).moveUp(button); //} if(currentBlock != 0) { if(gameLost()) quitGame(g); } if(!blocks.get(currentBlock).isPlaced()) blocks.get(currentBlock).placeBlock(); addBlock(RANDOM); currentBlock++; RANDOM = (int) (Math.random() * 7) + 1; } //System.out.println("Tick"); repaint(); } }, delay, period); } //==================================================// // KEYBOARD METHODS // //==================================================// class KeyListener extends KeyAdapter { public KeyListener() { } public void keyPressed(KeyEvent e) { super.keyPressed(e); thisBlock = blocks.get(currentBlock); trigger = true; if(e.getKeyCode() == KeyEvent.VK_LEFT) { if(button != 3) blocks.get(currentBlock).moveLeft(button); if(collide() && button != 3) blocks.get(currentBlock).moveRight(button); } if(e.getKeyCode() == KeyEvent.VK_RIGHT) { if(button != 3) blocks.get(currentBlock).moveRight(button); if(collide() && button != 3) blocks.get(currentBlock).moveLeft(button); } if(e.getKeyCode() == KeyEvent.VK_UP) { if(button != 3) { blocks.get(currentBlock).turnC(button, blocks, currentBlock); } } if(e.getKeyCode() == KeyEvent.VK_DOWN) { if(button != 3) blocks.get(currentBlock).moveDown(); if(collide() && button != 3) { blocks.get(currentBlock).moveUp(button); //if(!blocks.get(currentBlock).isPlaced()) //blocks.get(currentBlock).placeBlock(); //addBlock(RANDOM); //currentBlock++; //RANDOM = (int) (Math.random() * 7) + 1; //while(!collide() && blocks.get(currentBlock).canMoveUp()); //{ // blocks.get(currentBlock).moveUp(button); //} if(currentBlock != 0) { if(gameLost()) quitGame(g); } } } if(e.getKeyCode() == KeyEvent.VK_ESCAPE) { if(!gameLost) { if(button == 3 && button != 2) { button = 1; blocks.get(currentBlock).b = 1; gBuffer.drawImage(paused, 0, 0, null); } else { if(button == 1) { button = 3; blocks.get(currentBlock).b = 3; } } if(button == 8) { button = 2; } } } if(e.getKeyCode() == KeyEvent.VK_SPACE) { do { blocks.get(currentBlock).moveDown(); } while(!collide() && button != 3); blocks.get(currentBlock).moveUp(button); if(!blocks.get(currentBlock).isPlaced()) blocks.get(currentBlock).placeBlock(); addBlock(RANDOM); currentBlock++; RANDOM = (int) (Math.random() * 7) + 1; if(gameLost()) quitGame(g); } repaint(); } } //==================================================// // COLLISION CHECK // //==================================================// public boolean collide() { boolean chk = false; int current = -1; for(Block b : blocks) { current++; if(current != currentBlock) { for(int x = 0; x < 4; x++) { for(int y = 0; y < 4; y++) { if(b.locs[x][0] == blocks.get(currentBlock).locs[y][0] && b.locs[x][1] == blocks.get(currentBlock).locs[y][1]) { chk = true; } } } } } for(int x = 0; x < 4; x++) { if(blocks.get(currentBlock).locs[x][1] == 21) chk = true; } return chk; } //==================================================// // MOUSE METHODS // //==================================================// class MouseListener extends MouseAdapter { public MouseListener() { } public void mouseEntered (MouseEvent mouseEvent) { } public void mousePressed (MouseEvent mouseEvent) { } public void mouseReleased (MouseEvent mouseEvent) { } public void mouseExited (MouseEvent mouseEvent) { } public void mouseClicked(MouseEvent e) { int x = e.getX(); int y = e.getY(); if(button == 2) { if(playGame.inside(x, y)) { button = 6; repaint(); } if(highScores.inside(x, y)) { button = 5; repaint(); } if(options.inside(x, y)) { button = 8; repaint(); } } } } //==================================================// // HIGH SCORES METHODS // //==================================================// public void createTable(String s, int x) { JFrame frame = new JFrame("High Scores List"); String columns[] = {"Name", "Score"}; Object data[][] = { {new String("TheBest"),new Integer(1000000)}, {new String(playerName),new Integer(x)}, }; JTable scores = new JTable(data,columns); frame.setVisible(true); frame.setBounds(500,350,500,200); frame.add(scores.getTableHeader(),BorderLayout.PAGE_START); frame.add(scores); } //==================================================// // DIFFICULTY/FONT METHODS // //==================================================// class RadioButton implements ActionListener { JRadioButton box1; JRadioButton box2; JButton box3; Choice pullBox = new Choice(); Label name = new Label("Player Name"); TextField nameBox = new TextField(20); GridLayout grid = new GridLayout(2, 2); JFrame frame = new JFrame(); RadioButton() { box1 = new JRadioButton("Easy Mode"); box2 = new JRadioButton("Normal Mode"); box3 = new JButton("Submit"); JRadioButton anotherRadio = new JRadioButton("..."); anotherRadio.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JRadioButton rb = (JRadioButton)e.getSource(); } }); JRadioButton button = new JRadioButton("..."); button.addActionListener(this); pullBox.addItem("Arial"); pullBox.addItem("Courier"); pullBox.addItem("Serif"); } public void actionPerformed(ActionEvent e) { JRadioButton button = (JRadioButton)e.getSource(); } public void show(String s) { Container pane = frame.getContentPane(); setLayout(grid); pane.setLayout(new GridLayout(3,1)); pane.add(name); pane.add(nameBox); pane.add(pullBox); pane.add(new JLabel("")); pane.add(box1); pane.add(box2); frame.setSize(400, 300); frame.setVisible(true); } public void close() { playerName = nameBox.getText(); fontIndex = pullBox.getSelectedIndex(); frame.dispose(); } } //==================================================// // OPTIONS MENU // //==================================================// public void outputOptions(Graphics g) { clear(g); g.setColor(Color.black); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(Color.white); f = new Font("Arial", Font.BOLD, 32); g.setFont(f); g.drawString("Up Arrow Rotate Piece", 50, 50); g.drawString("Left Arrow Move Piece Left", 50, 100); g.drawString("Right Arrow Move Piece Right", 50, 150); g.drawString("Down Arrow Move Piece Down", 50, 200); g.drawString("Spacebar Rush Piece Down", 50, 250); g.drawString("Escape Pause Game", 50, 300); g.drawString("Created by Nick Suggs and Jake Hackim, 2013", 50, 425); g.drawString("Press ESC to go back", 50, 500); } //==================================================// // DRAW METHODS // //==================================================// public void drawGrid(Graphics g) { g.setColor(Color.black); g.fillRect(0, 0, appletWidth, appletHeight); gBuffer.fillRect(0, 0, appletWidth, appletHeight); g.setColor(new Color(150, 150, 200)); g.fillRect(BLOCKSCALE, BLOCKSCALE, BLOCKSCALE * 8, BLOCKSCALE * 20); g.fillRect(BLOCKSCALE * 10, BLOCKSCALE, BLOCKSCALE * 10, BLOCKSCALE * 20); g.fillRect(BLOCKSCALE * 21, BLOCKSCALE, BLOCKSCALE * 8, BLOCKSCALE * 20); g.setColor(Color.black); for(int x = 0; x < 10; x++) { for(int y = 0; y < 20; y++) { g.drawRect(BLOCKSCALE * x + BLOCKSCALE * 10, BLOCKSCALE * y + BLOCKSCALE, BLOCKSCALE, BLOCKSCALE); } } drawGameInfo(g); } //==================================================// // BLOCK METHODS // //==================================================// public void addBlock() { int r = (int) (Math.random() * 7) + 1; blocks.add(new Block(r, button, false)); cleared[r - 1]++; } public void addBlock(int type) { blocks.add(new Block(type, button, false)); cleared[type - 1]++; } public void eraseBlock(Graphics g, Block b) { g.setColor(Color.white); for(int x = 0; x < 4; x++) { g.fillRect(b.locs[x][0] * BLOCKSCALE + BLOCKSCALE * 10, b.locs[x][1] * BLOCKSCALE, BLOCKSCALE + 1, BLOCKSCALE + 1); } } public void lineIsFull() { int holdLINES = LINES; boolean chk = false; int[] lines = new int[24]; for(Block b : blocks) { for(int x = 0; x < 4; x++) { if(b.isPlaced()) lines[b.locs[x][1]]++; } } for(int x = 1; x < 24; x++) { if(lines[x] == 10 && !chk) { deleteLine(x); moveDown(x); chk = true; x--; } } if(chk) { lineWasFull = true; lineIsFull(); } SCORE += (LINES - holdLINES) * (500 * DIFF); } public void deleteLine(int y) { int current = -1; for(Block b : blocks) { current++; for(int x = 0; x < 4; x++) { if(b.locs[x][1] == y) blocks.get(current).locs[x][1] = 0; } } LINES++; } public void moveDown(int y) { int current = -1; for(Block b : blocks) { current++; for(int x = 0; x < 4; x++) { if(b.locs[x][1] < y && b.locs[x][1] != 0) blocks.get(current).locs[x][1]++; } } } //==================================================// // PAINT METHODS // //==================================================// public void update(Graphics g) { paint(g); } public void clear(Graphics gBuffer) { drawGrid(gBuffer); } public void updateMem(Graphics g) { g.drawImage(board, 0, 0, getWidth(), getHeight(), this); vMem = createImage(appletWidth,appletHeight); gBuffer = vMem.getGraphics(); gBuffer.setColor(Color.white); gBuffer.fillRect(0,0,appletWidth,appletHeight); } //==================================================// // LOSE METHODS // //==================================================// public boolean gameLost() { for(int x = 0; x < 4; x++) { if(blocks.get(currentBlock - 1).locs[x][1] == SPAWNY && blocks.get(currentBlock - 1).locs[x][0] == SPAWNX) { return true; } } return false; } public void quitGame(Graphics g) { button = 4; repaint(); } public void drawLostGame(Graphics g) { g.setColor(Color.black); g.fillRect(0, 0, getWidth(), getHeight()); } //==================================================// // MAIN MENU GRAPHICS METHODS // //==================================================// public void outputMenu(Graphics g) { g.drawImage(mainScreen, 0, 0, 812, 588, this); } //==================================================// // GAME INFORMATION // //==================================================// public void drawGameInfo(Graphics g) { Image[] images = {img1, img2, img3, img4, img5, img6, img7}; Font font; switch(fontIndex) { case 0: font = new Font("Arial", Font.BOLD, 32); break; case 1: font = new Font("Courier", Font.BOLD, 32); break; case 2: font = new Font("Serif", Font.BOLD, 32); break; default: font = new Font("Arial", Font.BOLD, 32); } g.setFont(font); if(fontIndex != 1) { g.drawString("Next Block", BLOCKSCALE * 2, BLOCKSCALE * 2); g.drawString("Statistics", BLOCKSCALE * 2 + 10, BLOCKSCALE * 7); } else { g.drawString("Next Block", BLOCKSCALE * 1 + 10, BLOCKSCALE * 2); g.drawString("Statistics", BLOCKSCALE * 1 + 10, BLOCKSCALE * 7); } g.drawString("Lines", BLOCKSCALE * 4 + BLOCKSCALE * 19 + 10, BLOCKSCALE * 2); g.drawString("Score", BLOCKSCALE * 4 + BLOCKSCALE * 19 + 10, BLOCKSCALE * 7); //==================================================// // DISPLAY BLOCKS // //==================================================// int hold = BLOCKSCALE; BLOCKSCALE = 16; for(int x = 0; x < 4; x++) { if(icons[0].locs[x][1] != 0) g.drawImage(images[0], icons[0].locs[x][0] * BLOCKSCALE - BLOCKSCALE * 1, icons[0].locs[x][1] * BLOCKSCALE + BLOCKSCALE * 12 - 10, BLOCKSCALE + 1, BLOCKSCALE + 1, null); } for(int x = 0; x < 4; x++) { if(icons[1].locs[x][1] != 0) g.drawImage(images[1], icons[1].locs[x][0] * BLOCKSCALE - BLOCKSCALE * 1, icons[1].locs[x][1] * BLOCKSCALE + BLOCKSCALE * 16 - 10, BLOCKSCALE + 1, BLOCKSCALE + 1, null); } for(int x = 0; x < 4; x++) { if(icons[2].locs[x][1] != 0) g.drawImage(images[2], icons[2].locs[x][0] * BLOCKSCALE - BLOCKSCALE * 1, icons[2].locs[x][1] * BLOCKSCALE + BLOCKSCALE * 19 - 10, BLOCKSCALE + 1, BLOCKSCALE + 1, null); } for(int x = 0; x < 4; x++) { if(icons[3].locs[x][1] != 0) g.drawImage(images[3], icons[3].locs[x][0] * BLOCKSCALE - BLOCKSCALE * 1, icons[3].locs[x][1] * BLOCKSCALE + BLOCKSCALE * 22 - 10, BLOCKSCALE + 1, BLOCKSCALE + 1, null); } for(int x = 0; x < 4; x++) { if(icons[4].locs[x][1] != 0) g.drawImage(images[4], icons[4].locs[x][0] * BLOCKSCALE - BLOCKSCALE * 1, icons[4].locs[x][1] * BLOCKSCALE + BLOCKSCALE * 25 - 10, BLOCKSCALE + 1, BLOCKSCALE + 1, null); } for(int x = 0; x < 4; x++) { if(icons[5].locs[x][1] != 0) g.drawImage(images[5], icons[5].locs[x][0] * BLOCKSCALE - BLOCKSCALE * 1, icons[5].locs[x][1] * BLOCKSCALE + BLOCKSCALE * 28 - 10, BLOCKSCALE + 1, BLOCKSCALE + 1, null); } for(int x = 0; x < 4; x++) { if(icons[6].locs[x][1] != 0) g.drawImage(images[6], icons[6].locs[x][0] * BLOCKSCALE - BLOCKSCALE * 1, icons[6].locs[x][1] * BLOCKSCALE + BLOCKSCALE * 31 - 10, BLOCKSCALE + 1, BLOCKSCALE + 1, null); } BLOCKSCALE = hold; for(int x = 0; x < 4; x++) { g.drawImage(images[RANDOM - 1], icons[RANDOM - 1].locs[x][0] * BLOCKSCALE - BLOCKSCALE, icons[RANDOM - 1].locs[x][1] * BLOCKSCALE + 8, BLOCKSCALE, BLOCKSCALE, null); } //==================================================// // DISPLAY NUMBER INFORMATION // //==================================================// g.setColor(Color.black); g.drawString("x" + cleared[0], BLOCKSCALE * 6, 250); g.drawString("x" + cleared[1], BLOCKSCALE * 6, 314); g.drawString("x" + cleared[2], BLOCKSCALE * 6, 362); g.drawString("x" + cleared[3], BLOCKSCALE * 6, 410); g.drawString("x" + cleared[4], BLOCKSCALE * 6, 458); g.drawString("x" + cleared[5], BLOCKSCALE * 6, 506); g.drawString("x" + cleared[6], BLOCKSCALE * 6, 554); DecimalFormat f = new DecimalFormat("00000000"); g.drawString(f.format(LINES), BLOCKSCALE * 4 + BLOCKSCALE * 18 + 8, BLOCKSCALE * 4); g.drawString(f.format(SCORE), BLOCKSCALE * 4 + BLOCKSCALE * 18 + 8, BLOCKSCALE * 9); } }