interface Stage { void init(); boolean won(); boolean lost(); String name(); } abstract class SortingLevel extends TimedLevel { final int timeToStaySorted; // in seconds int sortedFrom; ArrayList toSort; boolean isSorted = false; Countdown count; SortingLevel(int timeToStaySorted) { this.timeToStaySorted = timeToStaySorted; } void init() { super.init(); lossReason = "You ran out of time."; duration = 30000; (new Countdown("Time remaining: ", millis(), 30, (arenaWidth - leftBorder - rightBorder) / 2.0, (mouseMaxY + arenaHeight) / 2.0, 2)).addToLevel(); toSort = new ArrayList(); this.count = new Countdown("Keep sorted: ", millis(), this.timeToStaySorted, width/2-50, height/2, 4); this.count.addToLevel(); } void addHeart(Heart h) { toSort.add(h); h.addToLevel(); } boolean won() { double lastX = -1000; // no x < this ever ... I hope boolean sorted = true; for (int i = 0; i < toSort.size(); i++) { Heart h = (Heart)toSort.get(i); if (h.x < lastX) { sorted = false; break; } lastX = h.x; } if (sorted) { if (!isSorted) { sortedFrom = millis(); isSorted = true; count.enable(); } else { return (millis() - sortedFrom > timeToStaySorted * 1000); } } else { isSorted = false; count.disable(); } return false; } boolean lost() { return millis()-startTime > duration && !isSorted; } } abstract class TimedLevel implements Stage { final static int winDelay = 50; int startTime; int duration; int noTimeLeft; void init() { startTime = millis(); noTimeLeft = -1; lossReason = "You ran out of hearts."; } boolean won() { if (noTimeLeft == -1) { if (millis()-startTime > duration) noTimeLeft = t; return false; } else return t >= noTimeLeft + winDelay; } boolean lost() { return nLiveHearts == 0 && noTimeLeft == -1; } } abstract class HappyCoupleLevel implements Stage { final static int winDelay = 50; int noMoreSinglesT; void init() { lossReason = "You ran out of hearts."; noMoreSinglesT = -1; } boolean won() { if (noMoreSinglesT == -1) { if (coupleCount == 0) noMoreSinglesT = t; return false; } else return t >= noMoreSinglesT + winDelay; } boolean lost() { return nLiveHearts == 0 && coupleCount > 0; } } abstract class KillAllHeartsLevel implements Stage { final static int winDelay = 50; int noMoreHeartsT; void init() { noMoreHeartsT = -1; } boolean won() { if (noMoreHeartsT == -1) { if (nLiveHearts == 0) noMoreHeartsT = t; return false; } else return t >= noMoreHeartsT + winDelay; } boolean lost() { return false; } } abstract class FeedTheChomperLevel extends ChomperLevel { final int nHeartsFeed; final static int winDelay = 50; int winT; LevelMessage levelMessage; FeedTheChomperLevel(int initialSize, int nHeartsFeed, float chomperY) { super(initialSize, 10, 390, chomperY); this.nHeartsFeed = nHeartsFeed; } void init() { lossReason = "The chomper died."; super.init(); winT = -1; levelMessage = new LevelMessage("Feed the chomper " + nHeartsFeed + " hearts."); levelMessage.addToLevel(); } boolean won() { if (hungry.size > initialSize) { int nRem = nHeartsFeed + initialSize - hungry.size; if (nRem < 0) nRem = 0; levelMessage.message = "Feed the chomper " + nRem + " more heart" + (nRem == 1 ? "." : "s."); levelMessage.centre(); } if (winT == -1) { if (hungry.size >= initialSize + nHeartsFeed) winT = t; return false; } else return t >= winT + winDelay; } boolean lost() { return hungry.dead; } } class SimpleFeedTheChomperLevel extends FeedTheChomperLevel { final int nHeartsAvail; String name; SimpleFeedTheChomperLevel(int initialSize, int nHeartsAvail, int nHeartsFeed, String name) { super(initialSize, nHeartsFeed, 325); this.nHeartsAvail = nHeartsAvail; this.name = name; } void init() { super.init(); for (int i = 0; i < nHeartsAvail; ++ i) (new Heart(20 + i * 50, 520)).addToLevel(); } String name() { return name; } } abstract class ChomperLevel implements Stage { final int initialSize; final int chomperMinX, chomperMaxX; final float chomperY; Chomper hungry; ChomperLevel(int initialSize, int chomperMinX, int chomperMaxX, float chomperY) { this.initialSize = initialSize; this.chomperMinX = chomperMinX; this.chomperMaxX = chomperMaxX; this.chomperY = chomperY; } void init() { hungry = new Chomper(chomperMinX, chomperMaxX, chomperY, initialSize); hungry.addToLevel(); } } Stage stageLonely = new HappyCoupleLevel() { void init() { super.init(); (new LevelMessage("Make the couple happy.")).addToLevel(); (new Couple(200, 100)).addToLevel(); (new Heart(200, 520)).addToLevel(); } String name() { return "lonely lovers"; } }; abstract class KillTheChomperLevel extends ChomperLevel { KillTheChomperLevel(int initialSize, int chomperMinX, int chomperMaxX, float chomperY) { super(initialSize, chomperMinX, chomperMaxX, chomperY); } boolean won() { return hungry.dead; } boolean lost() { return false; } } Stage stageSpikes = new KillAllHeartsLevel() { void init() { super.init(); (new LevelMessage("Hit the spikes.")).addToLevel(); (new Spiky(100,100)).addToLevel(); (new Heart(200,520)).addToLevel(); (new Bumper(110, 300, 10)).addToLevel(); (new Bumper(290, 300, 10)).addToLevel(); (new Bumper(295, 200, 10)).addToLevel(); (new Bumper(50, 400, 10)).addToLevel(); (new Bumper(350, 400, 10)).addToLevel(); // (new Cannon(200,200,10)).addToLevel(); } String name() { return "emo"; } }; Stage stageHappyCouples1 = new HappyCoupleLevel() { void init() { super.init(); (new LevelMessage("Unite every couple.")).addToLevel(); (new Couple(80, 100)).addToLevel(); (new Couple(220, 50)).addToLevel(); (new Couple(320, 10)).addToLevel(); (new Chomper(80, 220, 200)).addToLevel(); (new Bumper(290, 300, 10)).addToLevel(); (new Heart(10, 10)).addToLevel(); (new Heart(150, 400)).addToLevel(); (new Heart(300, 200)).addToLevel(); (new Bomb(3500, 10)).addToLevel(); } String name() { return "joy missionary"; } }; Stage stageHappyCouples2 = new HappyCoupleLevel() { void init() { super.init(); (new LevelMessage("Unite every couple.")).addToLevel(); (new Couple(202, 100)).addToLevel(); (new Couple(100, 250)).addToLevel(); (new Couple(300, 250)).addToLevel(); (new Couple(200, 400)).addToLevel(); (new Bumper(101, 100, 10)).addToLevel(); (new Bumper(301, 100, 10)).addToLevel(); (new Bumper(200, 250, 10)).addToLevel(); (new Bumper(101, 400, 10)).addToLevel(); (new Bumper(301, 400, 10)).addToLevel(); (new Chomper(50, 200, 175)).addToLevel(); (new Chomper(200, 350, 325)).addToLevel(); (new Heart(200, 450)).addToLevel(); } String name() { return "couple mania"; } }; Stage stageSurvive1 = new TimedLevel() { void init() { super.init(); this.duration = 10000; (new LevelMessage("Survive 10 seconds.")).addToLevel(); (new Countdown(millis(), 10)).addToLevel(); (new Couple(320, 10)).addToLevel(); (new Heart(300, 200)).addToLevel(); (new Bomb(350, 10)).addToLevel(); } String name() { return "juggling 101"; } }; Stage stageSurvive2 = new TimedLevel() { void init() { super.init(); this.duration = 10000; (new LevelMessage("Survive 10 seconds.")).addToLevel(); (new Countdown(millis(), 10)).addToLevel(); (new Heart(350, 50)).addToLevel(); (new Bomb(90, 250)).addToLevel(); (new Bumper(100, 200, 10)).addToLevel(); (new Bumper(300, 200, 10)).addToLevel(); (new Bumper(200, 300, 10)).addToLevel(); (new Bumper(100, 400, 10)).addToLevel(); (new Bumper(300, 400, 10)).addToLevel(); } String name() { return "juggling 101"; } }; Stage bankshot = new HappyCoupleLevel() { void init() { super.init(); (new LevelMessage("Unite the couple.")).addToLevel(); (new Couple(100, 100)).addToLevel(); int sx = 50, sy = 200; for (int i = 0; i < 5; i++) { (new Spiky(25+i*sx,sy)).addToLevel(); } (new Heart(300, 350)).addToLevel(); } String name() { return "off the wall"; } }; Stage hoard = new TimedLevel() { void init() { super.init(); this.duration = 10000; (new LevelMessage("Survive 10 seconds.")).addToLevel(); (new Countdown(millis(), 10)).addToLevel(); (new Couple(200, 10)).addToLevel(); (new Heart(300, 400)).addToLevel(); (new Chomper(80, 130, 60)).addToLevel(); (new Chomper(300, 380, 90)).addToLevel(); (new Chomper(180, 220, 100)).addToLevel(); (new Chomper(40, 350, 150)).addToLevel(); (new Chomper(200, 250, 205)).addToLevel(); (new Chomper(100, 150, 250)).addToLevel(); (new Chomper(300, 340, 290)).addToLevel(); (new Chomper(80, 130, 300)).addToLevel(); (new Chomper(300, 380, 340)).addToLevel(); (new Chomper(180, 220, 390)).addToLevel(); (new Chomper(40, 350, 420)).addToLevel(); (new Chomper(50, 350, 465)).addToLevel(); (new Chomper(100, 350, 600)).addToLevel(); //(new Chomper(300, 340, 490)).addToLevel(); } String name() { return "the hoard"; } }; Stage bouncy = new HappyCoupleLevel() { void init() { super.init(); (new LevelMessage("Unite the couples.")).addToLevel(); (new Couple(50, 50)).addToLevel(); (new Couple(350, 50)).addToLevel(); (new Couple(150, 130)).addToLevel(); (new Couple(280, 150)).addToLevel(); (new Couple(35, 300)).addToLevel(); (new Bumper(210, 400)).addToLevel(); (new Bumper(340, 400)).addToLevel(); (new Bumper(375, 200)).addToLevel(); (new Bumper(220, 300)).addToLevel(); (new Bumper(260, 250)).addToLevel(); (new Bumper(110, 400)).addToLevel(); (new Bumper(40, 400)).addToLevel(); (new Bumper(55, 200)).addToLevel(); (new Bumper(90, 300)).addToLevel(); (new Bumper(170, 250)).addToLevel(); (new Bumper(105, 100)).addToLevel(); (new Bumper(280, 50)).addToLevel(); (new Bumper(330, 150)).addToLevel(); (new Heart(300, 350)).addToLevel(); } String name() { return "ricochet rodeo"; } }; Stage juggling2 = new TimedLevel() { void init() { super.init(); this.duration = 10000; (new LevelMessage("Survive 10 seconds.")).addToLevel(); (new Countdown(millis(), 10)).addToLevel(); // (new Couple(320, 10)).addToLevel(); int sx = 50, sy = 50; for (int i = 0; i < 8; i++) { (new Spiky(25+i*sx,sy)).addToLevel(); } (new Heart(300, 200)).addToLevel(); (new Bomb(3500, 10)).addToLevel(); } String name() { return "juggling master"; } }; Stage stageSort3Hearts = new SortingLevel(10) { void init() { super.init(); (new LevelMessage("Sort the hearts.")).addToLevel(); this.addHeart(new Heart(350, 10, 1)); this.addHeart(new Heart(200, 10, 2)); this.addHeart(new Heart(60, 10, 3)); } String name() { return "Sort it out"; } }; Stage stageSort4Hearts = new SortingLevel(10) { void init() { super.init(); (new LevelMessage("Sort the hearts.")).addToLevel(); this.addHeart(new Heart(350, 10, 1)); this.addHeart(new Heart(200, 10, 2)); this.addHeart(new Heart(60, 10, 3)); this.addHeart(new Heart(100, 300, 4)); } String name() { return "sorting silliness"; } }; /* Stage destroyChomperStage = new KillTheChomperLevel(6, 10, 390, 300) { void init() { super.init(); (new Bomb(100, 400)).addToLevel(); (new Bomb(200, 400)).addToLevel(); (new Bomb(300, 400)).addToLevel(); (new LevelMessage("Destroy the chomper.")).addToLevel(); } String name() { return "chomper hunting"; } }; */ Stage bossStage = new KillTheChomperLevel(10, 200, 300, 300) { void init() { super.init(); (new LevelMessage("Destroy the boss chomper.")).addToLevel(); (new Bomb(150, 400)).addToLevel(); //(new Couple(100, 50)).addToLevel(); //(new Couple(300, 50)).addToLevel(); (new Cannon(50, 150, 10)).addToLevel(); (new Cannon(350, 150, 10, true)).addToLevel(); lossReason = "You ran out of bombs."; } boolean lost() { return 0 == nLiveHearts && 0 == theBombs.size(); } String name() { return "boss chomper"; } }; Stage cannonDemoStage = new KillAllHeartsLevel() { void init() { super.init(); (new Cannon(200, 200, 10)).addToLevel(); (new Heart(100, 300)).addToLevel(); (new Heart(200, 300)).addToLevel(); (new Heart(300, 300)).addToLevel(); (new LevelMessage("Destroy all hearts.")).addToLevel(); } String name() { return "the cannon"; } }; Stage []theStages = { stageLonely, stageSpikes, stageSurvive1, bouncy, stageSort3Hearts, new SimpleFeedTheChomperLevel(2, 7, 4, "baby chomper"), bankshot, // hoard, stageSurvive2, stageHappyCouples1, juggling2, new SimpleFeedTheChomperLevel(6, 6, 4, "snacktime"), stageHappyCouples2, // stageSort4Hearts, cannonDemoStage, bossStage, };