JavaFX打砖块游戏开发 第一课

  突然发现,之前还有个JavaFX游戏开发 第一课。不过,这两个教程并不冲突。目前这个系列是做一个完整的打砖块游戏。

 第一课主要用到的知识有,JavaFX的动态绑定,Rectangle的使用,简单的MouseMove事件,BoxBlur特效。


  那么,我们首先创建一个名叫BrickBlock的JavaFX Project。本人是使用的e(fx)clipse进行开发的。

  e(fx)clipse的官方网站为:http://www.efxclipse.org/ ,下载整合插件的eclipse即可。

  

  首先创建一个游戏对象的基类BaseObject,继承于Parent。

  

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Parent;

/**
 * @author wing
 * @date 2012/7/26
 */
public abstract class BaseObject extends Parent{
    protected DoubleProperty widthProperty = new SimpleDoubleProperty(0);
    protected DoubleProperty heightProperty = new SimpleDoubleProperty(0);
    protected DoubleProperty xProperty = new SimpleDoubleProperty(0);
    protected DoubleProperty yProperty = new SimpleDoubleProperty(0);
    
    public  DoubleProperty widthProperty() {
        return  widthProperty;
    }
    public double getWidth(){
        return widthProperty.get();
    }
    public void setWidth(double width){
        this.widthProperty.set(width);
    }
    
     public  DoubleProperty heightProperty() {
        return  heightProperty;
    }
    public double getHeight(){
        return heightProperty.get();
    }
    public void setHeight(double height){
        this.heightProperty.set(height);
    }   
    
    public  DoubleProperty xProperty() {
        return  xProperty;
    }
    public double getX(){
        return xProperty.get();
    }
    public void setX(double x){
        this.xProperty.set(x);
    }      
          
   public  DoubleProperty yProperty() {
        return  yProperty;
    }
    public double getY(){
        return yProperty.get();
    }
    public void setY(double y){
        this.yProperty.set(y);
    }   
    
    public void moveX(double x){
    	this.xProperty.set(getX() + x);
    }
    
    public void moveY(double y){
    	this.yProperty.set(getY() + y);
    }
    
    public boolean isCollisionWith(BaseObject baseObject){
    	if(getX() + getWidth() > baseObject.getX() && getX() < baseObject.getX() + baseObject.getWidth() && getY() + getHeight() > baseObject.getY() && getY() < baseObject.getY() + baseObject.getHeight()){
    		return true;
    	}
    	return false;
    }
    
}

  可以看到,基类BaseObject中,包含有坐标和宽高的属性,并且还有一个检测碰撞的isCollisionWith方法。

  大家可以看到,基类BaseObject中没有使用常规的数据类型,而是使用的DoubleProperty。而DoubleProperty这样

的类型,也正是JavaFX中的动态绑定的机制,set get方法只是改变DoubleProperty的值。

  为了方便,isCollisionWith只是简单的矩形碰撞。


  下面我们创建一个打砖块中底部拦截的游戏对象类MainBrick。


  

import javafx.scene.effect.BoxBlur;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import org.wing.game.BrickBlock;

/**
 * @author wing
 * @date 2012/7/25
 */
public class MainBrick extends BaseObject{
    private Rectangle mRectangle;
    private BoxBlur mBlur;
    public MainBrick(){   
        mRectangle = new Rectangle();
        mRectangle.widthProperty().bindBidirectional(widthProperty());
        mRectangle.heightProperty().bindBidirectional(heightProperty());
        mRectangle.xProperty().bindBidirectional(xProperty());
        mRectangle.yProperty().bindBidirectional(yProperty());
        mRectangle.setArcWidth(20);
        mRectangle.setArcHeight(20);
        mRectangle.setFill(Color.YELLOW);
        mBlur = new BoxBlur();
        mBlur.setWidth(5);
        mBlur.setHeight(5);
        mRectangle.setEffect(mBlur);
        setWidth(150);
        setHeight(25);
        getChildren().add(mRectangle);
    }
    
    public void onMouseMove(MouseEvent event){
        if (event.getX() >= getWidth()/2 && event.getX() <= BrickBlock.WIDTH - getWidth()/2) {
            setX(event.getX() - getWidth()/2);
        }
    }
 
}

  MainBrick中的代码也很简单。

  1.创建了一个Rectangle,这里使用了bindBidirectional方法,这个方法在JavaFX中的意义是双向绑定,只能对Property使用。

  我们将Rectangle的宽度,高度,坐标与基类的属性进行了双向绑定,也就是说整个MainBrick已经是一个Rectangle了。

  2.设置Rectangle的圆角,让它成为一个圆角矩形。

  3.创建了一个BoxBlur效果,通过setEffect给Rectangle设置BoxBlur效果。

  4.设置MainBrick的宽度和高度,由于进行了双向绑定,在这里setWidth,setHeight属性将会同步更新到Rectangle的width和height属性。

  5.这里还有一个onMouseMove的事件,主要是让Rectangle跟着鼠标动,通过判断使矩形不会超出左右边界,并且将Rectangle中心与鼠标对齐。当然,这个事件现在是不能执行的。


  

  接下来,我们创建一个游戏场景类GameScene,继承Parent。


  

import org.wing.game.object.MainBrick;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Parent;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;

public class GameScene extends Parent {
    private int width, height;
    private Rectangle background;
    private MainBrick mainBrick = new MainBrick();
 
    public GameScene(int width, int height){
    	this.width = width;
    	this.height = height;
        
    	initGameObjects();
    }
	
    private void initGameObjects(){
        background = new Rectangle(0, 0, this.width, this.height);
        background.setOnMouseMoved(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                mainBrick.onMouseMove(event);
            }
        });
        background.setFill(Color.BLACK);
		
        mainBrick.setX(0);
        mainBrick.setY(height - mainBrick.getHeight());
        
        getChildren().add(background);
        getChildren().add(mainBrick);    
	}
}

    在游戏场景类GameScene中,我们通过构造函数,传入场景的宽度和高度。

    然后创建了一个背景Rectangle。

    设置Rectangle的onMouseMove事件,在其中执行MainBrick中我们刚才写的onMouseMove函数。通过setFill将Rectangle的填充色设为黑色。


     接下来,将MainBrick的作为设置为屏幕最下方。

     最后,通过getChildern().add()将背景Rectangle和MainBrick添加进GameScene中。


     最后就是我们的JavaFX Main Class了。

     

     

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
 * @author wing
 * @date 2012/7/26
 */
public class BrickBlock extends Application {
    public static final int WIDTH = 800;
    public static final int HEIGHT = 600;
    public static void main(String[] args) {
        launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) {
        GameScene  root = new GameScene(WIDTH, HEIGHT);
        primaryStage.setTitle("BrickBlock");
        primaryStage.setScene(new Scene(root, WIDTH, HEIGHT));
        primaryStage.show();
    }
}

    大家可以看到,由于将游戏对象和游戏场景都分离出来,主类已经变得很简洁了。

    那么我们运行运行看看效果。

   


  图中的黄色的砖块会跟着鼠标移动,并且不会超过左右的边界。(截图看不到鼠标...)

  

  看似效果很简单,不过我们整体的结构已经差不多了,这将有利于我们后续的开发。

  

  在第二课中,我们将会增加一个小球在这个空间中弹来弹去,并且可以与图中的黄色砖块进行碰撞。


  转载请注明出处:http://blog.csdn.net/ml3947/

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值