Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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"
Ejemplo n.º 4
0
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', ))