def shop(): # TODO: show species collected record.combinemoney() vista.mapinit() feat.startlevel() clock = pygame.time.Clock() speffect = effect.PressSpaceEffect(["Press Space to upgrade"]) speffect.position(vista.screen) ueffect = effect.UpgradeTitle(["Upgrade abilities"]) ueffect.position(vista.screen) deffect = effect.ContinueIndicator() deffect.position(vista.screen) beffect = effect.BankIndicator(record.bank) beffect.position(vista.screen) pointer = 0 nfeat = len(feat.known) + 1 pointerys = [82 + int(32 * j) for j in list(range(len(feat.known))) + [7.5]] feats = [f for f in feat.allfeats if f in feat.known] pricetags = [effect.CostIndicator(feat.getupgradecost(f), j) for j,f in enumerate(feats)] while True: dt = clock.tick(60) * 0.001 if settings.printfps and random.random() < dt: print clock.get_fps() for event in pygame.event.get(): if event.type == QUIT: exit() elif event.type == KEYDOWN and event.key == K_ESCAPE: return elif event.type == KEYDOWN and event.key == K_F12: pygame.image.save(vista.screen, "screenshot.png") elif event.type == KEYDOWN and event.key == K_UP: pointer -= 1 pointer %= nfeat elif event.type == KEYDOWN and event.key == K_DOWN: pointer += 1 pointer %= nfeat elif event.type == KEYDOWN and event.key == K_SPACE: if pointer == nfeat - 1: return cost = feat.getupgradecost(feats[pointer]) if cost and record.bank >= cost: record.bank -= cost feat.known[feats[pointer]] += 1 feat.bars[feats[pointer]] = feat.known[feats[pointer]] pricetags[pointer].update(feat.getupgradecost(feats[pointer])) beffect.update(record.bank) beffect.position(vista.screen) noise.play("cha-ching") vista.mapclear() feat.draw(shopping = True) pygame.draw.circle(vista.screen, (255, 128, 0), (152, pointerys[pointer]), 4) if pointer != nfeat - 1: speffect.draw(vista.screen) deffect.draw(vista.screen) beffect.draw(vista.screen) ueffect.draw(vista.screen) for tag in pricetags: tag.draw(vista.screen) pygame.display.flip()
def main(): global level pygame.mixer.pre_init(11025, -16, 2, 256) pygame.init() pygame.joystick.init() joysticks = [ pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count()) ] if len(joysticks) > 0: for joystick in joysticks: joystick.init() vista.init() noise.init() sprite.load() level = record.unlocked if record.maxvisited: noise.play("girl") while True: if settings.startInShop: shop() if settings.startInWorldMap: settings.startInWorldMap = False worldmap() elif record.maxvisited: worldmap() # noise.stop() if level in (1, 4): noise.play("gnos") if level in (2, 5): noise.play("one") if level in (3, 6): noise.play("xylo") cutscene() record.visit(level) showtip() action() record.combinemoney() game.save() if record.unlocked > 6: # Ending sequence level = 7 cutscene() level = 6 game.save() rollcredits() theend() noise.play("girl") if not settings.startInShop: shop() settings.startInShop = False game.save()
def handlerightclick(self, mousepos): if vista.prect.collidepoint(mousepos): # Click on panel self.clearselections() if settings.trashonrightclick: jtile = panels.iconpoint(mousepos) if jtile in range(mechanics.ntiles): panels.claimtile(jtile) noise.play("trash") elif vista.vrect.collidepoint(mousepos): # Click on main window if settings.panonrightclick: vista.jumptoscreenpos(mousepos) else: self.clearselections()
def handlerightclick(self, mousepos): if vista.prect.collidepoint(mousepos): # Click on panel self.clearselections() if settings.trashonrightclick: jtile = self.panel.iconp(mousepos) if jtile in (0, 1, 2, 3, 4, 5): self.panel.selecttile(jtile) self.panel.claimtile() noise.play("trash") elif vista.vrect.collidepoint(mousepos): # Click on main window if settings.panonrightclick: vista.jumptoscreenpos(mousepos) else: self.clearselections()
def main(): global level pygame.mixer.pre_init(11025, -16, 2, 256) pygame.init() vista.init() noise.init() sprite.load() level = record.unlocked while True: if record.maxvisited: noise.play("girl") worldmap() noise.stop() if level in (1, 4): noise.play("gnos") if level in (2, 5): noise.play("one") if level in (3, 6): noise.play("xylo") cutscene() record.visit(level) showtip() action() game.save() effect.savecache() if record.unlocked > 6: # Ending sequence level = 7 cutscene() record.unlocked = 6 level = 6 game.save() theend() shop() game.save() noise.stop()
def main(): global level pygame.mixer.pre_init(11025, -16, 2, 256) pygame.init() vista.init() noise.init() sprite.load() level = record.unlocked while True: if record.maxvisited: noise.play("girl") worldmap() noise.stop() if level in (1,4): noise.play("gnos") if level in (2,5): noise.play("one") if level in (3,6): noise.play("xylo") cutscene() record.visit(level) showtip() action() game.save() effect.savecache() if record.unlocked > 6: # Ending sequence level = 7 cutscene() record.unlocked = 6 level = 6 game.save() theend() shop() game.save() noise.stop()
def think(self, dt): self.t -= dt self.angle += self.omega * dt self.x = self.tx + self.t * self.dx self.y = self.ty + self.t * self.dy for shield in self.target.body.shields: if shield in self.passedshields: continue sx, sy = shield.worldpos if (sx - self.x)**2 + (sy - self.y)**2 < shield.shield**2: if random.random() < self.shieldprob: self.passedshields.append(shield) shield.wobble() else: self.active = False noise.play("dink") if self.t <= 0 and self.active: self.active = False self.complete()
def think(self, dt): self.t -= dt self.angle += self.omega * dt self.x = self.tx + self.t * self.dx self.y = self.ty + self.t * self.dy for shield in self.target.body.shields: if shield in self.passedshields: continue sx, sy = shield.worldpos if (sx - self.x) ** 2 + (sy - self.y) ** 2 < shield.shield ** 2: if random.random() < self.shieldprob: self.passedshields.append(shield) shield.wobble() else: self.active = False noise.play("dink") if self.t <= 0 and self.active: self.active = False self.complete()
def handleleftclick(self, mousepos): # TODO: handle dragging vs clicking more reliably if self.clickat is None: # It's a drag return (x0, y0), (x1, y1) = self.clickat, mousepos if abs(x0-x1) + abs(y0-y1) > 25: return vicon = vista.iconhit(mousepos) # Any vista icons pointed to if vicon is not None: self.handleiconclick(vicon) return bicon = panels.iconpoint(mousepos) # Any panel tile or icon pointed to if bicon is not None: panels.selecticon(bicon) return # Click on the main gameplay area if vista.vrect.collidepoint(mousepos): if self.cutmode and self.target is not None: self.target.die() self.clearselections() elif self.healmode and self.target is not None: self.target.autoheal = not self.target.autoheal elif self.parttobuild is not None and self.canbuild and game.state.body.canaddpart(self.parttobuild): if panels.selectedtile is not None: panels.claimtile() if panels.selectedorgan is not None: panels.claimorgan() game.state.body.addpart(self.parttobuild) self.clearselections() else: worldpos = vista.screentoworld(mousepos) if vista.HexGrid.nearesttile(worldpos) == (0,0): settings.showtips = not settings.showtips noise.play("addpart") return # Click on one of the panels self.clearselections()
def think(self, dt): if self.sucker: sx, sy = self.sucker.worldpos f = math.exp(-dt) self.vx *= f self.vy *= f self.vx += (sx - self.x) * dt self.vy += (sy - self.y) * dt else: self.ax = random.uniform(-4, 4) self.ay = random.uniform(-4, 4) self.vx += self.ax * dt self.vy += self.ay * dt self.x += self.vx * dt self.y += self.vy * dt self.t += dt if self.sucker: if (self.x - sx) ** 2 + (self.y - sy) ** 2 < 0.3 ** 2: self.claimed = True self.sucker.energize() self.sucker = None noise.play("energize")
def think(self, dt): if self.sucker: sx, sy = self.sucker.worldpos f = math.exp(-dt) self.vx *= f self.vy *= f self.vx += (sx - self.x) * dt self.vy += (sy - self.y) * dt else: self.ax = random.uniform(-4, 4) self.ay = random.uniform(-4, 4) self.vx += self.ax * dt self.vy += self.ay * dt self.x += self.vx * dt self.y += self.vy * dt self.t += dt if self.sucker: if (self.x - sx)**2 + (self.y - sy)**2 < 0.3**2: self.claimed = True self.sucker.energize() self.sucker = None noise.play("energize")
def think(self, dt): # TODO: come up with a different motion formula that doesn't depend on framerate if self.sucker: sx, sy = self.sucker.worldpos f = math.exp(-dt) self.vx *= f self.vy *= f self.vx += (sx - self.x) * dt self.vy += (sy - self.y) * dt else: self.ax = random.uniform(-4, 4) self.ay = random.uniform(-4, 4) self.vx += self.ax * dt self.vy += self.ay * dt self.x += self.vx * dt self.y += self.vy * dt self.t += dt if self.sucker: if (self.x - sx) ** 2 + (self.y - sy) ** 2 < 0.3 ** 2: self.claimed = True self.sucker.energize() self.sucker = None noise.play("energize")
def render(self): if self.n == 0: noise.play("win-1") elif self.n == 1: noise.play("win-2") else: noise.play("win-3") self.n += 1 Effect.render(self)
def render(self): if "incomplete" not in self.texts[0]: if self.n == 0: noise.play("win-1") elif self.n == 1: noise.play("win-2") else: noise.play("win-3") self.n += 1 Effect.render(self)
def __init__(self, hb): noise.play("cha-ching") Effect.__init__(self, [u"\u00A3%s" % hb])
def play(self): #Start zee music! noise.play(self.music)
def action(): global level vista.levelinit(level) butterflies, goal, timeout = loadlevel.load(level) clock = pygame.time.Clock() facingright = True x, y, g, vy = 200, 0, (250 if settings.easy else 500), 0 leapvx, leapvy = 200., 200. twirlvy = 200. nabvx = 400. runvx = 300. rollvx, rollvy = 250., 250. dartvx, dartvy = 250., 300. boundvx, boundvy = -100., 250. nabtick, nabtime = 0, 0.25 nabradius = 50 twirlradius = 80 rollradius = 80 leaping = 0 runtick = 0 twirltick = 0 rolltick = 0 currentfeat = "" combocount = 0 grounded = True paused = False title = effect.Effect(["READY", "SET", "COLLECT"]) endtitle = True ending = False effects = [] heffect = effect.HeightIndicator() ceffect = effect.ComboIndicator() peffect = effect.ProgressIndicator(goal) cdeffect = effect.CountdownIndicator(timeout) seffect = effect.StageNameEffect(level, goal, timeout) feat.startlevel() pygame.event.get() while True: dt = clock.tick(60) * 0.001 if settings.printfps and random.random() < dt: print clock.get_fps() if paused: for event in pygame.event.get(): if event.type == QUIT: exit() elif event.type == KEYDOWN and event.key == K_ESCAPE: ending = True endtitle = None feat.checknewfeat(len(record.collected)) if record.catchamount >= goal: unlocked = record.unlocked record.checkhiscore(level) if record.unlocked > unlocked: level = record.unlocked paused = False elif event.type == KEYDOWN and event.key == K_F12: pygame.image.save(vista.screen, "screenshot.png") elif event.type == KEYDOWN and event.key == K_RETURN: paused = False vista.screen.blit(pausescreen, (0, 0)) pygame.display.flip() continue for event in pygame.event.get(): if event.type == QUIT: exit() elif event.type == KEYDOWN and event.key == K_ESCAPE: paused = True pausescreen = pygame.Surface( vista.screen.get_size()).convert_alpha() fade = pygame.Surface(vista.screen.get_size()).convert_alpha() fade.fill((0, 0, 0, 128)) pausescreen.blit(vista.screen, (0, 0)) pausescreen.blit(fade, (0, 0)) pausetitle = effect.PauseTitle(["PAUSED"]) pauseinfo = effect.PauseInfo( ["Press Enter to resume|or Esc to exit level"]) pausetitle.position(pausescreen) pauseinfo.position(pausescreen) pausetitle.draw(pausescreen) pauseinfo.draw(pausescreen) elif event.type == KEYDOWN and event.key == K_F12: pygame.image.save(vista.screen, "screenshot.png") elif event.type == KEYDOWN and event.key == K_TAB: settings.hidefeatnames = not settings.hidefeatnames feat.startlevel(False) k = pygame.key.get_pressed() kcombo = combo.check(k) if grounded: dx = 0 if k[K_RIGHT]: dx += runvx * dt if k[K_LEFT]: dx -= runvx * dt if nabtick: dx = 0 if not cdeffect: dx = 0 kcombo = "" if dx: facingright = dx > 0 currentfeat = "run" x += dx elif not nabtick: currentfeat = "" if kcombo == "leap" and "leap" in feat.known: if feat.attempt("leap"): vx = leapvx if facingright else -leapvx vy = leapvy combocount = 1 grounded = False currentfeat = "leap" noise.play("hop") elif kcombo == "twirl" and "twirl" in feat.known: if feat.attempt("twirl"): combocount = 1 grounded = False currentfeat = "twirl" vx = 0 vy = twirlvy twirltick = 1 noise.play("rotor") elif kcombo == "nab" and "nab" in feat.known: if feat.attempt("nab"): currentfeat = "nab" nabtick = nabtime noise.play("woosh") elif kcombo == ("roll-r" if facingright else "roll-l") and "roll" in feat.known: if feat.attempt("roll"): grounded = False currentfeat = "roll" vx = (rollvx if facingright else -rollvx) vy = rollvy combocount = 1 rolltick = 1 twirltick = 0 noise.play("rotor") elif kcombo == ("dart-r" if facingright else "dart-l") and "dart" in feat.known: if feat.attempt("dart"): grounded = False currentfeat = "dart" vx = (dartvx if facingright else -dartvx) vy = dartvy combocount = 1 rolltick = 0 twirltick = 0 noise.play("hop") elif kcombo == ("dart-l" if facingright else "dart-r") and "bound" in feat.known: if feat.attempt("bound"): grounded = False currentfeat = "bound" vx = (boundvx if facingright else -boundvx) vy = boundvy combocount = 1 rolltick = 0 twirltick = 0 noise.play("hop") else: if kcombo == "leap" and "leap" in feat.known: if feat.attempt("leap"): vx = leapvx if facingright else -leapvx vy = leapvy combocount += 1 currentfeat = "leap" twirltick = 0 noise.play("hop") elif kcombo == ("turn-r" if facingright else "turn-l") and "turn" in feat.known: if feat.attempt("turn"): facingright = not facingright vx = leapvx if facingright else -leapvx vy = leapvy combocount += 1 twirltick = 0 rolltick = 0 currentfeat = "leap" noise.play("hop") elif kcombo == "nab" and "nab" in feat.known: if feat.attempt("nab"): currentfeat = "nab" nabtick = nabtime vx = nabvx if facingright else -nabvx combocount += 1 twirltick = 0 rolltick = 0 noise.play("woosh") elif kcombo == "twirl" and "twirl" in feat.known: if feat.attempt("twirl"): currentfeat = "twirl" vx = 0 vy = twirlvy combocount += 1 twirltick = 1 rolltick = 0 noise.play("rotor") elif kcombo == ("roll-r" if facingright else "roll-l") and "roll" in feat.known: if feat.attempt("roll"): currentfeat = "roll" vx = (rollvx if facingright else -rollvx) vy = rollvy combocount += 1 rolltick = 1 twirltick = 0 noise.play("rotor") elif kcombo == ("dart-r" if facingright else "dart-l") and "dart" in feat.known: if feat.attempt("dart"): currentfeat = "dart" vx = (dartvx if facingright else -dartvx) vy = dartvy combocount += 1 rolltick = 0 twirltick = 0 noise.play("hop") elif kcombo == ("dart-l" if facingright else "dart-r") and "bound" in feat.known: if feat.attempt("bound"): currentfeat = "bound" vx = (boundvx if facingright else -boundvx) vy = boundvy combocount += 1 rolltick = 0 twirltick = 0 noise.play("hop") if nabtick: x += vx * dt else: x += vx * dt y += vy * dt - 0.5 * g * dt**2 vy -= g * dt if y < 0: y = 0 vy = 0 grounded = True combocount = 0 feat.land() ach = record.getrecords() if ach: effects.append(effect.AchievementEffect(ach)) currentfeat = "" twirltick = 0 rolltick = 0 x, y = vista.constrain(x, y, 30) nx, ny, nr = None, None, None if nabtick: nabtick = max(nabtick - dt, 0) if not nabtick: currentfeat = "" if grounded else "leap" nx, ny = x + (40 if facingright else -40), y + 80 nr = nabradius elif currentfeat == "twirl": nx, ny = x, y + 80 nr = twirlradius elif currentfeat == "roll": nx, ny = x, y + 50 nr = rollradius if nx is not None: for b in list(butterflies): adx, ady = b.x - nx, b.y - ny if adx**2 + ady**2 < nr**2: b.nabbed = True butterflies.remove(b) value = 3 * b.value if settings.easy else b.value effects.append(effect.NabBonusIndicator(value, (b.x, b.y))) if grounded: ach = record.checknabgrounded(b) if ach: effects.append(effect.AchievementEffect(ach)) else: record.checknab(b) heffect.update(y / 25.) heffect.position(vista.screen) ceffect.update(combocount) ceffect.position(vista.screen) peffect.update(record.catchamount) cdeffect.position(vista.screen) hbonus = record.checkheightrecord(y / 25.) if hbonus: effects.append(effect.HeightBonusIndicator(hbonus)) cbonus = record.checkcomborecord(combocount) if cbonus: effects.append(effect.ComboBonusIndicator(cbonus)) if currentfeat == "leap": picname = "run2" elif currentfeat == "run": picname = ("run0", "run1", "run2", "run1")[int(4 * runtick / 0.5)] runtick += dt runtick %= 0.5 elif currentfeat == "nab": picname = ("nab3", "nab2", "nab1", "nab0")[int(4. * nabtick / nabtime)] if not grounded: picname = "sky" + picname elif currentfeat == "twirl": twirltick += dt picname = ("twirl0", "twirl1", "twirl2", "twirl3")[int(4 * twirltick / 0.25) % 4] elif currentfeat == "roll": rolltick += dt picname = "roll%s" % (int(8 * rolltick / 0.35) % 8) elif currentfeat == "dart": picname = "dart" elif currentfeat == "bound": picname = "bound" else: picname = "stand" if "twirl" not in picname and not facingright: picname = picname + "-b" vista.position((x, y), facingright, vy) butterflies += loadlevel.newbutterflies(level, dt) feat.think(dt) vista.think(dt) for b in butterflies: b.think(dt) seffect.think(dt) if not seffect: title.think(dt) for e in effects: e.think(dt) effects = [e for e in effects if e] ceffect.think(dt) if not title: cdeffect.think(dt) if grounded and not cdeffect and not effects and not ending: ending = True if record.catchamount >= goal: w = ["Stage complete!"] unlocked = record.unlocked w += record.checkhiscore(level) if record.unlocked > unlocked: level = record.unlocked else: w = ["Stage incomplete"] w += feat.checknewfeat(len(record.collected)) endtitle = effect.EndEffect(w) if ending and endtitle: endtitle.think(dt) vista.clear() sprite.frames[picname].draw((x, y)) for b in butterflies: b.draw() if nr is not None and settings.showdots: vista.circle((int(nx), int(ny)), int(nr)) feat.draw(facingright=facingright) heffect.draw(vista.screen) ceffect.draw(vista.screen) cdeffect.draw(vista.screen) peffect.draw(vista.screen) for e in effects: e.draw(vista.screen) seffect.draw(vista.screen) if not seffect: title.draw(vista.screen) if ending and endtitle: endtitle.draw(vista.screen) pygame.display.flip() if not endtitle: return
def worldmap(): global level if settings.unlockall: record.unlocked = 6 vista.mapinit() levelnames = ["Stage 1: Mortimer's backyard", "Stage 2: Dojo of the Royal Lepidopteral Society", "Stage 3: Bucolic Meadow of Doom", "Stage 4: Some field you have to cross", "Stage 5: Imperial palace of|the Royal Society of Lepidopterists", "Final stage:|The Lost Buttefly Garden of Verdania"] levelps = [(150, 90), (250, 130), (350, 110), (450, 150), (550, 130), (650,170)] clock = pygame.time.Clock() teffect = effect.LevelNameEffect("") speffect = effect.PressSpaceEffect(["Press Space to choose level"]) speffect.position(vista.screen) hseffect = effect.HighScoreEffect("") hceffect = effect.HCRecord([record.gethcrecord()]) hceffect.position(vista.screen) updateteffect = True udseq = [] esign = None while True: dt = clock.tick(60) * 0.001 if settings.printfps and random.random() < dt: print clock.get_fps() for event in pygame.event.get(): if event.type == QUIT: exit() elif event.type == KEYDOWN and event.key == K_ESCAPE: exit() elif event.type == KEYDOWN and event.key == K_F12: pygame.image.save(vista.screen, "screenshot.png") elif event.type == KEYDOWN and event.key == K_RIGHT: udseq = [] if level < record.unlocked: level += 1 updateteffect = True elif event.type == KEYDOWN and event.key == K_LEFT: udseq = [] if level > 1: level -= 1 updateteffect = True elif event.type == KEYDOWN and event.key in (K_UP, K_DOWN): udseq.append(0 if event.key == K_UP else 1) if len(udseq) >= 8 and tuple(udseq[-8:]) == (0,0,1,1,0,0,1,1) and not settings.easy: settings.easy = True esign = effect.EasyModeIndicator(["Easy Mode Activated!"]) esign.position(vista.screen) udseq = [] noise.play("cha-ching") elif event.type == KEYDOWN and event.key == K_SPACE: return if updateteffect: teffect.update(levelnames[level-1]) teffect.position(vista.screen) updateteffect = False hstext = u"high score: \u00A3%s" % record.hiscore[level] if level in record.hiscore else "" hseffect.update(hstext) hseffect.position(vista.screen) if esign: esign.think(dt) vista.mapclear() for j in range(1,record.unlocked): x0, y0 = levelps[j-1] x1, y1 = levelps[j] vista.line((x0, y0-6), (x1, y1-6), (0,0,0), (200,200,200)) for p in levelps: sprite.frames["leveldisk"].draw(p) sprite.frames["stand"].draw(levelps[level-1]) teffect.draw(vista.screen) # speffect.draw(vista.screen) hseffect.draw(vista.screen) hceffect.draw(vista.screen) if esign: esign.draw(vista.screen) pygame.display.flip()
def action(): global level vista.levelinit(level) butterflies, goal, timeout = loadlevel.load(level) clock = pygame.time.Clock() facingright = True x, y, g, vy = 200, 0, (250 if settings.easy else 500), 0 leapvx, leapvy = 200., 200. twirlvy = 200. nabvx = 400. runvx = 300. rollvx, rollvy = 250., 250. dartvx, dartvy = 250., 300. boundvx, boundvy = -100., 250. nabtick, nabtime = 0, 0.25 nabradius = 50 twirlradius = 80 rollradius = 80 leaping = 0 runtick = 0 twirltick = 0 rolltick = 0 currentfeat = "" combocount = 0 grounded = True paused = False title = effect.Effect(["READY", "SET", "COLLECT"]) endtitle = True ending = False effects = [] heffect = effect.HeightIndicator() ceffect = effect.ComboIndicator() peffect = effect.ProgressIndicator(goal) cdeffect = effect.CountdownIndicator(timeout) seffect = effect.StageNameEffect(level, goal, timeout) feat.startlevel() pygame.event.get() while True: dt = clock.tick(60) * 0.001 if settings.printfps and random.random() < dt: print clock.get_fps() if paused: for event in pygame.event.get(): if event.type == QUIT: exit() elif event.type == KEYDOWN and event.key == K_ESCAPE: ending = True endtitle = None feat.checknewfeat(len(record.collected)) if record.catchamount >= goal: unlocked = record.unlocked record.checkhiscore(level) if record.unlocked > unlocked: level = record.unlocked paused = False elif event.type == KEYDOWN and event.key == K_F12: pygame.image.save(vista.screen, "screenshot.png") elif event.type == KEYDOWN and event.key == K_RETURN: paused = False vista.screen.blit(pausescreen, (0,0)) pygame.display.flip() continue for event in pygame.event.get(): if event.type == QUIT: exit() elif event.type == KEYDOWN and event.key == K_ESCAPE: paused = True pausescreen = pygame.Surface(vista.screen.get_size()).convert_alpha() fade = pygame.Surface(vista.screen.get_size()).convert_alpha() fade.fill((0,0,0,128)) pausescreen.blit(vista.screen,(0,0)) pausescreen.blit(fade,(0,0)) pausetitle = effect.PauseTitle(["PAUSED"]) pauseinfo = effect.PauseInfo(["Press Enter to resume|or Esc to exit level"]) pausetitle.position(pausescreen) pauseinfo.position(pausescreen) pausetitle.draw(pausescreen) pauseinfo.draw(pausescreen) elif event.type == KEYDOWN and event.key == K_F12: pygame.image.save(vista.screen, "screenshot.png") elif event.type == KEYDOWN and event.key == K_TAB: settings.hidefeatnames = not settings.hidefeatnames feat.startlevel(False) k = pygame.key.get_pressed() kcombo = combo.check(k) if grounded: dx = 0 if k[K_RIGHT]: dx += runvx * dt if k[K_LEFT]: dx -= runvx * dt if nabtick: dx = 0 if not cdeffect: dx = 0 kcombo = "" if dx: facingright = dx > 0 currentfeat = "run" x += dx elif not nabtick: currentfeat = "" if kcombo == "leap" and "leap" in feat.known: if feat.attempt("leap"): vx = leapvx if facingright else -leapvx vy = leapvy combocount = 1 grounded = False currentfeat = "leap" noise.play("hop") elif kcombo == "twirl" and "twirl" in feat.known: if feat.attempt("twirl"): combocount = 1 grounded = False currentfeat = "twirl" vx = 0 vy = twirlvy twirltick = 1 noise.play("rotor") elif kcombo == "nab" and "nab" in feat.known: if feat.attempt("nab"): currentfeat = "nab" nabtick = nabtime noise.play("woosh") elif kcombo == ("roll-r" if facingright else "roll-l") and "roll" in feat.known: if feat.attempt("roll"): grounded = False currentfeat = "roll" vx = (rollvx if facingright else -rollvx) vy = rollvy combocount = 1 rolltick = 1 twirltick = 0 noise.play("rotor") elif kcombo == ("dart-r" if facingright else "dart-l") and "dart" in feat.known: if feat.attempt("dart"): grounded = False currentfeat = "dart" vx = (dartvx if facingright else -dartvx) vy = dartvy combocount = 1 rolltick = 0 twirltick = 0 noise.play("hop") elif kcombo == ("dart-l" if facingright else "dart-r") and "bound" in feat.known: if feat.attempt("bound"): grounded = False currentfeat = "bound" vx = (boundvx if facingright else -boundvx) vy = boundvy combocount = 1 rolltick = 0 twirltick = 0 noise.play("hop") else: if kcombo == "leap" and "leap" in feat.known: if feat.attempt("leap"): vx = leapvx if facingright else -leapvx vy = leapvy combocount += 1 currentfeat = "leap" twirltick = 0 noise.play("hop") elif kcombo == ("turn-r" if facingright else "turn-l") and "turn" in feat.known: if feat.attempt("turn"): facingright = not facingright vx = leapvx if facingright else -leapvx vy = leapvy combocount += 1 twirltick = 0 rolltick = 0 currentfeat = "leap" noise.play("hop") elif kcombo == "nab" and "nab" in feat.known: if feat.attempt("nab"): currentfeat = "nab" nabtick = nabtime vx = nabvx if facingright else -nabvx combocount += 1 twirltick = 0 rolltick = 0 noise.play("woosh") elif kcombo == "twirl" and "twirl" in feat.known: if feat.attempt("twirl"): currentfeat = "twirl" vx = 0 vy = twirlvy combocount += 1 twirltick = 1 rolltick = 0 noise.play("rotor") elif kcombo == ("roll-r" if facingright else "roll-l") and "roll" in feat.known: if feat.attempt("roll"): currentfeat = "roll" vx = (rollvx if facingright else -rollvx) vy = rollvy combocount += 1 rolltick = 1 twirltick = 0 noise.play("rotor") elif kcombo == ("dart-r" if facingright else "dart-l") and "dart" in feat.known: if feat.attempt("dart"): currentfeat = "dart" vx = (dartvx if facingright else -dartvx) vy = dartvy combocount += 1 rolltick = 0 twirltick = 0 noise.play("hop") elif kcombo == ("dart-l" if facingright else "dart-r") and "bound" in feat.known: if feat.attempt("bound"): currentfeat = "bound" vx = (boundvx if facingright else -boundvx) vy = boundvy combocount += 1 rolltick = 0 twirltick = 0 noise.play("hop") if nabtick: x += vx * dt else: x += vx * dt y += vy * dt - 0.5 * g * dt ** 2 vy -= g * dt if y < 0: y = 0 vy = 0 grounded = True combocount = 0 feat.land() ach = record.getrecords() if ach: effects.append(effect.AchievementEffect(ach)) currentfeat = "" twirltick = 0 rolltick = 0 x, y = vista.constrain(x, y, 30) nx, ny, nr = None, None, None if nabtick: nabtick = max(nabtick - dt, 0) if not nabtick: currentfeat = "" if grounded else "leap" nx, ny = x + (40 if facingright else -40), y + 80 nr = nabradius elif currentfeat == "twirl": nx, ny = x, y + 80 nr = twirlradius elif currentfeat == "roll": nx, ny = x, y + 50 nr = rollradius if nx is not None: for b in list(butterflies): adx, ady = b.x - nx, b.y - ny if adx ** 2 + ady ** 2 < nr ** 2: b.nabbed = True butterflies.remove(b) value = 3 * b.value if settings.easy else b.value effects.append(effect.NabBonusIndicator(value, (b.x, b.y))) if grounded: ach = record.checknabgrounded(b) if ach: effects.append(effect.AchievementEffect(ach)) else: record.checknab(b) heffect.update(y/25.) heffect.position(vista.screen) ceffect.update(combocount) ceffect.position(vista.screen) peffect.update(record.catchamount) cdeffect.position(vista.screen) hbonus = record.checkheightrecord(y/25.) if hbonus: effects.append(effect.HeightBonusIndicator(hbonus)) cbonus = record.checkcomborecord(combocount) if cbonus: effects.append(effect.ComboBonusIndicator(cbonus)) if currentfeat == "leap": picname = "run2" elif currentfeat == "run": picname = ("run0", "run1", "run2", "run1")[int(4 * runtick / 0.5)] runtick += dt runtick %= 0.5 elif currentfeat == "nab": picname = ("nab3", "nab2", "nab1", "nab0")[int(4. * nabtick / nabtime)] if not grounded: picname = "sky" + picname elif currentfeat == "twirl": twirltick += dt picname = ("twirl0", "twirl1", "twirl2", "twirl3")[int(4 * twirltick / 0.25) % 4] elif currentfeat == "roll": rolltick += dt picname = "roll%s" % (int(8 * rolltick / 0.35) % 8) elif currentfeat == "dart": picname = "dart" elif currentfeat == "bound": picname = "bound" else: picname = "stand" if "twirl" not in picname and not facingright: picname = picname + "-b" vista.position((x, y), facingright, vy) butterflies += loadlevel.newbutterflies(level, dt) feat.think(dt) vista.think(dt) for b in butterflies: b.think(dt) seffect.think(dt) if not seffect: title.think(dt) for e in effects: e.think(dt) effects = [e for e in effects if e] ceffect.think(dt) if not title: cdeffect.think(dt) if grounded and not cdeffect and not effects and not ending: ending = True if record.catchamount >= goal: w = ["Stage complete!"] unlocked = record.unlocked w += record.checkhiscore(level) if record.unlocked > unlocked: level = record.unlocked else: w = ["Stage incomplete"] w += feat.checknewfeat(len(record.collected)) endtitle = effect.EndEffect(w) if ending and endtitle: endtitle.think(dt) vista.clear() sprite.frames[picname].draw((x, y)) for b in butterflies: b.draw() if nr is not None and settings.showdots: vista.circle((int(nx), int(ny)), int(nr)) feat.draw(facingright=facingright) heffect.draw(vista.screen) ceffect.draw(vista.screen) cdeffect.draw(vista.screen) peffect.draw(vista.screen) for e in effects: e.draw(vista.screen) seffect.draw(vista.screen) if not seffect: title.draw(vista.screen) if ending and endtitle: endtitle.draw(vista.screen) pygame.display.flip() if not endtitle: return
def handleleftclick(self, mousepos): if self.clickat is None: # It's a drag return (x0, y0), (x1, y1) = self.clickat, mousepos if abs(x0 - x1) + abs(y0 - y1) > 25: return bicon = self.status.iconpoint(mousepos) # Any build icons pointed to vicon = vista.iconhit(mousepos) # Any vista icons pointed to if vicon == "trash": if self.panel.selected is not None: self.panel.claimtile() noise.play("trash") self.clearselections() elif vicon == "zoomin": vista.zoomin() elif vicon == "zoomout": vista.zoomout() elif vicon == "pause": self.pause() elif vicon == "music": noise.nexttrack() elif vicon == "heal": self.body.core.setbranchstatus() if self.healmode: self.clearselections() else: self.clearselections() if vista.icons["heal"].active: self.healmode = True elif vicon == "cut": if self.cutmode: self.clearselections() else: self.clearselections() if vista.icons["cut"].active: self.cutmode = True elif vista.prect.collidepoint(mousepos): # Click on panel self.clearselections(clearpanel=False) jtile = self.panel.iconp(mousepos) if jtile in (None, 0, 1, 2, 3, 4, 5): self.panel.selecttile(jtile) elif bicon is not None: self.clearselections(clearstatus=False) self.status.select(bicon.name) elif vista.vrect.collidepoint(mousepos): if self.cutmode and self.target is not None: self.target.die() self.clearselections() elif self.healmode and self.target is not None: self.target.autoheal = not self.target.autoheal elif self.parttobuild is not None and self.canbuild and self.body.canaddpart( self.parttobuild): if self.panel.selected is not None: self.panel.claimtile() if self.status.selected is not None: self.status.build() self.body.addpart(self.parttobuild) self.clearselections() else: worldpos = vista.screentoworld(mousepos) if vista.HexGrid.nearesttile(worldpos) == (0, 0): settings.showtips = not settings.showtips noise.play("addpart")
def shop(): # TODO: show species collected record.combinemoney() vista.mapinit() feat.startlevel() clock = pygame.time.Clock() speffect = effect.PressSpaceEffect(["Press Space to upgrade"]) speffect.position(vista.screen) ueffect = effect.UpgradeTitle(["Upgrade abilities"]) ueffect.position(vista.screen) deffect = effect.ContinueIndicator() deffect.position(vista.screen) beffect = effect.BankIndicator(record.bank) beffect.position(vista.screen) pointer = 0 nfeat = len(feat.known) + 1 pointerys = [ 82 + int(32 * j) for j in list(range(len(feat.known))) + [7.5] ] feats = [f for f in feat.allfeats if f in feat.known] pricetags = [ effect.CostIndicator(feat.getupgradecost(f), j) for j, f in enumerate(feats) ] while True: dt = clock.tick(60) * 0.001 if settings.printfps and random.random() < dt: print clock.get_fps() for event in pygame.event.get(): if event.type == QUIT: exit() elif event.type == KEYDOWN and event.key == K_ESCAPE: return elif event.type == KEYDOWN and event.key == K_F12: pygame.image.save(vista.screen, "screenshot.png") elif event.type == KEYDOWN and event.key == K_UP: pointer -= 1 pointer %= nfeat elif event.type == KEYDOWN and event.key == K_DOWN: pointer += 1 pointer %= nfeat elif event.type == KEYDOWN and event.key == K_SPACE: if pointer == nfeat - 1: return cost = feat.getupgradecost(feats[pointer]) if cost and record.bank >= cost: record.bank -= cost feat.known[feats[pointer]] += 1 feat.bars[feats[pointer]] = feat.known[feats[pointer]] pricetags[pointer].update( feat.getupgradecost(feats[pointer])) beffect.update(record.bank) beffect.position(vista.screen) noise.play("cha-ching") vista.mapclear() feat.draw(shopping=True) pygame.draw.circle(vista.screen, (255, 128, 0), (152, pointerys[pointer]), 4) if pointer != nfeat - 1: speffect.draw(vista.screen) deffect.draw(vista.screen) beffect.draw(vista.screen) ueffect.draw(vista.screen) for tag in pricetags: tag.draw(vista.screen) pygame.display.flip()
def handleleftclick(self, mousepos): if self.clickat is None: # It's a drag return (x0, y0), (x1, y1) = self.clickat, mousepos if abs(x0-x1) + abs(y0-y1) > 25: return bicon = self.status.iconpoint(mousepos) # Any build icons pointed to vicon = vista.iconhit(mousepos) # Any vista icons pointed to if vicon == "trash": if self.panel.selected is not None: self.panel.claimtile() noise.play("trash") self.clearselections() elif vicon == "zoomin": vista.zoomin() elif vicon == "zoomout": vista.zoomout() elif vicon == "pause": self.pause() elif vicon == "music": noise.nexttrack() elif vicon == "heal": self.body.core.setbranchstatus() if self.healmode: self.clearselections() else: self.clearselections() if vista.icons["heal"].active: self.healmode = True elif vicon == "cut": if self.cutmode: self.clearselections() else: self.clearselections() if vista.icons["cut"].active: self.cutmode = True elif vista.prect.collidepoint(mousepos): # Click on panel self.clearselections(clearpanel = False) jtile = self.panel.iconp(mousepos) if jtile in (None, 0, 1, 2, 3, 4, 5): self.panel.selecttile(jtile) elif bicon is not None: self.clearselections(clearstatus = False) self.status.select(bicon.name) elif vista.vrect.collidepoint(mousepos): if self.cutmode and self.target is not None: self.target.die() self.clearselections() elif self.healmode and self.target is not None: self.target.autoheal = not self.target.autoheal elif self.parttobuild is not None and self.canbuild and self.body.canaddpart(self.parttobuild): if self.panel.selected is not None: self.panel.claimtile() if self.status.selected is not None: self.status.build() self.body.addpart(self.parttobuild) self.clearselections() else: worldpos = vista.screentoworld(mousepos) if vista.HexGrid.nearesttile(worldpos) == (0,0): settings.showtips = not settings.showtips noise.play("addpart")
def action(): ''' This is part of the gameplay event loop runs when the state is not in a menu, cutscene, or other non-gameplay state. However, the paused state is included here. ''' global level vista.levelinit(level) global prevPCKey global touchEffect global touchEffectPos global touchColor butterflies, goal, timeout = loadlevel.load(level) clock = pygame.time.Clock() facingright = True x, y, g, vy = 200, 0, (250 if settings.easy else 500), 0 leapvx, leapvy = 200., 200. twirlvy = 200. nabvx = 400. runvx = 300. rollvx, rollvy = 250., 250. dartvx, dartvy = 250., 300. boundvx, boundvy = -100., 250. nabtick, nabtime = 0, 0.25 nabradius = 50 twirlradius = 80 rollradius = 80 leaping = 0 runtick = 0 twirltick = 0 rolltick = 0 currentfeat = "" combocount = 0 grounded = True paused = False titleEffect = effect.Effect(["READY", "SET", "COLLECT"]) endtitle = True ending = False effects = [] heffect = effect.HeightIndicator() ceffect = effect.ComboIndicator() peffect = effect.ProgressIndicator(goal) cdeffect = effect.CountdownIndicator(timeout) seffect = effect.StageNameEffect(level, goal, timeout) feat.startlevel() pygame.event.get() prevTitleStr = None pcRect = None pcPos = None while True: dt = clock.tick(60) * 0.001 if settings.printfps and random.random() < dt: print(clock.get_fps()) if paused: for event in pygame.event.get(): result = 0 if event.type == QUIT: sys.exit() else: result = read_event( controller1, event, pcRect=pcRect, mb_sids=('nab', None, 'BACK'), # always_collide_mb=2, ) if result < 2: vista.screen.blit(pausescreen, (0, 0)) pygame.display.flip() # Try to prevent a black screen when switching # away from the game and back. continue if controller1.getBool('BACK'): ending = True endtitle = None feat.checknewfeat(len(record.collected)) if record.catchamount >= goal: unlocked = record.unlocked record.checkhiscore(level) if record.unlocked > unlocked: level = record.unlocked paused = False noise.unpause() elif controller1.getBool('SCREENSHOT'): screenshot(vista.screen) elif controller1.getBool('nab'): paused = False noise.unpause() elif controller1.getBool('FULLSCREEN'): settings.fullscreen = not settings.fullscreen vista.init() vista.screen.blit(pausescreen, (0, 0)) pygame.display.flip() continue # action main event loop (when not paused): up_events = [] for event in pygame.event.get(): result = 0 if event.type == QUIT: sys.exit() elif event.type == MOUSEBUTTONUP: # Process this separately in case the button was # pressed and released in the same frame such as # with the scroll wheel turning. up_events.append(event) else: # pcRect may be None for a frame but read_event # is ok with that. always_collide_mb = None if event.type == MOUSEBUTTONDOWN: if not grounded: # Double-jump if in the air # - 3: Change right-click from 'x' to 'jump' # even if not clicking the character # - 4&5: Change wheel roll to nab to allow roll # ('x' and 'nab' at the same time) with # only a mouse. always_collide_mb = (2, 3, 4, 5) elif (pcRect is not None) and (event.pos[1] < pcRect.top): # Jump if clicking above the character's head # even if on the ground and not clicking in # pcRect. always_collide_mb = (3) if settings.verbose: print("[main.action] pcRect={}" "".format(pcRect)) if pcRect is not None: print("[main.action] pcRect.top={}" "".format(pcRect.top)) print("[main.action] event.pos={}" "".format(event.pos)) print("[main.action] always_collide_mb={}" "".format(always_collide_mb)) result = read_event( controller1, event, pcRect=pcRect, mb_sids=('nab', 'nab', 'jump'), always_collide_mb=always_collide_mb, ) # ^ Set the wheel to nab and add 3, 4 & 5 to # always_collide_mb when in the air to allow # the roll combo using only a mouse but still # allowing both: # - nab would be impossible if left button # were in always_collide_mb--when not, click on # the character to nab, and click away to dart # or turn # - See "Mouse Controls" in readme.md. # 1: left # 2: middle # 3: right # 4: scroll up # 5: scroll down # ^ The first one in mb_sids is used for button 1. controller_changed = result > 0 if controller1.getBool('EXIT') and controller_changed: # The same button for exit is also pause. paused = True noise.pause() pausescreen = pygame.Surface( vista.screen.get_size()).convert_alpha() fade = pygame.Surface(vista.screen.get_size()).convert_alpha() fade.fill((0, 0, 0, 128)) pausescreen.blit(vista.screen, (0, 0)) pausescreen.blit(fade, (0, 0)) pausetitle = effect.PauseTitle(["PAUSED"]) pauseFmt = "Press [nab] to resume|or [BACK] to exit level" pauseStr = control_format(pauseFmt, controller1) pauseinfo = effect.PauseInfo([pauseStr]) pausetitle.position(pausescreen) pauseinfo.position(pausescreen) pausetitle.draw(pausescreen) pauseinfo.draw(pausescreen) if controller1.getBool('SCREENSHOT') and controller_changed: screenshot(vista.screen) if controller1.getBool('feat') and controller_changed: settings.hidefeatnames = not settings.hidefeatnames feat.startlevel(False) if controller1.getBool('FULLSCREEN') and controller_changed: settings.fullscreen = not settings.fullscreen vista.init() # k = pygame.key.get_pressed() # k = controller1.toKeys() kcombo = combo.get_combo(controller1) if settings.verbose: if (kcombo is not None) and (kcombo != ""): print("[main] kcombo={}".format(kcombo)) # else: # print("[main] controller1._states={}" # "".format(controller1._states)) for event in up_events: # Process these after combos in case down and up were on # the same frame. For further details about # read_event see the first call (this one should match it, # but always_collide_mb doesn't matter on MOUSEBUTTONUP. always_collide_mb = None result = read_event( controller1, event, pcRect=pcRect, mb_sids=('nab', 'nab', 'jump', 'nab', 'nab'), always_collide_mb=always_collide_mb, ) # print("PRESSED:{}".format(controller1.getTrues())) if grounded: # print("ground combo:{}".format(kcombo)) dx = 0 if controller1.getInt('x') > 0: dx += runvx * dt elif controller1.getInt('x') < 0: dx -= runvx * dt if nabtick: dx = 0 if not is_active(cdeffect): dx = 0 kcombo = "" if dx: facingright = dx > 0 currentfeat = "run" x += dx elif not nabtick: currentfeat = "" if kcombo == "leap" and "leap" in feat.known: if feat.attempt("leap"): vx = leapvx if facingright else -leapvx vy = leapvy combocount = 1 grounded = False currentfeat = "leap" noise.play("hop") elif kcombo == "twirl" and "twirl" in feat.known: if feat.attempt("twirl"): combocount = 1 grounded = False currentfeat = "twirl" vx = 0 vy = twirlvy twirltick = 1 noise.play("rotor") elif kcombo == "nab" and "nab" in feat.known: if feat.attempt("nab"): currentfeat = "nab" nabtick = nabtime noise.play("woosh") elif kcombo == ("roll-r" if facingright else "roll-l") and "roll" in feat.known: if feat.attempt("roll"): grounded = False currentfeat = "roll" vx = (rollvx if facingright else -rollvx) vy = rollvy combocount = 1 rolltick = 1 twirltick = 0 noise.play("rotor") elif kcombo == ("dart-r" if facingright else "dart-l") and "dart" in feat.known: if feat.attempt("dart"): grounded = False currentfeat = "dart" vx = (dartvx if facingright else -dartvx) vy = dartvy combocount = 1 rolltick = 0 twirltick = 0 noise.play("hop") elif kcombo == ("dart-l" if facingright else "dart-r") and "bound" in feat.known: if feat.attempt("bound"): grounded = False currentfeat = "bound" vx = (boundvx if facingright else -boundvx) vy = boundvy combocount = 1 rolltick = 0 twirltick = 0 noise.play("hop") else: # print("air combo:{}".format(kcombo)) if kcombo == "leap" and "leap" in feat.known: if feat.attempt("leap"): vx = leapvx if facingright else -leapvx vy = leapvy combocount += 1 currentfeat = "leap" twirltick = 0 noise.play("hop") elif kcombo == ("turn-r" if facingright else "turn-l") and "turn" in feat.known: if feat.attempt("turn"): facingright = not facingright vx = leapvx if facingright else -leapvx vy = leapvy combocount += 1 twirltick = 0 rolltick = 0 currentfeat = "leap" noise.play("hop") elif kcombo == "nab" and "nab" in feat.known: if feat.attempt("nab"): currentfeat = "nab" nabtick = nabtime vx = nabvx if facingright else -nabvx combocount += 1 twirltick = 0 rolltick = 0 noise.play("woosh") elif kcombo == "twirl" and "twirl" in feat.known: if feat.attempt("twirl"): currentfeat = "twirl" vx = 0 vy = twirlvy combocount += 1 twirltick = 1 rolltick = 0 noise.play("rotor") elif kcombo == ("roll-r" if facingright else "roll-l") and "roll" in feat.known: if feat.attempt("roll"): currentfeat = "roll" vx = (rollvx if facingright else -rollvx) vy = rollvy combocount += 1 rolltick = 1 twirltick = 0 noise.play("rotor") elif kcombo == ("dart-r" if facingright else "dart-l") and "dart" in feat.known: if feat.attempt("dart"): currentfeat = "dart" vx = (dartvx if facingright else -dartvx) vy = dartvy combocount += 1 rolltick = 0 twirltick = 0 noise.play("hop") elif kcombo == ("dart-l" if facingright else "dart-r") and "bound" in feat.known: if feat.attempt("bound"): currentfeat = "bound" vx = (boundvx if facingright else -boundvx) vy = boundvy combocount += 1 rolltick = 0 twirltick = 0 noise.play("hop") if nabtick: x += vx * dt else: x += vx * dt y += vy * dt - 0.5 * g * dt**2 vy -= g * dt if y < 0: y = 0 vy = 0 grounded = True combocount = 0 feat.land() ach = record.getrecords() if ach: effects.append(effect.AchievementEffect(ach)) currentfeat = "" twirltick = 0 rolltick = 0 x, y = vista.constrain(x, y, 30) nx, ny, nr = None, None, None if nabtick: nabtick = max(nabtick - dt, 0) if not nabtick: currentfeat = "" if grounded else "leap" nx, ny = x + (40 if facingright else -40), y + 80 nr = nabradius elif currentfeat == "twirl": nx, ny = x, y + 80 nr = twirlradius elif currentfeat == "roll": nx, ny = x, y + 50 nr = rollradius if nx is not None: for b in list(butterflies): adx, ady = b.x - nx, b.y - ny if adx**2 + ady**2 < nr**2: b.nabbed = True butterflies.remove(b) value = 3 * b.value if settings.easy else b.value effects.append(effect.NabBonusIndicator(value, (b.x, b.y))) if grounded: ach = record.checknabgrounded(b) if ach: effects.append(effect.AchievementEffect(ach)) else: record.checknab(b) heffect.update(y / 25.) heffect.position(vista.screen) ceffect.update(combocount) ceffect.position(vista.screen) peffect.update(record.catchamount) cdeffect.position(vista.screen) hbonus = record.checkheightrecord(y / 25.) if hbonus: effects.append(effect.HeightBonusIndicator(hbonus)) cbonus = record.checkcomborecord(combocount) if cbonus: effects.append(effect.ComboBonusIndicator(cbonus)) if currentfeat == "leap": picname = "run2" elif currentfeat == "run": picname = ("run0", "run1", "run2", "run1")[int(4 * runtick / 0.5)] runtick += dt runtick %= 0.5 elif currentfeat == "nab": picname = ("nab3", "nab2", "nab1", "nab0")[int(4. * nabtick / nabtime)] if not grounded: picname = "sky" + picname elif currentfeat == "twirl": twirltick += dt picname = ("twirl0", "twirl1", "twirl2", "twirl3")[int(4 * twirltick / 0.25) % 4] elif currentfeat == "roll": rolltick += dt picname = "roll%s" % (int(8 * rolltick / 0.35) % 8) elif currentfeat == "dart": picname = "dart" elif currentfeat == "bound": picname = "bound" else: picname = "stand" if "twirl" not in picname and not facingright: picname = picname + "-b" vista.position((x, y), facingright, vy) butterflies += loadlevel.newbutterflies(level, dt) feat.think(dt) vista.think(dt) for b in butterflies: b.think(dt) # seffect.set_verbose(True) seffect.think(dt) # if not seffect: # never occurs :( # if not bool(seffect): # never occurs :( if not is_active(seffect): # ^ __bool__() must be called manually-- # The reason seffect is always True even when is the # self.texts evaluates to False in the method is unknown. # Redefining __bool__ in the subclass doesn't help. See # <https://github.com/poikilos/lepidopterist/issues/12>. titleEffect.think(dt) for fx in effects: fx.think(dt) effects = [fx for fx in effects if is_active(fx)] ceffect.think(dt) if not is_active(titleEffect): cdeffect.think(dt) # titleEffect.set_verbose(True) # if prevTitleStr != titleEffect.debug(): # print("titleEffect: '{}'".format(titleEffect.debug())) # prevTitleStr = titleEffect.debug() if grounded and not is_active(cdeffect) and not effects and not ending: ending = True if record.catchamount >= goal: w = ["Stage complete!"] unlocked = record.unlocked w += record.checkhiscore(level) if record.unlocked > unlocked: level = record.unlocked else: w = ["Stage incomplete"] with open('contestdata.txt', 'a') as myfile: now = datetime.now() myfile.write(str(now) + '\n') myfile.write('level=' + str(level) + '\n') myfile.write('record.catchamount=' + str(record.catchamount) + '\n') myfile.write('record.collected=' + str(record.collected) + '\n') w += feat.checknewfeat(len(record.collected)) endtitle = effect.EndEffect(w) if ending and is_active(endtitle): endtitle.think(dt) vista.clear() sprite.frames[picname].draw((x, y)) # ^ draw uses vista so x,y is modifies by camera panning # Player Character: if prevPCKey is None: prevPCKey = "stand" ''' pcPos = vista.get_screen_pos((x, y)) pcRect = sprite.frames[prevPCKey].image.get_rect() pcRect.width = pcRect.width * 1.5 pcRect.center = pcPos pcRect.height = pcRect.height * .4 pcRect.top -= pcRect.height / 2 ''' pcInternalRect = sprite.frames[prevPCKey].image.get_rect() pcRect = vista.get_frame_screen_rect( sprite.frames[prevPCKey], (x, y), width=pcInternalRect.width * 1.5, height=pcInternalRect.height / 2, ) pcRect.height *= 6 # ^ allow clicking below the character for nab prevPCKey = picname for b in butterflies: b.draw() if nr is not None and settings.showdots: vista.circle((int(nx), int(ny)), int(nr)) feat.draw(facingright=facingright) heffect.draw(vista.screen) ceffect.draw(vista.screen) cdeffect.draw(vista.screen) peffect.draw(vista.screen) for fx in effects: fx.draw(vista.screen) seffect.draw(vista.screen) if not is_active(seffect): titleEffect.draw(vista.screen) if ending and is_active(endtitle): endtitle.draw(vista.screen) if is_active(touchEffect): if pcRect is not None: if settings.visualDebug: pygame.draw.rect(vista.screen, idleColor, pcRect) pygame.draw.circle(vista.screen, whiteColor, (int(pcPos[0]), int(pcPos[1])), 10) touchEffect.draw(vista.screen) pygame.draw.circle(vista.screen, touchColor, (touchEffect.x0, touchEffect.y0), 10) pygame.display.flip() if not is_active(endtitle): return
def update(): """Update ball/paddle/bricks based on physics""" #Keep track of variables changes with gameplay score = 0 lives = 0 #Update paddle location location = PADDLE.sprites()[0].rect.left offset = 0 if events.get("LEFT", 0) or events.get("LEFT", 1): offset = -16 if location + offset < 0: offset = 0 if events.get("RIGHT", 0) or events.get("RIGHT", 1): offset = 16 if location + offset > 1152: offset = 0 PADDLE.sprites()[0].update(x=offset) #Update ball locations for i in BALLS.sprites(): v = i.custom['v'] #Collisions ballEdge = (i.rect.topleft[0], i.rect.topleft[1], i.rect.topleft[0] + 16, i.rect.topleft[1] + 16) collide = None #Screen edge collisions if ballEdge[0] <= 0 or ballEdge[2] >= 1280: collide = 'x' noise.play('bounce') if ballEdge[1] <= 32: collide = 'y' noise.play('bounce') if ballEdge[3] >= 780: lives = -1 i.remove(BALLS) noise.play('miss') break collisions = pygame.sprite.spritecollide(i, BRICKS, 0) #Brick collisions if len(collisions) > 0: for j in collisions: #For each collision... score += 250 j.custom['i'] -= 1 if j.custom['i'] < 0: #Remove brick if it was the final brick j.remove(BRICKS) noise.play('break') else: #Reduce brick in toughness j.image = img.CACHE['brick%i' % j.custom['i']] noise.play('bounce') if i.rect.top <= j.rect.bottom and i.custom['v'][1] > 0: collide = 'y' if i.rect.bottom >= j.rect.top and i.custom['v'][1] < 0: collide = 'y' if i.rect.left <= j.rect.right and i.custom['v'][ 0] < 0 and i.rect.right > j.rect.right: collide = 'x' if i.rect.right >= j.rect.left and i.custom['v'][ 0] > 0 and i.rect.left < j.rect.left: collide = 'x' collisions = pygame.sprite.spritecollide(i, PADDLE, 0) #Paddle collision if len(collisions) > 0: paddleXY = collisions[0].rect.topleft paddleCenter = collisions[0].rect.centerx ballCenter = i.rect.centerx hitBox = ballCenter - paddleCenter newX = float(hitBox) / (paddleCenter - paddleXY[0]) if newX > 0.45: hitPercent = 0.45 elif newX < -0.45: hitPercent = -0.45 if newX >= 0: newY = 1 - newX elif newX < 0: newY = 1 + newX i.custom['v'] = [newX, newY] noise.play('bounce') if collide == 'x': i.custom['v'][0] *= -1 if collide == 'y': i.custom['v'][1] *= -1 #Update ball location based off magnitude and rise/run x = int(round(i.custom['v'][0] * 16, 0)) y = int(round(i.custom['v'][1] * 16 * -1, 0)) i.update(x, y) return (score, lives)
def worldmap(): global level if settings.unlockall: record.unlocked = 6 vista.mapinit() levelnames = [ "Stage 1: Mortimer's backyard", "Stage 2: Dojo of the Royal Lepidopteral Society", "Stage 3: Bucolic Meadow of Doom", "Stage 4: Some field you have to cross", "Stage 5: Imperial palace of|the Royal Society of Lepidopterists", "Final stage:|The Lost Buttefly Garden of Verdania" ] levelps = [(150, 90), (250, 130), (350, 110), (450, 150), (550, 130), (650, 170)] clock = pygame.time.Clock() teffect = effect.LevelNameEffect("") speffect = effect.PressSpaceEffect(["Press Space to choose level"]) speffect.position(vista.screen) hseffect = effect.HighScoreEffect("") hceffect = effect.HCRecord([record.gethcrecord()]) hceffect.position(vista.screen) updateteffect = True udseq = [] esign = None while True: dt = clock.tick(60) * 0.001 if settings.printfps and random.random() < dt: print clock.get_fps() for event in pygame.event.get(): if event.type == QUIT: exit() elif event.type == KEYDOWN and event.key == K_ESCAPE: exit() elif event.type == KEYDOWN and event.key == K_F12: pygame.image.save(vista.screen, "screenshot.png") elif event.type == KEYDOWN and event.key == K_RIGHT: udseq = [] if level < record.unlocked: level += 1 updateteffect = True elif event.type == KEYDOWN and event.key == K_LEFT: udseq = [] if level > 1: level -= 1 updateteffect = True elif event.type == KEYDOWN and event.key in (K_UP, K_DOWN): udseq.append(0 if event.key == K_UP else 1) if len(udseq) >= 8 and tuple( udseq[-8:]) == (0, 0, 1, 1, 0, 0, 1, 1) and not settings.easy: settings.easy = True esign = effect.EasyModeIndicator(["Easy Mode Activated!"]) esign.position(vista.screen) udseq = [] noise.play("cha-ching") elif event.type == KEYDOWN and event.key == K_SPACE: return if updateteffect: teffect.update(levelnames[level - 1]) teffect.position(vista.screen) updateteffect = False hstext = u"high score: \u00A3%s" % record.hiscore[ level] if level in record.hiscore else "" hseffect.update(hstext) hseffect.position(vista.screen) if esign: esign.think(dt) vista.mapclear() for j in range(1, record.unlocked): x0, y0 = levelps[j - 1] x1, y1 = levelps[j] vista.line((x0, y0 - 6), (x1, y1 - 6), (0, 0, 0), (200, 200, 200)) for p in levelps: sprite.frames["leveldisk"].draw(p) sprite.frames["stand"].draw(levelps[level - 1]) teffect.draw(vista.screen) # speffect.draw(vista.screen) hseffect.draw(vista.screen) hceffect.draw(vista.screen) if esign: esign.draw(vista.screen) pygame.display.flip()
def worldmap(): global level global touchEffect global touchEffectPos global touchColor controller1.clearPressed() if settings.unlockall: record.unlocked = 6 vista.mapinit() levelnames = [ "Stage 1: Mortimer's backyard", "Stage 2: Dojo of the Royal Lepidopteral Society", "Stage 3: Bucolic Meadow of Doom", "Stage 4: Some field you have to cross", "Stage 5: Imperial palace of|the Royal Society of Lepidopterists", "Final stage:|The Lost Buttefly Garden of Verdania" ] levelps = [(150, 90), (250, 130), (350, 110), (450, 150), (550, 130), (650, 170)] clock = pygame.time.Clock() teffect = effect.LevelNameEffect("") chooseLevelFmt = "Press nab to choose level" chooseLevelStr = control_format(chooseLevelFmt, controller1) speffect = effect.PressSpaceEffect([chooseLevelStr]) speffect.position(vista.screen) hseffect = effect.HighScoreEffect("") hceffect = effect.HCRecord([record.gethcrecord()]) hceffect.position(vista.screen) updateteffect = True udseq = [] esign, rsign = None, None pcRect = None pcPos = None while True: dt = clock.tick(60) * 0.001 if settings.printfps and random.random() < dt: print(clock.get_fps()) events = [] if pcPos is not None: # Don't check or discard events until the rect is obtained. events = pygame.event.get() touchText = None for event in events: result = 0 if event.type == QUIT: sys.exit() # ^ This is OK since QUIT already occurred. else: # pcRect may be None for a frame but read_event # is ok with that. result = read_event( controller1, event, pcRect=pcRect, mb_sids=('nab', ), # always_collide_mb=always_collide_mb, ) # if touchText is not None: # touchText = str(result) + ": " + touchText # print(touchText) if result < 2: # ^ 2 is for if hat is being pressed down or the # analog stick is past the deadZone and wasn't before. continue ''' print( "worldmap event result: {}; x:{}; y:{}; pressed:{};" " last_read_actuator_info:{}" "".format( result, controller1.getInt('x'), controller1.getInt('y'), controller1.getTrues(), last_read_actuator_info(), ) ) ''' if controller1.getBool('SCREENSHOT'): screenshot(vista.screen) if controller1.getInt('x') > 0: udseq = [] if level < record.unlocked: level += 1 updateteffect = True if controller1.getInt('x') < 0: udseq = [] if level > 1: level -= 1 updateteffect = True upValue = controller1.getInt('y') < 0 downValue = controller1.getInt('y') > 0 if (upValue or downValue) and not easy_locked(): udseq.append(0 if upValue else 1) # Activate Easy Mode if len(udseq) >= 8 and tuple( udseq[-8:]) == (0, 0, 1, 1, 0, 0, 1, 1) and not settings.easy: settings.easy = True esign = effect.EasyModeIndicator(["Easy Mode Activated!"]) esign.position(vista.screen) udseq = [] noise.play("cha-ching") # Display all cut scenes if len(udseq) >= 8 and tuple( udseq[-8:]) == (0, 1, 1, 1, 1, 0, 0, 0): settings.alwaysshow = True for level in (1, 2, 3, 4, 5, 6, 7): if level in (1, 4): noise.play("gnos") if level in (2, 5): noise.play("one") if level in (3, 6): noise.play("xylo") cutscene() rollcredits() theend() # Delete the saved game if len(udseq) >= 8 and tuple( udseq[-8:]) == (0, 1, 0, 0, 1, 0, 1, 1): game.remove() rsign = effect.EasyModeIndicator(["Save game deleted!"]) rsign.position(vista.screen) udseq = [] noise.play("cha-ching") if controller1.getBool('nab'): # Enter an area (exit the world map): print("* exiting world map") controller1._states['x'] = 0 return if controller1.getBool('FULLSCREEN'): settings.fullscreen = not settings.fullscreen vista.init() if updateteffect: teffect.update(levelnames[level - 1]) teffect.position(vista.screen) updateteffect = False hstext = "high score: LLL%s" % record.hiscore[ level] if level in record.hiscore else "" hseffect.update(hstext) hseffect.position(vista.screen) if (esign is not None) and is_active(esign): esign.think(dt) if (rsign is not None) and is_active(rsign): rsign.think(dt) if not is_active(rsign): sys.exit() vista.mapclear() for j in range(1, record.unlocked): x0, y0 = levelps[j - 1] x1, y1 = levelps[j] vista.line((x0, y0 - 6), (x1, y1 - 6), (0, 0, 0), (200, 200, 200)) for p in levelps: sprite.frames["leveldisk"].draw(p) sprite.frames["stand"].draw(levelps[level - 1]) pcRect = vista.get_frame_screen_rect( sprite.frames["stand"], levelps[level - 1], width=sprite.frames["stand"].image.get_rect().width * .7, ) pcPos = vista.get_screen_pos(levelps[level - 1]) # ^ Player Character teffect.draw(vista.screen) # speffect.draw(vista.screen) hseffect.draw(vista.screen) hceffect.draw(vista.screen) if is_active(esign): esign.draw(vista.screen) if is_active(rsign): rsign.draw(vista.screen) if pcRect is not None: if settings.visualDebug: pygame.draw.rect(vista.screen, idleColor, pcRect) if is_active(touchEffect): # touchEffect.draw(vista.screen, center=touchEffectPos) touchEffect.draw(vista.screen) pygame.draw.circle(vista.screen, touchColor, (touchEffect.x0, touchEffect.y0), 10) pygame.display.flip()
def shop(): vista.mapinit() feat.startlevel() clock = pygame.time.Clock() shopHelpFmt = " [EXIT] |or Choose an upgrade" if gamepad_used(): shopHelpFmt += " [nab]" shopHelpStr = controller1.format( shopHelpFmt, gamepad_used(), keycode_to_str=pygame.key.name, add_key_str=False, add_btn_str=False, opening='(', closing=')', ) speffect = effect.PressSpaceEffect([shopHelpStr]) speffect.position(vista.screen) ueffect = effect.UpgradeTitle(["Upgrade abilities"]) ueffect.position(vista.screen) deffect = effect.ContinueIndicator() deffect.position(vista.screen) beffect = effect.BankIndicator(record.bank) beffect.position(vista.screen) pointer = 0 nfeat = len(feat.known) + 1 pointerys = [ 82 + int(32 * j) for j in list(range(len(feat.known))) + [7.5] ] feats = [featK for featK in feat.allfeats if featK in feat.known] pricetags = [ effect.CostIndicator(feat.getupgradecost(featK), j) for j, featK in enumerate(feats) ] while True: dt = clock.tick(60) * 0.001 if settings.printfps and random.random() < dt: print(clock.get_fps()) for event in pygame.event.get(): buy = False result = 0 done = False if event.type == QUIT: sys.exit() elif event.type == MOUSEBUTTONDOWN: x, y = event.pos if deffect.rect.collidepoint(x, y): # ^ deffect is the ContinueIndicator instance. # done = True return else: for i, featK in enumerate(feats): tmpFeat = feat.feateffects[featK] # ^ These rects are near the top left. # Instead see `def draw` in the feat module # (the shopping boolean is True case). tmpRect = tmpFeat.rect.move(feat.shop_pos) if tmpRect.collidepoint(x, y): pointer = i buy = True # else: # print("{} is not in {}" # "".format((x,y), tmpFeat.rect)) else: result = read_event( controller1, event, # pcRect=None, # leave default None--non-directional # mb_sids=('nab', None, 'EXIT'), # ^ unused in shop since MOUSEBUTTONDOWN is custom # always_collide_mb=2, # ^ leave default None--non-directional ) if (not buy) and (result < 2): continue # print("shop event result: {}; y: {}" # "".format(result, controller1.getInt('y'))) if controller1.getBool('EXIT'): # done = True return elif controller1.getBool('SCREENSHOT'): screenshot(vista.screen) elif controller1.getBool('FULLSCREEN'): settings.fullscreen = not settings.fullscreen vista.init() elif controller1.getInt('y') < 0: pointer -= 1 pointer %= nfeat elif controller1.getInt('y') > 0: pointer += 1 pointer %= nfeat elif controller1.getBool('nab'): buy = True if buy: buy = False if pointer == nfeat - 1: return cost = feat.getupgradecost(feats[pointer]) if cost and record.bank >= cost: record.bank -= cost feat.known[feats[pointer]] += 1 feat.bars[feats[pointer]] = feat.known[feats[pointer]] pricetags[pointer].update( feat.getupgradecost(feats[pointer])) beffect.update(record.bank) beffect.position(vista.screen) noise.play("cha-ching") vista.mapclear() feat.draw(shopping=True) pygame.draw.circle(vista.screen, (255, 128, 0), (152, pointerys[pointer]), 4) if pointer != nfeat - 1: speffect.draw(vista.screen) deffect.draw(vista.screen) beffect.draw(vista.screen) ueffect.draw(vista.screen) for tag in pricetags: tag.draw(vista.screen) pygame.display.flip()
def __init__(self, hb): noise.play("cha-ching") Effect.__init__(self, ["LLL%s" % hb])
def update(): """Update ball/paddle/bricks based on physics""" #Keep track of variables changes with gameplay score = 0 lives = 0 #Update paddle location location = PADDLE.sprites()[0].rect.left offset = 0 if events.get("LEFT", 0) or events.get("LEFT", 1): offset = -16 if location + offset < 0: offset = 0 if events.get("RIGHT", 0) or events.get("RIGHT", 1): offset = 16 if location + offset > 1152: offset = 0 PADDLE.sprites()[0].update(x=offset) #Update ball locations for i in BALLS.sprites(): v = i.custom['v'] #Collisions ballEdge = (i.rect.topleft[0], i.rect.topleft[1], i.rect.topleft[0]+16, i.rect.topleft[1]+16) collide = None #Screen edge collisions if ballEdge[0] <= 0 or ballEdge[2] >= 1280: collide = 'x' noise.play('bounce') if ballEdge[1] <= 32: collide = 'y' noise.play('bounce') if ballEdge[3] >= 780: lives = -1 i.remove(BALLS) noise.play('miss') break collisions = pygame.sprite.spritecollide(i, BRICKS, 0) #Brick collisions if len(collisions) > 0: for j in collisions: #For each collision... score += 250 j.custom['i'] -= 1 if j.custom['i'] < 0: #Remove brick if it was the final brick j.remove(BRICKS) noise.play('break') else: #Reduce brick in toughness j.image = img.CACHE['brick%i' % j.custom['i']] noise.play('bounce') if i.rect.top <= j.rect.bottom and i.custom['v'][1] > 0: collide = 'y' if i.rect.bottom >= j.rect.top and i.custom['v'][1] < 0: collide = 'y' if i.rect.left <= j.rect.right and i.custom['v'][0] < 0 and i.rect.right > j.rect.right: collide = 'x' if i.rect.right >= j.rect.left and i.custom['v'][0] > 0 and i.rect.left < j.rect.left: collide = 'x' collisions = pygame.sprite.spritecollide(i, PADDLE, 0) #Paddle collision if len(collisions) > 0: paddleXY = collisions[0].rect.topleft paddleCenter = collisions[0].rect.centerx ballCenter = i.rect.centerx hitBox = ballCenter - paddleCenter newX = float(hitBox) / (paddleCenter - paddleXY[0]) if newX > 0.45: hitPercent = 0.45 elif newX < -0.45: hitPercent = -0.45 if newX >= 0: newY = 1 - newX elif newX < 0: newY = 1 + newX i.custom['v'] = [newX, newY] noise.play('bounce') if collide == 'x': i.custom['v'][0] *= -1 if collide == 'y': i.custom['v'][1] *= -1 #Update ball location based off magnitude and rise/run x = int( round(i.custom['v'][0] * 16, 0) ) y = int( round(i.custom['v'][1] * 16 * -1, 0) ) i.update(x,y) return (score, lives)