class Main_Menu(): def __init__(self, screen, screenw, screenh, spriteList, soundManager): self.sprites = spriteList self.screen = screen self.screenw = screenw self.screenh = screenh self.soundManager = soundManager self.state = "Main" self.mainButtons = [] self.mainButtons.append(Button(self.screen, self.sprites.getSprite("login"), self.sprites.getSprite("loginHighlighted"), 368, 350, 281, 68, "Login", 'Start Button.ogg', soundManager)) self.mainButtons.append(Button(self.screen, self.sprites.getSprite("start"), self.sprites.getSprite("startHighlighted"), 368, 442, 281, 68, "Game", 'Start Button.ogg', soundManager)) self.mainButtons.append(Button(self.screen, self.sprites.getSprite("exit"), self.sprites.getSprite("exitHighlighted"), 368, 534, 281, 68, "Exit", 'Exit.ogg', soundManager)) self.fontsize = 30 self.font = pygame.font.Font(os.path.join('Fonts', 'nasalization-rg.ttf'), self.fontsize) self.loginButtons = [] self.ip = textInput(self.screen, "Server IP", (50, 30), (self.font.get_height() * 8), 50, 15) self.port = textInput(self.screen, "Port", (300 + (self.font.get_height() * 8), 30), (self.font.get_height() * 5), 50, 5) self.username = textInput(self.screen, "Username", (self.screenw/2 - 200, 130), (self.font.get_height() * 8), 50, 8) self.password = textInput(self.screen, "Password", (self.screenw/2 - 200, 230), (self.font.get_height() * 8), 50, 8, True) self.loginButtons.append(Button(self.screen, self.sprites.getSprite("login"), self.sprites.getSprite("loginHighlighted"), 368, 442, 281, 68, "Lobby", 'Start Button.ogg', soundManager)) self.loginButtons.append(Button(self.screen, self.sprites.getSprite("exit"), self.sprites.getSprite("exitHighlighted"), 368, 534, 281, 68, "Main", 'Exit.ogg', soundManager)) self.mouseDelay = 50 self.mouseNext = pygame.time.get_ticks() self.connected = False #for server self.socket = None self.loginStatus = "" def draw(self): if self.state == "Main": self.screen.blit(self.sprites.getSprite("titlescreen"), (0, 0)) for button in self.mainButtons: button.draw() elif self.state == "Login": self.screen.blit(self.sprites.getSprite("titlescreenbg"), (0, 0)) self.ip.draw() self.port.draw() self.username.draw() self.password.draw() if self.loginStatus == "Invalid Password": self.screen.blit(self.font.render("Wrong Password. Try again.", True, pygame.Color(255,255,255)),(300,self.screenh/2 - 100)) elif self.loginStatus == "No Server": self.screen.blit(self.font.render("Could not reach server. Wrong Info/Poor connection.", True, pygame.Color(255,255,255)),(100,self.screenh/2 - 100)) elif self.loginStatus == "Waiting": self.screen.blit(self.font.render("Waiting for server.", True, pygame.Color(255,255,255)),(self.screenw/2 - (len("Invalid Format.") * 30)/4,self.screenh/2 - 100)) elif self.loginStatus == "Missing Field(s)": self.screen.blit(self.font.render("Missing Field(s).", True, pygame.Color(255,255,255)),(self.screenw/2 - (len("Invalid Format.") * 30)/4,self.screenh/2 - 100)) for button in self.loginButtons: button.draw() def mouseUpdate(self): if pygame.time.get_ticks() >= self.mouseNext: if pygame.mouse.get_pressed()[0]: if self.state == "Main": for button in self.mainButtons: if button.checkClicked(pygame.mouse.get_pos()): self.state = button.click() elif self.state == "Login": for button in self.loginButtons: if button.checkClicked(pygame.mouse.get_pos()): self.state = button.click() if self.state == "Main": if self.connected: self.connected = False self.socket.send("STOP") if self.state == "Lobby": if self.ip.input != "" and self.port.input != "" and self.username.input != "" and self.password.input != "": message = self.username.input + ":" + self.password.input if not self.connected: try: self.socket = Connect(self.ip.input, int(self.port.input)) self.connected = True except: self.loginStatus = "No Server" self.state = "Login" if self.connected: self.socket.send("LOG:" + message) self.state = "Login" self.loginStatus = "Waiting" # modifiedMessage = self.socket.receive() # modifiedMessage = modifiedMessage.split(":") # self.loginStatus = "" # if modifiedMessage[0] == "Invalid Password": # self.loginStatus = "Invalid Password" # self.state = "Login" # elif modifiedMessage[0] == "Success": # self.connected = False # self.state = "Lobby" # elif modifiedMessage[0] == "": # self.loginStatus = "Waiting" # self.state = "Login" else: self.state = "Login" self.loginStatus = "Missing Field(s)" self.ip.checkClicked(pygame.mouse.get_pos()) self.port.checkClicked(pygame.mouse.get_pos()) self.username.checkClicked(pygame.mouse.get_pos()) self.password.checkClicked(pygame.mouse.get_pos()) self.mouseNext = pygame.time.get_ticks() + self.mouseDelay def update(self): self.mouseUpdate() if self.state == "Main": for button in self.mainButtons: button.checkHover(pygame.mouse.get_pos()) return "Menu" elif self.state == "Login": if self.connected: message = None while message != "": message = self.socket.receive() if message != None: modifiedMessage = message.split(":") if modifiedMessage[0] == "Invalid Password": self.loginStatus = "Invalid Password" self.state = "Login" elif modifiedMessage[0] == "Success": self.loginStatus = "" self.connected = False self.state = "Lobby" else: if self.loginStatus == "Waiting": #self.state = "Login" self.socket.send("CHECKLOG") for button in self.loginButtons: button.checkHover(pygame.mouse.get_pos()) self.ip.update() self.port.update() self.username.update() self.password.update() return "Menu" else: return self.state
class Main_Menu(): def __init__(self, screen, screenw, screenh, spriteList, soundManager): self.sprites = spriteList self.screen = screen self.screenw = screenw self.screenh = screenh self.soundManager = soundManager self.state = "Main" self.mainButtons = [] self.mainButtons.append(Button(self.screen, self.sprites.getSprite("login"), self.sprites.getSprite("loginHighlighted"), 368, 350, 281, 68, "Login", 'Start Button.ogg', soundManager)) self.mainButtons.append(Button(self.screen, self.sprites.getSprite("start"), self.sprites.getSprite("startHighlighted"), 368, 442, 281, 68, "Game", 'Start Button.ogg', soundManager)) self.mainButtons.append(Button(self.screen, self.sprites.getSprite("exit"), self.sprites.getSprite("exitHighlighted"), 368, 534, 281, 68, "Exit", 'Exit.ogg', soundManager)) self.fontsize = 30 self.font = pygame.font.Font(os.path.join('Fonts', 'nasalization-rg.ttf'), self.fontsize) self.loginButtons = [] self.ip = textInput(self.screen, "Server IP", (self.screenw/2 - 200, 30), (self.font.get_height() * 8), 50, 15) self.username = textInput(self.screen, "Username", (self.screenw/2 - 200, 130), (self.font.get_height() * 8), 50, 8) self.password = textInput(self.screen, "Password", (self.screenw/2 - 200, 230), (self.font.get_height() * 8), 50, 8, True) self.loginButtons.append(Button(self.screen, self.sprites.getSprite("login"), self.sprites.getSprite("loginHighlighted"), 368, 442, 281, 68, "Lobby", 'Start Button.ogg', soundManager)) self.loginButtons.append(Button(self.screen, self.sprites.getSprite("exit"), self.sprites.getSprite("exitHighlighted"), 368, 534, 281, 68, "Main", 'Exit.ogg', soundManager)) self.mouseDelay = 50 self.mouseNext = pygame.time.get_ticks() self.loginPressed = False #for server self.socket = Connect() self.socket.serverName = None self.socket.clientSocket.settimeout(0.0) self.loginStatus = "" def draw(self): if self.state == "Main": self.screen.blit(self.sprites.getSprite("titlescreen"), (0, 0)) for button in self.mainButtons: button.draw() elif self.state == "Login": self.screen.blit(self.sprites.getSprite("titlescreenbg"), (0, 0)) self.ip.draw() self.username.draw() self.password.draw() if self.loginStatus == "Invalid Password": self.screen.blit(self.font.render("Wrong Password. Try again.", True, pygame.Color(255,255,255)),(300,self.screenh/2 - 100)) elif self.loginStatus == "No Server": self.screen.blit(self.font.render("Waiting for server. Double check info.", True, pygame.Color(255,255,255)),(300,self.screenh/2 - 100)) elif self.loginStatus == "Missing Field(s)": self.screen.blit(self.font.render("Missing Field(s).", True, pygame.Color(255,255,255)),(self.screenw/2 - (len("Invalid Format.") * 30)/4,self.screenh/2 - 100)) for button in self.loginButtons: button.draw() def mouseUpdate(self): if pygame.time.get_ticks() >= self.mouseNext: if pygame.mouse.get_pressed()[0]: if self.state == "Main": for button in self.mainButtons: if button.checkClicked(pygame.mouse.get_pos()): self.state = button.click() elif self.state == "Login": for button in self.loginButtons: if button.checkClicked(pygame.mouse.get_pos()): self.state = button.click() if self.state == "Lobby": self.loginPressed = True if self.ip.input != "" and self.username.input != "" and self.password.input != "": message = self.username.input + ":" + self.password.input self.socket.serverName = self.ip.input try: self.socket.send("LOG:" + message) modifiedMessage, serverAddress = self.socket.clientSocket.recvfrom(2048) self.loginStatus = "" if modifiedMessage.decode() == "Invalid Password": self.loginStatus = "Invalid Password" self.state = "Login" except: self.loginStatus = "No Server" self.state = "Login" else: self.state = "Login" self.loginStatus = "Missing Field(s)" else: self.loginStatus = "" self.loginPressed = False self.ip.checkClicked(pygame.mouse.get_pos()) self.username.checkClicked(pygame.mouse.get_pos()) self.password.checkClicked(pygame.mouse.get_pos()) self.mouseNext = pygame.time.get_ticks() + self.mouseDelay def update(self): self.mouseUpdate() if self.state == "Main": for button in self.mainButtons: button.checkHover(pygame.mouse.get_pos()) return "Menu" elif self.state == "Login": if self.loginPressed: try: message = self.username.input + ":" + self.password.input self.socket.send("LOG:" + message) modifiedMessage, serverAddress = self.socket.clientSocket.recvfrom(2048) self.loginStatus = "" if modifiedMessage.decode() == "Invalid Password": self.loginStatus = "Invalid Password" self.state = "Login" elif modifiedMessage.decode() == "Success": self.state = "Lobby" except: self.loginStatus = "No Server" self.state = "Login" for button in self.loginButtons: button.checkHover(pygame.mouse.get_pos()) self.ip.update() self.username.update() self.password.update() return "Menu" else: return self.state
class game: def __init__(self, screen, screenw, screenh, spriteList, soundManager): self.sprites = spriteList self.screen = screen self.screenw = screenw self.screenh = screenh self.soundManager = soundManager self.player = Player(1, "ship1", "missile1", (500, 700), 32, 32) #self.player = Player(player, "ship" + str(player), "missile"+ str(player + 1), (200 * player,700), 32, 32) self.paused = False self.start = True self.level = 1 self.background = "GameBackground" self.background2 = "GameBackground" self.enemyGrid = [] self.enemyRowCount = 5 self.enemyColumnCount = 10 self.enemyCount = 50 #self.player.score = 0 self.setGrid() self.missiles = [] self.missileDelay = 100 self.enemyDelay = 100 self.enemyFireChance = 100 self.nextMissile = pygame.time.get_ticks() + self.missileDelay self.nextEnemyMove = pygame.time.get_ticks() + self.enemyDelay self.bgHeight = 1536 self.currentBG1Height = 0 self.currentBG2Height = -self.bgHeight self.state = "Game" self.keyDelay = 500 self.nextKeyInput = pygame.time.get_ticks() self.fontsize = 30 self.font = pygame.font.Font(os.path.join('Fonts', 'nasalization-rg.ttf'), self.fontsize) self.pauseButtons = [] self.pauseButtons.append(Button(screen, self.sprites.getSprite("exit"), self.sprites.getSprite("exitHighlighted"), 368, 330, 281, 68, "Menu", 'Exit.ogg', soundManager)) self.mouseDelay = 100 self.mouseNext = pygame.time.get_ticks() #for server self.socket = Connect() self.socket.serverName = '169.234.82.138' random.seed(datetime.now()) self.startTime = None def reset(self): self.player = Player(1, "ship1", "missile2", (500, 700), 32, 32) self.enemyGrid = [] self.missiles = [] self.enemyCount = 50 self.setGrid() self.level = 1 self.player.score = 0 self.state = "Game" self.paused = False self.start = True self.startTime = pygame.time.get_ticks() #Creates the grid for the enemies in the game def setGrid(self, speed = 16, health = 1): for row in range(self.enemyRowCount): self.enemyGrid.append([]) for column in range(self.enemyColumnCount): rnum = random.randint(1, 100) enemySprite = "Alien1SpriteSheet" if rnum <= 45: enemySprite = "Alien2SpriteSheet" elif rnum >= 90 and rnum < 98: enemySprite = "Alien3SpriteSheet" elif rnum >= 98: enemySprite = "Alien4SpriteSheet" self.enemyGrid[row].append(Enemy((32 + (column * 96), (row * 64) - self.enemyRowCount * 64), 32, 32, Animate(self.sprites.getSprite(enemySprite), 2, 2, 32, 32, 10), health, speed, row, column, enemySprite)) def draw(self): self.screen.blit(self.sprites.getSprite(self.background), (0, self.currentBG1Height)) self.screen.blit(self.sprites.getSprite(self.background2), (0, self.currentBG2Height)) self.screen.blit(self.sprites.getSprite(self.player.image), self.player.getPos()) for missile in self.missiles: self.screen.blit(self.sprites.getSprite(missile.image), missile.getPos()) for row in range(self.enemyRowCount): for column in range(self.enemyColumnCount): self.enemyGrid[row][column].anim.draw(self.screen, self.enemyGrid[row][column].getPos()) self.screen.blit(self.font.render("Lives: " + str(self.player.lives), True, pygame.Color(255,255,255)), (0, 670)) self.screen.blit(self.font.render("Ammo: " + str(self.player.missileCap - self.player.missileCount), True, pygame.Color(255,255,255)), (0, 670 + self.fontsize)) self.screen.blit(self.font.render("Score: " + str(self.player.score), True, pygame.Color(255,255,255)),(0,670 + (self.fontsize * 2))) self.screen.blit(self.font.render("Level: " + str(self.level), True, pygame.Color(255,255,255)), (0, 670 - self.fontsize)) if self.paused: for button in self.pauseButtons: button.draw() #Handles everything that needs to go on in the game def update(self): if self.start: if pygame.time.get_ticks() >= self.startTime + 100: self.soundManager.playSound("Enemy_entrance.ogg") pygame.time.delay(2000) self.soundManager.playNewMusic("ScumInvadersTheme(Final).ogg", .2) self.start = False self.keyUpdate() if not self.paused: self.backgroundUpdate() self.state = self.enemyUpdate() if self.checkState(): return self.state self.checkMissiles() self.state = self.checkPlayerLives() if self.checkState(): return self.state self.checkEnemyCount() else: return self.mouseUpdate() return self.state def togglePause(self): self.paused = not self.paused def checkState(self): return self.state != "Game" def checkPlayerLives(self): if (self.player.lives <= 0): return "Menu" return "Game" def checkEnemyCount(self): if self.enemyCount == 0: self.enemyCount = 50 self.nextLevel() '''Odd levels -> change speed; even levels -> change health''' def nextLevel(self): self.enemyGrid = [] self.level += 1 if self.level == 5: self.soundManager.playSound("LevelUp.ogg") self.player.image = "ship1upgrade2" elif self.level == 10: self.soundManager.playSound("LevelUp.ogg") self.player.image = "ship1upgrade3" if self.level % 2 == 0: if self.enemyFireChance > 20: self.enemyFireChance -= 2; self.setGrid(16 + self.level/2, self.level/2) else: self.setGrid(16 + (self.level -1)/2, self.level//2 + 1) #for row in range(self.enemyRowCount): # for column in range(self.enemyColumnCount): # if self.level % 2 == 0: # self.enemyGrid[row][column].speed += self.level * 5 # else: # rnum = random.randint(self.level - 1, self.level) # self.enemyGrid[row][column].health = rnum if self.level %2 == 1: self.player.missileCap += 1 #Handles all of the keypresses (Movement, Shooting and pause) def keyUpdate(self): keys = pygame.key.get_pressed() if pygame.time.get_ticks() > self.nextKeyInput: if keys[pygame.K_ESCAPE]: self.togglePause() self.nextKeyInput = pygame.time.get_ticks() + self.keyDelay if not self.paused: if keys[pygame.K_a]: if not ((self.player.posx - self.player.speed) <= 0): self.player.moveLeft() self.socket.send("MOV:" + str(self.player.posx) + ":" + str(self.player.posy)) if keys[pygame.K_d]: if not ((self.player.posx + self.player.speed + self.player.imagew) >= self.screenw): self.player.moveRight() self.socket.send("MOV:" + str(self.player.posx) + ":" + str(self.player.posy)) if pygame.time.get_ticks() > self.nextMissile: self.nextMissile = pygame.time.get_ticks() + self.missileDelay if keys[pygame.K_SPACE]: if self.player.missileCount < self.player.missileCap: self.missiles.append(self.player.fire()) self.soundManager.playSound("Player_Shoot.ogg") #Only used in the pause menu, captures the clicks from the mouse on the pause screen def mouseUpdate(self): for button in self.pauseButtons: button.checkHover(pygame.mouse.get_pos()) if pygame.time.get_ticks() >= self.mouseNext: if pygame.mouse.get_pressed()[0]: for button in self.pauseButtons: if button.checkClicked(pygame.mouse.get_pos()): return button.click() self.mouseNext = pygame.time.get_ticks() + self.mouseDelay return "Game" def checkHit(self, numMissiles): for row in range(self.enemyRowCount): for column in range(self.enemyColumnCount): if self.enemyGrid[row][column].health != 0: if self.enemyGrid[row][column].collider.colliderect(self.missiles[numMissiles].collider): attacker = self.missiles.pop(numMissiles).owner self.enemyGrid[row][column].health -= 1 self.player.missileCount -= 1 if self.enemyGrid[row][column].health == 0 and not self.enemyGrid[row][column].dead: self.enemyGrid[row][column].dead = True self.enemyGrid[row][column].anim = Animate(self.sprites.getSprite(self.enemyGrid[row][column].type[:6] + "DeathSpriteSheet"), 3, 3, 32, 32, 2, False) self.enemyCount -= 1 if self.enemyGrid[row][column].type == "Alien4SpriteSheet": self.player.score += (100 * self.level) * 10 elif self.enemyGrid[row][column].type != "Alien3SpriteSheet": self.player.score += (100 * self.level) * 2 else: self.player.score += 100 * self.level return #Handles the effects of the missiles from both players(1) and enemies(0) def checkMissiles(self): numMissiles = 0 while numMissiles < len(self.missiles): self.missiles[numMissiles].update() attacker = self.missiles[numMissiles].owner #1 is the player's missile shots if attacker == 1: if ((self.missiles[numMissiles].posy + self.missiles[numMissiles].imageh) < 0): self.missiles.pop(numMissiles) self.player.missileCount -= 1 else: self.checkHit(numMissiles) #-1 is the enemy's missile shots elif attacker == -1: if (self.missiles[numMissiles].collider.colliderect(self.player.collider)): self.player.lives -= 1 enemyGridPos = self.missiles.pop(numMissiles).getEnemyPos() self.enemyGrid[enemyGridPos[0]][enemyGridPos[1]].missileCount -= 1 elif ((self.missiles[numMissiles].posy) > self.screenh): enemyGridPos = self.missiles.pop(numMissiles).getEnemyPos() self.enemyGrid[enemyGridPos[0]][enemyGridPos[1]].missileCount -= 1 numMissiles += 1 def enemyUpdate(self): if pygame.time.get_ticks() > self.nextEnemyMove: self.nextEnemyMove = pygame.time.get_ticks() + self.enemyDelay for row in range(self.enemyRowCount): for column in range(self.enemyColumnCount): if self.enemyGrid[row][column].health != 0 and (self.enemyGrid[row][column].posy + 32 >= 768 or (self.enemyGrid[row][column].posy + 32 > self.player.posy and self.player.posx < self.enemyGrid[row][column].posx < self.player.posx + 64)) : self.togglePause() return "Menu" self.enemyGrid[row][column].anim.update() rNum2 = random.randint(1,self.enemyFireChance) if rNum2 == 1: if (self.enemyGrid[row][column].health != 0 and self.enemyGrid[row][column].missileCount < self.enemyGrid[row][column].missileCap): self.missiles.append(self.enemyGrid[row][column].fire()) if self.enemyGrid[row][column].lastMove == None: if row % 2 == 0: self.enemyGrid[row][column].lastMove = "Left" else: self.enemyGrid[row][column].lastMove = "Right" self.enemyGrid[row][column].moveDown() self.enemyGrid[row][column].moveDown() self.enemyGrid[row][column].moveDown() #print("This happened.") elif self.enemyGrid[row][column].lastMove == "Left": if self.enemyGrid[row][column].posx <= 0: self.enemyGrid[row][column].lastMove = "Right" self.enemyGrid[row][column].moveDown() # self.enemyGrid[row][column].moveRight() else: self.enemyGrid[row][column].moveLeft() elif self.enemyGrid[row][column].lastMove == "Right": if self.enemyGrid[row][column].posx + self.enemyGrid[row][column].imagew >= 1024: self.enemyGrid[row][column].lastMove = "Left" self.enemyGrid[row][column].moveDown() # self.enemyGrid[row][column].moveLeft() else: self.enemyGrid[row][column].moveRight() #rNum = random.randint(1, 5) #for row in range(self.enemyRowCount): # for column in range(self.enemyColumnCount): ##checks if enemies have reached the bottom of the screen #if self.enemyGrid[row][column].posy + 32 >= 768 or (self.enemyGrid[row][column].posy + 32 > self.player.posy and self.player.posx < self.enemyGrid[row][column].posx < self.player.posx + 64) : # return "Menu" # if self.enemyGrid[row][column].health != 0: # if rNum >= 3: # self.enemyGrid[row][column].lastMove = "Down" # self.enemyGrid[row][column].moveDown() # elif rNum == 1: # if (self.enemyGrid[row][column].posx - 16 >= 0) and self.enemyGrid[row][column].lastMove != "Left": # self.enemyGrid[row][column].lastMove = "Left" # self.enemyGrid[row][column].moveLeft() # elif rNum == 2: # if ((self.enemyGrid[row][column].posx + 16 + self.enemyGrid[row][column].imagew) <= self.screenw) and self.enemyGrid[row][column].lastMove != "Right": # self.enemyGrid[row][column].lastMove = "Right" # self.enemyGrid[row][column].moveRight() return "Game" #scrolls through the background def backgroundUpdate(self): self.currentBG1Height += 1 self.currentBG2Height += 1 if (self.currentBG1Height >= self.bgHeight): self.currentBG1Height = -self.bgHeight rnum = random.randint(1,3) if rnum == 1: self.background = "GameBackground" elif rnum == 2: self.background = "GameBackground2" else: self.background = "GameBackground3" elif (self.currentBG2Height >= self.bgHeight): self.currentBG2Height = -self.bgHeight rnum = random.randint(1,3) if rnum == 1: self.background2 = "GameBackground" elif rnum == 2: self.background2 = "GameBackground2" else: self.background2 = "GameBackground3"
class Battle(cocos.layer.ColorLayer): is_event_handler = True def __init__(self): super().__init__(162, 205, 90, 255) self.cnum = 4 # TODO delete self.status = 'ready' self.debug = True self.initImage() def assistDebug(self): # TODO delete self.me.modCrystal(10, 10) self.connect.send(('debug', [self.cnum])) time.sleep(1) act, local.args = recvMsgs.pop(0) self.me.drawCard(self.cnum) # 匹配 def match(self): self.connect = Connect() self.connect.connect(local.id, local.curDeckID) data = self.connect.recv() if data == None: return logger.error('匹配超时') self.cardlist = [] #待选 self.selected = [] #选中 self.commitArgs = [] #暂存变量 self.status = 'beforeBattle' self.renderOpening(data) # 绘制开场信息并等待换牌 #卡牌选择或替换 def renderBigCards(self, cards): #双方战场绘制区域初始化 x, y = self.center num = len(cards) w, h = local.winWidth, local.winHeight posx0 = x - (0.3 * w) # 第一张牌的位置 distance = 0.6 * w / (num - 1) # 相邻两张牌的距离 for card in cards: logger.debug(card.name) card.initImage() # 将其加入场景 local.battleScene.add(card) i = cards.index(card) card.do( MoveTo((posx0 + distance * i, y + h / 10), 1.5) + ScaleBy(2, 0.5)) self.cardlist = cards # 确定按钮 self.add(self.confirmBtn, z=3) #开场 def renderOpening(self, data): # 对方昵称,对方英雄,己方英雄,起始手牌 opNickName, myHeroID, opHeroID, self.cardlist = data #获取开场信息、起始手牌 # print(data) # 公共战场信息 local.battle = PublicBattle() me = self.me = Player(openingHeros[myHeroID](), isOpponent=False) me.opponent = Player(openingHeros[opHeroID](), isOpponent=True) # 我对手的对手是我 me.opponent.opponent = me # 昵称 enemyNickName = opNickName myNickName = local.nickName # 绘制待替换卡牌 self.selected = [] # 换牌时selected比较特殊,是个list self.renderBigCards(self.cardlist) #起手换牌 def replace(self): newCards = self.connect.send_recv(self.selected) logger.debug('换来的牌%s', newCards) cards = self.cardlist #重新安排cards for i in self.selected: cards[i] = newCards.pop(0) cards[i].initImage() # 将其加入场景 local.battleScene.add(cards[i]) if len(cards) == 4: #硬币入手 coin = Coin() cards.append(coin) local.battleScene.add(coin) #将开场卡牌加入手牌 for card in cards: card.getDrawed(self.me) # card.holder = self.me # self.me.hand = cards self.me.renderHand() self.me.opponent.drawCard(5 if len(cards) == 3 else 3) #重置cardlist和selected self.cardlist = [] self.selected = None #另起线程监听服务端order _thread.start_new_thread(self.listenOrder, ()) #若先手,则置为我的回合 if len(cards) == 3: self.status = 'myTurnReady' else: self.status = 'enemyTurn' # 设置玩家回合 self.me.opponent.myTurn = True # 回合开始 def myTurnStart(self): logger.info('回合开始') #回合开始 while not recvMsgs: time.sleep(0.1) # 设置玩家回合 self.me.myTurn = True self.me.opponent.myTurn = False # 处理命令和参数 order, local.args = recvMsgs.pop(0) self.me.genEvent(order, self.me) self.me.clear() if self.debug: self.assistDebug() self.debug = False self.cardlist = self.me.getAvailables() # 显示回合结束按钮 self.add(self.endTurnBtn) # 对手行动 def enemyAction(self): if not recvMsgs: return print('enemyAction', recvMsgs) order, local.args = recvMsgs.pop(0) # print('local args ss', local.args) player = self.me.opponent if isinstance(order, Event): self.me.genEvent(order, player) if order == Event.回合结束: self.status = 'myTurn' self.myTurnStart() # break elif order == 'play': # args = local.args[0] # handIdx = args[0] player.play() elif order == 'attack': args = local.args.pop(0) card = fromLocation(args[0], player) target = fromLocation(args[1], player) card.attacking(target) elif order == 'power': pass elif order == 'debug': self.me.opponent.modCrystal(10, 10) self.me.opponent.drawCard(self.cnum) self.me.clear() # 监听通知 def listenOrder(self): while True: order = self.connect.recv(1024) recvMsgs.append(order) log(('listen', recvMsgs)) _thread.start_new_thread(self.mousemove, ()) def commitOrder(self, act): card = self.selected log(card) self.connect.send((act, self.commitArgs)) while not recvMsgs: time.sleep(0.2) order, local.args = recvMsgs.pop(0) if act == 'play': # 随从:handIdx, minionIdx, [targetLoc] # 其他:handIdx, [targetLoc] handIdx = self.commitArgs.pop(0) #TODO 待测 self.me.hand[handIdx].play(*self.commitArgs) elif act == 'attack': log(self.commitArgs) fromLocation(self.commitArgs[0], self.me).attacking( fromLocation(self.commitArgs[1], self.me)) elif act == 'turnEnd': self.me.genEvent(Event.回合结束) # 设置玩家回合 self.me.myTurn = False self.me.opponent.myTurn = True self.status = 'enemyTurn' self.fade() self.remove(self.endTurnBtn) self.me.clear() def mousemove(self): while True: if local.animingMutex == 0: curx, cury = simuInput.getPos() if self.status == 'enemyTurn' and recvMsgs: simuInput.moveTo(local.winWidth - 6, local.winHeight - 6) elif self.status == 'myTurnReady': simuInput.moveTo(local.winWidth - 6, local.winHeight - 3) #功成身退,回到原位 # time.sleep(0.05) # print(self.status) # simuInput.moveTo(curx, cury) return else: time.sleep(0.1) def on_mouse_motion(self, x, y, dx, dy): if self.status == 'enemyTurn' and recvMsgs: self.enemyAction() elif self.status == 'myTurnReady' and x >= local.winWidth - 6 and y >= local.winHeight - 6: self.status = 'myTurn' self.myTurnStart() def on_mouse_press(self, posx, posy, buttons, modifiers): if self.status == 'myTurn' and self.me.myTurn: card = self.clickCard(self.cardlist, posx, posy) if card: logger.warning('箭头') self.add(self.arrow, z=4) self.status = 'arrow' self.selected = card self.fade() card.do(ScaleBy(1.5, 0)) if self.hitIt(posx, posy, self.endTurnBtn, self): # 回合结束 logger.info('回合结束按钮') self.commitOrder('turnEnd') elif self.status == 'battlecry': target = self.clickCard(self.cardlist, posx, posy) if target: # getLocation(target) self.commitArgs.append(toLocation(target)) self.commitOrder('play') elif self.status == 'enemyTurn': self.enemyAction() elif self.status == 'beforeBattle': ##换牌 card = self.clickCard(self.cardlist, posx, posy) if card: idx = self.cardlist.index(card) #此时比较特殊,selected存放的是序号 if idx in self.selected: card.remove(card.cross) self.selected.remove(idx) else: card.cross = Sprite(local.res['cross'], position=card.items['frame'].position, scale=local.itemScale * card.scale * 4) card.add(card.cross, z=3) self.selected.append(idx) return if self.hitIt(posx, posy, self.confirmBtn, self): # self.status = 'myTurnReady' for idx in self.selected: local.battleScene.remove(self.cardlist[idx]) self.remove(self.confirmBtn) self.replace() #判断指定对象是否被点击 def hitIt(self, posx, posy, sprite, node): nodex, nodey = node.position spritex, spritey = sprite.position x, y = spritex + nodex, spritey + nodey w, h = sprite.width * node.scale, sprite.height * node.scale if x - w / 2 < posx < x + w / 2 and y - h / 2 < posy < y + h / 2: return True def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): if self.status == 'arrow': #箭头跟随鼠标 self.arrow.position = x, y def on_mouse_release(self, posx, posy, buttons, modifiers): if self.status != 'arrow': return #箭头消失 self.remove(self.arrow) self.status = 'none' #当前操纵卡牌 card = self.selected me = self.me # 若为手牌,将其位置作为提交的第一个参数 if card in self.me.hand: self.commitArgs = [self.me.hand.index(card)] # 随从牌 if card in self.me.hand and card.type == 'minion': x, y, w, h = me.minionRegion if x < posx < x + w and y < posy < y + h: fieldIdx = 0 for m in me.minionField: if m.position[0] < posx: fieldIdx += 1 else: break self.commitArgs.append(fieldIdx) # 若有战吼目标 # 或有连击、有连击计数且有连击目标 # 直接返回,保留self.selected if card.targetType and ( ('combo' not in card.exts) or ('combo' in card.exts and card.holder.comboCount > 0)): logger.info('战吼或连击') self.cardlist = card.getSelectables() if self.cardlist: self.status == 'battlecry' return #若没有符合条件的战吼目标,取消战吼直接登场 # print(card.name, '直接登场') self.commitOrder('play') #无需指定目标的手牌 elif posy < me.minionRegion[1]: # 需上移一定距离才可打出,防误触 pass elif card in self.me.hand and not card.targetType: self.commitOrder('play') else: print('法术',me.minionRegion[1],posy) #获得所有可针对的目标 targets = card.getSelectables() #获取当前位置且可针对的目标 target = self.clickCard(targets, posx, posy) #没有满足条件的目标 if not target: return #若卡牌为场上角色,发起攻击 if card in card.holder.minionField + [self.me.hero]: self.commitArgs = [ toLocation(card, me), toLocation(target, me) ] self.commitOrder('attack') else: self.commitArgs.append(self.getLocation(target)) self.commitOrder('play') self.settle() #整理场面 def settle(self): self.status = 'myTurn' self.arrow.position = (-100, -100) self.fade() self.cardlist = self.me.getAvailables() self.selected.scale = local.cardScale self.selected = None self.commitArgs = [] self.me.renderHand() if not self.cardlist: #没有可做的事了 #TODO 特殊提示 pass # 键盘按压 def on_key_press(self, key, modifiers): if self.status == 'ready' and key == local.keyCode['space']: self.status = '' logger.info('匹配中') self.match() #消除可选/可操作光圈 def fade(self): log(self.cardlist) for card in self.cardlist: try: card.remove(card.items['circle']) except: logger.debug('%s没有光圈', card.name) #若有卡牌在点击范围,返回这张卡 def clickCard(self, cards, posx, posy): for card in cards: # x,y=card.position # print(x,y) # w,h = card.items['frame'].width*card.scale, card.items['frame'].height*card.scale # if x-w/2<posx<x+w/2 and y-h/2<posy<y+h/2: if self.hitIt(posx, posy, card.items['frame'], card): return card return None #绘制战场按钮 def initImage(self): self.center = (director.get_window_size()[0] / 2, director.get_window_size()[1] / 2) posx, posy = self.center # 棋盘 self.chessboard = Sprite(local.res['chessboard'], position=self.center, scale=local.winHeight * 0.8 / 1000) self.add(self.chessboard) # 确认按钮 self.confirmBtn = Sprite(local.res['confirm'], position=(posx, posy - 0.2 * local.winHeight), scale=local.winHeight * 0.6 / 1000) # 红箭头 self.arrow = Sprite(local.res['arrow'], position=(-100, -100)) # 回合结束按钮 self.endTurnBtn = Sprite(local.res['end_turn'], position=local.endTurnPos) #初始化模拟点击 simuInput.init(local.director) _thread.start_new_thread(simuInput.key_press, ('space', ))