public interface ShapeListner {
void ShapemoveDwon(Shape shape);
boolean isShapeAutoMoveDwon(Shape shape);
}
public class Global {
public static final int CELL=20;
public static final int WIDTH=15;
public static final int HEIGHT=15;
}
public class Shape {
public static final int ROATET=0;
public static final int MOLEFT=1;
public static final int MORIGHT=2;
public static final int MODOWN=3;
private int body[][];
private int status;
private ShapeListner shapelistener;
private int left;
private int top;
public void moveleft(){
System.out.println("shape's moveleft");
left--;
}
public void moveright(){
System.out.println("shape's moveright");
left++;
}
public void movedown(){
System.out.println("shape's movedown");
top++;
}
public void rotate(){
System.out.println("shape's rotate");
status=(status+1)%body.length;
}
public void drawMe(Graphics g){
System.out.println("shape's drawMe");
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(getFlagByPoint(i, j)){
g.setColor(Color.BLUE);
g.fill3DRect((left+i)*Global.CELL, (top+j)*Global.CELL,
Global.CELL, Global.CELL, true);
}
}
}
}
private boolean getFlagByPoint(int x,int y){
return body[status][4*y+x]==1;
}
public boolean getFlagByPoint1(int x,int y,boolean rotate){
int tempStatus=status;
if(rotate){
tempStatus=(status+1)%body.length;
}
return body[tempStatus][4*y+x]==1;
}
class shapeDriver implements Runnable{
@Override
public void run() {
while(shapelistener.isShapeAutoMoveDwon(Shape.this)){
movedown();
shapelistener.ShapemoveDwon(Shape.this);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public Shape(){
new Thread(new shapeDriver()).start();;
}
public void addShapeListener(ShapeListner l){
this.shapelistener=l;
}
public void setBody(int body[][]){
this.body=body;
}
public void setStatus(int status){
this.status=status;
}
public int getTop(){
return top;
}
public int getLeft(){
return left;
}
}
public class Game {
public static void main(String[] args) {
Ground ground=new Ground();
ShapeFactory shapefactory=new ShapeFactory();
GamePanel gamepanel=new GamePanel();
Controller controller=new Controller(ground, shapefactory, gamepanel);
JFrame frame=new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(gamepanel.getSize().width+10, gamepanel.getSize().height+35);
frame.add(gamepanel);
gamepanel.addKeyListener(controller);
frame.addKeyListener(controller);
frame.setVisible(true);
controller.newGame();
}
}
public class Controller extends KeyAdapter implements ShapeListner{
private Shape shape;
private ShapeFactory shapefactory;
private Ground ground;
private GamePanel gamepanel;
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_DOWN: {
if(ground.isShapeMoveable(shape, Shape.MODOWN))
shape.movedown();
break;
}
case KeyEvent.VK_LEFT: {
if(ground.isShapeMoveable(shape, Shape.MOLEFT))
shape.moveleft();
break;
}
case KeyEvent.VK_RIGHT: {
if(ground.isShapeMoveable(shape, Shape.MORIGHT))
shape.moveright();
break;
}
case KeyEvent.VK_UP: {
if(ground.isShapeMoveable(shape, Shape.ROATET))
shape.rotate();
break;
}
}
gamepanel.display(ground, shape);
}
@Override
public void ShapemoveDwon(Shape shape) {
gamepanel.display(ground, shape);
}
public void newGame(){
shape=shapefactory.getShape(this);
}
public Controller(Ground ground,ShapeFactory shapefactory,GamePanel gamepanel){
this.gamepanel=gamepanel;
this.ground=ground;
this.shapefactory=shapefactory;
}
@Override
public synchronized boolean isShapeAutoMoveDwon(Shape shape) {
if( ground.isShapeMoveable(shape, Shape.MODOWN)){
return true;
}
ground.accept(this.shape);
if(!ground.isFull()){
this.shape=shapefactory.getShape(this);
}
return false;
}
}
public class GamePanel extends JPanel{
private Ground ground;
private Shape shape;
public void display(Ground ground,Shape shape){
this.ground=ground;
this.shape=shape;
System.out.println("GamePanel's display");
this.repaint();//调用paintComponent方法
}
@Override
protected void paintComponent(Graphics g) {
g.setColor(new Color(0xcfcfcf));
g.fillRect(0, 0, Global.WIDTH*Global.CELL,Global.HEIGHT*Global.CELL);
if(shape!=null && ground!=null){
ground.drawMe(g);
shape.drawMe(g);
}
}
public GamePanel(){
this.setSize(Global.WIDTH*Global.CELL,Global.HEIGHT*Global.CELL);
}
}
public class ShapeFactory {
private int shapefactory[][][] = {
{
{ 1, 0, 0, 0,
1, 1, 1, 0,
0, 0, 0, 0,
0, 0, 0, 0 },
{ 1, 1, 0, 0,
1, 0, 0, 0,
1, 0, 0, 0,
0, 0, 0, 0 },
{ 1, 1, 1, 0,
0, 0, 1, 0,
0, 0, 0, 0,
0, 0, 0, 0 },
{ 0, 1, 0, 0,
0, 1, 0, 0,
1, 1, 0, 0,
0, 0, 0, 0 }
},
{
{ 0, 0, 0, 0,
0, 1, 1, 0,
0, 1, 1, 0,
0, 0, 0, 0 }
},
{
{ 0, 1, 0, 0,
0, 1, 0, 0,
0, 1, 0, 0,
0, 1, 0, 0 },
{ 0, 0, 0, 0,
1, 1, 1, 1,
0, 0, 0, 0,
0, 0, 0, 0 }
},
{
{ 0, 1, 0, 0,
1, 1, 1, 0,
0, 0, 0, 0,
0, 0, 0, 0 },
{ 0, 1, 0, 0,
1, 1, 0, 0,
0, 1, 0, 0,
0, 0, 0, 0 },
{ 0, 0, 0, 0,
1, 1, 1, 0,
0, 1, 0, 0,
0, 0, 0, 0 },
{ 0, 1, 0, 0,
0, 1, 1, 0,
0, 1, 0, 0,
0, 0, 0, 0 },
},
{
{ 0, 0, 0, 0,
1, 1, 1, 0,
1, 0, 0, 0,
0, 0, 0, 0 },
{ 1, 1, 0, 0,
0, 1, 0, 0,
0, 1, 0, 0,
0, 0, 0, 0 },
{ 0, 0, 1, 0,
1, 1, 1, 0,
0, 0, 0, 0,
0, 0, 0, 0 },
{ 0, 1, 0, 0,
0, 1, 0, 0,
0, 1, 1, 0,
0, 0, 0, 0 }
},
{
{ 1, 1, 0, 0,
0, 1, 1, 0,
0, 0, 0, 0,
0, 0, 0, 0 },
{ 0, 0, 1, 0,
0, 1, 1, 0,
0, 1, 0, 0,
0, 0, 0, 0 }
},
{
{ 0, 1, 1, 0,
1, 1, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0 },
{ 1, 0, 0, 0,
1, 1, 0, 0,
0, 1, 0, 0,
0, 0, 0, 0 }
}
};
public Shape getShape(ShapeListner shapelistner) {
System.out.println("shapeFactory's getShape");
Shape shape = new Shape();
int shapestatus = new Random().nextInt(shapefactory.length);
shape.setBody(shapefactory[shapestatus]);
shape.setStatus(0);
shape.addShapeListener(shapelistner);
return shape;
}
}
public class Ground {
private int obstacle[][] = new int[Global.WIDTH][Global.HEIGHT];
public void accept(Shape shape) {
System.out.println("Ground's accept");
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 4; y++) {
if (shape.getFlagByPoint1(x, y, false)) {
obstacle[shape.getLeft() + x][shape.getTop() + y] = 1;
}
}
}
deleteFullLine();
}
public void drawMe(Graphics g) {
System.out.println("Ground's drawMe");
g.setColor(Color.RED);
for (int x = 0; x < Global.WIDTH; x++) {
for (int y = 0; y < Global.HEIGHT; y++) {
if (obstacle[x][y] == 1) {
g.fill3DRect(x * Global.CELL, y * Global.CELL, Global.CELL,
Global.CELL, true);
}
}
}
}
private void deleteFullLine() {
for (int y = Global.HEIGHT - 1; y >= 0; y--) {
boolean full = true;
for (int x = 0; x < Global.WIDTH; x++) {
if (obstacle[x][y] == 0){
full = false;
}
}
if (full) {
deletefullline(y);
}
}
}
private void deletefullline(int linty) {
for (int y = linty; y > 0; y--) {
for (int x = 0; x < Global.WIDTH; x++) {
obstacle[x][y] = obstacle[x][y - 1];
}
}
for(int x=0;x<Global.WIDTH;x++){
obstacle[x][0]=0;
}
}
public boolean isShapeMoveable(Shape shape, int action) {
int top = shape.getTop();
int left = shape.getLeft();
switch (action) {
case Shape.MODOWN: {
top++;
break;
}
case Shape.MOLEFT: {
left--;
break;
}
case Shape.MORIGHT: {
left++;
break;
}
}
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 4; y++) {
if (shape.getFlagByPoint1(x, y, action == Shape.ROATET)) {
if (top + y > Global.HEIGHT - 1
|| left + x > Global.WIDTH - 1 || left + x < 0
|| obstacle[left + x][top + y] == 1) {
return false;
}
}
}
}
return true;
}
public boolean isFull(){
for(int x=0;x<Global.WIDTH;x++){
if(obstacle[x][0]==1){
return true;
}
}
return false;
}
}