def __init__(self): Base.clearTime() Base.CurrentUserFacer = self self.clock = pygame.time.Clock() self.buttonColorGenerator = Anima.ButtonToggleColor( (Con.LocalButtonColor, Con.OnlineButtonColor), Con.ColorToggleTime ) self.startSize = Con.ScreenSize self.fontSize = lambda: int(Base.CurrentScreen.get_width() / Con.FontRelation) # 根据屏幕大小更改字体大小 self.Font: pygame.font.Font = Base.getFont(Con.Font, self.fontSize()) self.fontColor = Con.TextColor self.background = Con.BackGround self.ifOnline = False self.playerNum = 1 self.min_enemy_num = Con.LeastEnemy # 最小敌人数 self.max_enemy_num = Con.MostEnemy # 最大敌人数 self.last_enemy_num = 0 # 可忽视 self.settingKey = [pygame.K_LALT] self.startKey = [pygame.K_RETURN] self.refreshKey = [pygame.K_r] self.quitKey = [pygame.K_ESCAPE, pygame.K_q] self.fullKey = [pygame.K_F11] self.upPlayerKey = [pygame.K_UP] self.downPlayerKey = [pygame.K_DOWN] self.toggleOnlineKey = [pygame.K_SPACE] Con.ButtonSize = sum(Con.ScreenSize) // 2 // 6 self.clickRect = pygame.Rect([0, 0, 0, 0]) # 点击开始游戏区域 self.settingClickRect = pygame.Rect([0, 0, 0, 0]) # 点击设置区域
def registering(self): Base.clearTime() while self.controller.state == self.controller.STATE_FIRST: events = pygame.event.get() for e in events: if e.type == pygame.QUIT: self.close() return if e.type == pygame.KEYDOWN: if e.key == pygame.K_SPACE: self.controller.startGame() return if e.key == pygame.K_ESCAPE: self.close() return if e.key == pygame.K_F11: self.fullScreen() if e.type == pygame.VIDEORESIZE: if Con.FullScreen: # 全屏不缩放 continue if Con.ScreenSize[0] != e.size[0]: # 横改变 width = e.size[0] height = int(e.size[0] / Con.ScreenSizeRatio) else: # 纵改变 height = e.size[1] width = int(e.size[1] * Con.ScreenSizeRatio) size = max(width, Con.MinSize[0]), max(height, Con.MinSize[1]) self.resize(size, pygame.RESIZABLE) self.controller.holdConnection() self.flush() self.clock.tick(Con.FPS)
def update(self, text=''): self.fill(Con.BackGround) get = self.render(text) get = Base.relateResize(get, w=min(get.get_width(), self.get_width())) get = Base.relateResize(get, h=min(get.get_height(), self.get_height())) self.blit(get, (0, 0))
def __init__(self): Base.clearTime() # 重置游戏计时 self.clock = pygame.time.Clock() self.fullScreen = Con.FullScreen # noinspection PyTypeChecker self.manager: Controller.LocalManager = None self.frame = Base.MyFrame() self.running = False self.caption = f'Escape_Rect Version:{Con.Version}' self.enemy_num = 1 self.Font = None
def flush(self): self.controller.flush() Base.flushAll() self.controller.target.print() # 显示帧率 if Con.FPSShowing: Base.printFPS(int(self.clock.get_fps())) pygame.display.update() self.controller.target.fill(Con.BackGround)
def generateAngle(self): if self.twoPoint: x, y = self.bezier_line.evaluate(float(self.__p)) startAngle, endAngle = Base.angleToFloat( (-(y[0]) * 360) + 90), Base.angleToFloat(-self.__p * 360 + 90) startAngle, endAngle = min(startAngle, endAngle), max(startAngle, endAngle) return startAngle, endAngle else: return Base.angleToFloat((-self.__p) * 360 + 90), Base.angleToFloat(90)
def __init__(self, targetScreen: Base.MyFrame = None): self._target = targetScreen or Base.MyFrame() self.playerHandler = PlayerHandler(self) self.enemyHandler = EnemyHandler(self) self.originEnemyNum = 0 self.originPlayerList: Dict[int, str] = {} self.state = self.STATE_FIRST self.alive = True self.lastIncreaseTime = Base.getTimeMil() self.process = 0 self.processIncrease = 0 self.endProcess = 0 self.font = Base.getFont(Con.Font, int(self.target.get_size()[0] / Con.FontRelation))
def startingAnimation(self): if not Con.ProgressBarShowing: return loader = Anima.Loader(Base.CurrentScreen, int(min(Base.CurrentScreen.get_size()) * 0.5), Const.CENTER_POSITION, twoPoint=True) lastingTime = 500 startTime = Base.getTimeMil() while lastingTime + startTime >= Base.getTimeMil(): nowTime = Base.getTimeMil() loader.percent = 1 - (lastingTime + startTime - nowTime) / lastingTime loader.flush() self.update() pygame.event.clear()
def _handleActivities(self, seq: int): player = self.getPlayer(seq) socketPlayer = self.client.getPlayer(seq) events = self.client.fetchPlayerEvent() if not player or not socketPlayer: return player.start_pos = socketPlayer[Client.KEY_START_POS] player.lives = socketPlayer[Client.KEY_PLAYER_LIVES] # print(player.seq, bool(player), player.alive, player.lives, socketPlayer[Client.KEY_PLAYER_LIVES], # Client.KEY_EVENT_HURT in events, events) # todo player.skillPosition = socketPlayer[Client.KEY_PLAYER_SKILL_POS] player.cd = socketPlayer[Client.KEY_PLAYER_CD] if Client.KEY_EVENT_HURT in events: Base.playSound(player.hurtSound) player.update()
def __init__(self, target: pygame.Surface = None): super().__init__(target) self.tabCur = 0 # 用tab切换焦点 self.nameEntry = Widget.Entry( size=( int(self.target.get_width() * 0.5), int(self.target.get_height() * 0.1) ), pos=( int(self.target.get_width() * 0.25), int(self.target.get_height() * 0.2) ), originText=f'Type Player Name' ) self.addressEntry = Widget.Entry( size=( int(self.target.get_width() * 0.6), int(self.target.get_height() * 0.1) ), pos=( int(self.target.get_width() * 0.2), int(self.target.get_height() * 0.5) ), originText=f'Input Server Address' ) self.ticker = Base.TimesTicker()
def updateSituation(self): """call this while gaming""" self.checkState(self.STATE_GAMING) if not self.server.alive: self.alive = False return nowTime = Base.getTimeMil() self.holdConnection() if nowTime - self.lastIncreaseTime > 1000: # 增长process self.process += self.processIncrease self.lastIncreaseTime = nowTime self.server.setProcess(self.process, self.endProcess) super(ServerManager, self).updateSituation() if self.process > self.endProcess: # 胜利判定 condition = Const.WIN self.state = self.STATE_WIN self.server.finishGame(self.summonResult()) elif self.playerHandler.checkAllDead(): # 检查玩家是否全部死亡 condition = Const.LOST self.state = self.STATE_LOST self.server.finishGame(self.summonResult()) else: condition = Const.RUNNING result = self.server.gameResult return condition, self.process / self.endProcess, result
def flush(self, screen=None): if screen: self.screen = screen self.surfaceFrame.fill(Con.BackGround) start, end = self.generateAngle() pygame.draw.arc(self.surfaceFrame, Con.ProgressBarColor, (*(0, 0), *self.size), start, end, width=self.thick) text = self.font.render(f'{self.percent:.2%}', True, Con.TextColor) Base.printToCenter(self.surfaceFrame, text) if self.pos == Const.CENTER_POSITION: Base.printToCenter(self.screen, self.surfaceFrame) else: self.screen.blit(self.surfaceFrame, self.pos)
def __init__(self, target: pygame.Surface = None): super().__init__(target) font = Base.getFont(Con.Font, int(self.target.get_width() / Con.FontRelation * 10)) text = f'Create Server At: {socket.gethostbyname(socket.gethostname())}:{Con.ServerPort}' self.widget = Base.MyWidget( size=( int(self.target.get_width() * 0.9), int(self.target.get_height() * 0.1) ), pos=Const.CENTER_POSITION ) self.text_surface = font.render( text, True, Con.TextColor ) self.text_surface = Base.relateResize(self.text_surface, w=self.widget.get_width())
def calcColor(self): nowTime = Base.getTimeMil() reachedPercent = (nowTime - self.lastToggleTime) / self.toggleTime reachedPercent = max(reachedPercent, 0) reachedPercent = min(reachedPercent, 1) return tuple([ int((b - a) * reachedPercent + a) for a, b in zip(*self.colorArc) ])
def update(self, text: str = None): """ 更新敌人的状态 :return: """ self.movingTime = max(-0.04 * Base.getTimeMil() + 2000, 150) # 随时间增加movingTime越小,最小为max中的定者 if (randint(0, 1000) < 15 and ((Base.getTimeMil() - self.lastMoveTime) > self.sleepTime) and not self.moving): self.summonPoint() self.movetimes += 1 else: self.checkSkilled() self.smoothMove() super(Enemy, self).update( text=f'{self.sleepTime}' if Con.EnemySleepTimeShowing else '')
def keepAlive(self): """keep the connection every once in a while""" self.checkAlive() nowTime = Base.getTimeSec() if nowTime > self.LONGEST_RESPONSE_TIME * 0.7 + self.lastResponseTime: msg = Message.dumps(Message.TYPE_CLIENT_KEEP_ALIVE) self._sendMsg(msg) self.lastResponseTime = nowTime
def flush(self, playerPos=None): # 只有在RelShowing成立时,playerPos才会起作用 pygame.display.update() Base.CurrentScreen.fill([int(i - 20) % 256 for i in Con.BackGround]) # 周围变色 self.frame.fill(Con.BackGround) # 更新manager内的角色 self.manager.flush() # 执行打印任务 Base.flushAll() # 更新Frame if Con.RelativeShowing and playerPos and self.onePlayer: pos = [-i for i in playerPos] w, h = Con.ScreenSize pos[0] += w // 2 pos[1] += h // 2 self.frame.print(pos) else: self.frame.print((0, 0))
def receiveClient(self): self.checkState(self.STATE_FIRST) nowTime = Base.getTimeSec() try: client, address = self.socket.accept() self.clients[address] = client self.responseTime[address] = nowTime print(f'{address} get, {self.clientsLength} clients remain.') except BlockingIOError: pass
def gaming(self): Base.clearTime() Base.CurrentScreen = pygame.display.set_mode(Con.ScreenSize) self.controller.initEnemy(random.randint(Con.LeastEnemy, Con.MostEnemy)) # 创建敌人 while self.controller.state == self.controller.STATE_GAMING: events = pygame.event.get() for e in events: if e.type == pygame.QUIT: self.close() return if e.type == pygame.KEYDOWN: if e.key == pygame.K_ESCAPE: self.close() return self.controller.holdConnection() self.controller.updateSituation() self.flush() self.clock.tick(Con.FPS) self.controller.close()
def writeText(self): if self.text: self.text_surface = self.font.render(self.text, True, Con.TextColor) else: self.text_surface = self.font.render(self.placeHolder, True, Con.TextColor) self.text_surface.set_alpha(0.5 * 255) targetH = self.get_height() - 4 # 留出内边距 self.text_surface = Base.relateResize(self.text_surface, h=targetH) self.blit(self.text_surface, (self.startX, 2))
def summonResult(self): result = Base.GameResult() if self.state == self.STATE_WIN: result.result = Const.WIN elif self.state == self.STATE_LOST: result.result = Const.LOST else: result = None return result result.bestPlayer = self.getBestPlayer() result.endProcess = self.endProcess result.enemyNum = self.originEnemyNum result.escapeTimes = sum([self.enemies[i].movetimes for i in range(self.enemyHandler.length)]) result.fps = Con.FPS result.playerList = self.originPlayerList result.playerOLives = Con.Lives result.reachedProcess = self.process result.screenSize = Con.ScreenSize result.keepTime = Base.getTimeMil() return result
def _detectMotion(self, seq: int): """ 检测玩家是否移动 :param seq: 目标玩家在管理器中的索引 """ nowTime = Base.getTimeMil() player = self.getPlayer(seq) if self.playerLastPositions[seq] != player.pos: self.playerLastMoveTimeStamps[seq] = nowTime # 重置静止时间 self.playerLastPositions[seq] = player.pos return True # 玩家移动了
def popDisconnectedClients(self): self.checkAlive() if not Con.PopClientOnTimeout: return nowTime = Base.getTimeSec() disconnected = [] for address, lastTime in self.responseTime.items(): if lastTime + self.LONGEST_RESPONSE_TIME < nowTime: # detect disconnected.append(address) for address in disconnected: self.popClientAndPlayer(address)
def __init__(self, size=None, parent: pygame.Surface = None, pos=(0, 0), alpha=None, text=''): super().__init__(size, parent, pos, alpha) self._text = text self.font = Base.getFont( Con.Font, int(self.parent.get_width() / Con.FontRelation)) self.text = text
def __init__(self, targetScreen, width, height, color): super(MyChar, self).__init__((int(width), int(height))) self.target = targetScreen self.color = color self.alive = True self.seq = 0 self.name = 'Unnamed' self._rect = self.get_rect() self.font = Base.getFont( Con.Font, int(targetScreen.get_size()[0] / Con.FontRelation)) import src.GameControl.Controller as Controller self.belong = None # type: Controller.CharHandler
def smoothMove(self): if self.moving: nowTime = Base.getTimeMil() process = max( ((nowTime - self.lastMoveTime) / self.movingTime)**0.3, 0.01) # 冲刺进度 start, end = self.moveArc # 计算坐标 nowPos = [(e - s) * process + s for s, e in zip(start, end)] self.moveto(*nowPos) if process >= 1: self.moving = False
def __init__(self, size=None, parent: pygame.Surface = None, pos=(0, 0), alpha=None, originText=''): super().__init__(size, parent, pos, alpha) self._text = '' self.placeHolder = originText self.font = Base.getFont( Con.Font, int(self.parent.get_width() / Con.FontRelation * 10)) self.text_surface = self.font.render(self.placeHolder, True, Con.TextColor) self.x = 0 self.moveDelta = 50 self.deleter = Base.TimesTicker() self.paster = Base.TimesTicker() self.color = Anima.ButtonToggleColor( (Con.BackGround, [(i - 50) % 256 for i in Con.BackGround]), Con.ColorToggleTime) self._focus = False
def synchronize(self): self.checkState(self.STATE_GAMING) nowTime = Base.getTimeSec() if self.lastSyncTime + 1 / Con.ServerSyncSpeed > nowTime: return msg = Message.dumps( Message.TYPE_SERVER_GAME_SYNCHRONIZE, { self.KEY_ENEMY: list(self.enemies.values()), self.KEY_PLAYER: list(self.players.values()), self.KEY_PROCESS: self.nowProcess, self.KEY_KEEP_TIME: nowTime, }) self._sendMsgToClient(msg) self.lastSyncTime = nowTime
def reportPlayersTotal(self): """report the players remain here every once in a while""" self.checkAlive() nowTime = Base.getTimeSec() if not nowTime > self.LONGEST_RESPONSE_TIME + self.lastReportTotalTime: return addresses = self.players.keys() # get player message players: Dict[int, str] = {} for address in addresses: name = self.players[address][self.KEY_PLAYER_NAME] index = int(self.players[address][self.KEY_SEQ]) players[index] = name # send message typ = Message.TYPE_SERVER_PLAYER_TOTAL msg = Message.dumps(typ, players) self._sendMsgToClient(msg=msg) self.lastReportTotalTime = nowTime
def finishGame(self, msg: Message): self.checkState(self.STATE_GAMING) self.state = self.STATE_GAME_END decoded = msg.getDecoded() self.gameResult = Base.GameResult() self.gameResult.enemyNum = decoded[self.KEY_GAME_END_ENEMY_NUM] self.gameResult.escapeTimes = decoded[self.KEY_GAME_END_ESCAPE_TIMES] self.gameResult.playerOLives = decoded[self.KEY_GAME_END_PLAYER_OLIVES] self.gameResult.result = decoded[self.KEY_GAME_END_RESULT] self.gameResult.bestPlayer = tuple( decoded[self.KEY_GAME_END_BEST_PLAYER]) self.gameResult.endProcess = decoded[self.KEY_GAME_START_END_PROCESS] self.gameResult.reachedProcess = decoded[ self.KEY_GAME_END_REACHED_PROCESS] self.gameResult.keepTime = decoded[self.KEY_GAME_END_KEEP_TIME] self.gameResult.playerList = decoded[self.KEY_GAME_END_PLAYER_LIST] self.gameResult.fps = decoded[self.KEY_GAME_END_FPS] self.gameResult.screenSize = tuple( decoded[self.KEY_GAME_END_SCREEN_SIZE])