接着上一篇,继续---------------------------------
碰到游戏面板的边界时,要让方块做出反应。碰左壁,不能再向左移。碰右壁,不能再向右移
在Global.java添加两个常量
public static final int WIDTH=15;
public static final int HEIGHT=15;
修改GamePanel.java的大小
@Override
protected void paintComponent(Graphicsg) {
//重新显示
super.paintComponent(g);
g.fillRect(0, 0, Global.WIDTH*Global.CELL_SIZE,Global.HEIGHT*Global.CELL_SIZE);
g.setColor(new Color(0xcfcfcf));
if(shape!=null && ground!=null){
shape.drawMe(g);
ground.drawMe();
}
}
public GamePanel(){
this.setSize(Global.WIDTH*Global.CELL_SIZE,Global.HEIGHT*Global.CELL_SIZE);
}
在Shape.java中添加几个方向常量
public classShape {
public static final int ROTATE=0;
public static final int LEFT=1;
public static final int RIGHT=2;
public static final int DOWN=3;
在Shape.java中添加取得方块坐标的方法和判断是否自己成员的方法
public int getTop(){
return top;
}
public int getLeft(){
return left;
}
public boolean isMember(int x,int y,boolean rotate){
int tempStatus=status;
if(rotate){
tempStatus=(status+1)%body.length;
}
return body[tempStatus][y*4+x]==1;
}
在Ground.java中添加如下方法
public boolean isMoveable(Shape shape,int action){
int left=shape.getLeft();
int top=shape.getTop();
switch(action){
case Shape.LEFT:
left--;
break;
case Shape.RIGHT:
left++;
break;
case Shape.DOWN:
top++;
break;
}
for(int x=0;x<4;x++){
for(int y=0;y<4;y++){
if(shape.isMember(x, y,action==Shape.ROTATE)){
if(top+y>=Global.HEIGHT ||
left+x<0||
left+x>=Global.WIDTH)
return false;
}
}
}
return true;
}
在Controller.java下添加如下代码
@Override
public void keyPressed(KeyEvent e){
// TODO Auto-generated method stub
super.keyPressed(e);
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
if(ground.isMoveable(shape,Shape.LEFT))
shape.moveLeft();
break;
case KeyEvent.VK_UP:
if(ground.isMoveable(shape, Shape.ROTATE))
shape.rotate();
break;
case KeyEvent.VK_RIGHT:
if(ground.isMoveable(shape,Shape.RIGHT))
shape.moveRight();
break;
case KeyEvent.VK_DOWN:
if(ground.isMoveable(shape,Shape.DOWN))
shape.moveDown();
default:
break;
}
gamePanel.display(ground, shape);
}
在ShapeListener.java下添加一个抽象方法
public interfaceShapeListener {
void shapeMoveDown(Shapeshape);
booleanisShapeMoveDownable(Shapeshape);
}
修改实现该接口的类Controller.java
@Override
public boolean isShapeMoveDownable(Shape shape) {
boolean result=ground.isMoveable(shape,Shape.DOWN);
return result;
}
修改Shape.java的定时下落
private class ShapeDriver implements Runnable {
@Override
public void run() {
// 定时向下落
while (listener.isShapeMoveDownable(Shape.this)){
moveDown();
listener.shapeMoveDown(Shape.this);
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
将图形变成障碍物和显示
修改Controller类的方法isShapeMoveDownable为同步。
@Override
public synchronizedboolean isShapeMoveDownable(Shape shape) {
boolean result=ground.isMoveable(shape,Shape.DOWN);
return result;
}
修改Controller类的方法isShapeMoveDownable,图形到达底部,产生新图形
@Override
public synchronized boolean isShapeMoveDownable(Shape shape) {
if(ground.isMoveable(shape,Shape.DOWN))
return true;
ground.accept(this.shape);
this.shape=shapeFactory.getShape(this);
return false;
}
在Ground.java中添加增加障碍物,显示障碍物的判断
public classGround {
private int[][] obstacles=new int[Global.WIDTH][Global.HEIGHT];
public void accept(Shape shape){
System.out.println("把方块变成障碍物");
for(int x=0;x<4;x++){
for(int y=0;y<4;y++){
if(shape.isMember(x, y, false)){
obstacles[shape.getLeft()+x][shape.getTop()+y]=1;
}
}
}
}
public void drawMe(Graphics g){
System.out.println("画出障碍物");
for(int x=0;x<Global.WIDTH;x++){
for(int y=0;y<Global.HEIGHT;y++){
if(obstacles[x][y]==1){
g.fill3DRect(x*Global.CELL_SIZE, y*Global.CELL_SIZE,
Global.CELL_SIZE, Global.CELL_SIZE, true);
}
}
}
}
修改GamePanel.java
@Override
protected void paintComponent(Graphicsg) {
//重新显示
super.paintComponent(g);
g.fillRect(0,0, Global.WIDTH*Global.CELL_SIZE,Global.HEIGHT*Global.CELL_SIZE);
g.setColor(new Color(0xcfcfcf));
if(shape!=null && ground!=null){
shape.drawMe(g);
ground.drawMe(g);
}
}
当碰到障碍物的时候也停止,修改GamePanel.java下的
public boolean isMoveable(Shape shape,int action){
int left=shape.getLeft();
int top=shape.getTop();
switch(action){
case Shape.LEFT:
left--;
break;
case Shape.RIGHT:
left++;
break;
case Shape.DOWN:
top++;
break;
}
for(int x=0;x<4;x++){
for(int y=0;y<4;y++){
if(shape.isMember(x,y,action==Shape.ROTATE)){
if(top+y>=Global.HEIGHT ||
left+x<0||
left+x>=Global.WIDTH ||
1==obstacles[left+x][top+y])
return false;
}
}
}
return true;
}
消除满行的障碍物
这一行没有空白,则这一行就是满行了。
上面所有的行,整体下移一行
在Ground.java下添加
public void accept(Shape shape){
System.out.println("把方块变成障碍物");
for(int x=0;x<4;x++){
for(int y=0;y<4;y++){
if(shape.isMember(x, y, false)){
obstacles[shape.getLeft()+x][shape.getTop()+y]=1;
}
}
}
deleteFullLine();
}
private void deleteFullLine(){
for(int y=Global.HEIGHT-1;y>0;y--){
boolean full=true;
for(int x=0;x<Global.WIDTH;x++){
if(0==this.obstacles[x][y]){
full=false;
}
}
if(full){
deleteLine(y++);
}
}
}
private void deleteLine(int lineNum) {
for(int y=lineNum;y>0;y--){
for(int x=0;x<Global.WIDTH;x++){
this.obstacles[x][y]=this.obstacles[x][y-1];
}
}
for(int x=0;x<Global.WIDTH;x++){
this.obstacles[x][0]=0;
}
}
增加游戏结束功能
如果有的障碍物超出了上边界,就是游戏结束
第一行如果有障碍物,就是游戏结束
在Ground.java下添加
public boolean isFull(){
for(int x=0;x<Global.WIDTH;x++){
if(1==this.obstacles[x][0]){
return true;
}
}
return false;
}
在Controller.java下判断
@Override
public synchronized booleanisShapeMoveDownable(Shape shape) {
if(ground.isMoveable(shape,Shape.DOWN))
return true;
ground.accept(this.shape);
if(!ground.isFull()){
this.shape=shapeFactory.getShape(this);
}else{
System.out.println("game over");
}
return false;
}
解决定时下落与按下键同时生成障碍物的问题
在controller.java中修改
@Override
public void keyPressed(KeyEvent e){
// TODO Auto-generated method stub
super.keyPressed(e);
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
if(ground.isMoveable(shape, Shape.LEFT))
shape.moveLeft();
break;
case KeyEvent.VK_UP:
if(ground.isMoveable(shape, Shape.ROTATE))
shape.rotate();
break;
case KeyEvent.VK_RIGHT:
if(ground.isMoveable(shape, Shape.RIGHT))
shape.moveRight();
break;
case KeyEvent.VK_DOWN:
if(this.isShapeMoveDownable(shape))
shape.moveDown();
default:
break;
}
gamePanel.display(ground, shape);
}
@Override
public synchronized booleanisShapeMoveDownable(Shape shape) {
if(this.shape!=shape){
returnfalse;
}
if(ground.isMoveable(shape,Shape.DOWN))
return true;
ground.accept(this.shape);
if(!ground.isFull()){
this.shape=shapeFactory.getShape(this);
}else{
System.out.println("game over");
}
return false;
}
后续问题:
给游戏添加各种形状的图形
解决游戏时的画面闪烁问题