zoukankan      html  css  js  c++  java
  • 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

    然后上整个工程包:

  • 相关阅读:
    剑指offer39-平衡二叉树
    剑指offer37-数字在排序数组中出现的次数
    剑指offer36-两个链表的第一个公共结点
    剑指offer31-整数中1出现的次数
    剑指offer30-连续子数组的最大和
    剑指offer28-数组中出现次数超过一半的数字
    剑指offer26-二叉搜索树与双向链表
    剑指offer21-栈的压入、弹出序列
    剑指offer16-合并两个排序的链表
    C#-杂碎
  • 原文地址:https://www.cnblogs.com/lnu161403214/p/9997004.html
Copyright © 2011-2022 走看看