你能帮我找到我的问题吗?碰撞后我的变量没有变化

时间:2015-03-03 02:12:39

标签: python pygame sprite collision

我还是初学者,我正在尝试更频繁地使用课程。我刚遇到一个问题,我一直试图弄清楚几个小时。当敌人攻击我的星球时,我的星球的价值应该随着舰队的价值而降低。如果我的星球的值低于0,我的星球应该成为敌人的星球。但是,当敌人的舰队与我的星球发生碰撞时,我的星球的价值会上升而且所有者变量保持不变。我相信我的错误是在我的舰队Class的更新功能中的某个地方。我试图从代码输出很多打印语句,所以我可以看到每个循环的每个变量的状态。结果,玩家的星球并没有改变所有者,但我确实看到了这个星球的价值下降。如果你们有任何建议可以帮助我解决其他问题,我将非常感谢你的帮助。哦,我的颜色是硬编码的我知道,这是暂时的。

import sys
import math
import pygame

screen_size = (640, 480)
fps = 60

class Planet(pygame.sprite.Sprite):
    ''''''

    def __init__(self, x, y, value, owner = 'free', color = (0, 0, 255)):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface((32, 32))
        self.image.fill(color)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.value = value
        self.owner = owner
        self.color = color

        self.grow = False
        self.selected = False
        self.text = str(self.value)

    def update(self):
        if self.grow == True:
            self.value += 1
            self.grow = False
        self.text = str(self.value)
        if self.owner == 'player':
            color = (0, 255, 0)
        elif self.owner == 'free':
            color = (0, 0, 255)
        elif self.owner == 'enemy':
            color = (255, 0, 0)
        if self.selected:
            color = (255, 0, 255)
        self.image.fill(color)

    def drawValue(self):
        textToScreen(screen, self.text, self.rect.centerx, self.rect.centery)

class Fleet(pygame.sprite.Sprite):

    def __init__(self, x, y, value, owner, home, target):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((16, 16))
        self.image.fill((255, 0, 0))
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.value = value
        self.owner = owner
        self.text = str(self.value)
        self.home = home
        self.target = target
        self.speed = 2

    def update(self):
        self.text = str(self.value)

        for planet in playerplanets: #fleet collision with
            if planet.rect.collidepoint(self.rect.x, self.rect.y):
                if self.home != planet.rect:
                    if self.owner == 'player':
                        planet.value += self.value
                    elif self.owner == 'enemy':
                        planet.value -= self.value
                        if planet.value <= 0:
                            playerplanets.remove(planet)
                            planet.owner = 'enemy'
                            enemyplanets.add(planet)
                            #planet.value = planet.value - (planet.value * 2)
                    self.kill()

        for planet in freeplanets:
            if planet.rect.collidepoint(self.rect.x, self.rect.y):
                planet.value -= self.value
                if planet.value <= 0:
                    planet.value = planet.value - (planet.value * 2)
                    freeplanets.remove(planet)
                    if self.owner == 'player':
                        planet.owner = 'player'
                        playerplanets.add(planet)
                    elif self.owner == 'enemy':
                        planet.owner = 'enemy'
                        enemyplanets.add(planet)
                self.kill()

        for planet in enemyplanets:
            if planet.rect.collidepoint(self.rect.x, self.rect.y):
                if self.home != planet.rect:
                    planet.value -= self.value
                    if planet.value <= 0:
                        planet.value = planet.value - (planet.value * 2)
                        enemyplanets.remove(planet)
                        planet.owner = 'player'
                        playerplanets.add(planet)


        dx, dy = self.rect.centerx - self.target[0], self.rect.centery - self.target[1]
        dist = math.hypot(dx, dy)
        if dist == 0:
            dist = 1
        else:
            dx, dy = dx / dist, dy / dist
        self.rect.centerx -= dx * self.speed
        self.rect.centery -= dy * self.speed



    def drawValue(self):
        textToScreen(screen, self.text, self.rect.centerx, self.rect.centery)


def main():
    global screen, clock, timer, homeplanets, playerplanets, freeplanets, enemyplanets, allplanets, playerfleets, enemyfleets, allfleets
    pygame.init()

    screen = pygame.display.set_mode((screen_size), 0)
    clock = pygame.time.Clock()
    timer = 0

    homeplanets = pygame.sprite.Group()
    playerplanets = pygame.sprite.Group()
    freeplanets = pygame.sprite.Group()
    enemyplanets = pygame.sprite.Group()
    allplanets = pygame.sprite.Group()

    playerfleets = pygame.sprite.Group()
    enemyfleets = pygame.sprite.Group()
    allfleets = pygame.sprite.Group()

    background = (200, 200, 200)

    planet01 = Planet(50, 50, 100, 'player', (0, 255, 0))
    planet02 = Planet(100, 200, 50, 'free', (0, 0, 255))
    planet03 = Planet(300, 100, 200, 'enemy', (255, 0, 0))


    homeplanets.add(planet01)
    playerplanets.add(planet01)
    allplanets.add(planet01)

    freeplanets.add(planet02)
    allplanets.add(planet02)

    enemyplanets.add(planet03)
    allplanets.add(planet03)


    while True:

        processTimer()
        processInput()
        processAI()

        allplanets.update()
        allfleets.update()

        screen.fill(background)
        allplanets.draw(screen)
        allfleets.draw(screen)

        for planet in allplanets:
            planet.drawValue()
        for fleet in allfleets:
            fleet.drawValue()


        pygame.display.flip()
        clock.tick(fps)

        #TEST
        for planet in allplanets:
            print planet.owner

def processTimer():
    global timer
    timer += 1
    if timer == 100:
        for planet in allplanets:
            planet.grow = True
        timer = 0

def processInput():
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
                sys.exit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            mousex, mousey = pygame.mouse.get_pos()
            if event.button == 1:
                processLeftClicked(mousex, mousey)
            elif event.button == 3:
                processRightClicked(mousex, mousey)

def processAI():
    for eplanet in enemyplanets:
        if eplanet.value > 10:
            for pplanet in playerplanets:
                if eplanet.value / 2 > pplanet.value + 10:
                    target = pplanet.rect.center
                    x = eplanet.rect.x
                    y = eplanet.rect.y
                    value = eplanet.value / 2
                    home = eplanet.rect

                    eplanet.value = eplanet.value / 2

                    fleet = Fleet(x, y, value, 'enemy', home, target)
                    enemyfleets.add(fleet)
                    allfleets.add(fleet)

def processLeftClicked(mousex, mousey):
    for planet in playerplanets:
        if planet.rect.collidepoint((mousex, mousey)):
            if planet.selected == True:
                planet.selected = False
            elif planet.selected == False:
                planet.selected = True

def processRightClicked(mousex, mousey):
    for planet_ in allplanets:
        if planet_.rect.collidepoint((mousex, mousey)):
            planet_.selected = False
            target = planet_.rect.center
            for planet in playerplanets:
                if planet.selected == True:
                    if planet.value != 0:
                        x = planet.rect.x
                        y = planet.rect.y
                        value = planet.value / 2
                        home = planet.rect
                        if value == 0:
                            value = 1

                        planet.value = planet.value / 2

                        fleet = Fleet(x, y, value, 'player', home, target)
                        playerfleets.add(fleet)
                        allfleets.add(fleet)



def textToScreen(screen, text, x = 100, y = 100, text_size = 15, text_color = (0, 0, 0), font_type = 'freesans.ttf'):
    try:    
        font = pygame.font.SysFont(font_type, text_size)
        text = str(text)
        text = font.render(text, True, text_color)
        text_rect = text.get_rect()
        text_rect.centerx = x
        text_rect.centery = y
        screen.blit(text, (text_rect))

    except Exception as exception:
        print('Font Error')
        raise exception


if __name__ == '__main__':
    main()

1 个答案:

答案 0 :(得分:0)

问题是你要将它添加到敌人列表中,但是当你处理敌人的时候,它现在在那个列表中,所以它会再次被添加回到playerplanets。换句话说,它在一次更新中被处理两次。向地球添加某种旗帜,表明它已经被处理过了。