一直在关注JavaFX的发展,最近想试试使用JavaFX开发游戏是什么样的情况。可惜令我汗颜的是--没有找到类似于Java 2D中Graphics/Graphics2D之类的类。自己单纯的继承Node的话,也没办法自己进行绘制。看来目前使用JavaFX进行游戏开发,只能使用JavaFX的Shape和ImageView了。
今天花时间写了个JavaFX的精灵的动画的例子,让我们看看在JavaFX中如何操作精灵的动画吧。
首先创建一个JavaFX项目。
暂时不进行Scene的创建,因为我们要使用自定义的Parent。
我们先进行创建一个Sprite类,继承Parent。 这就是我们的精灵类了。
下面来看看代码:
import javafx.geometry.Rectangle2D;
import javafx.scene.Parent;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
/**
* 精灵类
* @author wing
* @date 2012/7/17
*/
public class Sprite extends Parent {
private enum Direction {
Left, Right, Up, Down
};
private Direction direction = Direction.Left;
private Direction lastDirection;
private int x, y, width, height;
private int index = 0;
private int indexDiv = 5;
private ImageView mImageView;
private int speed = 4;
public Sprite(int x, int y, int width, int height, String url) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
Image actor = new Image(getClass().getResourceAsStream(url));
mImageView = new ImageView(actor);
mImageView.setViewport(new Rectangle2D(0, 0, width, height));
mImageView.setLayoutX(x);
mImageView.setLayoutY(y);
getChildren().add(mImageView);
}
/**
* 像下移动
*/
public void moveDown() {
direction = Direction.Down;
if(lastDirection != direction){
index = 0;
}
index++;
if (index / indexDiv > 2) {
index = 0;
}
mImageView.setViewport(new Rectangle2D(((index / indexDiv) % 3) * width, ((index / indexDiv) / 3) * height, width,
height));
mImageView.setLayoutY(mImageView.getLayoutY() + speed);
lastDirection = direction;
}
/**
* 像左移动
*/
public void moveLeft() {
direction = Direction.Left;
if(lastDirection != direction){
index = 3 * indexDiv;
}
index++;
if (index / indexDiv > 5) {
index = 3 * indexDiv;
}
mImageView.setViewport(new Rectangle2D(((index / indexDiv) % 3) * width, ((index / indexDiv) / 3) * height, width,
height));
mImageView.setLayoutX(mImageView.getLayoutX() - speed);
lastDirection = direction;
}
/**
* 像右移动
*/
public void moveRight() {
direction = Direction.Right;
if(lastDirection != direction){
index = 6 * indexDiv;
}
index++;
if (index / indexDiv > 8) {
index = 6 * indexDiv;
}
mImageView.setViewport(new Rectangle2D(((index / indexDiv) % 3) * width, ((index / indexDiv) / 3) * height, width,
height));
mImageView.setLayoutX(mImageView.getLayoutX() + speed);
lastDirection = direction;
}
/**
* 像右移动
*/
public void moveUp() {
direction = Direction.Up;
if(lastDirection != direction){
index = 9 * indexDiv;
}
index++;
if (index / indexDiv > 11) {
index = 9 * indexDiv;
}
mImageView.setViewport(new Rectangle2D(((index / indexDiv) % 3) * width, ((index / indexDiv) / 3) * height, width,
height));
mImageView.setLayoutY(mImageView.getLayoutY() - speed);
lastDirection = direction;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
1.首先定义了一个枚举类型,用来标明当前精灵的方向。
2.x, y, width, height这几个参数顾名思义,就是表明精灵的X,Y坐标和宽,高。
3.我们创建了一个Image,然后基于Image创建了一个ImageView。Image的图片加载是通过getClass().getResourceAsStream(String str)来进行。
4.ImageView有个setViewport(Rectangle2D rect2D)是个很重要的方法,就是显示这个ImageView中图片以rect2D的x,y为起点,width,height为宽高的一部分。 其实就是切割显示。这在所有的精灵动画中都是很常用的。
至于indexDiv大家暂时可以不用看,这个只是为了减慢精灵动画的(太快看起来不协调)。所以你们可以把index /
indexDiv都当作index来看待。
精灵动画,我这里暂且使用很常见的RPGMaker VX中的默认的精灵图片。
我们以这个精灵为标准,从左上到右下,索引也就是Sprite中的index是从0-11。
那么我们在使用ImageView.setViewport()时就要进行相应的处理。最简单的就是X方向(index % 3) * width, Y方向(index / 3 ) * height。 当index到3时,就进入第二行动画。相应的从0, 0,width, height 也变为了0, height, width, height。
然后通过setLayoutX()进行改变精灵的坐标,产生正在行走的效果。
为了避免精灵方向切换的时候,动画出现异常问题(可能会停留一帧上一个方向的动画帧)。我们又创建了一个lastDirection的方向枚举类型。用来标识上一次的方向。如果方向相同,则不做处理,如果方向不同,则要把当前帧切换到当前方向的第一帧。
/**
* 像下移动
*/
public void moveDown() {
direction = Direction.Down;
if(lastDirection != direction){
index = 0;
}
index++;
if (index / indexDiv > 2) {
index = 0;
}
mImageView.setViewport(new Rectangle2D(((index / indexDiv) % 3) * width, ((index / indexDiv) / 3) * height, width,
height));
mImageView.setLayoutY(mImageView.getLayoutY() + speed);
lastDirection = direction;
}
另外,由于只有3帧,如果当index 大于当前方向动画帧数的最大值,得重置为最小。我这里只是简单的标注了数字 2 ,5, 8, 11。
然后创建一个类GamePanel,用来添加我们的所有精灵和地图绘制(以后课程)。
import javafx.event.EventHandler;
import javafx.scene.Parent;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
/**
* @author wing
* @date 2012/7/17
*/
public class GamePanel extends Parent {
private Sprite sprite;
public GamePanel() {
}
public void load(){
sprite = new Sprite(50, 50, 32, 32, "actor.png");
getChildren().add(sprite);
getScene().setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
onKeyPressed(event);
}
});
}
public void onKeyPressed(KeyEvent event){
if(event.getCode() == KeyCode.LEFT){
sprite.moveLeft();
}else if(event.getCode() == KeyCode.RIGHT){
sprite.moveRight();
}else if(event.getCode() == KeyCode.UP){
sprite.moveUp();
}else if(event.getCode() == KeyCode.DOWN){
sprite.moveDown();
}
}
public void update(long now){
}
}
这个类现在很简单,只是单纯的在50,50坐标处,创建了一个Sprite。然后给Scene添加了一个按键事件,在按Left right up 和 down的时候,将会控制精灵进行各个方向的移动。
下面来写我们的主类。
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class MainClass extends Application {
@Override
public void start(Stage stage) throws Exception {
GamePanel mPanel = new GamePanel();
final Scene scene = new Scene(mPanel,800, 600);
mPanel.load();
scene.setFill(Color.BLACK);
stage.setScene(scene);
stage.setTitle("JavaFX游戏开发--第一课 精灵动画");
stage.show();
}
/**
* @param args
*/
public static void main(String[] args) {
launch(MainClass.class, args);
}
}
我们在主类中创建了GamePanel,根据GamePanel创建了一个Scene,调用了GamePanel的load方法,进行加载精灵和添加事件。然后将Scene背景设为了黑色。
下面我们来看看运行效果吧~
向右走:
向下走:
那么JavaFX游戏开发的第一课就讲到这里了。其实很简单,就是单纯的一个精灵动画的实现而已。所以我们并没有创建精灵的基类等工作。
后面的课程中,我们将会进行游戏地图,对话框等的加入。
本人水平不佳,望大家指正。一起进步。
转载请注明出处:http://blog.csdn.net/ml3947
分享到:
相关推荐
JavaFX SDK 11.0.2 是一个用于开发富客户端应用程序的工具包,它在Java 11及更高版本中不再作为标准JDK的一部分。这个独立的SDK提供了必要的库和工具,使得开发者能够在Java平台上构建具有丰富图形用户界面(GUI)的...
javafx.base-11.0.0-SNAPSHOT-linux.jar,javafx.base-11.0.0-SNAPSHOT-mac.jar,javafx.base-11.0.0-SNAPSHOT-win.jar,javafx-base-11.jar,javafx-base-11-win.jar,javafx-graphics-11.jar,javafx-graphics-11-win....
JavaFX SDK 17.0.2 LTS 是一个用于创建桌面和基于浏览器的富客户端应用程序的工具包,专为Windows x64平台设计。这个版本是长期支持(LTS)版本,意味着它将提供更长期的维护和支持,适合于那些需要稳定开发环境的...
linux系统下,可用如下两...java --module-path /home/ubuntu20/javafx-sdk-18/lib --add-modules javafx.controls,javafx.fxml -jar EQMSAny_jar.jar 其中 /home/ubuntu20/javafx-sdk-18 是上包所解压后的你放置的路径
javaFX-jps-plugin.jar
利用javafx绘制动画风扇图,提供pause、reverse、resume按钮
在"javafx-sdk-11.0.2"这个压缩包中,包含了运行和开发JavaFX应用所需的所有资源。 3. **打包工具**:为了便于部署,JavaFX 11提供了新的打包工具,如`jlink`和`jpackage`,可以创建自包含的运行时环境,减小最终...
javaFx 学习--之布局菜单
总之,JavaFX为Java开发者提供了一个强大且灵活的工具,使得开发具有丰富图形界面的应用程序变得更加容易。如果你对桌面应用开发有兴趣,或者希望提升你的UI设计技能,那么学习JavaFX无疑是值得投入的。这个中文PDF...
标题中的"javafx-11.0.2 jar.rar"指的是JavaFX 11.0.2版本的库文件,这些文件被压缩在RAR格式的压缩包中。这个压缩包包含了JavaFX的不同模块,如base、controls、media、graphics、swing、web以及awt等,同时也包含...
javafx_sdk-2_2_21-windows-i586
1. 桌面应用程序:JavaFX 可以用于开发桌面应用程序,例如图形编辑器、视频播放器和游戏等。 2. 移动应用程序:JavaFX 可以用于开发移动应用程序,例如智能手机和平板电脑上的应用程序。 3. 网络应用程序:JavaFX ...
JavaFX支持2D和3D图形,动画效果,以及跨平台兼容性,使得Luke可以在多种操作系统上运行,包括Windows 7。在Luke 7.4.0中,用户可以期待一个更加直观且响应迅速的界面,便于浏览和查询索引中的文档和字段。 在...
总的来说,"luke-javafx-7.3.1-luke-release.zip"是一个结合了JavaFX的最新技术与Lucene的强大搜索功能的工具包,对于Lucene开发者和信息检索领域的专业人士来说,它是一个不可或缺的辅助工具,帮助他们深入理解、...
本示例"javafx-textfield-change-demo"就是关于如何实现这一功能的演示。 JavaFX提供了事件处理机制,我们可以使用ChangeListener接口来监听TextField的文本变化。当TextField中的文本发生改变时,ChangeListener的...
在压缩包中,`javafx-samples-8u102-ea`这个子目录可能包含了各种示例项目,每个项目都展示了JavaFX的不同功能。开发者可以通过查看源码学习如何使用JavaFX API来实现特定功能,也可以直接运行jar文件查看运行效果。...
javafx-commons-2.0.1
这个压缩包文件"javafx-rest-archetype-1.1.zip"包含了项目的核心源代码,帮助开发者快速启动一个新的JavaFX应用,该应用能够与RESTful Web服务进行交互。 JavaFX是Oracle提供的一个用于创建桌面应用的富客户端平台...
javafx-sdk-18.zip
先决条件JDK 11 Maven 3在本地安装原型要将所有原型安装在本地存储库中,请执行以下命令: git clone https://github.com/openjfx/javafx-maven-archetypes.gitcd javafx-maven-archetypesmvn clean install这将在...