四时宝库

程序员的知识宝库

FXGL引擎Texture随机改变颜色(texturer材质)

#以书之名#

在FXGL游戏引擎中,使用Texture组件可以非常方便地为游戏中的实体对象设置外观。一个非常常见的需求是随机改变对象的颜色,这对于生成多样化的游戏世界或产生不同的视觉效果非常有用。本文将介绍如何在FXGL引擎中实现这一功能,通过随机改变对象的颜色来丰富游戏的表现。

1.核心概念

在FXGL引擎中,Texture用于为实体设置图像或图形外观。通过对Texture应用颜色变换,开发者可以改变其外观效果。FXGL提供了multiplyColor()方法,该方法允许将一个颜色乘到纹理上,从而实现颜色的修改。

2.实现随机颜色变化

我们将通过创建一个Tank实体来展示如何为Texture对象应用随机颜色。在ImageEntityFactory类中,我们使用FXGLMath.randomColor()生成一个随机颜色,并将其应用到Tank的纹理上。为了使颜色更加鲜亮,我们还使用了brighter()方法来加深效果。

package com.alatus.game;

import com.almasb.fxgl.core.math.FXGLMath;
import com.almasb.fxgl.dsl.FXGL;
import com.almasb.fxgl.dsl.components.ExpireCleanComponent;
import com.almasb.fxgl.entity.Entity;
import com.almasb.fxgl.entity.EntityFactory;
import com.almasb.fxgl.entity.SpawnData;
import com.almasb.fxgl.entity.Spawns;
import com.almasb.fxgl.physics.BoundingShape;
import com.almasb.fxgl.texture.AnimatedTexture;
import com.almasb.fxgl.texture.AnimationChannel;
import com.almasb.fxgl.texture.Texture;
import javafx.util.Duration;

public class ImageEntityFactory implements EntityFactory {

    // 创建Car实体
    @Spawns("Car")
    public Entity newCar(SpawnData data) {
        Texture carLeft = FXGL.texture("car.png");
        Texture carRight = carLeft.copy();
        carRight.setScaleX(-1);
        carRight.setTranslateX(carLeft.getWidth());
        return FXGL.entityBuilder(data)
                .view(carLeft)
                .view(carRight)
                .bbox(BoundingShape.box(carLeft.getWidth() * 2, carLeft.getHeight()))
                .build();
    }

    // 创建FatCar实体
    @Spawns("FatCar")
    public Entity newFatCar(SpawnData data) {
        Texture leftCar = FXGL.texture("fat_car.png");
        Texture rightCar = leftCar.copy();
        rightCar.setScaleX(-1);
        rightCar.setTranslateX(leftCar.getWidth());
        return FXGL.entityBuilder(data)
                .view(leftCar)
                .view(rightCar)
                .bbox(BoundingShape.box(leftCar.getWidth() * 2, leftCar.getHeight()))
                .build();
    }

    // 创建Boom实体
    @Spawns("Boom")
    public Entity newBoom(SpawnData data) {
        AnimationChannel animationChannel = new AnimationChannel(FXGL.image("Boom.png"),
                Duration.seconds(2),
                13);
        AnimatedTexture animatedTexture = new AnimatedTexture(animationChannel);
        animatedTexture.play();
        return FXGL.entityBuilder(data)
                .view(animatedTexture)
                .with(new ExpireCleanComponent(Duration.seconds(2.5)))
                .build();
    }

    // 创建Warrior实体
    @Spawns("Warrior")
    public Entity newWarrior(SpawnData data) {
        AnimationChannel animationChannel = new AnimationChannel(FXGL.image("warrior.png"),
                4, 32, 48, Duration.seconds(0.8), 0, 3);
        AnimatedTexture animatedTexture = new AnimatedTexture(animationChannel);
        animatedTexture.loop();
        return FXGL.entityBuilder(data)
                .view(animatedTexture)
                .build();
    }

    // 创建Tank实体并应用随机颜色
    @Spawns("Tank")
    public Entity newTank(SpawnData data) {
        // 加载Tank纹理
        Texture tank = FXGL.texture("Tank.png", 100, 100);
        
        // 应用随机颜色
        Texture tank1 = tank.multiplyColor(FXGLMath.randomColor()).brighter();
        
        return FXGL.entityBuilder(data)
                .view(tank1)  // 将随机颜色应用到Tank实体
                .build();
    }
}

newTank()方法中,我们通过FXGLMath.randomColor()生成一个随机颜色,并使用multiplyColor()方法将其应用到Tank的纹理上。为了让颜色更加鲜亮,调用了brighter()方法。

3.生成随机位置的实体

我们通过spawn()方法生成多个Tank实体,并让它们随机出现在屏幕上的不同位置。通过FXGLMath.randomPoint()方法生成一个随机坐标,使得每次生成的坦克的位置不同。

package com.alatus.game;

import com.almasb.fxgl.app.GameApplication;
import com.almasb.fxgl.app.GameSettings;
import com.almasb.fxgl.core.math.FXGLMath;
import com.almasb.fxgl.entity.SpawnData;
import javafx.geometry.Rectangle2D;

import static com.almasb.fxgl.dsl.FXGL.*;

public class ImageGame extends GameApplication {

    @Override
    protected void initSettings(GameSettings gameSettings) {
        // 设置游戏窗口大小等
    }

    @Override
    protected void initGame() {
        // 向游戏世界添加实体工厂
        getGameWorld().addEntityFactory(new ImageEntityFactory());
        
        // 创建不同的实体
        spawn("Car", new SpawnData(100, 100));
        spawn("FatCar", new SpawnData(350, 350));
        spawn("Boom", new SpawnData(200, 200));
        spawn("Warrior", new SpawnData(300, 300));
        
        // 随机生成5个Tank实体
        for (int i = 0; i < 5; i++) {
            spawn("Tank", FXGLMath.randomPoint(
                    new Rectangle2D(0, 0, 500, 500)  // 随机生成位置
            ));
        }
    }

    public static void main(String[] args) {
        launch(args);  // 启动游戏
    }
}

initGame()方法中,我们使用了spawn("Tank", FXGLMath.randomPoint(new Rectangle2D(0, 0, 500, 500)))来随机生成5个坦克,每个坦克都有一个随机的颜色和随机的生成位置。

4.总结

通过以上代码,我们已经在FXGL引擎中实现了随机改变Texture颜色的功能。通过FXGLMath.randomColor()生成随机颜色并应用到实体的纹理上,我们能够为每个实体带来独特的视觉效果,增加了游戏世界的多样性和趣味性。

这种方式不仅适用于简单的图像变换,还可以用于生成具有不同外观的敌人、道具等,提供更多的视觉变化和随机性。

完整代码示例

package com.alatus.game;

import com.almasb.fxgl.core.math.FXGLMath;
import com.almasb.fxgl.dsl.FXGL;
import com.almasb.fxgl.dsl.components.ExpireCleanComponent;
import com.almasb.fxgl.entity.Entity;
import com.almasb.fxgl.entity.EntityFactory;
import com.almasb.fxgl.entity.SpawnData;
import com.almasb.fxgl.entity.Spawns;
import com.almasb.fxgl.physics.BoundingShape;
import com.almasb.fxgl.texture.AnimatedTexture;
import com.almasb.fxgl.texture.AnimationChannel;
import com.almasb.fxgl.texture.Texture;
import javafx.util.Duration;

public class ImageEntityFactory implements EntityFactory {
    @Spawns("Car")
    public Entity newCar(SpawnData data){
//        一般就是在这里读取图片的时候就设置一波像素大小,节省内存,而且后面也不用缩放那么麻烦
        Texture carLeft = FXGL.texture("car.png");
        Texture carRight = carLeft.copy();
//        翻转-1就是水平镜像翻转,虽然我不懂原理
        carRight.setScaleX(-1);
        carRight.setTranslateX(carLeft.getWidth());
        return FXGL.entityBuilder(data)
                .view(carLeft)
                .view(carRight)
                .bbox(BoundingShape.box(carLeft.getWidth()*2,carLeft.getHeight()))
                .build();
    }
    @Spawns("FatCar")
    public Entity newFatCar(SpawnData data){
        Texture leftCar = FXGL.texture("fat_car.png");
        Texture rightCar = leftCar.copy();
        rightCar.setScaleX(-1);
        rightCar.setTranslateX(leftCar.getWidth());
        return FXGL.entityBuilder(data)
                .view(leftCar)
                .view(rightCar)
                .bbox(BoundingShape.box(leftCar.getWidth()*2,leftCar.getHeight()))
                .build();
    }
    @Spawns("Boom")
    public Entity newBoom(SpawnData data){
        AnimationChannel animationChannel = new AnimationChannel(FXGL.image("Boom.png"),
                Duration.seconds(2),
                13);
        AnimatedTexture animatedTexture = new AnimatedTexture(animationChannel);
        animatedTexture.play();
        return FXGL.entityBuilder(data)
                .view(animatedTexture)
                .with(new ExpireCleanComponent(Duration.seconds(2.5)))
                .build();
    }
    @Spawns("Warrior")
    public Entity newWarrior(SpawnData data){
        AnimationChannel animationChannel = new AnimationChannel(FXGL.image("warrior.png"),
                4,32,48,Duration.seconds(0.8),0,3);
        AnimatedTexture animatedTexture = new AnimatedTexture(animationChannel);
        animatedTexture.loop();
        return FXGL.entityBuilder(data)
                .view(animatedTexture)
                .build();
    }
    @Spawns("Tank")
    public Entity newTank(SpawnData data){
        Texture tank = FXGL.texture("Tank.png", 100, 100);
        Texture tank1 = tank.multiplyColor(FXGLMath.randomColor()).brighter();
        return FXGL.entityBuilder(data)
                .view(tank1)
                .build();
    }
}
package com.alatus.game;

import com.almasb.fxgl.app.GameApplication;
import com.almasb.fxgl.app.GameSettings;
import com.almasb.fxgl.core.math.FXGLMath;
import com.almasb.fxgl.entity.SpawnData;
import javafx.geometry.Rectangle2D;

import static com.almasb.fxgl.dsl.FXGL.*;

public class ImageGame extends GameApplication {

    @Override
    protected void initSettings(GameSettings gameSettings) {

    }

    @Override
    protected void initGame() {
        getGameWorld().addEntityFactory(new ImageEntityFactory());
        spawn("Car",new SpawnData(100,100));
        spawn("FatCar",new SpawnData(350,350));
        spawn("Boom",new SpawnData(200,200));
        spawn("Warrior",new SpawnData(300,300));
        for (int i = 0; i < 5; i++) {
            spawn("Tank", FXGLMath.randomPoint(
                    new Rectangle2D(0,0,500,500)
            ));
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言