网站首页 > 技术文章 正文
在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);
}
}
猜你喜欢
- 2025-05-21 BIOS中英文对照表
- 2025-05-21 微软 Edge 92 版浏览器默认禁止媒体自动播放
- 2025-05-21 China Launches First Space-Based Large AI Model, Surpassing Global Rivals in Satellite Intelligence
- 2025-05-21 【报纸词汇】fizzical → physical
- 2025-05-21 每日一词:rudimentary
- 2025-05-21 上厕所别带手机!9 个错误动作增加你感染病毒的风险
- 2025-05-21 FXGL引擎图片音频资源的缓存和爆炸图效果优化-----FXGL
- 2025-05-21 FXGL引擎序列帧与图片组件使用创建动画对象和汽车对象-----FXGL
- 2025-05-21 Android通用Dialog的封装
- 2024-07-25 告白文案:遇见你,流星我都不觉得璀璨
- 05-27Python进阶 - day1:深入理解数据结构
- 05-27Java中transient字段的作用
- 05-27深度学习数据集处理常用函数示例(Python)
- 05-27Go语言-指针
- 05-27什么是 happens-before 规则?
- 05-27「Java」一张图教会你关于null的几种处理方式(内附代码)
- 05-27Python 中常用的数据结构,帮助你从基础到精通
- 05-271、数值类型
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- sqlset (64)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)