@Override public void tick(int tick) { final J2hGame game = Game.getGame(); final Player player = game.getPlayer(); final Boss boss = (Boss) getOwner(); if (tick % 500 == 0) { Texture sparkTexture = Loader.texture(Gdx.files.internal("enemy/sleepyyuuka/laser.png")); sparkTexture.setFilter(TextureFilter.MipMapLinearNearest, TextureFilter.Nearest); HitboxSprite sprite = new HitboxSprite(new Sprite(sparkTexture)); sprite.setScale(4f, 4f); sprite.setHitbox( HitboxUtil.makeHitboxFromSprite( new TextureRegion(sparkTexture), HitboxUtil.StandardBulletSpecification.get())); sprite.setOrigin(0, sprite.getHeight() / 2f); sprite.getHitbox().setOrigin(0, sprite.getHitbox().getBoundingRectangle().height / 2f); sprite.getHitbox().rotate(180f); sprite.setHitboxScaleOffsetModifierX(1f); sprite.setHitboxScaleOffsetModifierY(0.7f); Animation ani = new Animation(1f, sprite); Spark spark = new Spark(ani, boss.getX(), boss.getY()) { @Override public void onUpdate(long tick) { super.onUpdate(tick); if (getTicksAlive() > 400) Game.getGame().delete(this); setRotationDeg(getTicksAlive()); } }; Game.getGame().spawn(spark); } }
{ final DeveloperMenu screen = this; final J2hGame game = Game.getGame(); final float startX = game.getMinX() + (game.getMaxX() - game.getMinX()) / 2; final float startY = Game.getGame().getHeight() - 150; addButton( "3D Background tester", new Runnable() { @Override public void run() { final Runnable run = new Runnable() { @Override public void run() { Game.getGame().spawn(new MoonBG()); } }; Getter getter = new Getter<TestScheme>() { @Override public TestScheme get() { return new TestScheme() { @Override public GameFlowScheme getRestartInstance() { return get(); } @Override public void startSpellcard() { run.run(); } }; } }; Game.getGame().setScheme((GameFlowScheme) getter.get()); Game.getGame().getScheme().start(); } }); final Getter<SpecialFlowScheme> getter = new Getter<SpecialFlowScheme>() { @Override public SpecialFlowScheme get() { DialogueFlowScheme holder = new DialogueFlowScheme( new Getter<FaceToFaceDialogue>() { @Override public FaceToFaceDialogue get() { final DDCDialogueTextBalloon balloon = new DDCDialogueTextBalloon(); final DialogueParticipant left = new MarisaDP(); final DialogueParticipant right = new MarisaDP(); final FaceToFaceDialogue d = new FaceToFaceDialogue(balloon, left, right); String ipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur a luctus risus, vel fringilla metus. Nunc commodo dui sed lectus viverra, in tincidunt felis tincidunt. Mauris metus ex, bibendum et nulla eu, pharetra iaculis arcu. Curabitur at malesuada libero, non bibendum tellus. Maecenas non luctus est. Suspendisse id lectus nisi. Donec pharetra orci ultrices, aliquam magna quis, iaculis lorem. Sed imperdiet feugiat pretium. In fringilla diam magna, vulputate dignissim lectus hendrerit eget. Suspendisse potenti. Nulla sit amet nisi vitae mi pharetra volutpat. Sed erat quam, rhoncus id elit id, sollicitudin laoreet purus. Donec sodales eleifend ex, a interdum elit consequat non. Maecenas nibh tellus, commodo sed risus eu, imperdiet commodo dui. Nam id mollis leo, vitae congue eros. Phasellus eget libero at eros laoreet commodo nec in eros."; String[] array = ipsum.split("\\. "); DialogueMaker m = new DialogueMaker(left); m.text("Hey, I'm about to say something really long and boring") .enterStage() .nextDialogue(right); m.text("k, ignored you anyways.") .face(MarisaDPFace.SIGH) .enterStage() .nextDialogue(left); for (int i = 0; i < array.length - 2; i += 2) { String str = array[i] + "\n" + array[i + 1]; m.text(str).face(MarisaDPFace.CONFUSED).nextDialogue(right); String[] replies = { "Very nice...", "Alright.", "Interesting...", "Good for you.", "Uhu", "Sooooo innnnteerreeessstttinnggg... -ZZZZ-" }; m.text(replies[(int) (Math.random() * replies.length)]) .face(MarisaDPFace.SIGH) .nextDialogue(left); } m.text("Remember to take it easy!") .face(MarisaDPFace.YUKKURI) .speechBubbleType(DDCBalloonType.SCREAM) .nextDialogue(right); m.text("What was that!?").face(MarisaDPFace.IDIOCY); d.addDialogue(m.getDialogue()); return d; } }); return holder; } }; addButton( "Simple Dialogue between 2xMarisa", new Runnable() { @Override public void run() { Getter<GameFlowScheme> schemeGetter = new Getter<GameFlowScheme>() { @Override public GameFlowScheme get() { return new GameFlowScheme() { @Override public GameFlowScheme getRestartInstance() { return get(); } @Override public void runScheme() { getter.get().executeFight(this); } }; } }; Game.getGame().setScheme(schemeGetter.get()); Game.getGame().getScheme().start(); } }); TextBounds bound = botFont.getBounds("Exit"); getButtonManager() .addButton( new ShadowedTextButton( Game.getGame().getWidth() / 2 - bound.width / 2, 100, botFont, "Exit", new Runnable() { @Override public void run() { TouhouSounds.Hud.OK.play(); Game.getGame().delete(screen); } }) { { setFont(botFont); } }); setZIndex(J2hGame.GUI_Z_ORDER + 2); }
@Override public void tick(int tick, J2hGame game, final Ringo boss) { final Player player = game.getPlayer(); if (tick == 60) { boss.playSpecial(true); BossUtil.charge(boss, boss.getAuraColor(), false); TouhouSounds.Enemy.ACTIVATE_3.play(); } if (tick == 100) boss.playSpecial(false); if (tick < 100) { return; } tick -= 100; if (tick % 50 == 0) { for (final boolean bool : new boolean[] {true, false}) { Bullet bullet = ThBullet.makeBullet(ThBulletType.BALL_BIG, ThBulletColor.PURPLE, boss); bullet.setScale(0.2f, 4f); final float finalAngle = MathUtil.getAngle(bullet, player) + ((bool ? 1f : -1f) * 60f); final float finalRad = (float) Math.toRadians(finalAngle); bullet.setDirectionDeg(finalAngle, 300f); bullet.setRotationFromVelocity(); // bullet.getSpawnAnimation().setAlpha(-0.5f); // bullet.getSpawnAnimation().setTime(60); // bullet.getSpawnAnimation().setAddedScale(0f); bullet.useSpawnAnimation(false); bullet.setGlowing(); bullet.addEffect( new Plugin<Bullet>() { private ZIndexHelper indexer = new ZIndexHelper(); @Override public void update(Bullet object, long tick) { if (object.getTicksAlive() < 12) return; tick = object.getTicksAlive() - 12; final float mul = -(1f * (Math.min(object.getTicksAlive() - 30, 200f) / 200f)); if (tick % 6 == 0 && tick % (10 * 6) <= (4 * 6)) { TouhouSounds.Enemy.RELEASE_1.play(0.1f); final int returnTime = 200; final Bullet bullet = new Bullet( new ThBullet(ThBulletType.BALL_BIG, ThBulletColor.WHITE), (float) (object.getX() - (Math.cos(finalRad) * 140)), (float) (object.getY() - (Math.sin(finalRad) * 140))) { @Override public void checkCollision() { if (getTicksAlive() > returnTime) { return; } super.checkCollision(); }; }; // bullet.useSpawnAnimation(false); bullet.addEffect( new Plugin<Bullet>() { @Override public void update(Bullet object, long tick) { float speed = 300f + -200f * (mul); if (object.getTicksAlive() < 40) { speed = 0f; } if (object.getTicksAlive() > returnTime) { Position mouth = new Position(boss).add(new Position(0, 35f)); bullet.setDirectionDeg(MathUtil.getAngle(bullet, mouth), 500f); double dist = MathUtil.getDistance(bullet, mouth); float mul = (float) (dist < 20 ? (dist / 20f) : 1f); bullet.setScale(0.4f * mul); bullet.getCurrentSprite().setAlpha(0.5f); bullet.useDeathAnimation(false); bullet.useSpawnAnimation(false); if (dist < 2) { game.delete(object); } } else { bullet.setDirectionDeg( finalAngle + ((bool ? 0.12f : -0.12f) * (object.getTicksAlive())) + (((bool ? -90f : 90f))), speed); } } }); indexer.index(bullet); game.spawn(bullet); } } }); game.spawn(bullet); } } if (tick % 14 == 0) { Bullet bullet = ThBullet.makeBullet(ThBulletType.BALL_BIG, ThBulletColor.BLUE, boss); bullet.setDirectionDeg(MathUtil.getAngle(bullet, player), 400f); bullet.setGlowing(); game.spawn(bullet); } if (tick % 200 == 0) { boss.getPathing().path(new SimpleTouhouBossPath(boss)); } }
static { final J2hGame game = Game.getGame(); final float startX = game.getMinX() + (game.getMaxX() - game.getMinX()) / 2; final float startY = Game.getGame().getHeight() - 150; final float startHP = 100f; int day = 1; EnvironmentType type = EnvironmentType.MIST_LAKE; // Day 1 { // Mist lake addCharacter( day, type, "Wakasagihime", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Wakasagihime boss = new Wakasagihime(startHP, startX, startY); return boss; } }); addCharacter( day, type, "Cirno", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Cirno boss = new Cirno(startHP, startX, startY); return boss; } }); // Letty // Three Faries // Hong Meiling type = EnvironmentType.DREAM_DIM; // Dream Dimension: (People who can't use danmaku can here!) // Maribel & Renko // Heida no Akyu // Rinnosuke addCharacter( day, type, Doremy.FULL_NAME, new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Doremy boss = new Doremy(startHP, startX, startY); return boss; } }); } day++; type = EnvironmentType.BAMBOO; // Day 2 { // Bamboo forest // Rumia // Wriggle // Mystia // Keine addCharacter( day, type, "Kagerou Imaizumi", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Kagerou boss = new Kagerou(startHP, startX, startY); return boss; } }); // Tewi addCharacter( day, type, "Fujiwara No Mokou", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { return new Mokou(startHP, startX, startY); } }); } day++; type = EnvironmentType.UNDERGROUND_CITY; // Day 3 { // Underground City: // Kisume // Yamame // Parsee // Satori // Yuugi // Rin // Utusho // Suika // Koishi } day++; type = EnvironmentType.YOUKAI_MOUNTAIN; // Day 4 { // Youkai Mountain: // Aki Sisters // Hina // Nitori // Momiji // Hatate // Aya // Sanae // Kanako & Suwako } day++; type = EnvironmentType.ABOVE_THE_CLOUDS; // Day 5 { // Above the clouds: addCharacter( day, type, "Seiran", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Seiran boss = new Seiran(startHP, startX, startY); return boss; } }); // Kogasa // Nazrin // Lily White // Ichirin // Murusa // Prismriver Sisters addCharacter( day, type, Iku.FULL_NAME, new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Iku boss = new Iku(startHP, startX, startY); return boss; } }); // Nue addCharacter( day, type, Tenshi.FULL_NAME, new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Tenshi boss = new Tenshi(startHP, startX, startY); return boss; } }); } day++; type = EnvironmentType.CEMETRY_ROAD; // Day 6 { // Cemetry road: // Kyouko addCharacter( day, type, "Sekibanki", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { return new Sekibanki(startHP, startX, startY); } }); // Seiga & Zombie // Tojiko // Youmu // Monobe no Futo // Yuyuko // Miko } day++; type = EnvironmentType.THUNDER_CLOUDS; // Day 7 { // Thundering clouds: addSpecial( day, type, "Yatsuhashi & Benben Tsukumo", new Getter<SpecialFlowScheme>() { @Override public SpecialFlowScheme get() { final TsukumoGeneral boss = new TsukumoGeneral(); return boss; } }); addCharacter( day, type, "Seija Kijin", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Seija boss = Seija.newInstance(startX, startY); return boss; } }); addCharacter( day, type, "Sukuna Shinmyoumaru", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Sukuna boss = new Sukuna(startHP, startX, startY); return boss; } }); addCharacter( day, type, "Raiko Horikawa", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Raiko boss = Raiko.newInstance(startX, startY); return boss; } }); type = EnvironmentType.MOON; // The Moon: addCharacter( day, type, "Ringo", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Ringo boss = new Ringo(startHP, startX, startY); return boss; } }); // Rei'sen (Reisen 2) // Reisen // Watatsuki's // Eirin // Kaguya } day++; type = EnvironmentType.MAKAI; // Day 8 { addSpecial( day, EnvironmentType.MAKAI_STAGE, "Stage", new Getter<SpecialFlowScheme>() { @Override public SpecialFlowScheme get() { final MakaiStage stage = new MakaiStage(); return stage; } }); addSpecial( day, type, "Mai & Yuki", new Getter<SpecialFlowScheme>() { @Override public SpecialFlowScheme get() { final MaiYukiGeneral boss = new MaiYukiGeneral(startX, startY); return boss; } }); addCharacter( day, type, "Shou Toramaru", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Shou shou = Shou.newInstance(startX, startY); return shou; } }); addCharacter( day, type, "Yumeko", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Yumeko yumeko = Yumeko.newInstance(startX, startY); return yumeko; } }); addSpecial( day, type, "Alice Margatroid", new Getter<SpecialFlowScheme>() { @Override public SpecialFlowScheme get() { final AliceGeneral boss = new AliceGeneral(startX, startY); return boss; } }); addCharacter( day, type, "Byakuren Hijiri", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Byakuren byakuren = Byakuren.newInstance(startX, startY); return byakuren; } }); addSpecial(day, type, "Dialogue", new Day7Dialogue()); addCharacter( day, type, "Shinki", new Getter<AllStarBoss>() { @Override public AllStarBoss get() { final Shinki shinki = Shinki.newInstance(startX, startY, false); return shinki; } }); addSpecial( day, type, "Gengetsu & Mugetsu", new Getter<SpecialFlowScheme>() { @Override public SpecialFlowScheme get() { final GetsusGeneral boss = new GetsusGeneral(); return boss; } }); type = EnvironmentType.SCARLET_DEVIL_MANSION; // SDM: // Patchouli // Sakuya // Remilia & Flandre } day++; type = EnvironmentType.FLOWER_FIELD; // Day 9 { // Flower field: // Medicine addSpecial( day, type, "Yuuka Kazami", new Getter<SpecialFlowScheme>() { @Override public SpecialFlowScheme get() { final YuukaGeneral boss = new YuukaGeneral(startX, startY); return boss; } }); // Komachi // Kasen Ibara // Chiyuri // Futatsuiwa // addCharacter(day, type, Yumemi.FULL_NAME, new Getter<AllStarBoss>() // { // @Override // public AllStarBoss get() // { // final Yumemi yumemi = new Yumemi(100f, startX, startY); // // return yumemi; // } // }); // Shiki Eiki } day++; type = EnvironmentType.HAKURAI; // Day 10 { // Hakurai Shrine/Border: // Ran & Chen // Sariel // Konngara // Marisa // Reimu // Yukari // Mima } }
@Override public void tick(int tick, J2hGame game, Ringo boss) { final Player player = game.getPlayer(); if (tick == 100) { boss.playSpecial(true); BossUtil.chargeExplosion(boss, boss.getAuraColor()); } if (tick < 130) { return; } final int COLOR_PERIOD = 400; tick -= 130; if (tick % 8 == 0) { TouhouSounds.Enemy.BULLET_1.play(0.3f); } if (tick % 6 == 0) { int amount = 30; for (int i = 0; i < amount; i++) { float angle = ((float) i / (float) amount) * 360; double mul = RNG.multiplierMirror(1000, tick); angle += (Math.sin(RNG.multiplier(200, tick) * Math.PI) * (50 + (200 * mul))); Bullet bullet = new Bullet( new ThBullet( ThBulletType.BALL_2, RNG.booleanMultiplier(COLOR_PERIOD, tick) ? ThBulletColor.BLUE : ThBulletColor.PURPLE), boss.getX(), boss.getY()); final float speed = 400f; bullet.setDirectionDeg(angle, speed * 2f); bullet.setZIndex(bullet.getZIndex() + i); bullet.addEffect( new Plugin<Bullet>() { @Override public void update(Bullet object, long tick) { if (object.getTicksAlive() == 15) { object.setDirectionDeg(object.getVelocityRotationDeg(), speed); } object.getCurrentSprite().rotate(2f); float mul = 1f; // Math.min(1, object.getTicksAlive() / 10f); object.setScale(mul); } }); bullet.useSpawnAnimation(false); bullet.setGlowing(); game.spawn(bullet); } } if (tick % 10 == 0) { int directions = 6; for (int i = 0; i < directions; i++) { float angle = ((float) i / (float) directions) * 360; ArrayList<Bullet> circle = circle(boss.getX(), boss.getY(), 2, 20); for (Bullet bullet : circle) { bullet.setDirectionDeg((float) (angle + (RNG.multiplier(600, tick)) * 360f), 300f); bullet.setBullet( ThBullet.make( ThBulletType.DOT_SMALL_MOON, RNG.booleanMultiplier(COLOR_PERIOD, tick) ? ThBulletColor.BLUE : ThBulletColor.PURPLE)); bullet.setGlowing(); } } } }