Upgrade to Pro — share decks privately, control downloads, hide ads and more …

よくわかんないけど最近つくってるゲームで RxJava つかってみてる

よくわかんないけど最近つくってるゲームで RxJava つかってみてる

社内RxJava勉強会で発表した時の資料です。

0e463e4432ba6d9b7ef02dbebe99c70d?s=128

Tomohiro Moro

March 18, 2015
Tweet

Transcript

  1. Α͘Θ͔Μͳ͍͚Ͳ ࠷ۙͭͬͯ͘ΔήʔϜͰ RxJava ͔ͭͬͯΈͯΔ RxJavaษڧձ 2015.3.17 @slightair

  2. ※ Android ͷ࿩͸ग़·ͤΜ

  3. ήʔϜͭͬͯ͘·͢

  4. ͜Μͳ΍ͭ

  5. None
  6. ஍໘͕ྲྀΕͯ͘Δ ϑϦοΫͰࠨӈʹಈ͘ λοϓ͢ΔͱͭͿΕΔ ͸ͳ͢ͱδϟϯϓ͢Δ Ωϟϥʹ߹Θͤͯ Χϝϥ͕ಈ͘

  7. LibGDX + RxJava

  8. 1. Input

  9. ೖྗΠϕϯτ • touchDown -> δϟϯϓ४උ • tap -> δϟϯϓ •

    fling -> ࠨӈҠಈ • panStop -> δϟϯϓΩϟϯηϧ
  10. GameMaster Input Character ը໘͕ λοϓ͞ΕͨΜ͕ͩ ͪΐͬͱ δϟϯϓͯ͠ΈΖ

  11. GameMaster Input Character ը໘͕ λοϓ͞ΕͨΜ͕ͩ ͪΐͬͱ δϟϯϓͯ͠ΈΖ

  12. GameMaster Input Character ήʔϜʹؔ܎ͦ͠͏ͳ Πϕϯτ؂ࢹ͠·͢ ͍ͭδϟϯϓ͢Ε͹͍͍͔ ؂ࢹ͠·͢ ͍ͬͯ͏͔Πϕϯτ શ෦؂ࢹͤͯ͞ observable͘Ε

    observable͘Ε
  13. // Input PublishSubject<GameMaster.Action> subject = PublishSubject.create(); ! @Override public boolean

    touchDown(float x, float y, int pointer, int button) { subject.onNext(GameMaster.Action.CHARACTER_PREPARE_JUM return false; } ! @Override public boolean tap(float x, float y, int count, int button) { subject.onNext(GameMaster.Action.CHARACTER_JUMP); return false; } ! … ! public Observable<GameMaster.Action> getActions() {return subject;}
  14. // GameMaster public enum Action { CHARACTER_MOVE_LEFT, CHARACTER_MOVE_RIG ! public

    GameMaster(Observable<Action> input) { this.input = input; this.character = new Character(input); … ! // Character public enum Action { MOVE_LEFT, MOVE_RIGHT, JUMP, … } public Character(Observable<GameMaster.Action> input) { this.input = input; } ! public Observable<Action> getActions() { return input.map(new ActionConverter()); } !
  15. // Character private class ActionConverter implements Func1<GameMaster.Action, Action> { !

    @Override public Action call(GameMaster.Action action) { Action result = null; switch (action) { case CHARACTER_MOVE_LEFT: result = Action.MOVE_LEFT; break; case CHARACTER_MOVE_RIGHT: result = Action.MOVE_RIGHT; break; case CHARACTER_PREPARE_JUMP: result = Action.PREPARE_JUMP; break; … } return result; }
  16. 2. Character ModelInstance

  17. Model Instance • LibGDX (3D) Ͱඳը͢ΔϞσϧΛ දݱ͢ΔΫϥε • xyz࠲ඪ ճస

    εέʔϧ ͳͲΛࢦఆ͢Δ • ύϥϝʔλΛม͑ΔΞχϝʔγϣϯΛ࣮ߦ͢Δ
  18. ҠಈͱΞχϝʔγϣϯ • δϟϯϓ४උ -> ্͔Βԡ͞ΕͨΑ͏ʹͭͿΕΔ • δϟϯϓ -> ͭͿΕΛ໭্ͭͭ͠ԼҠಈ •

    ࠨӈҠಈ -> ࠨӈʹඳըҐஔΛҠಈ • δϟϯϓΩϟϯηϧ -> ͭͿΕΛ໭͢
  19. Character CharacterModelInstance getActions() Observable<Character.Action> ΩϟϥΫλʔʹى͖ͨ ΞΫγϣϯΛ؂ࢹ

  20. // CharacterModelInstance public CharacterModelInstance(Model model, Character character) { super(model); …

    character.getActions().subscribe(new Action1<Character.Action>() { @Override public void call(Character.Action action) { switch (action) { case MOVE_LEFT: transform.translate(GroundBlockModel.SIZE, 0.0f, 0.0f); break; case MOVE_RIGHT: transform.translate(-GroundBlockModel.SIZE, 0.0f, 0.0f); break; case PREPARE_JUMP: animationController.animate("shrink", 0.0f); break; …
  21. 3. Camera

  22. ΧϝϥͷҠಈ • ΩϟϥΫλʔʹ߹Θͤͯಈ͘ • ඍົʹΞχϝʔγϣϯೖͬͯΔ • Exponential Ease Out •

    TweenEngine Ͱ࣮૷
  23. Character CameraMan getActions() Observable<Character.Action> ΩϟϥΫλʔʹى͖ͨ ΞΫγϣϯΛ؂ࢹ

  24. // CameraMan public CameraMan(final OrthographicCamera camera, Character character) { this.camera

    = camera; this.character = character; character.getActions().subscribe(new Action1<Character.Action>() { @Override public void call(Character.Action action) { switch (action) { case MOVE_LEFT: Tween.to(camera, CameraTween.POSITION_X, cameraMoveDuration) .targetRelative(-GroundBlockModel.SIZE) .ease(TweenEquations.easeOutExpo) .start(tweenManager); break; …
  25. 4. Ground Blocks

  26. ஍໘ϒϩοΫ • ԞʹϒϩοΫΛൃੜͤ͞Δ • खલʹྲྀΕͯ͘Δ • खલͷϥΠϯ͕ফ͑ͯ͘ • ͜Εͷ܁Γฦ͠ •

    ήʔϜϧʔϓͰGameMasterͷupdate() Λఆظతʹୟ͍ͯϒϩοΫੜ੒
  27. 0.12 0.32 0.10 0.21 update update update update

  28. 0.12 0.32 0.14 0.21 update update update update 0.12 0.44

    0.58 0.79 Observable<Float> timeline = updates.scan((t1, t2) -> return t1 + t2);
  29. // GameMaster private PublishSubject<Action> actions = PublishSubject.create(); public GameMaster(Observable<Action> input)

    { this.input = input; this.character = new Character(input); this.groundGenerator = new GroundGenerator(); this.groundLineEmitter = new GroundLineEmitter(timeline, GROUND_LINE_SPAWN_INTERVAL); actions .mergeWith(input) .mergeWith(groundLineEmitter.getEmits()) .subscribe(new ActionProcessor());
  30. 0.12 0.44 0.58 0.79 timeline emits.onNext(Action.GROUND_SPAWN_NEW_LINE); GroundLineEmitter ActionProcessor GroundGenerator#next()

  31. Ground Generator Ground Ground Layouter Ground Line #MPDL #MPDL #MPDL

    #MPDL *OTUBODF #MPDL *OTUBODF #MPDL *OTUBODF getNewLines() putLine(line) Layout next()
  32. None