def reset_blocks(self): level = Level() level.levels = self.save_as # 通过文件生成块 level.reset() # 删除已存在的块 for b in self.blocks: self.remove(b.sprite) # 清空存储的块和坐标 self.blocks.clear() # self.props.clear() # 添加新的块 for b in level.blocks: self.add(b.sprite) self.blocks.append(b)
class DataModel(QGraphicsScene): ################################################################################ def __init__(self) -> None: """ Creates a data model which is used for a graphic representation of Sokoban level (QGraphics View framework). QGraphicsScene.keyPressEvent() is implemented to process various player input. """ super().__init__() self._level = Level("levels/01/01") self.setSceneRect( QRectF(QPointF(0, 0), QPointF(self._level.width, self._level.height))) [ self.addItem(item) for item in self._level.tiles + self._level.boxes + tuple([self._level.player]) ] self._level.player.moveFinished.connect(self.unlockGame) self._gameLock = False ################################################################################ @property def level(self) -> Level: """ :return: current level object """ return self._level ################################################################################ def lockGame(self) -> None: """ Locks the game to deny the player any input. :return: None """ self._gameLock = True ################################################################################ def unlockGame(self) -> None: """ Unlocks the game to allow the player any input. :return: None """ self._gameLock = False ################################################################################ def keyPressEvent(self, event: QKeyEvent) -> None: """ Handles the player's keyboard input. Possible actions: -move player up, down, left, right -reset level to the initial state -start bfs algorithm (deterministic) -start bfs algorithm (non-deterministic) -start dfs algorithm (deterministic) -start dfs algorithm (non-deterministic) :param event: QKeyEvent to be handled :return: None """ if not self._gameLock: key = event.key() if key in self._level.DIRECTIONS: dRow = self._level.DIRECTIONS[key][0] dColumn = self._level.DIRECTIONS[key][1] self._level.movePlayer(dRow, dColumn, animated=True) elif key == Qt.Key_R: self._level.reset() elif key == Qt.Key_B: if event.modifiers() == Qt.ShiftModifier: self._level.bfs(deterministic=False) else: self._level.bfs() elif key == Qt.Key_D: if event.modifiers() == Qt.ShiftModifier: self._level.dfs(deterministic=False) else: self._level.dfs() super().keyPressEvent(event)
class GameLayer(Layer): is_event_handler = True def __init__(self, hud): super(GameLayer, self).__init__() # 添加板子和球 self.is_on_exiting = True self.paddle = Paddle('images/paddle.png') self.add(self.paddle.sprite) self.ball = Ball('images/ball.png') self.ball.reset_position = (320, self.paddle.sprite.height + self.ball.sprite.height / 2) self.add(self.ball.sprite) # hud 用于记录,更新关卡,死亡,金币数据 self.hud = hud # 生成关卡 self.level = Level() self.level.levels = self.hud.levels self.add(self.hud.gold_hud) self.add(self.hud.level_hud) self.add(self.hud.death_hud) # 添加按键状态 self.key_pressed_left = False self.key_pressed_right = False self.key_pressed_up = False self.key_pressed_down = False self.reset() # 定期调用 self.update 函数 # FPS frame per second 每秒帧数 self.schedule(self.update) def reset(self): self.paddle.reset() self.ball.reset() # 清空界面上的block for b in self.level.blocks: self.remove(b.sprite) # 再初始化新的砖块 self.level.reset() for b in self.level.blocks: self.add(b.sprite) def game_over(self): self.hud.death += 1 self.is_on_exiting = False scene = create_scene(GameOver(self.hud)) director.replace(scene) def update_hud(self): self.hud.update() def update_blocks(self): for b in self.level.blocks: if collised(b.sprite, self.ball.sprite): print(1) self.ball.hit() b.live -= 1 if b.live < 0: self.level.blocks.remove(b) self.remove(b.sprite) else: b.reset() self.hud.gold += 1 self.update_hud() print('金币:', self.hud.gold) break def update_ball(self): if self.ball.fired: self.ball.update() else: bx, by = self.ball.sprite.position px, py = self.paddle.sprite.position self.ball.sprite.position = (px, by) collide = collised(self.ball.sprite, self.paddle.sprite) if collide: xisu = 1 bx, by = self.ball.sprite.position px, py = self.paddle.sprite.position offect_scale = (bx - px) / (self.paddle.sprite.width / 2) ball_speedx_change = offect_scale * xisu self.ball.speedx += ball_speedx_change self.ball.hit() if self.ball.dead(): self.game_over() def update_paddle(self): self.paddle.update() def update_input(self): self.paddle.move_right = self.key_pressed_right self.paddle.move_left = self.key_pressed_left if self.key_pressed_up: self.ball.fire() def update_newlevel(self): if len(self.level.blocks) == 0: self.is_on_exiting = False if self.level.next(): print(self.level.levels) self.hud.levels += 1 scene = create_scene(GuoCangDongHua(self.hud)) else: scene = create_scene(GameComplite(self.hud)) director.replace(scene) def update(self, dt): if self.is_on_exiting: self.update_newlevel() self.update_ball() self.update_paddle() self.update_input() self.update_blocks() self.update_hud() def on_key_press(self, key, modifiers): k = symbol_string(key) status = True if k == 'LEFT': self.key_pressed_left = status elif k == 'RIGHT': self.key_pressed_right = status elif k == 'UP': self.key_pressed_up = status def on_key_release(self, key, modifiers): k = symbol_string(key) status = False if k == 'LEFT': self.key_pressed_left = status elif k == 'RIGHT': self.key_pressed_right = status elif k == 'UP': self.key_pressed_up = status
class GameLayer(Layer): is_event_handler = True def __init__(self, levels=1, golds=0, deadcount=0): super(GameLayer, self).__init__() # 添加板子和球 self.paddle = Paddle('images/paddle.png') self.add(self.paddle.sprite) self.ball = Ball('images/ball.png') self.ball.reset_position = (320, self.paddle.sprite.height + self.ball.sprite.height / 2) self.add(self.ball.sprite) # 生成关卡 self.level = Level() self.level.levels = levels # 添加标签用于记录金币和关卡。死亡次数 self.gold = golds self.deadcount = deadcount self.hud = Label('金币: ' + str(golds)) self.level_hud = Label('关卡: ' + str(levels)) self.deadstu = Label('死亡: ' + str(deadcount)) self.hud.position = (0, 460) self.level_hud.position = (80, 460) self.deadstu.position = (160, 460) self.add(self.hud) self.add(self.level_hud) self.add(self.deadstu) # 添加按键状态 self.key_pressed_left = False self.key_pressed_right = False self.key_pressed_up = False self.key_pressed_down = False self.reset() # 定期调用 self.update 函数 # FPS frame per second 每秒帧数 self.schedule(self.update) def reset(self): self.paddle.reset() self.ball.reset() # 清空界面上的block for b in self.level.blocks: self.remove(b) # 再初始化新的砖块 self.level.reset() for b in self.level.blocks: self.add(b) def game_over(self): self.deadcount += 1 scene = Scene(GameOver(self.level.levels, self.gold, self.deadcount)) director.replace(scene) def update_hud(self): self.hud.element.text = '金币: ' + str(self.gold) self.level_hud.element.text = '关卡: ' + str(self.level.levels) def update_blocks(self): for b in self.level.blocks: if collised(b, self.ball.sprite): self.ball.hit() self.level.blocks.remove(b) self.remove(b) self.gold += 1 self.update_hud() print('金币:', self.gold) break def update_ball(self): if self.ball.fired: self.ball.update() else: bx, by = self.ball.sprite.position px, py = self.paddle.sprite.position self.ball.sprite.position = (px, by) collide = collised(self.ball.sprite, self.paddle.sprite) if collide: self.ball.hit() if self.ball.dead(): self.game_over() def update_paddle(self): self.paddle.update() def update_input(self): self.paddle.move_right = self.key_pressed_right self.paddle.move_left = self.key_pressed_left if self.key_pressed_up: self.ball.fire() def update_newlevel(self): if len(self.level.blocks) == 0: if self.level.next(): print(self.level.levels) # self.reset() scene = Scene(GuoCangDongHua(self.level.levels, self.gold, self.deadcount)) else: scene = Scene(GameComplite(self.level.levels, self.gold, self.deadcount)) director.replace(scene) def update(self, dt): self.update_newlevel() self.update_ball() self.update_paddle() self.update_input() self.update_blocks() self.update_hud() def on_key_press(self, key, modifiers): k = symbol_string(key) status = True if k == 'LEFT': self.key_pressed_left = status elif k == 'RIGHT': self.key_pressed_right = status elif k == 'UP': self.key_pressed_up = status def on_key_release(self, key, modifiers): k = symbol_string(key) status = False if k == 'LEFT': self.key_pressed_left = status elif k == 'RIGHT': self.key_pressed_right = status elif k == 'UP': self.key_pressed_up = status