javafx+fxgl引擎做的一款飞机大战

先放效果图:

1,javafx和fxgl介绍

javafx类似awt,swing,是一个图形化界面的库。

(似乎都喜欢采用mvc模式,把界面和其它东西分开来写)

fxgl:https://almasb.github.io/FXGL/

外国人写的一个游戏引擎,其实就是把javafx的一些东西整理封装了起来,但封装也有坏处,,用起来不怎么灵活,网上也搜不到用法(。。还是作者提供的api文档我看不懂)。

导入jar包就能使用了。

2,fxgl里的一些东西分析

(1)还是要在主代码里继承一个类(fxgl的作者封装成了GameApplication),然后再main函数里调用launch(args);

(2)键盘输入

  fxgl的方法是重写父类的initInput函数,然后在理添加行为与对应键盘绑定就行了

1         getInput().addAction(new UserAction("Shoot") {
2             @Override
3             protected void onAction() {
4                 playerComponent.shoot();
5             }
6         }, MouseButton.PRIMARY);

(3)实体机制

将游戏里的元素(玩家,子弹,敌人,爆炸效果等)都看成一个实体加上不同的组件,也就是先建立一个实体,然后往里面加组件,或者配置外观等

        return Entities.builder()
                .type(SpaceRunnerType.PLAYER)
                .from(data)
                .viewFromNodeWithBBox(FXGL.getAssetLoader().loadTexture("sprite_player.png", 40, 40))
                .with(new CollidableComponent(true), new ParticleComponent(emitter))
                .with(new PlayerComponent())
                .build();

(4)加载声音,图片等资源

这里需要按照规定,比如图片放于assets/textures中,在代码中则不需要设置文件路径。

还是直接放代码吧

  1 package hzh;
  2 
  3 import com.almasb.fxgl.animation.Animation;
  4 import com.almasb.fxgl.animation.Interpolators;
  5 import com.almasb.fxgl.app.GameApplication;
  6 import com.almasb.fxgl.core.math.FXGLMath;
  7 import com.almasb.fxgl.entity.Entity;
  8 
  9 import com.almasb.fxgl.entity.SpawnData;
 10 import com.almasb.fxgl.entity.view.ScrollingBackgroundView;
 11 import com.almasb.fxgl.extra.entity.components.HealthComponent;
 12 import com.almasb.fxgl.input.UserAction;
 13 import com.almasb.fxgl.settings.GameSettings;
 14 import com.almasb.fxgl.texture.Texture;
 15 import com.almasb.fxgl.ui.ProgressBar;
 16 
 17 import hzh.collision.BulletEnemyHandler;
 18 import hzh.collision.PlayerBulletHandler;
 19 import hzh.components.PlayerComponent;
 20 import hzh.level.Level;
 21 import javafx.beans.binding.Bindings;
 22 import javafx.geometry.HorizontalDirection;
 23 import javafx.geometry.Orientation;
 24 import javafx.geometry.Point2D;
 25 import javafx.scene.effect.DropShadow;
 26 import javafx.scene.input.KeyCode;
 27 import javafx.scene.input.MouseButton;
 28 import javafx.scene.layout.HBox;
 29 import javafx.scene.layout.Pane;
 30 import javafx.scene.layout.VBox;
 31 import javafx.scene.paint.Color;
 32 import javafx.scene.shape.Rectangle;
 33 import javafx.scene.text.Text;
 34 import javafx.util.Duration;
 35 import static com.almasb.fxgl.app.DSLKt.*;
 36 import java.util.Map;
 37 
 38 
 39 
 40 
 41 public class SpaceRunnerApp extends GameApplication {
 42 
 43     private PlayerComponent playerComponent;
 44     private Level level;
 45     private Texture weaponTexture;
 46     private Text bullets;
 47     private Text uiTextLevel;
 48 
 49     /**
 50      * 初始化舞台(窗口)
 51      */
 52     @Override
 53     protected void initSettings(GameSettings settings) {
 54         
 55         settings.setTitle("太空大战");
 56         settings.setWidth(1000);
 57         settings.setHeight(700);
 58 
 59     }
 60     /**
 61      * 预设置  
 62      */
 63     @Override
 64     protected void preInit() {
 65         loopBGM("bgm.mp3");
 66     }
 67     /**
 68      * 初始化输入
 69      */
 70     @Override
 71     protected void initInput() {
 72         getInput().addAction(new UserAction("Move Up") {
 73             @Override
 74             protected void onAction() {
 75                 playerComponent.up();
 76             }
 77         }, KeyCode.W);
 78 
 79         getInput().addAction(new UserAction("Move Down") {
 80             @Override
 81             protected void onAction() {
 82                 playerComponent.down();
 83             }
 84         }, KeyCode.S);
 85 
 86         getInput().addAction(new UserAction("Change Weapon") {
 87             @Override
 88             protected void onAction() {
 89                 playerComponent.changeWeapon();
 90 
 91                 weaponTexture.setImage(image("sprite_laser.png"));
 92                 bullets.textProperty().bind(getip("laser").asString("x %d"));
 93 
 94             }
 95         }, KeyCode.F);
 96 
 97         getInput().addAction(new UserAction("Shoot") {
 98             @Override
 99             protected void onAction() {
100                 playerComponent.shoot();
101             }
102         }, MouseButton.PRIMARY);
103     }
104     /**
105      * 建立map表
106      */
107     @Override
108     protected void initGameVars(Map<String, Object> vars) {
109         vars.put("score", 0);
110         vars.put("bullets", 999);
111         vars.put("laser", 50);
112         vars.put("rockets", 10);
113         vars.put("HP", 100);
114         vars.put("MP", 0);
115         vars.put("leveltype", 0);
116         vars.put("enemies", 5);
117     }
118     /**
119      * 初始化游戏元素
120      */
121     @Override
122     protected void initGame() {
123 
124 
125         getGameWorld().addEntityFactory(new SpaceRunnerFactory());
126         //设置背景,并且以卷动式铺满
127         Texture t = getAssetLoader().loadTexture("bg_0.png");
128 
129         getGameScene().addGameView(new ScrollingBackgroundView(t.superTexture(t, HorizontalDirection.RIGHT),
130                 Orientation.HORIZONTAL));
131 
132         Entity player = getGameWorld().spawn("Player", 180, getHeight() / 2);
133 
134         playerComponent = player.getComponent(PlayerComponent.class);
135         //设置视口,并与玩家绑定
136         getGameScene().getViewport().setBounds(0, 0, Integer.MAX_VALUE, getHeight());
137         getGameScene().getViewport().bindToEntity(player, 180, getHeight() / 2);
138 
139         nextLevel();
140 
141     }
142     /**
143      * 初始化物理环境(比如碰撞)
144      */
145     @Override
146     protected void initPhysics() {
147         getPhysicsWorld().addCollisionHandler(new BulletEnemyHandler());
148         getPhysicsWorld().addCollisionHandler(new PlayerBulletHandler());
149 
150     }
151 
152    /**
153     * 初始化ui
154     */
155     @Override
156     protected void initUI() {
157         //子弹框
158         weaponTexture = texture("sprite_bullet.png", 22, 11);
159 
160         bullets = getUIFactory().newText("", Color.rgb(20, 20, 20), 16);
161         bullets.textProperty().bind(getip("bullets").asString("x %d")); //属性绑定
162 
163         HBox ui = new HBox(15,  //水平框
164                 weaponTexture,
165                 bullets
166                 );
167 
168         Text laser = getUIFactory().newText("", Color.rgb(20, 20, 20), 16);
169         laser.textProperty().bind(getip("laser").asString("x %d"));
170 
171         HBox ui2 = new HBox(15,
172                 texture("sprite_laser.png"),
173                 laser
174         );
175 
176         Text rockets = getUIFactory().newText("", Color.rgb(20, 20, 20), 16);
177         rockets.textProperty().bind(getip("rockets").asString("x %d"));
178 
179         HBox ui3 = new HBox(15,
180                 texture("rocket.png", 30, 8),
181                 rockets
182         );
183 
184         VBox boxWeapons = new VBox(15, ui, ui2, ui3);
185         boxWeapons.setTranslateX(getWidth() - 150);
186         boxWeapons.setTranslateY(550);
187         boxWeapons.setScaleX(1.4);
188         boxWeapons.setScaleY(1.4);
189 
190         Texture uiBorder = texture("ui.png");
191         uiBorder.setTranslateY(getHeight() - uiBorder.getHeight());
192 
193         getGameScene().addUINode(uiBorder);
194         Text texthp = new Text("HP:");
195         ProgressBar barHP = new ProgressBar(false);
196         barHP.setHeight(30.0);
197         barHP.setLabelVisible(false);
198 
199 
200         barHP.setFill(Color.RED);
201         barHP.setBackgroundFill(Color.DARKGREY);
202         barHP.setTraceFill(Color.LIGHTGREEN);
203         barHP.currentValueProperty().bind(getip("HP"));
204         HBox hb1=new HBox(-10,texthp,barHP);
205 
206         // MP
207         Text textmp = new Text("MP:");
208         ProgressBar barMP = new ProgressBar(false);
209         barMP.setHeight(30.0);
210         barMP.setLabelVisible(false);
211 
212         barMP.setFill(Color.BLUE);
213         barMP.setBackgroundFill(Color.DARKGREY);
214         barMP.setTraceFill(Color.YELLOW);
215         barMP.currentValueProperty().bind(getip("MP"));
216         HBox hb2=new HBox(-10,textmp,barMP);
217 
218 
219         HBox bars = new HBox(50, hb1, hb2);
220         bars.setTranslateX(0);
221         bars.setTranslateY(520);
222 
223 
224         Text textScore = getUIFactory().newText("", Color.BLACK, 22);
225         textScore.setTranslateX(350);
226         textScore.setTranslateY(650);
227         textScore.textProperty().bind(getip("score").asString("Score: %d"));
228 
229         uiTextLevel = getUIFactory().newText("", Color.BLACK, 22);
230         uiTextLevel.setTranslateX(250);
231         uiTextLevel.setTranslateY(650);
232         uiTextLevel.textProperty().bind(getip("leveltype").asString("level: %d"));
233         uiTextLevel.setVisible(false);
234 
235 
236 
237         getGameScene().addUINodes(bars,  boxWeapons);
238         getGameScene().addUINodes(textScore);
239         getGameScene().addUINodes(uiTextLevel);
240         play("player_1.wav");
241 
242         runOnce(() -> play("begin.wav"), Duration.seconds(1));
243     }
244 
245     private void nextLevel() {
246         inc("leveltype", +1);
247         if(geti("leveltype")>3) inc("leveltype", -3);
248         level = new Level();
249 
250         level.spawnNewWave();
251 
252 
253         Text textLevel = getUIFactory().newText("", Color.WHITE, 22);
254         textLevel.setEffect(new DropShadow(7, Color.BLACK));
255         textLevel.setOpacity(0);
256         textLevel.textProperty().bind(getip("leveltype").asString("level: %d"));
257         centerText(textLevel);
258         textLevel.setTranslateY(250);
259 
260         getGameScene().addUINode(textLevel);
261 
262         Animation<?> anim = fadeIn(textLevel, Duration.seconds(1.66), () -> {
263             Animation<?> anim2 = translate(textLevel,
264                     new Point2D(textLevel.getTranslateX(), textLevel.getTranslateY()),
265                     new Point2D(350, 540),
266                     Duration.ZERO,
267                     Duration.seconds(1.66),
268                     () -> {
269                         getGameScene().removeUINode(textLevel);
270                         uiTextLevel.setVisible(true);
271                     });
272 
273             anim2.getAnimatedValue().setInterpolator(Interpolators.EXPONENTIAL.EASE_IN());
274             anim2.startInPlayState();
275         });
276 
277         anim.getAnimatedValue().setInterpolator(Interpolators.SMOOTH.EASE_OUT());
278 
279         anim.startInPlayState();
280     }
281 
282 
283 
284     public static void main(String[] args) {
285         launch(args);
286     }
287 }
View Code

然后上整个工程包:

原文地址:https://www.cnblogs.com/lnu161403214/p/9997004.html