tetris

Post on 18-Dec-2015

6 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Code java game tetris

TRANSCRIPT

/** * @(#)Main.java * * This work is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This work is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Copyright (c) 2003 Per Cederberg. All rights reserved. */import java.awt.BorderLayout;import java.awt.Button;import java.awt.Color;import java.awt.Component;import java.awt.Container;import java.awt.Dimension;import java.awt.Font;import java.awt.Frame;import java.awt.Graphics;import java.awt.GridLayout;import java.awt.Image;import java.awt.Insets;import java.awt.Rectangle;import java.awt.TextArea;import java.awt.TextField;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener;import java.beans.PropertyChangeSupport;import java.util.Hashtable;import javax.swing.JComponent;/** * The main class of the Tetris game. This class contains the * necessary methods to run the game either as a stand-alone * application or as an applet inside a web page. * * @version 1.2 * @author Per Cederberg, per@percederberg.net */public class Tetris {// /**// * The applet parameter information structure.// */// private static final String PARAMETER[][] = {// { "tetris.color.background", "color", // "The overall background color." },// { "tetris.color.label", "color", // "The text color of the labels." },// { "tetris.color.button", "color", // "The start and pause button bolor." }, // { "tetris.color.board.background", "color", // "The background game board color." },// { "tetris.color.board.message", "color", // "The game board message color." },// { "tetris.color.figure.square", "color", // "The color of the square figure." },// { "tetris.color.figure.line", "color", // "The color of the line figure." },// { "tetris.color.figure.s", "color", // "The color of the 's' curved figure." },// { "tetris.color.figure.z", "color", // "The color of the 'z' curved figure." },// { "tetris.color.figure.right", "color", // "The color of the right angle figure." },// { "tetris.color.figure.left", "color", // "The color of the left angle figure." },// { "tetris.color.figure.triangle", "color", // "The color of the triangle figure." }// }; /** * The Tetris game being played (in applet mode). */ private Game game = null; /** * The stand-alone main routine. * * @param args the command-line arguments */ public static void main(String[] args) { System.out.println("starting"); Frame frame = new Frame("Tetris"); final Game game = new Game(); game.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { System.out.println("PCE "+evt.getPropertyName()+" "+evt.getNewValue()); } }); final TextArea taHiScores = new TextArea("",10,10,TextArea.SCROLLBARS_NONE); taHiScores.setBackground(Color.black); taHiScores.setForeground(Color.white); taHiScores.setFont(new Font("monospaced",0,11)); taHiScores.setText(" High Scores \n"+ " -----------------------------\n\n"+ " PLAYER LEVEL SCORE \n\n"+ " Lorenzo 12 1 50280 \n"+ " Lorenzo 12 1 50280 \n" ); taHiScores.setEditable(false); final TextField txt = new TextField(); txt.setEnabled(false); game.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals("state")) { int state = ((Integer) evt.getNewValue()).intValue(); if (state == Game.STATE_GAMEOVER) { txt.setEnabled(true); txt.requestFocus(); txt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { txt.setEnabled(false); game.init(); } }); // show score... } } } }); Button btnStart = new Button("Start"); btnStart.setFocusable(false); btnStart.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { game.start(); } }); final Container c = new Container(); c.setLayout(new BorderLayout()); c.add(txt, BorderLayout.NORTH); c.add(game.getSquareBoardComponent(), BorderLayout.CENTER); c.add(btnStart,BorderLayout.SOUTH); final Container c2 = new Container(); c2.setLayout(new GridLayout(1,2)); c2.add(c); c2.add(taHiScores); frame.add(c2); System.out.println("packing"); frame.pack(); // Add frame window listener frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); // Show frame (and start game) frame.show(); }// /**// * Returns information about the parameters that are understood by // * this applet.// * // * @return an array describing the parameters to this applet// */// public String[][] getParameterInfo() {// return PARAMETER;// }// /**// * Initializes the game in applet mode.// */// public void init() {// String value;//// // Set all configuration parameters// for (int i = 0; i < PARAMETER.length; i++) {// value = getParameter(PARAMETER[i][0]);// if (value != null) {// Configuration.setValue(PARAMETER[i][0], value);// }// }//// // Create game object// game = new Game();//// // Initialize applet component// setLayout(new BorderLayout());// add(game.getComponent(), "Center");// }//// /**// * Stops the game in applet mode.// */// public void stop() {// game.quit();// } }/* * @(#)SquareBoard.java * * This work is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This work is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Copyright (c) 2003 Per Cederberg. All rights reserved. *//** * A Tetris square board. The board is rectangular and contains a grid * of colored squares. The board is considered to be constrained to * both sides (left and right), and to the bottom. There is no * constraint to the top of the board, although colors assigned to * positions above the board are not saved. * * @version 1.2 * @author Per Cederberg, per@percederberg.net */ class SquareBoard extends Object { /** * The board width (in squares) */ private final int width; /** * The board height (in squares). */ private final int height; /** * The square board color matrix. This matrix (or grid) contains * a color entry for each square in the board. The matrix is * indexed by the vertical, and then the horizontal coordinate. */ private Color[][] matrix = null; /** * An optional board message. The board message can be set at any * time, printing it on top of the board. */ private String message = null; /** * The number of lines removed. This counter is increased each * time a line is removed from the board. */ private int removedLines = 0; /** * The graphical sqare board component. This graphical * representation is created upon the first call to * getComponent(). */ private final SquareBoardComponent component; /** * Creates a new square board with the specified size. The square * board will initially be empty. * * @param width the width of the board (in squares) * @param height the height of the board (in squares) */ public SquareBoard(int width, int height) { this.width = width; this.height = height; this.matrix = new Color[height][width]; this.component = new SquareBoardComponent(); clear(); } /** * Checks if a specified square is empty, i.e. if it is not * marked with a color. If the square is outside the board, * false will be returned in all cases except when the square is * directly above the board. * * @param x the horizontal position (0 = height) { return x >= 0 && x < width && y < 0; } else { return matrix[y][x] == null; } } /** * Checks if a specified line is empty, i.e. only contains * empty squares. If the line is outside the board, false will * always be returned. * * @param y the vertical position (0 = height) { return false; } for (int x = 0; x < width; x++) { if (matrix[y][x] != null) { return false; } } return true; } /** * Checks if a specified line is full, i.e. only contains no empty * squares. If the line is outside the board, true will always be * returned. * * @param y the vertical position (0 = height) { return true; } for (int x = 0; x < width; x++) { if (matrix[y][x] == null) { return false; } } return true; } /** * Checks if the board contains any full lines. * * @return true if there are full lines on the board, or * false otherwise */ public boolean hasFullLines() { for (int y = height - 1; y >= 0; y--) { if (isLineFull(y)) { return true; } } return false; } /** * Returns a graphical component to draw the board. The component * returned will automatically be updated when changes are made to * this board. Multiple calls to this method will return the same * component, as a square board can only have a single graphical * representation. * * @return a graphical component that draws this board */ public Component getComponent() { return component; } /** * Returns the board height (in squares). This method returns, * i.e, the number of vertical squares that fit on the board. * * @return the board height in squares */ public int getBoardHeight() { return height; } /** * Returns the board width (in squares). This method returns, i.e, * the number of horizontal squares that fit on the board. * * @return the board width in squares */ public int getBoardWidth() { return width; } /** * Returns the number of lines removed since the last clear(). * * @return the number of lines removed since the last clear call */ public int getRemovedLines() { return removedLines; } /** * Returns the color of an individual square on the board. If the * square is empty or outside the board, null will be returned. * * @param x the horizontal position (0 = height) { return null; } else { return matrix[y][x]; } } /** * Changes the color of an individual square on the board. The * square will be marked as in need of a repaint, but the * graphical component will NOT be repainted until the update() * method is called. * * @param x the horizontal position (0 = height) { return; } matrix[y][x] = color; if (component != null) { component.invalidateSquare(x, y); } } /** * Sets a message to display on the square board. This is supposed * to be used when the board is not being used for active drawing, * as it slows down the drawing considerably. * * @param message a message to display, or null to remove a * previous message */ public void setMessage(String message) { this.message = message; if (component != null) { component.redrawAll(); } } /** * Clears the board, i.e. removes all the colored squares. As * side-effects, the number of removed lines will be reset to * zero, and the component will be repainted immediately. */ public void clear() { removedLines = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { this.matrix[y][x] = null; } } if (component != null) { component.redrawAll(); } } /** * Removes all full lines. All lines above a removed line will be * moved downward one step, and a new empty line will be added at * the top. After removing all full lines, the component will be * repainted. * * @see #hasFullLines */ public void removeFullLines() { boolean repaint = false; // Remove full lines for (int y = height - 1; y >= 0; y--) { if (isLineFull(y)) { removeLine(y); removedLines++; repaint = true; y++; } } // Repaint if necessary if (repaint && component != null) { component.redrawAll(); } } /** * Removes a single line. All lines above are moved down one step, * and a new empty line is added at the top. No repainting will be * done after removing the line. * * @param y the vertical position (0 = height) { return; } for (; y > 0; y--) { for (int x = 0; x < width; x++) { matrix[y][x] = matrix[y - 1][x]; } } for (int x = 0; x < width; x++) { matrix[0][x] = null; } } /** * Updates the graphical component. Any squares previously changed * will be repainted by this method. */ public void update() { component.redraw(); } /** * The graphical component that paints the square board. This is * implemented as an inner class in order to better abstract the * detailed information that must be sent between the square board * and its graphical representation. */ private class SquareBoardComponent extends JComponent { /** * The component size. If the component has been resized, that * will be detected when the paint method executes. If this * value is set to null, the component dimensions are unknown. */ private Dimension size = null; /** * The component insets. The inset values are used to create a * border around the board to compensate for a skewed aspect * ratio. If the component has been resized, the insets values * will be recalculated when the paint method executes. */ private Insets insets = new Insets(0, 0, 0, 0); /** * The square size in pixels. This value is updated when the * component size is changed, i.e. when the size * variable is modified. */ private Dimension squareSize = new Dimension(0, 0); /** * An image used for double buffering. The board is first * painted onto this image, and that image is then painted * onto the real surface in order to avoid making the drawing * process visible to the user. This image is recreated each * time the component size changes. */ private Image bufferImage = null; /** * A clip boundary buffer rectangle. This rectangle is used * when calculating the clip boundaries, in order to avoid * allocating a new clip rectangle for each board square. */ private Rectangle bufferRect = new Rectangle(); /** * The board message color. */ private Color messageColor = Color.white; /** * A lookup table containing lighter versions of the colors. * This table is used to avoid calculating the lighter * versions of the colors for each and every square drawn. */ private Hashtable lighterColors = new Hashtable(); /** * A lookup table containing darker versions of the colors. * This table is used to avoid calculating the darker * versions of the colors for each and every square drawn. */ private Hashtable darkerColors = new Hashtable(); /** * A flag set when the component has been updated. */ private boolean updated = true; /** * A bounding box of the squares to update. The coordinates * used in the rectangle refers to the square matrix. */ private Rectangle updateRect = new Rectangle(); /** * Creates a new square board component. */ public SquareBoardComponent() { setBackground(Configuration.getColor("board.background", "#000000")); messageColor = Configuration.getColor("board.message", "#ffffff"); } /** * Adds a square to the set of squares in need of redrawing. * * @param x the horizontal position (0 updateRect.y + updateRect.height) { updateRect.height = y - updateRect.y; } } } /** * Redraws all the invalidated squares. If no squares have * been marked as in need of redrawing, no redrawing will * occur. */ public void redraw() { Graphics g; if (!updated) { updated = true; g = getGraphics(); if (g==null) return; g.setClip(insets.left + updateRect.x * squareSize.width, insets.top + updateRect.y * squareSize.height, (updateRect.width + 1) * squareSize.width, (updateRect.height + 1) * squareSize.height); paint(g); } } /** * Redraws the whole component. */ public void redrawAll() { Graphics g; updated = true; g = getGraphics(); if (g==null) return; g.setClip(insets.left, insets.top, width * squareSize.width, height * squareSize.height); paint(g); } /** * Returns true as this component is double buffered. * * @return true as this component is double buffered */ public boolean isDoubleBuffered() { return true; } /** * Returns the preferred size of this component. * * @return the preferred component size */ public Dimension getPreferredSize() { return new Dimension(width * 20, height * 20); } /** * Returns the minimum size of this component. * * @return the minimum component size */ public Dimension getMinimumSize() { return getPreferredSize(); } /** * Returns the maximum size of this component. * * @return the maximum component size */ public Dimension getMaximumSize() { return getPreferredSize(); } /** * Returns a lighter version of the specified color. The * lighter color will looked up in a hashtable, making this * method fast. If the color is not found, the ligher color * will be calculated and added to the lookup table for later * reference. * * @param c the base color * * @return the lighter version of the color */ private Color getLighterColor(Color c) { Color lighter; lighter = (Color) lighterColors.get(c); if (lighter == null) { lighter = c.brighter().brighter(); lighterColors.put(c, lighter); } return lighter; } /** * Returns a darker version of the specified color. The * darker color will looked up in a hashtable, making this * method fast. If the color is not found, the darker color * will be calculated and added to the lookup table for later * reference. * * @param c the base color * * @return the darker version of the color */ private Color getDarkerColor(Color c) { Color darker; darker = (Color) darkerColors.get(c); if (darker == null) { darker = c.darker().darker(); darkerColors.put(c, darker); } return darker; } /** * Paints this component indirectly. The painting is first * done to a buffer image, that is then painted directly to * the specified graphics context. * * @param g the graphics context to use */ public synchronized void paint(Graphics g) { Graphics bufferGraphics; Rectangle rect; // Handle component size change if (size == null || !size.equals(getSize())) { size = getSize(); squareSize.width = size.width / width; squareSize.height = size.height / height; //if (squareSize.width

top related