def __init__(self, pid, config, songconf, game): self.theme = GFXTheme(mainconfig.get("%s-theme" % game.theme, "default"), pid, game) self.pid = pid self.failed = False self.escaped = False self.__dict__.update(config) if self.speed < 0: self.target_bpm = -self.speed else: self.target_bpm = None self.game = game if self.scrollstyle == 2: self.top = 240 - game.width / 2 elif self.scrollstyle == 1: self.top = 352 else: self.top = 64 self.secret_kind = songconf["secret"] self.score = scores.scores[songconf["scoring"]](pid, "NONE", game) self.combos = combos.combos[songconf["combo"]](pid, game) self.grade = grades.grades[songconf["grade"]]() Lifebar = lifebars.bars[songconf["lifebar"]] self.lifebar = Lifebar(pid, self.theme, songconf, game) self.judging_disp = JudgingDisp(self.pid, game) self.stats = stats.Stats() self.announcer = Announcer(mainconfig["djtheme"]) self.listeners = [self.combos, self.score, self.grade, self.lifebar, self.judging_disp, self.stats, self.announcer] if not game.double: self.judge = judge.judges[songconf["judge"]](self.pid, songconf) self.listeners.append(self.judge) arr, arrfx = self.theme.toparrows(self.top, self.pid) self.toparr = arr self.toparrfx = arrfx self.listeners.extend(arr.values() + arrfx.values()) self.holdtext = HoldJudgeDisp(self.pid, self, self.game) self.listeners.append(self.holdtext) else: Judge = judge.judges[songconf["judge"]] self.judge = [Judge(self.pid * 2, songconf), Judge(self.pid * 2 + 1, songconf)] self.listeners.extend(self.judge) arr1, arrfx1 = self.theme.toparrows(self.top, self.pid * 2) arr2, arrfx2 = self.theme.toparrows(self.top, self.pid * 2 + 1) self.arrows = [self.theme.arrows(self.pid * 2), self.theme.arrows(self.pid * 2 + 1)] self.toparr = [arr1, arr2] self.toparrfx = [arrfx1, arrfx2] self.listeners.extend(arr1.values() + arr2.values() + arrfx1.values() + arrfx2.values()) self.holdtext = [HoldJudgeDisp(self.pid * 2, self, self.game), HoldJudgeDisp(self.pid * 2 + 1, self, self.game)] self.listeners.extend(self.holdtext)
def __init__(self, pid, config, songconf, game): self.theme = GFXTheme( mainconfig.get("%s-theme" % game.theme, "default"), pid, game) self.pid = pid self.failed = False self.escaped = False self.__dict__.update(config) if self.speed < 0: self.target_bpm = -self.speed else: self.target_bpm = None self.game = game if self.scrollstyle == 2: self.top = 240 - game.width / 2 elif self.scrollstyle == 1: self.top = 352 else: self.top = 64 self.secret_kind = songconf["secret"] self.score = scores.scores[songconf["scoring"]](pid, "NONE", game) self.combos = combos.combos[songconf["combo"]](pid, game) self.grade = grades.grades[songconf["grade"]]() Lifebar = lifebars.bars[songconf["lifebar"]] self.lifebar = Lifebar(pid, self.theme, songconf, game) self.judging_disp = JudgingDisp(self.pid, game) self.stats = stats.Stats() self.announcer = Announcer(mainconfig["djtheme"]) self.listeners = [ self.combos, self.score, self.grade, self.lifebar, self.judging_disp, self.stats, self.announcer ] if not game.double: self.judge = judge.judges[songconf["judge"]](self.pid, songconf) self.listeners.append(self.judge) arr, arrfx = self.theme.toparrows(self.top, self.pid) self.toparr = arr self.toparrfx = arrfx self.listeners.extend(arr.values() + arrfx.values()) self.holdtext = HoldJudgeDisp(self.pid, self, self.game) self.listeners.append(self.holdtext) else: Judge = judge.judges[songconf["judge"]] self.judge = [ Judge(self.pid * 2, songconf), Judge(self.pid * 2 + 1, songconf) ] self.listeners.extend(self.judge) arr1, arrfx1 = self.theme.toparrows(self.top, self.pid * 2) arr2, arrfx2 = self.theme.toparrows(self.top, self.pid * 2 + 1) self.arrows = [ self.theme.arrows(self.pid * 2), self.theme.arrows(self.pid * 2 + 1) ] self.toparr = [arr1, arr2] self.toparrfx = [arrfx1, arrfx2] self.listeners.extend(arr1.values() + arr2.values() + arrfx1.values() + arrfx2.values()) self.holdtext = [ HoldJudgeDisp(self.pid * 2, self, self.game), HoldJudgeDisp(self.pid * 2 + 1, self, self.game) ] self.listeners.extend(self.holdtext)
class Player(object): def __init__(self, pid, config, songconf, game): self.theme = GFXTheme( mainconfig.get("%s-theme" % game.theme, "default"), pid, game) self.pid = pid self.failed = False self.escaped = False self.__dict__.update(config) if self.speed < 0: self.target_bpm = -self.speed else: self.target_bpm = None self.game = game if self.scrollstyle == 2: self.top = 240 - game.width / 2 elif self.scrollstyle == 1: self.top = 352 else: self.top = 64 self.secret_kind = songconf["secret"] self.score = scores.scores[songconf["scoring"]](pid, "NONE", game) self.combos = combos.combos[songconf["combo"]](pid, game) self.grade = grades.grades[songconf["grade"]]() Lifebar = lifebars.bars[songconf["lifebar"]] self.lifebar = Lifebar(pid, self.theme, songconf, game) self.judging_disp = JudgingDisp(self.pid, game) self.stats = stats.Stats() self.announcer = Announcer(mainconfig["djtheme"]) self.listeners = [ self.combos, self.score, self.grade, self.lifebar, self.judging_disp, self.stats, self.announcer ] if not game.double: self.judge = judge.judges[songconf["judge"]](self.pid, songconf) self.listeners.append(self.judge) arr, arrfx = self.theme.toparrows(self.top, self.pid) self.toparr = arr self.toparrfx = arrfx self.listeners.extend(arr.values() + arrfx.values()) self.holdtext = HoldJudgeDisp(self.pid, self, self.game) self.listeners.append(self.holdtext) else: Judge = judge.judges[songconf["judge"]] self.judge = [ Judge(self.pid * 2, songconf), Judge(self.pid * 2 + 1, songconf) ] self.listeners.extend(self.judge) arr1, arrfx1 = self.theme.toparrows(self.top, self.pid * 2) arr2, arrfx2 = self.theme.toparrows(self.top, self.pid * 2 + 1) self.arrows = [ self.theme.arrows(self.pid * 2), self.theme.arrows(self.pid * 2 + 1) ] self.toparr = [arr1, arr2] self.toparrfx = [arrfx1, arrfx2] self.listeners.extend(arr1.values() + arr2.values() + arrfx1.values() + arrfx2.values()) self.holdtext = [ HoldJudgeDisp(self.pid * 2, self, self.game), HoldJudgeDisp(self.pid * 2 + 1, self, self.game) ] self.listeners.extend(self.holdtext) def set_song(self, song, diff, lyrics): self.difficulty = diff if self.game.double: self.holding = [[-1] * len(self.game.dirs), [-1] * len(self.game.dirs)] if self.transform == 1: # In double mirror mode, we have to swap the step sets for this # player's pids. This ensures, e.g., 1R becomes 2L, rather than 1L. self.steps = [ steps.Steps(song, diff, self, self.pid * 2 + 1, lyrics, self.game.name), steps.Steps(song, diff, self, self.pid * 2, lyrics, self.game.name) ] else: self.steps = [ steps.Steps(song, diff, self, self.pid * 2, lyrics, self.game.name), steps.Steps(song, diff, self, self.pid * 2 + 1, lyrics, self.game.name) ] self.length = max(self.steps[0].length, self.steps[1].length) self.ready = min(self.steps[0].ready, self.steps[1].ready) self.bpm = self.steps[0].bpm count = self.steps[0].totalarrows + self.steps[1].totalarrows total_holds = 0 for i in range(2): total_holds += len(self.steps[i].holdref) args = (self.pid, self.bpm, diff, count, total_holds, self.steps[0].feet) for l in self.listeners: l.set_song(*args) else: self.holding = [-1] * len(self.game.dirs) self.steps = steps.Steps(song, diff, self, self.pid, lyrics, self.game.name) self.length = self.steps.length self.ready = self.steps.ready self.bpm = self.steps.bpm self.arrows = self.theme.arrows(self.pid) holds = len(self.steps.holdref) args = (self.pid, self.bpm, diff, self.steps.totalarrows, holds, self.steps.feet) for l in self.listeners: l.set_song(*args) def start_song(self): self.toparr_group = RenderUpdates() self.fx_group = RenderUpdates() self.text_group = RenderUpdates() self.text_group.add([self.score, self.lifebar, self.judging_disp]) self.text_group.add(self.holdtext) if mainconfig["showcombo"]: self.text_group.add(self.combos) if self.game.double: self.arrow_group = [OrderedRenderUpdates(), OrderedRenderUpdates()] for i in range(2): self.steps[i].play() for d in self.game.dirs: if mainconfig["explodestyle"] > -1: self.toparrfx[i][d].add(self.fx_group) if not self.dark: self.toparr[i][d].add(self.toparr_group) self.sprite_groups = [ self.toparr_group, self.arrow_group[0], self.arrow_group[1], self.fx_group, self.text_group ] else: self.steps.play() self.arrow_group = OrderedRenderUpdates() for d in self.game.dirs: if mainconfig["explodestyle"] > -1: self.toparrfx[d].add(self.fx_group) if not self.dark: self.toparr[d].add(self.toparr_group) self.sprite_groups = [ self.toparr_group, self.arrow_group, self.fx_group, self.text_group ] def get_next_events(self, song): if self.game.double: self.fx_data = [[], []] for i in range(2): self._get_next_events(song, self.arrow_group[i], self.arrows[i], self.steps[i], self.judge[i]) else: self.fx_data = [] self._get_next_events(song, self.arrow_group, self.arrows, self.steps, self.judge) def _get_next_events(self, song, arrow_grp, arrow_gfx, steps, judge): evt = steps.get_events() if evt is not None: events, nevents, time, bpm = evt for ev in events: if ev.feet: for (dir, num) in zip(self.game.dirs, ev.feet): if num & 1: judge.handle_arrow(dir, ev.when, num & 4) if self.fade == 5: return # Stealth mode newsprites = [] for ev in nevents: if ev.feet: for (dir, num) in zip(self.game.dirs, ev.feet): # Don't make hidden arrow sprites if we have hidden arrows # off entirely, or have them set not to display. if not num & 4 or self.secret_kind == 2: dirstr = dir + repr(int(ev.color) % self.colortype) if num & 1 and not num & 2: ns = arrows.ArrowSprite( arrow_gfx[dirstr], ev.beat, num & 4, ev.when, self, song) newsprites.append(ns) elif num & 2: holdindex = steps.holdref.index( (self.game.dirs.index(dir), ev.when)) ns = arrows.HoldArrowSprite( arrow_gfx[dirstr], steps.holdbeats[holdindex], num & 4, steps.holdinfo[holdindex], self, song) newsprites.append(ns) arrow_grp.add(newsprites) def check_sprites(self, curtime, curbeat, arrows, steps, fx_data, judge): misses = judge.expire_arrows(curtime) for d in misses: for l in self.listeners: l.stepped(self.pid, d, curtime, -1, "M", self.combos.combo) for rating, dir, time in fx_data: if (rating == "V" or rating == "P" or rating == "G"): for spr in arrows.sprites(): if spr.endtime == time and spr.dir == dir: if not spr.hold: spr.kill() arrows.update(curtime, self.bpm, curbeat, judge) self.toparr_group.update(curtime, curbeat) def should_hold(self, steps, direction, curtime): for i, l in enumerate(steps.holdinfo): if l[0] == self.game.dirs.index(direction): if ((curtime - 15.0 / steps.playingbpm > l[1]) and (curtime < l[2])): return i def check_holds(self, pid, curtime, arrows, steps, judge, toparrfx, holding): # FIXME THis needs to go away keymap_kludge = { "u": pad.UP, "k": pad.UPLEFT, "z": pad.UPRIGHT, "d": pad.DOWN, "l": pad.LEFT, "r": pad.RIGHT, "g": pad.DOWNRIGHT, "w": pad.DOWNLEFT, "c": pad.CENTER } for dir in self.game.dirs: toparrfx[dir].holding(0) current_hold = self.should_hold(steps, dir, curtime) dir_idx = self.game.dirs.index(dir) if current_hold is not None: if pad.states[(pid, keymap_kludge[dir])]: if judge.holdsub.get(holding[dir_idx]) != -1: toparrfx[dir].holding(1) holding[dir_idx] = current_hold botchdir, timef1, timef2 = steps.holdinfo[current_hold] for spr in arrows.sprites(): if (spr.endtime == timef1 and spr.dir == dir): spr.held() break else: if judge.holdsub.get(current_hold) != -1: botchdir, timef1, timef2 = steps.holdinfo[current_hold] for spr in arrows.sprites(): if (spr.endtime == timef1 and spr.dir == dir): if spr.broken_at(curtime, judge): args = (pid, curtime, dir, current_hold) for l in self.listeners: l.broke_hold(*args) break else: if holding[dir_idx] > -1: if judge.holdsub.get(holding[dir_idx]) != -1: args = (pid, curtime, dir, holding[dir_idx]) for l in self.listeners: l.ok_hold(*args) holding[dir_idx] = -1 def handle_key(self, ev, time): ev = ev[0], self.game.dirmap.get(ev[1], ev[1]) if ev[1] not in self.game.dirs: return if self.game.double: pid = ev[0] & 1 rating, dir, etime = self.judge[pid].handle_key(ev[1], time) for l in self.listeners: l.stepped(ev[0], dir, time, etime, rating, self.combos.combo) self.fx_data[pid].append((rating, dir, etime)) else: rating, dir, etime = self.judge.handle_key(ev[1], time) for l in self.listeners: l.stepped(ev[0], dir, time, etime, rating, self.combos.combo) self.fx_data.append((rating, dir, etime)) def check_bpm_change(self, pid, time, steps, judge): newbpm = self.bpm for bpm in steps.lastbpmchangetime: if time >= bpm[0]: newbpm = bpm[1] if newbpm != self.bpm: self.bpm = newbpm for l in self.listeners: l.change_bpm(pid, time, newbpm) def clear_sprites(self, screen, bg): for g in self.sprite_groups: g.clear(screen, bg) def game_loop(self, time, screen): if self.game.double: for i in range(2): if len(self.steps[i].lastbpmchangetime) == 0: cur_beat = (time - self.steps[i].offset) / (60.0 / self.bpm) else: cur_beat = 0 oldbpmsub = [self.steps[i].offset, self.steps[i].bpm] for bpmsub in self.steps[i].lastbpmchangetime: if bpmsub[0] <= time: cur_beat += (bpmsub[0] - oldbpmsub[0]) / (60.0 / oldbpmsub[1]) oldbpmsub = bpmsub else: break cur_beat += (time - oldbpmsub[0]) / (60.0 / oldbpmsub[1]) self.check_holds(self.pid * 2 + i, time, self.arrow_group[i], self.steps[i], self.judge[i], self.toparrfx[i], self.holding[i]) self.check_bpm_change(self.pid * 2 + i, time, self.steps[i], self.judge[i]) self.check_sprites(time, cur_beat, self.arrow_group[i], self.steps[i], self.fx_data[i], self.judge[i]) else: if len(self.steps.lastbpmchangetime) == 0: cur_beat = (time - self.steps.offset) / (60.0 / self.bpm) else: cur_beat = 0 oldbpmsub = [self.steps.offset, self.steps.bpm] for bpmsub in self.steps.lastbpmchangetime: if bpmsub[0] <= time: cur_beat += (bpmsub[0] - oldbpmsub[0]) / (60.0 / oldbpmsub[1]) oldbpmsub = bpmsub else: break cur_beat += (time - oldbpmsub[0]) / (60.0 / oldbpmsub[1]) self.check_holds(self.pid, time, self.arrow_group, self.steps, self.judge, self.toparrfx, self.holding) self.check_bpm_change(self.pid, time, self.steps, self.judge) self.check_sprites(time, cur_beat, self.arrow_group, self.steps, self.fx_data, self.judge) self.fx_group.update(time) self.text_group.update(time) if self.lifebar.gameover == lifebars.FAILED and not self.failed: self.failed = True rects = [] for g in self.sprite_groups: rects.extend(g.draw(screen)) return rects
class Player(object): def __init__(self, pid, config, songconf, game): self.theme = GFXTheme(mainconfig.get("%s-theme" % game.theme, "default"), pid, game) self.pid = pid self.failed = False self.escaped = False self.__dict__.update(config) if self.speed < 0: self.target_bpm = -self.speed else: self.target_bpm = None self.game = game if self.scrollstyle == 2: self.top = 240 - game.width / 2 elif self.scrollstyle == 1: self.top = 352 else: self.top = 64 self.secret_kind = songconf["secret"] self.score = scores.scores[songconf["scoring"]](pid, "NONE", game) self.combos = combos.combos[songconf["combo"]](pid, game) self.grade = grades.grades[songconf["grade"]]() Lifebar = lifebars.bars[songconf["lifebar"]] self.lifebar = Lifebar(pid, self.theme, songconf, game) self.judging_disp = JudgingDisp(self.pid, game) self.stats = stats.Stats() self.announcer = Announcer(mainconfig["djtheme"]) self.listeners = [self.combos, self.score, self.grade, self.lifebar, self.judging_disp, self.stats, self.announcer] if not game.double: self.judge = judge.judges[songconf["judge"]](self.pid, songconf) self.listeners.append(self.judge) arr, arrfx = self.theme.toparrows(self.top, self.pid) self.toparr = arr self.toparrfx = arrfx self.listeners.extend(arr.values() + arrfx.values()) self.holdtext = HoldJudgeDisp(self.pid, self, self.game) self.listeners.append(self.holdtext) else: Judge = judge.judges[songconf["judge"]] self.judge = [Judge(self.pid * 2, songconf), Judge(self.pid * 2 + 1, songconf)] self.listeners.extend(self.judge) arr1, arrfx1 = self.theme.toparrows(self.top, self.pid * 2) arr2, arrfx2 = self.theme.toparrows(self.top, self.pid * 2 + 1) self.arrows = [self.theme.arrows(self.pid * 2), self.theme.arrows(self.pid * 2 + 1)] self.toparr = [arr1, arr2] self.toparrfx = [arrfx1, arrfx2] self.listeners.extend(arr1.values() + arr2.values() + arrfx1.values() + arrfx2.values()) self.holdtext = [HoldJudgeDisp(self.pid * 2, self, self.game), HoldJudgeDisp(self.pid * 2 + 1, self, self.game)] self.listeners.extend(self.holdtext) def set_song(self, song, diff, lyrics): self.difficulty = diff if self.game.double: self.holding = [[-1] * len(self.game.dirs), [-1] * len(self.game.dirs)] if self.transform == 1: # In double mirror mode, we have to swap the step sets for this # player's pids. This ensures, e.g., 1R becomes 2L, rather than 1L. self.steps = [steps.Steps(song, diff, self, self.pid * 2 + 1, lyrics, self.game.name), steps.Steps(song, diff, self, self.pid * 2, lyrics, self.game.name)] else: self.steps = [steps.Steps(song, diff, self, self.pid * 2, lyrics, self.game.name), steps.Steps(song, diff, self, self.pid * 2 + 1, lyrics, self.game.name)] self.length = max(self.steps[0].length, self.steps[1].length) self.ready = min(self.steps[0].ready, self.steps[1].ready) self.bpm = self.steps[0].bpm count = self.steps[0].totalarrows + self.steps[1].totalarrows total_holds = 0 for i in range(2): total_holds += len(self.steps[i].holdref) args = (self.pid, self.bpm, diff, count, total_holds, self.steps[0].feet) for l in self.listeners: l.set_song(*args) else: self.holding = [-1] * len(self.game.dirs) self.steps = steps.Steps(song, diff, self, self.pid, lyrics, self.game.name) self.length = self.steps.length self.ready = self.steps.ready self.bpm = self.steps.bpm self.arrows = self.theme.arrows(self.pid) holds = len(self.steps.holdref) args = (self.pid, self.bpm, diff, self.steps.totalarrows, holds, self.steps.feet) for l in self.listeners: l.set_song(*args) def start_song(self): self.toparr_group = RenderUpdates() self.fx_group = RenderUpdates() self.text_group = RenderUpdates() self.text_group.add([self.score, self.lifebar, self.judging_disp]) self.text_group.add(self.holdtext) if mainconfig["showcombo"]: self.text_group.add(self.combos) if self.game.double: self.arrow_group = [OrderedRenderUpdates(), OrderedRenderUpdates()] for i in range(2): self.steps[i].play() for d in self.game.dirs: if mainconfig["explodestyle"] > -1: self.toparrfx[i][d].add(self.fx_group) if not self.dark: self.toparr[i][d].add(self.toparr_group) self.sprite_groups = [self.toparr_group, self.arrow_group[0], self.arrow_group[1], self.fx_group, self.text_group] else: self.steps.play() self.arrow_group = OrderedRenderUpdates() for d in self.game.dirs: if mainconfig["explodestyle"] > -1: self.toparrfx[d].add(self.fx_group) if not self.dark: self.toparr[d].add(self.toparr_group) self.sprite_groups = [self.toparr_group, self.arrow_group, self.fx_group, self.text_group] def get_next_events(self, song): if self.game.double: self.fx_data = [[], []] for i in range(2): self._get_next_events(song, self.arrow_group[i], self.arrows[i], self.steps[i], self.judge[i]) else: self.fx_data = [] self._get_next_events(song, self.arrow_group, self.arrows, self.steps, self.judge) def _get_next_events(self, song, arrow_grp, arrow_gfx, steps, judge): evt = steps.get_events() if evt is not None: events, nevents, time, bpm = evt for ev in events: if ev.feet: for (dir, num) in zip(self.game.dirs, ev.feet): if num & 1: judge.handle_arrow(dir, ev.when, num & 4) if self.fade == 5: return # Stealth mode newsprites = [] for ev in nevents: if ev.feet: for (dir, num) in zip(self.game.dirs, ev.feet): # Don't make hidden arrow sprites if we have hidden arrows # off entirely, or have them set not to display. if not num & 4 or self.secret_kind == 2: dirstr = dir + repr(int(ev.color) % self.colortype) if num & 1 and not num & 2: ns = arrows.ArrowSprite(arrow_gfx[dirstr], ev.beat, num & 4, ev.when, self, song) newsprites.append(ns) elif num & 2: holdindex = steps.holdref.index((self.game.dirs.index(dir), ev.when)) ns = arrows.HoldArrowSprite(arrow_gfx[dirstr], steps.holdbeats[holdindex], num & 4, steps.holdinfo[holdindex], self, song) newsprites.append(ns) arrow_grp.add(newsprites) def check_sprites(self, curtime, curbeat, arrows, steps, fx_data, judge): misses = judge.expire_arrows(curtime) for d in misses: for l in self.listeners: l.stepped(self.pid, d, curtime, -1, "M", self.combos.combo) for rating, dir, time in fx_data: if (rating == "V" or rating == "P" or rating == "G"): for spr in arrows.sprites(): if spr.endtime == time and spr.dir == dir: if not spr.hold: spr.kill() arrows.update(curtime, self.bpm, curbeat, judge) self.toparr_group.update(curtime, curbeat) def should_hold(self, steps, direction, curtime): for i,l in enumerate(steps.holdinfo): if l[0] == self.game.dirs.index(direction): if ((curtime - 15.0/steps.playingbpm > l[1]) and (curtime < l[2])): return i def check_holds(self, pid, curtime, arrows, steps, judge, toparrfx, holding): # FIXME THis needs to go away keymap_kludge = { "u": pad.UP, "k": pad.UPLEFT, "z": pad.UPRIGHT, "d": pad.DOWN, "l": pad.LEFT, "r": pad.RIGHT, "g": pad.DOWNRIGHT, "w": pad.DOWNLEFT, "c": pad.CENTER } for dir in self.game.dirs: toparrfx[dir].holding(0) current_hold = self.should_hold(steps, dir, curtime) dir_idx = self.game.dirs.index(dir) if current_hold is not None: if pad.states[(pid, keymap_kludge[dir])]: if judge.holdsub.get(holding[dir_idx]) != -1: toparrfx[dir].holding(1) holding[dir_idx] = current_hold botchdir, timef1, timef2 = steps.holdinfo[current_hold] for spr in arrows.sprites(): if (spr.endtime == timef1 and spr.dir == dir): spr.held() break else: if judge.holdsub.get(current_hold) != -1: botchdir, timef1, timef2 = steps.holdinfo[current_hold] for spr in arrows.sprites(): if (spr.endtime == timef1 and spr.dir == dir): if spr.broken_at(curtime, judge): args = (pid, curtime, dir, current_hold) for l in self.listeners: l.broke_hold(*args) break else: if holding[dir_idx] > -1: if judge.holdsub.get(holding[dir_idx]) != -1: args = (pid, curtime, dir, holding[dir_idx]) for l in self.listeners: l.ok_hold(*args) holding[dir_idx] = -1 def handle_key(self, ev, time): ev = ev[0], self.game.dirmap.get(ev[1], ev[1]) if ev[1] not in self.game.dirs: return if self.game.double: pid = ev[0] & 1 rating, dir, etime = self.judge[pid].handle_key(ev[1], time) for l in self.listeners: l.stepped(ev[0], dir, time, etime, rating, self.combos.combo) self.fx_data[pid].append((rating, dir, etime)) else: rating, dir, etime = self.judge.handle_key(ev[1], time) for l in self.listeners: l.stepped(ev[0], dir, time, etime, rating, self.combos.combo) self.fx_data.append((rating, dir, etime)) def check_bpm_change(self, pid, time, steps, judge): newbpm = self.bpm for bpm in steps.lastbpmchangetime: if time >= bpm[0]: newbpm = bpm[1] if newbpm != self.bpm: self.bpm = newbpm for l in self.listeners: l.change_bpm(pid, time, newbpm) def clear_sprites(self, screen, bg): for g in self.sprite_groups: g.clear(screen, bg) def game_loop(self, time, screen): if self.game.double: for i in range(2): if len(self.steps[i].lastbpmchangetime) == 0: cur_beat = (time - self.steps[i].offset) / (60.0 / self.bpm) else: cur_beat = 0 oldbpmsub = [self.steps[i].offset, self.steps[i].bpm] for bpmsub in self.steps[i].lastbpmchangetime: if bpmsub[0] <= time: cur_beat += (bpmsub[0] - oldbpmsub[0]) / (60.0 / oldbpmsub[1]) oldbpmsub = bpmsub else: break cur_beat += (time - oldbpmsub[0]) / (60.0 / oldbpmsub[1]) self.check_holds(self.pid * 2 + i, time, self.arrow_group[i], self.steps[i], self.judge[i], self.toparrfx[i], self.holding[i]) self.check_bpm_change(self.pid * 2 + i, time, self.steps[i], self.judge[i]) self.check_sprites(time, cur_beat, self.arrow_group[i], self.steps[i], self.fx_data[i], self.judge[i]) else: if len(self.steps.lastbpmchangetime) == 0: cur_beat = (time - self.steps.offset) / (60.0 / self.bpm) else: cur_beat = 0 oldbpmsub = [self.steps.offset, self.steps.bpm] for bpmsub in self.steps.lastbpmchangetime: if bpmsub[0] <= time: cur_beat += (bpmsub[0] - oldbpmsub[0]) / (60.0 / oldbpmsub[1]) oldbpmsub = bpmsub else: break cur_beat += (time - oldbpmsub[0]) / (60.0 / oldbpmsub[1]) self.check_holds(self.pid, time, self.arrow_group, self.steps, self.judge, self.toparrfx, self.holding) self.check_bpm_change(self.pid, time, self.steps, self.judge) self.check_sprites(time, cur_beat, self.arrow_group, self.steps, self.fx_data, self.judge) self.fx_group.update(time) self.text_group.update(time) if self.lifebar.gameover == lifebars.FAILED and not self.failed: self.failed = True rects = [] for g in self.sprite_groups: rects.extend(g.draw(screen)) return rects