本游戏基本实现的经典俄罗斯方块游戏的全部功能,算是自学J2SE阶段的毕业作品
全程独立开发,未参考任何相关视频和教程
代码略繁琐,600多行,没办法,初学者
博主微信:manyu_2017,欢迎初学者交流
##控制类-Control
package yy.game.russiacell;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import javax.swing.JPanel;
public class Control {
static Map<Integer, Boolean> cellMap;
static Map<Integer, Cell> cellsMap;
static Cells cells;
static Cell cell;
static int score;
static RussianPanel cellPanel;
static ArrayList<Integer> keyPress;
static int sleepTime;
//static boolean flag = true;
public static void main(String[] args) throws InterruptedException {
init();
do {
dropToEnd();
cells = randomCells();
} while (ifGoOn());
}
protected static int getMaxKey() {
int cellMaxKey = 0;
for (int maxKey : cellsMap.keySet()) {
cellMaxKey = maxKey>cellMaxKey?maxKey:cellMaxKey;
}
return cellMaxKey;
}
private static void init() throws InterruptedException {
cells = randomCells();
sleepTime = 500;
keyPress = new ArrayList<>();
cellPanel = new RussianPanel();
cellPanel.init();
cellMap= new HashMap<>();
cellsMap= new HashMap<>();
for (int i = 1; i <= Cell.MAXCOL*Cell.MAXROW; i++) {
cellMap.put(i, true);
}
cellMap.put(-1, false);
}
private static Cells randomCells() {
return new Cells((int)(Math.random()*18) + 2);
}
private static void dropToEnd() throws InterruptedException {
HashSet<Integer> clearSet = new HashSet<>();
while (ifCellsDrop()) {
while (ifCellsDrop()) {
cells.drop();
keyControl();
Thread.sleep(sleepTime);
cellPanel.repaint();
//if(flag){Thread.currentThread().wait();}
}
keyControl();
Thread.sleep(200);
}
for (Cell cell : cells.cellsList) {
cellsMap.put(cell.getCellKey(), cell);
clearSet.add(cell.row);
}
for (Integer integer : clearSet) {
if (Cell.clear(integer)) {
score++;
sleepTime=sleepTime>50?sleepTime-50:50;
cellPanel.repaint();
}
}
}
private static boolean ifCellsDrop() {
boolean ifDrop = true;
for (Cell cell : cells.cellsList) {
cellMap.put(cell.getCellKey(), true);
}
for (Cell cell : cells.cellsList) {
if (!cellMap.get(cell.getDownCellKey())) {
ifDrop = false;
break;
}
}
for (Cell cell : cells.cellsList) {
cellMap.put(cell.getCellKey(), false);
}
return ifDrop;
}
private static boolean ifGoOn() {
boolean flag = true;
for (Cell cell : cells.cellsList) {
cellMap.put(cell.getCellKey(), true);
}
for (Cell cell : cells.cellsList) {
if (!cellMap.get(cell.getDownCellKey())) {
flag = false;
}
}
for (Cell cell : cells.cellsList) {
cellMap.put(cell.getCellKey(), false);
}
return flag;
}
private static void keyControl() {
Iterator<Integer> keyIt = keyPress.iterator();
while (keyIt.hasNext()) {
Integer key = (Integer) keyIt.next();
if (key==1) {
if (cells.ifRotate()) {
cells.Rotate();
}
}else if (cells.ifMoves(key)) {
cells.move(key);
}
keyIt.remove();
}
}
static class RussianPanel extends JPanel{
private static final long serialVersionUID = 1L;
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.GRAY);
g.setFont(new Font("score",Font.ITALIC, 40));
g.drawString("SCORE:"+score, 150, 200);
for (Cell cell : cells.cellsList) {
cellsMap.put(cell.getCellKey(), cell);
}
for (int key : cellsMap.keySet()) {
int ass = key%Cell.MAXCOL;
int x,y;
if (ass==0) {
x = (Cell.MAXCOL-1)*25;
y = (Cell.MAXROW-key/Cell.MAXCOL)*25;
}else {
x = (ass-1)*25;
y = (Cell.MAXROW-(key/Cell.MAXCOL)-1)*25;
}
switch (key%Cell.MAXCOL==0?key/Cell.MAXCOL-1:key/Cell.MAXCOL) {
case 0:g.setColor(Color.RED);break;
case 1:g.setColor(Color.YELLOW);break;
case 2:g.setColor(Color.GREEN);break;
case 3:g.setColor(Color.BLUE);break;
default:g.setColor(Color.PINK);break;
}
g.fillRoundRect(x, y, 25, 25, 5, 5);
}
for (Cell cell : cells.cellsList) {
cellsMap.remove(cell.getCellKey());
}
//flag = false;
//Thread.currentThread().notify();
}
public void init() throws InterruptedException{
GUI gui = new GUI();
gui.init();
gui.jFrame.getContentPane().add(cellPanel);
cellPanel.setVisible(true);
}
}
}
##界面类-GUI
package yy.game.russiacell;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
public class GUI{
protected JFrame jFrame;
public void init() throws InterruptedException {
jFrame = new JFrame("俄罗斯方块");
jFrame.setBounds(560, 140, 520, 850);
jFrame.setVisible(true);
jFrame.addKeyListener(new CellkeyListener());
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private class CellkeyListener extends KeyAdapter{
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
Control.keyPress.add(1);
break;
case KeyEvent.VK_DOWN:
Control.keyPress.add(2);
break;
case KeyEvent.VK_LEFT:
Control.keyPress.add(3);
break;
case KeyEvent.VK_RIGHT:
Control.keyPress.add(4);
break;
default:
break;
}
}
}
}
##方块类-Cell
package yy.game.russiacell;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class Cell {
int row;
int col;
static final int MAXROW = 32;
static final int MAXCOL = 20;
public Cell(int col) {
super();
this.row = 32;
this.col = col;
}
public Cell(int row,int col) {
super();
this.row = row;
this.col = col;
}
protected void drop() {
Control.cellMap.put(this.getCellKey(), true);
this.row--;
Control.cellMap.put(this.getCellKey(), false);
}
protected boolean ifMove(int key) {
boolean flag = true;
switch (key) {
case 2:
flag = (this.row>3&&Control.cellMap.get(this.getCellKey()-60))?true:false;
break;
case 3:
flag = (Control.cellMap.get(this.getCellKey()-1))?true:false;
if (this.getCellKey()%MAXCOL==1) flag = false;
break;
case 4:
flag = (Control.cellMap.get(this.getCellKey()+1))?true:false;
if (this.getCellKey()%MAXCOL==0) flag = false;
break;
default:
flag = false;
break;
}
return flag;
}
protected void move(int key) {
switch (key) {
case 2:
drop();
drop();
drop();
break;
case 3:
Control.cellMap.put(this.getCellKey(), true);
this.col--;
Control.cellMap.put(this.getCellKey(), false);
break;
case 4:
Control.cellMap.put(this.getCellKey(), true);
this.col++;
Control.cellMap.put(this.getCellKey(), false);
break;
default:
break;
}
}
protected static boolean clear(int rowNum) {
for (int i=1+(rowNum-1)*MAXCOL; i<=rowNum*MAXCOL; i++) {
if (Control.cellMap.get(i)) {
return false;
}
}
Iterator<Integer> iterator = Control.cellsMap.keySet().iterator();
Map<Integer, Cell> cellsMap2 = new HashMap<>();
while (iterator.hasNext()) {
int i = iterator.next();
if (i<=rowNum*MAXCOL && i>(rowNum-1)*MAXCOL) {
iterator.remove();
Control.cellMap.put(i, true);
continue;
}else if (i>rowNum*MAXCOL) {
cellsMap2.put(i-MAXCOL, Control.cellsMap.get(i));
Control.cellMap.put(i-MAXCOL, false);
iterator.remove();
Control.cellMap.put(i, true);
}
}
Control.cellsMap.putAll(cellsMap2);
return true;
}
protected int getCellKey() {
return (this.row-1)*MAXCOL+this.col;
}
protected int getDownCellKey() {
return this.row>1?(getCellKey()-MAXCOL):-1;
}
}
##方块集类—Cells
package yy.game.russiacell;
import java.util.ArrayList;
public class Cells {
ArrayList<Cell> cellsList;
int type;
int rotateNum;
protected Cells(int location) {
cellsList = new ArrayList<>();
switch (randomShape()) {
case ".":
type = 1;
cellsList.add(new Cell(location));
break;
case "o":
type = 2;
cellsList.add(new Cell(location+1));
cellsList.add(new Cell(31,location+1));
cellsList.add(new Cell(location));
cellsList.add(new Cell(31,location));
break;
case "I":
type = 3;
cellsList.add(new Cell(29,location));
cellsList.add(new Cell(30,location));
cellsList.add(new Cell(31,location));
cellsList.add(new Cell(location));
break;
case "T":
type = 4;
cellsList.add(new Cell(31,location));
cellsList.add(new Cell(location));
cellsList.add(new Cell(location-1));
cellsList.add(new Cell(location+1));
break;
case "L":
type = 5;
cellsList.add(new Cell(30,location));
cellsList.add(new Cell(30,location-1));
cellsList.add(new Cell(31,location));
cellsList.add(new Cell(location));
break;
case "LL":
type =6;
cellsList.add(new Cell(30,location));
cellsList.add(new Cell(30,location+1));
cellsList.add(new Cell(31,location));
cellsList.add(new Cell(location));
break;
case "Z":
type = 7;
cellsList.add(new Cell(31,location));
cellsList.add(new Cell(31,location+1));
cellsList.add(new Cell(location));
cellsList.add(new Cell(location-1));
break;
case "ZZ":
type = 8;
cellsList.add(new Cell(31,location));
cellsList.add(new Cell(31,location-1));
cellsList.add(new Cell(location));
cellsList.add(new Cell(location+1));
break;
default:
break;
}
}
protected Cells(int row,int col,int type,int rotNum) {
cellsList = new ArrayList<>();
switch (type) {
case 1:
cellsList.add(new Cell(row,col));
break;
case 2:
cellsList.add(new Cell(row,col));
cellsList.add(new Cell(row-1,col));
cellsList.add(new Cell(row,col-1));
cellsList.add(new Cell(row-1,col-1));
break;
case 3:
switch (rotNum) {
case 0:case 2:
cellsList.add(new Cell(row,col));
cellsList.add(new Cell(row,col+1));
cellsList.add(new Cell(row,col+2));
cellsList.add(new Cell(row,col-1));
break;
case 1:case 3:
cellsList.add(new Cell(row,col));
cellsList.add(new Cell(row+1,col));
cellsList.add(new Cell(row+2,col));
cellsList.add(new Cell(row-1,col));
break;
default:break;
}break;
case 4:
cellsList.add(new Cell(row,col));
cellsList.add(new Cell(row+1,col));
cellsList.add(new Cell(row-1,col));
cellsList.add(new Cell(row,col+1));
cellsList.add(new Cell(row,col-1));
switch (rotNum) {
case 0:cellsList.remove(3);break;
case 1:cellsList.remove(2);break;
case 2:cellsList.remove(4);break;
case 3:cellsList.remove(1);;break;
default:break;
}
break;
case 5:
switch (rotNum) {
case 0:
cellsList.add(new Cell(row,col-1));
cellsList.add(new Cell(row+1,col-1));
cellsList.add(new Cell(row+1,col));
cellsList.add(new Cell(row+1,col+1));break;
case 1:
cellsList.add(new Cell(row-1,col+1));
cellsList.add(new Cell(row,col+1));
cellsList.add(new Cell(row+1,col+1));
cellsList.add(new Cell(row+1,col));break;
case 2:
cellsList.add(new Cell(row-1,col));
cellsList.add(new Cell(row-1,col-1));
cellsList.add(new Cell(row-1,col+1));
cellsList.add(new Cell(row,col+1));break;
case 3:
cellsList.add(new Cell(row-1,col));
cellsList.add(new Cell(row-1,col-1));
cellsList.add(new Cell(row,col-1));
cellsList.add(new Cell(row+1,col-1));break;
default:break;
}
break;
case 6:
switch (rotNum) {
case 0:
cellsList.add(new Cell(row,col-1));
cellsList.add(new Cell(row-1,col-1));
cellsList.add(new Cell(row-1,col));
cellsList.add(new Cell(row-1,col+1));break;
case 1:
cellsList.add(new Cell(row-1,col-1));
cellsList.add(new Cell(row,col-1));
cellsList.add(new Cell(row+1,col-1));
cellsList.add(new Cell(row+1,col));break;
case 2:
cellsList.add(new Cell(row+1,col));
cellsList.add(new Cell(row+1,col-1));
cellsList.add(new Cell(row+1,col+1));
cellsList.add(new Cell(row,col+1));break;
case 3:
cellsList.add(new Cell(row-1,col));
cellsList.add(new Cell(row-1,col+1));
cellsList.add(new Cell(row,col+1));
cellsList.add(new Cell(row+1,col+1));break;
default:break;
}
break;
case 7:
switch (rotNum) {
case 0:case 2:
cellsList.add(new Cell(row,col));
cellsList.add(new Cell(row,col+1));
cellsList.add(new Cell(row+1,col+1));
cellsList.add(new Cell(row-1,col));break;
case 1:case 3:
cellsList.add(new Cell(row,col));
cellsList.add(new Cell(row,col-1));
cellsList.add(new Cell(row-1,col+1));
cellsList.add(new Cell(row-1,col));break;
default:break;
}
break;
case 8:
switch (rotNum) {
case 0:case 2:
cellsList.add(new Cell(row,col));
cellsList.add(new Cell(row,col+1));
cellsList.add(new Cell(row+1,col));
cellsList.add(new Cell(row-1,col+1));break;
case 1:case 3:
cellsList.add(new Cell(row,col));
cellsList.add(new Cell(row,col+1));
cellsList.add(new Cell(row-1,col-1));
cellsList.add(new Cell(row-1,col));break;
default:break;
}
break;
default:
break;
}
}
protected Cells copyCells() {
Cells copy = new Cells(5);
copy.cellsList.clear();
for (Cell cell : this.cellsList) {
copy.cellsList.add(cell);
}
return copy;
}
protected static String randomShape() {
int randomNum = (int) (Math.random()*50)+1;
if(randomNum>50) return "Z";
else if(randomNum>40) return "ZZ";
else if(randomNum>30) return "L";
else if(randomNum>20) return "LL";
else if(randomNum>10) return "T";
else if(randomNum>5) return "o";
else if(randomNum>1) return "I";
else return ".";
}
protected void drop() {
for (Cell cell : cellsList) {
cell.drop();
}
}
protected boolean ifMoves(int key) {
boolean flag = true;
for (Cell cell : this.cellsList) {
Control.cellMap.put(cell.getCellKey(), true);
}
for (Cell cell : this.cellsList) {
if (!cell.ifMove(key)) {
flag = false;
}
}
for (Cell cell : this.cellsList) {
Control.cellMap.put(cell.getCellKey(), false);
}
return flag;
}
protected void move(int key) {
for (Cell cell : this.cellsList) {
cell.move(key);
}
}
protected Cell getRotateCenter() {
Cell centerCell = new Cell(0, 0);
for (Cell cell : this.cellsList) {
centerCell = cell.getCellKey()>centerCell.getCellKey()?cell:centerCell;
}
switch ((this.type-1)*(this.rotateNum+1)+1) {
case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:break;
case 9:case 11: centerCell = new Cell(centerCell.row-2,centerCell.col); break;
case 10:case 12: centerCell = new Cell(centerCell.row,centerCell.col-2); break;
case 13: centerCell = new Cell(centerCell.row,centerCell.col-1); break;
case 14: centerCell = new Cell(centerCell.row-1,centerCell.col); break;
case 15: centerCell = new Cell(centerCell.row-1,centerCell.col); break;
case 16: centerCell = new Cell(centerCell.row-1,centerCell.col); break;
case 17: centerCell = new Cell(centerCell.row-1,centerCell.col+1); break;
case 18: centerCell = new Cell(centerCell.row-1,centerCell.col-1); break;
case 19: centerCell = new Cell(centerCell.row-1,centerCell.col-1); break;
case 20: centerCell = new Cell(centerCell.row,centerCell.col-1); break;
case 21: centerCell = new Cell(centerCell.row-1,centerCell.col-1); break;
case 22: centerCell = new Cell(centerCell.row,centerCell.col+1); break;
case 23: centerCell = new Cell(centerCell.row-1,centerCell.col); break;
case 24: centerCell = new Cell(centerCell.row-1,centerCell.col-1); break;
case 25:case 27: centerCell = new Cell(centerCell.row,centerCell.col-1); break;
case 26:case 28: centerCell = new Cell(centerCell.row-1,centerCell.col); break;
case 29:case 31: centerCell = new Cell(centerCell.row-2,centerCell.col); break;
case 30:case 32: centerCell = new Cell(centerCell.row-2,centerCell.col); break;
default:break;
}
return centerCell;
}
protected boolean ifRotate(){
Cell centerCell = this.getRotateCenter();
int centerRow = centerCell.row;
int centerCol = centerCell.col;
boolean flag = true;
if (centerCol>18||centerCol<3) {//防止边缘异常
return false;
}
for (Cell cell : this.cellsList) {
Control.cellMap.put(cell.getCellKey(), true);
}
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (!Control.cellMap.get(new Cell(centerRow+i,centerCol+j).getCellKey())) {
flag = false;
}
}
}
return flag;
}
protected void Rotate() {
Cell centerCell = this.getRotateCenter();
int centerRow = centerCell.row;
int centerCol = centerCell.col;
this.cellsList = new Cells(centerRow, centerCol, this.type, this.rotateNum).cellsList;
rotateNum = (rotateNum+1)%4;
}
}