com.alee.examples.groups.desktoppane.tetris.Figure Maven / Gradle / Ivy
/*
* This file is part of WebLookAndFeel library.
*
* WebLookAndFeel library 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 3 of the License, or
* (at your option) any later version.
*
* WebLookAndFeel library 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.
*
* You should have received a copy of the GNU General Public License
* along with WebLookAndFeel library. If not, see .
*/
package com.alee.examples.groups.desktoppane.tetris;
import com.alee.utils.MathUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.GeneralPath;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* User: mgarin Date: 02.06.11 Time: 17:09
*/
public class Figure
{
private int rotation = 0;
private FigureType figureType;
private Block[] blocks;
// Figure position on the field
private Point point;
// Blocks placement
private int[][] placement = new int[ 4 ][ 4 ];
public Figure ()
{
super ();
figureType = FigureType.values ()[ MathUtils.random ( FigureType.values ().length ) ];
fillWidthRandomBlocks ();
fillPlacement ();
fillStartPoint ();
}
public Figure ( FigureType figureType )
{
super ();
this.figureType = figureType;
fillWidthRandomBlocks ();
fillPlacement ();
fillStartPoint ();
}
public Figure ( FigureType figureType, Block[] blocks )
{
super ();
this.figureType = figureType;
this.blocks = blocks;
fillPlacement ();
fillStartPoint ();
}
private void fillWidthRandomBlocks ()
{
blocks = new Block[ 4 ];
blocks[ 0 ] = new Block ();
blocks[ 1 ] = new Block ();
blocks[ 2 ] = new Block ();
blocks[ 3 ] = new Block ();
}
private void fillPlacement ()
{
clearPlacement ();
if ( figureType.equals ( FigureType.trident ) )
{
if ( rotation == 0 )
{
placement[ 0 ][ 1 ] = 0;
placement[ 1 ][ 0 ] = 1;
placement[ 1 ][ 1 ] = 2;
placement[ 1 ][ 2 ] = 3;
}
else if ( rotation == 1 )
{
placement[ 1 ][ 2 ] = 0;
placement[ 0 ][ 1 ] = 1;
placement[ 1 ][ 1 ] = 2;
placement[ 2 ][ 1 ] = 3;
}
else if ( rotation == 2 )
{
placement[ 2 ][ 1 ] = 0;
placement[ 1 ][ 2 ] = 1;
placement[ 1 ][ 1 ] = 2;
placement[ 1 ][ 0 ] = 3;
}
else if ( rotation == 3 )
{
placement[ 1 ][ 0 ] = 0;
placement[ 0 ][ 1 ] = 3;
placement[ 1 ][ 1 ] = 2;
placement[ 2 ][ 1 ] = 1;
}
}
else if ( figureType.equals ( FigureType.line ) )
{
if ( rotation == 0 )
{
placement[ 1 ][ 0 ] = 0;
placement[ 1 ][ 1 ] = 1;
placement[ 1 ][ 2 ] = 2;
placement[ 1 ][ 3 ] = 3;
}
else if ( rotation == 1 )
{
placement[ 0 ][ 1 ] = 0;
placement[ 1 ][ 1 ] = 1;
placement[ 2 ][ 1 ] = 2;
placement[ 3 ][ 1 ] = 3;
}
else if ( rotation == 2 )
{
placement[ 1 ][ 0 ] = 3;
placement[ 1 ][ 1 ] = 2;
placement[ 1 ][ 2 ] = 1;
placement[ 1 ][ 3 ] = 0;
}
else if ( rotation == 3 )
{
placement[ 0 ][ 1 ] = 3;
placement[ 1 ][ 1 ] = 2;
placement[ 2 ][ 1 ] = 1;
placement[ 3 ][ 1 ] = 0;
}
}
else if ( figureType.equals ( FigureType.lineL ) )
{
if ( rotation == 0 )
{
placement[ 0 ][ 0 ] = 0;
placement[ 0 ][ 1 ] = 1;
placement[ 1 ][ 1 ] = 2;
placement[ 2 ][ 1 ] = 3;
}
else if ( rotation == 1 )
{
placement[ 0 ][ 2 ] = 0;
placement[ 1 ][ 2 ] = 1;
placement[ 1 ][ 1 ] = 2;
placement[ 1 ][ 0 ] = 3;
}
else if ( rotation == 2 )
{
placement[ 2 ][ 2 ] = 0;
placement[ 2 ][ 1 ] = 1;
placement[ 1 ][ 1 ] = 2;
placement[ 0 ][ 1 ] = 3;
}
else if ( rotation == 3 )
{
placement[ 2 ][ 0 ] = 0;
placement[ 1 ][ 0 ] = 1;
placement[ 1 ][ 1 ] = 2;
placement[ 1 ][ 2 ] = 3;
}
}
else if ( figureType.equals ( FigureType.lineR ) )
{
if ( rotation == 0 )
{
placement[ 0 ][ 2 ] = 0;
placement[ 0 ][ 1 ] = 1;
placement[ 1 ][ 1 ] = 2;
placement[ 2 ][ 1 ] = 3;
}
else if ( rotation == 1 )
{
placement[ 2 ][ 2 ] = 0;
placement[ 1 ][ 2 ] = 1;
placement[ 1 ][ 1 ] = 2;
placement[ 1 ][ 0 ] = 3;
}
else if ( rotation == 2 )
{
placement[ 2 ][ 0 ] = 0;
placement[ 2 ][ 1 ] = 1;
placement[ 1 ][ 1 ] = 2;
placement[ 0 ][ 1 ] = 3;
}
else if ( rotation == 3 )
{
placement[ 0 ][ 0 ] = 0;
placement[ 1 ][ 0 ] = 1;
placement[ 1 ][ 1 ] = 2;
placement[ 1 ][ 2 ] = 3;
}
}
else if ( figureType.equals ( FigureType.block ) )
{
if ( rotation == 0 )
{
placement[ 0 ][ 0 ] = 0;
placement[ 0 ][ 1 ] = 1;
placement[ 1 ][ 0 ] = 2;
placement[ 1 ][ 1 ] = 3;
}
else if ( rotation == 1 )
{
placement[ 0 ][ 0 ] = 2;
placement[ 0 ][ 1 ] = 0;
placement[ 1 ][ 0 ] = 3;
placement[ 1 ][ 1 ] = 1;
}
else if ( rotation == 2 )
{
placement[ 0 ][ 0 ] = 3;
placement[ 0 ][ 1 ] = 2;
placement[ 1 ][ 0 ] = 1;
placement[ 1 ][ 1 ] = 0;
}
else if ( rotation == 3 )
{
placement[ 0 ][ 0 ] = 1;
placement[ 0 ][ 1 ] = 3;
placement[ 1 ][ 0 ] = 0;
placement[ 1 ][ 1 ] = 2;
}
}
else if ( figureType.equals ( FigureType.blockL ) )
{
if ( rotation == 0 )
{
placement[ 1 ][ 0 ] = 0;
placement[ 1 ][ 1 ] = 1;
placement[ 2 ][ 1 ] = 2;
placement[ 2 ][ 2 ] = 3;
}
else if ( rotation == 1 )
{
placement[ 0 ][ 1 ] = 0;
placement[ 1 ][ 1 ] = 1;
placement[ 1 ][ 0 ] = 2;
placement[ 2 ][ 0 ] = 3;
}
else if ( rotation == 2 )
{
placement[ 1 ][ 2 ] = 0;
placement[ 1 ][ 1 ] = 1;
placement[ 0 ][ 1 ] = 2;
placement[ 0 ][ 0 ] = 3;
}
else if ( rotation == 3 )
{
placement[ 2 ][ 1 ] = 0;
placement[ 1 ][ 1 ] = 1;
placement[ 1 ][ 2 ] = 2;
placement[ 0 ][ 2 ] = 3;
}
}
else if ( figureType.equals ( FigureType.blockR ) )
{
if ( rotation == 0 )
{
placement[ 1 ][ 2 ] = 0;
placement[ 1 ][ 1 ] = 1;
placement[ 2 ][ 1 ] = 2;
placement[ 2 ][ 0 ] = 3;
}
else if ( rotation == 1 )
{
placement[ 2 ][ 1 ] = 0;
placement[ 1 ][ 1 ] = 1;
placement[ 1 ][ 0 ] = 2;
placement[ 0 ][ 0 ] = 3;
}
else if ( rotation == 2 )
{
placement[ 1 ][ 0 ] = 0;
placement[ 1 ][ 1 ] = 1;
placement[ 0 ][ 1 ] = 2;
placement[ 0 ][ 2 ] = 3;
}
else if ( rotation == 3 )
{
placement[ 0 ][ 1 ] = 0;
placement[ 1 ][ 1 ] = 1;
placement[ 1 ][ 2 ] = 2;
placement[ 2 ][ 2 ] = 3;
}
}
}
private void fillStartPoint ()
{
if ( figureType.equals ( FigureType.trident ) )
{
point = new Point ( Tetris.BLOCKS_IN_WIDTH / 2 - 2, -2 );
}
else if ( figureType.equals ( FigureType.line ) )
{
point = new Point ( Tetris.BLOCKS_IN_WIDTH / 2 - 2, -2 );
}
else if ( figureType.equals ( FigureType.lineL ) )
{
point = new Point ( Tetris.BLOCKS_IN_WIDTH / 2 - 1, -3 );
}
else if ( figureType.equals ( FigureType.lineR ) )
{
point = new Point ( Tetris.BLOCKS_IN_WIDTH / 2 - 2, -3 );
}
else if ( figureType.equals ( FigureType.block ) )
{
point = new Point ( Tetris.BLOCKS_IN_WIDTH / 2 - 1, -2 );
}
else if ( figureType.equals ( FigureType.blockL ) )
{
point = new Point ( Tetris.BLOCKS_IN_WIDTH / 2 - 2, -3 );
}
else if ( figureType.equals ( FigureType.blockR ) )
{
point = new Point ( Tetris.BLOCKS_IN_WIDTH / 2 - 2, -3 );
}
}
private void clearPlacement ()
{
for ( int i = 0; i < placement.length; i++ )
{
for ( int j = 0; j < placement[ i ].length; j++ )
{
placement[ i ][ j ] = -1;
}
}
}
public void rotate ( GeneralPath terrain )
{
changeRotation ( 1 );
fillPlacement ();
if ( intersects ( terrain ) )
{
changeRotation ( -1 );
fillPlacement ();
}
}
private void changeRotation ( int change )
{
if ( change == 1 )
{
if ( rotation < 3 )
{
rotation++;
}
else
{
rotation = 0;
}
}
else
{
if ( rotation > 0 )
{
rotation--;
}
else
{
rotation = 3;
}
}
}
public void moveLeft ( GeneralPath terrain )
{
point.x--;
if ( intersects ( terrain ) )
{
point.x++;
}
}
public void moveRight ( GeneralPath terrain )
{
point.x++;
if ( intersects ( terrain ) )
{
point.x--;
}
}
public void moveDown ()
{
point.y++;
}
public boolean canMoveDown ( GeneralPath terrain )
{
point.y++;
boolean intersects = intersects ( terrain );
point.y--;
return !intersects;
}
public void paintFigure ( Graphics2D g2d )
{
Point start = new Point ( point.x * Tetris.BLOCK_SIDE + point.x, point.y * Tetris.BLOCK_SIDE + point.y );
for ( int row = 0; row < placement.length; row++ )
{
for ( int col = 0; col < placement[ row ].length; col++ )
{
if ( placement[ row ][ col ] >= 0 )
{
blocks[ placement[ row ][ col ] ].paintBlock ( g2d,
new Rectangle ( start.x + col * Tetris.BLOCK_SIDE + col, start.y + row * Tetris.BLOCK_SIDE + row,
Tetris.BLOCK_SIDE, Tetris.BLOCK_SIDE ), rotation
);
}
}
}
}
private List> getPreviewData ()
{
List> data = new ArrayList> ();
for ( int row = 0; row < placement.length; row++ )
{
data.add ( new ArrayList () );
for ( int col = 0; col < placement[ row ].length; col++ )
{
data.get ( row ).add ( placement[ row ][ col ] );
}
}
// Checking rows
for ( int row = data.size () - 1; row >= 0; row-- )
{
List rowData = data.get ( row );
for ( int col = 0; col < rowData.size (); col++ )
{
if ( rowData.get ( col ) >= 0 )
{
break;
}
else if ( col == rowData.size () - 1 )
{
data.remove ( row );
}
}
}
// Checking columns
for ( int col = data.get ( 0 ).size () - 1; col >= 0; col-- )
{
for ( int row = 0; row < data.size (); row++ )
{
if ( data.get ( row ).get ( col ) >= 0 )
{
break;
}
else if ( row == data.size () - 1 )
{
//noinspection ForLoopReplaceableByForEach
for ( int r = 0; r < data.size (); r++ )
{
data.get ( r ).remove ( col );
}
}
}
}
return data;
}
public void paintFigurePreview ( Graphics2D g2d, JComponent component )
{
List> previewData = getPreviewData ();
int rows = previewData.size ();
int cols = previewData.get ( 0 ).size ();
int startX = component.getWidth () / 2 - ( cols * Tetris.BLOCK_SIDE + cols ) / 2;
int startY = component.getHeight () / 2 - ( rows * Tetris.BLOCK_SIDE + rows ) / 2;
for ( int row = 0; row < rows; row++ )
{
for ( int col = 0; col < cols; col++ )
{
if ( previewData.get ( row ).get ( col ) >= 0 )
{
blocks[ previewData.get ( row ).get ( col ) ].paintBlock ( g2d,
new Rectangle ( startX + col * Tetris.BLOCK_SIDE + col, startY + row * Tetris.BLOCK_SIDE + row,
Tetris.BLOCK_SIDE, Tetris.BLOCK_SIDE ), rotation
);
}
}
}
}
private boolean intersects ( GeneralPath terrain )
{
Point start = new Point ( point.x * Tetris.BLOCK_SIDE + point.x, point.y * Tetris.BLOCK_SIDE + point.y );
for ( int row = 0; row < placement.length; row++ )
{
for ( int col = 0; col < placement[ row ].length; col++ )
{
if ( placement[ row ][ col ] >= 0 && terrain.intersects (
new Rectangle ( start.x + col * Tetris.BLOCK_SIDE + col, start.y + row * Tetris.BLOCK_SIDE + row, Tetris.BLOCK_SIDE,
Tetris.BLOCK_SIDE )
) )
{
return true;
}
}
}
return false;
}
public Map getBlocks ()
{
Map blocksMap = new HashMap ();
Point start = new Point ( point.x * Tetris.BLOCK_SIDE + point.x, point.y * Tetris.BLOCK_SIDE + point.y );
for ( int row = 0; row < placement.length; row++ )
{
for ( int col = 0; col < placement[ row ].length; col++ )
{
if ( placement[ row ][ col ] >= 0 )
{
blocks[ placement[ row ][ col ] ].setRotation ( rotation );
blocks[ placement[ row ][ col ] ].setBlockPoint ( new Point ( point.x + col, point.y + row ) );
blocksMap.put ( new Point ( start.x + col * Tetris.BLOCK_SIDE + col, start.y + row * Tetris.BLOCK_SIDE + row ),
blocks[ placement[ row ][ col ] ] );
}
}
}
return blocksMap;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy