上一课中,我们制作了一个挡板,并跟随鼠标左右移动。
这一课我们中,将增加一个小球,在空间中弹来弹去。为了方便,我们只使用简单的碰撞,当然,在后面也会进行改进。
首先新建一个Ball类,继承上一课中的BaseObject。
import javafx.scene.effect.Lighting; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; /** * @author wing * @date 2012/7/26 */ public class Ball extends BaseObject{ private Circle circle; private int speedX = 2, speedY = -2; public Ball(int centerX,int centerY, int radius) { circle = new Circle(centerX, centerY, radius, Color.LIGHTBLUE); circle.translateXProperty().bindBidirectional(xProperty()); circle.translateYProperty().bindBidirectional(yProperty()); circle.setEffect(new Lighting()); setWidth(2 * radius); setHeight(2 * radius); getChildren().add(circle); } public void setSpeedX(int speedX) { this.speedX = speedX; } public int getSpeedX() { return speedX; } public void setSpeedY(int speedY) { this.speedY = speedY; } public int getSpeedY() { return speedY; } }
我们在Ball.java中,新建了一个Circle,然后进行属性绑定。增加了一个Lighting的Effect,让小球看起来稍微真实点。最后通过getChildren进行添加。
下面,我们将它添加进上一课的GameScene.java中。
import org.wing.game.object.Ball; 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(); private Ball ball = new Ball(15, 15, 15); private Timeline timeline; private KeyFrame keyFrame; public GameScene(int width, int height){ this.width = width; this.height = height; initGameObjects(); initTimeLine(); } 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()); ball.setX((mainBrick.getWidth() - ball.getWidth())/2); ball.setY(height - mainBrick.getHeight() - ball.getHeight()); getChildren().add(background); getChildren().add(mainBrick); getChildren().add(ball); } private void initTimeLine(){ timeline = new Timeline(); timeline.setCycleCount(Timeline.INDEFINITE); keyFrame = new KeyFrame(Duration.millis(5), new EventHandler<ActionEvent>(){ @Override public void handle(ActionEvent arg0) { ball.moveX(ball.getSpeedX()); ball.moveY(ball.getSpeedY()); if(ball.getX() <= 0 || ball.getX() >= BrickBlock.WIDTH - ball.getWidth()){ ball.setSpeedX(-ball.getSpeedX()); } if(ball.getY() <= 0 || ball.getY() >= BrickBlock.HEIGHT - ball.getHeight()){ ball.setSpeedY(-ball.getSpeedY()); } if(ball.isCollisionWith(mainBrick)) { ball.setSpeedY(-ball.getSpeedY()); } } }); timeline.getKeyFrames().add(keyFrame); timeline.play(); } }
当然,不只是添加。
我们在initGameObjects中,将小球默认位置设置在挡板的上面。
然后就要开始来创建我们的动画了。
JavaFX中的动画就是通过animation来控制的。而animation又有两个子类,其中一个是Transition,很明显就是一些属性改变的动画,JavaFX继承Transition的动画也有很多,详情可以看Doc文档。另外一个就是Timeline, 也就是俗称的时间轴,可以向时间轴Timeline中添加帧KeyFrame,每个KeyFrame主要包含帧运行的时间间隔和帧执行的回调事件EventHandler。
上面的代码中,我们就创建了一个时间轴Timeline,然后添加了一个KeyFrame。 每一帧执行的效果,就是小球的运动,当小球碰到程序的边距和碰到挡板时,会进行反弹。
同时设定TImeline中的帧的执行次数为无限循环。
下面看看程序运行情况:
如何所示,小球将会在空间中弹来弹去,移动鼠标可以移动挡板进行改变小球的运行轨迹。 不过由于此处使用的碰撞没做处理,会有一点其他的小毛病。
这一课就到此结束了,依然用到了上一课中的动态绑定,然后就是Timeline的使用。当然,也可以进行添加Transition来增加其他的动画,这将会在下一课中使用。
转载请注明出处:http://blog.csdn.net/ml3947
---------------------------------------------------------------------------------
本来上周末就准备更新博客的,但周日突然家里出了点事,请了三天假回家了,今天才回到武汉,更新博客。不过对于我而言,现阶段写博客,也只是纯粹积累和分享,与大家共同进步。