Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Random;
import java.awt.Color;
import java.lang.Math.*;
/**
* Write a description of class GamePanel here.
*
* @author Greg Johnson, University of Connecticut
* @version 0.3
*/
public class GamePanel extends JPanel implements ActionListener
{
// instance variables - replace the example below with your own
private PieceProxy _piece;
private Timer _timer;
private Random _generator;
private KeyUpListener _upKey;
private KeyDownListener _downKey;
private KeyLeftListener _leftKey;
private KeyRightListener _rightKey;
private KeyPListener _pauseKey;
private KeySpaceListener _spaceKey;
private SmartRectangle[][] _board;
/**
* Constructor for objects of class GamePanel
*/
public GamePanel()
{
// initialise instance variables
this.setBackground(Color.BLACK);
this.setSize(new Dimension(TetrisConstants.BLOCK_SIZE*(TetrisConstants.BOARD_WIDTH), TetrisConstants.BLOCK_SIZE*(TetrisConstants.BOARD_HEIGHT)+15));
this.setPreferredSize(new Dimension(TetrisConstants.BLOCK_SIZE*(TetrisConstants.BOARD_WIDTH), TetrisConstants.BLOCK_SIZE*(TetrisConstants.BOARD_HEIGHT)+15));
_board = new SmartRectangle[TetrisConstants.BOARD_HEIGHT][TetrisConstants.BOARD_WIDTH];
_upKey = new KeyUpListener(this);
_downKey = new KeyDownListener(this);
_leftKey = new KeyLeftListener(this);
_rightKey = new KeyRightListener(this);
_pauseKey = new KeyPListener(this);
_spaceKey = new KeySpaceListener(this);
_generator = new Random();
_piece = new PieceProxy();
_piece.setPiece(tetriminoFactory());
_timer = new Timer(700, this);
_timer.start();
}
public Tetrimino tetriminoFactory()
/**
* This method implements the factory method design pattern to build new tetriminos during Tetris game play.
*/
{
Tetrimino newPiece;
int randomNumber;
int x = (TetrisConstants.BOARD_WIDTH/2) * TetrisConstants.BLOCK_SIZE;
int y = 0;
randomNumber = (int) (Math.floor(Math.random()*7)+1);
switch(randomNumber) {
case 1: newPiece = new Z(x,y); break;
case 2: newPiece = new S(x,y); break;
case 3: newPiece = new L(x,y); break;
case 4: newPiece = new J(x,y); break;
case 5: newPiece = new O(x,y); break;
case 6: newPiece = new I(x,y); break;
default: newPiece = new T(x,y); break;
}
return newPiece;
}
public void paintComponent (java.awt.Graphics aBrush)
{
super.paintComponent(aBrush);
java.awt.Graphics2D betterBrush = (java.awt.Graphics2D)aBrush;
_piece.fill(betterBrush);
_piece.draw(betterBrush);
for(SmartRectangle[] row : _board)
{
for(SmartRectangle block : row)
{
if(block != null)
{
block.fill(betterBrush);
block.draw(betterBrush);
}
}
}
}
/**
* This method takes two integers representing the column and row of a cell on the game board a component rectangle into which a
* tetrimino wishes to move. This can be prevented by either the cell being off of the game board (not a valid cell) or by the
* cell being occupied by another SmartRectangle.
*
* @param c The column of the cell in question on the game board.
* @param r The row of the cell in question on the game board.
* @return boolean This function returns whether the component rectangle can be moved into this cell.
*/
public boolean canMove(int c, int r)
{
if(isFree(c, r) && isValid(c, r)) {
return true;
}
return false;
}
/**
* This method takes two integers representing the column and row of a cell on the game board a component rectangle into which a
* tetrimino wishes to move. This method returns a boolean indicating whether the cell on the game board is empty.
*
* @param c The column of the cell in question on the game board.
* @param r The row of the cell in question on the game board.
* @return boolean This function returns whether the cell on the game board is free.
*/
private boolean isFree(int c, int r)
{
if(!isValid(c, r) || _board[r][c] != null) {
return false;
}
return true;
}
/**
* This method takes two integers representing the column and row of a cell on the game board a component rectangle into which a
* tetrimino wishes to move. This function checks to see if the cell at (c, r) is a valid location on the game board.
*
* @param c The column of the cell in question on the game board.
* @param r The row of the cell in question on the game board.
* @return boolean This function returns whether the location (c, r) is within the bounds of the game board.
*/
private boolean isValid(int i, int j)
{
//int boardWidth = TetrisConstants.BLOCK_SIZE * TetrisConstants.BOARD_WIDTH;
//int boardHeight = TetrisConstants.BLOCK_SIZE * TetrisConstants.BOARD_HEIGHT;
if(i < 0 || i >= TetrisConstants.BOARD_WIDTH || j < 0 || j >= TetrisConstants.BOARD_HEIGHT) {
return false;
}
return true;
}
/**
* This method takes two integers representing the column and row of a cell on the game board a component rectangle into which a
* tetrimino wishes to move. This can be prevented by either the cell being off of the game board (not a valid cell) or by the
* cell being occupied by another SmartRectangle.
*
* @param r The SmartRectangle to add to the game board.
* @return Nothing
*/
public void addToBoard(SmartRectangle r)
{
int x = (int)Math.round(r.getX() / TetrisConstants.BLOCK_SIZE);
int y = (int)Math.round(r.getY() / TetrisConstants.BLOCK_SIZE);
_board[y][x] = r;
}
/**
* This method takes one integer representing the row of cells on the game board to move down on the screen after a full
* row of squares has been removed.
*
* @param row The row in question on the game board.
* @return Nothing
*/
private void moveBlocksDown(int row)
{
for(int i = row-1; i >= 0; i--)
{
for(int j = 0; j < _board[i].length; j++)
{
_board[i+1][j] = null;
if(_board[i][j] != null)
{
_board[i+1][j] = _board[i][j];
_board[i+1][j].setLocation(_board[i+1][j].getX(), _board[i+1][j].getY()+TetrisConstants.BLOCK_SIZE);
}
}
}
}
/**
* This method checks each row of the game board to see if it is full of rectangles and should be removed. It calls
* moveBlocksDown to adjust the game board after the removal of a row.
*
* @return Nothing
*/
private void checkRows(){
for(int i = 0; i < _board.length; i++)
{
boolean fullRow = true;
for(int j = 0; j < _board[i].length; j++)
{
if(_board[i][j] == null)
{
fullRow = false;
}
}
if(fullRow)
{
moveBlocksDown(i);
}
}
}
/**
* This method checks to see if the game has ended.
*
* @return boolean This function returns whether the game is over or not.
*/
private boolean checkEndGame()
{
for(int i = 0; i < TetrisConstants.BOARD_WIDTH; i++) {
if(_board[0][i] != null) {
return true;
}
}
return false;
}
public void actionPerformed(ActionEvent e)
{
if(validMove(2))
{
_piece.moveDown();
repaint();
}
else
{
// add piece to board if it can not move further down
for(int i = 1; i <= 4; i++)
addToBoard(_piece.getBlockAt(i));
checkRows();
if(checkEndGame())
_timer.stop();
_piece.setPiece(tetriminoFactory()); // reset piece
}
}
/**
* gets a list of coordinates (px) and tests if the corresponding cell is valid
* If all coordinates pass, return true. Otherwise false
*/
public boolean validMove(int dir) {
for(int i = 1; i <= 4; i++)
{
int x = (int)Math.round(_piece.getBlockAt(i).getX() / TetrisConstants.BLOCK_SIZE);
int y = (int)Math.round(_piece.getBlockAt(i).getY() / TetrisConstants.BLOCK_SIZE);
switch(dir)
{
case 0: // left
x--;
break;
case 1: // right
x++;
break;
case 2: // down
y++;
break;
}
if(!canMove(x, y))
{
return false;
}
}
return true;
}
private class KeyUpListener extends KeyInteractor
{
public KeyUpListener(JPanel p)
{
super(p,KeyEvent.VK_UP);
}
public void actionPerformed (ActionEvent e) {
if(_timer.isRunning())
{
// first turn right and test new coordinates
_piece.turnRight();
if(validMove(100)) { //if valid, repaint
repaint();
} else { //else, reverse the rotation
_piece.turnLeft();
}
}
}
}
private class KeyDownListener extends KeyInteractor
{
public KeyDownListener(JPanel p)
{
super(p,KeyEvent.VK_DOWN);
}
public void actionPerformed (ActionEvent e) {
if(_timer.isRunning())
{
if(validMove(2))
{
_piece.moveDown();
repaint();
}
}
}
}
private class KeyLeftListener extends KeyInteractor
{
public KeyLeftListener(JPanel p)
{
super(p,KeyEvent.VK_LEFT);
}
public void actionPerformed (ActionEvent e) {
if(_timer.isRunning())
{
if(validMove(0))
{
_piece.moveLeft();
repaint();
}
}
}
}
private class KeyRightListener extends KeyInteractor
{
public KeyRightListener(JPanel p)
{
super(p,KeyEvent.VK_RIGHT);
}
public void actionPerformed (ActionEvent e) {
if(_timer.isRunning())
{
if(validMove(1))
{
_piece.moveRight();
repaint();
}
}
}
}
private class KeyPListener extends KeyInteractor
{
public KeyPListener(JPanel p)
{
super(p,KeyEvent.VK_P);
}
public void actionPerformed (ActionEvent e) {
if(_timer.isRunning()){
_timer.stop();
}
else
_timer.start();
}
}
private class KeySpaceListener extends KeyInteractor
{
public KeySpaceListener(JPanel p)
{
super(p,KeyEvent.VK_SPACE);
}
public void actionPerformed (ActionEvent e) {
while(validMove(2))
{
_piece.moveDown();
repaint();
}
}
}
}