pygame中的优化和抽象

时间:2019-05-02 01:33:43

标签: python pygame

抽象和修复此代码的最佳方法是什么?我是编码和pygame的新手,需要一些帮助来完成该项目。明天到期,任何帮助将不胜感激。

我的目标是创建一个火箭游戏,让我的太空船躲避障碍物并收集硬币,并在收集到一定数量的硬币并到达顶部后最终赢得比赛。

到目前为止,我遇到了3个主要问题:

  • 我讨厌我有很多行相同的代码,并且想找到一种压缩它的方法。

  • 我有一个无法解决的漏洞碰撞问题,飞船穿过该块,而不是每次穿过该块的上半部都与之碰撞

  • 我想知道在收集硬币后创建一个if语句以增加用户得分的最佳方法是,该语句将使用户在收集到一定数量并达到最高额之后获胜

我尝试过创建一个类来容纳我的角色,但失败了,并且不知道如何为它们分配不同的属性,例如速度

    #  goals - get the scoring done by adding 1 to the score if the spaceship collides with the block, then deleting the block and printing the new score
    #  figure out the collision problem, fix the loophole where the spaceship can pass through the block if it is above the bottom of the block
    #  figure out a way to reduce redundancy by making a class for the stars and the block
    import pygame
    import time
    import random
    pygame.init()
    screenWidth = 700
    screenHeight = 700
    wn = pygame.display.set_mode((screenWidth, screenHeight))
    pygame.display.set_caption("Maxym's First Adventure")
    clock = pygame.time.Clock()

    spaceshipImg = pygame.image.load('spaceship.png')
    black = (0, 0, 0)
    blue = (50, 120, 200)


    def startmenu():
        intro = True
        while intro:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    quit()
            wn.fill(blue)
            messagedisplay("Spaceship")
            pygame.display.update()
            gameloop()


    def thing(thingx, thingy, thingw, thingh, color):
        pygame.draw.rect(wn, color, [thingx, thingy, thingw, thingh])


    def coin(coinx, coiny, coinw, coinh, color):
        pygame.draw.rect(wn, color, [coinx, coiny, coinw, coinh])


    def spaceship(x, y):
            wn.blit(spaceshipImg, (x, y))


    def messagedisplay(text):
        font = pygame.font.Font('freesansbold.ttf', 115)
        wn.blit(font.render(text, True, (0, 0, 0)), (0, 0))
        pygame.display.update()
        time.sleep(2)
        gameloop()


    def win():
        messagedisplay("You win")


    def crash():
        messagedisplay("You crashed")
    def collect():
        score +=1

    def gameloop():
        x = screenWidth * .45
        y = screenHeight * .8
        width = 75
        height = 132
        velocity = 50

        starx = random.randrange(0, screenWidth)
        stary = 0
        starspeed = 30
        starw = 50
        starh = 50
        star2x = random.randrange(0, screenWidth)
        star2y = 0
        star2speed = 50
        star2w = 80
        star2h = 80
        star3x = random.randrange(0, screenWidth)
        star3y = 0
        star3speed = 70
        star3w = 30
        star3h = 30
        star4x = random.randrange(0, screenWidth)
        star4y = 0
        star4speed = 30
        star4w = 200
        star4h = 40
        coinx = random.randrange(0, screenWidth/2)
        coiny = random.randrange(0, screenHeight)
        coinw = 20
        coinh = 20
        coin2x = random.randrange(0, screenWidth/2)
        coin2y = random.randrange(0, screenHeight)
        coin2w = 20
        coin2h = 20
        coin3x = random.randrange(screenWidth/2, screenWidth)
        coin3y = random.randrange(0, screenHeight)
        coin3w = 20
        coin3h = 20
        coin4x = random.randrange(screenWidth/2, screenWidth)
        coin4y = random.randrange(0, screenHeight)
        coin4w = 20
        coin4h = 20
        coin5x = random.randrange(0, screenWidth)
        coin5y = random.randrange(0, screenHeight)
        coin5w = 20
        coin5h = 20
        run = True
        while run:
            pygame.time.delay(100)
            wn.fill((255, 255, 255))

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    quit()
                print(event)

            keys = pygame.key.get_pressed()
            if keys[pygame.K_LEFT] and x > velocity:
                x -= velocity
            if keys[pygame.K_RIGHT] and x < screenWidth-width-velocity:
                x += velocity
            if keys[pygame.K_UP] and y > velocity:
                    y -= velocity
            if keys[pygame.K_DOWN] and y < screenHeight-height-velocity:
                    y += velocity
            pygame.draw.rect(wn, (255, 255, 255), (x, y, width, height))
            thing(starx, stary, starw, starh, black)
            thing(star2x, star2y, star2w, star2h, black)
            thing(star3x, star3y, star3w, star3h, black)
            thing(star4x, star4y, star4w, star4h, black)
            coin(coinx, coiny, coinw, coinh, blue)
            coin(coin2x, coin2y, coin2w, coin2h, blue)
            coin(coin3x, coin3y, coin3w, coin3h, blue)
            coin(coin4x, coin4y, coin4w, coin4h, blue)
            coin(coin5x, coin5y, coin5w, coin5h, blue)

            stary += starspeed
            star2y += star2speed
            star3y += star3speed
            star4y += star4speed
            if stary > screenHeight:
                stary = 0 - starh
                starx = random.randrange(0, screenWidth)
            if star2y > screenHeight:
                star2y = 0 - star2h
                star2x = random.randrange(0, screenWidth)
            if star3y > screenHeight:
                star3y = 0 - star3h
            if star4y > screenHeight:
                star4y = 0 - star4h
            score = 0
            if y + height >= stary and y + height <= stary + starh or y <= stary + starh and y + height >= stary + starh:
                if x + width >= starx and x + width <= starx + starw or x <= starx + starw and x + width >= starx + starw:
                    crash()
            if y + height >= star2y and y + height <= star2y + star2h or y <= star2y + star2h and y + height >= star2y + star2h:
                if x + width >= star2x and x + width <= star2x + star2w or x <= star2x + star2w and x + width >= star2x + star2w:
                    crash()
            if y + height >= star3y and y + height <= star3y + star3h or y <= star3y + star3h and y + height >= star3y + star3h:
                if x + width >= star3x and x + width <= star3x + star3w or x <= star3x + star3w and x + width >= star3x + star3w:
                    crash()
            if y + height >= star4y and y + height <= star4y + star4h or y <= star4y + star4h and y + height >= star4y + star4h:
                if x + width >= star4x and x + width <= star4x + star4w or x <= star4x + star4w and x + width >= star4x + star4w:
                    crash()
            if y + height >= coiny and y + height <= coiny + coinh or y <= coiny + coinh and y + height >= coiny + coinh:
                if x + width >= coinx and x + width <= coinx + coinw or x <= coinx + coinw and x + width >= coinx + coinw:
                    collect()
            if y + height >= coin2y and y + height <= coin2y + coin2h or y <= coin2y + coin2h and y + height >= coin2y + coin2h:
                if x + width >= coin2x and x + width <= coin2x + coin2w or x <= coin2x + coin2w and x + width >= coin2x + coin2w:
                    collect()
            if y + height >= coin3y and y + height <= coin3y + coin3h or y <= coin3y + coin3h and y + height >= coin3y + coin3h:
                if x + width >= coin3x and x + width <= coin3x + coin3w or x <= coin3x + coin3w and x + width >= coin3x + coin3w:
                    collect()
            if y + height >= coin4y and y + height <= coin4y + coin4h or y <= coin4y + coin4h and y + height >= coin4y + coin4h:
                if x + width >= coin4x and x + width <= coin4x + coin4w or x <= coin4x + coin4w and x + width >= coin4x + coin4w:
                    collect()
            if y + height >= coin5y and y + height <= coin5y + coin5h or y <= coin5y + coin5h and y + height >= coin5y + coin5h:
                if x + width >= coin5x and x + width <= coin5x + coin5w or x <= coin5x + coin5w and x + width >= coin5x + coin5w:
                    collect()

            if y <= 10 and score >= 3:
                win()
            spaceship(x, y)
            pygame.display.update()
            clock.tick(60)


    startmenu()
    gameloop()
    pygame.quit()
    quit()

2 个答案:

答案 0 :(得分:1)

保留list中的值,而不是变量starstar2等。然后,您可以使用for循环使代码更短。


您应该使用pygame.Rect()而不是thingx, thingy, thingw, thingh(和类似名称),然后才能拥有

def thing(thing_rect, color): 

代替

def thing(thingx, thingy, thingw, thingh, color): 

pygame.draw.rect(wn, color, thing_rect) 

代替

pygame.draw.rect(wn, color, [thingx, thingy, thingw, thingh])

pygame.Rect具有检查冲突的功能,因此您不必在if中编写长代码。


pygame.Rectrect.bottom得到rect.y + rect.height,有rect.right得到rect.x + rect.width

答案 1 :(得分:1)

将“硬币”移动到简单的数据结构中,然后保留它们的列表,而不是6个准静态对象的列表,将立即获得收益。

这允许您仅使用一组测试代码就可以遍历硬币列表。考虑一下代码段:

MAX_COINS = 6
all_coins = []

def addCoin( colour=(0,30,240), coinw=20, coinh=20 ):
    global all_coins
    coinx = random.randrange(0, screenWidth/2)
    coiny = random.randrange(0, screenHeight)
    all_coins.append( [ colour, pygame.Rect( coinx, coiny, coinw, coinh ) ] )

def drawCoin( window, coin ):
    coin_colour = coin[0]
    coin_rect   = coin[1]
    pygame.draw.rect( window, coin_colour, coin_rect )

...

# Create 6 coins, or add more if one/some collected
for i in range( MAX_COINS - len( all_coins ) ):
    addCoin()

# Draw all coins
for coin in all_coins:
    drawCoin( screen, coin )

# Check coin collision with player
for coin in all_coins:
    player_rect = pygame.Rect( x, y, width, height )
    coin_rect   = coin[1]
    if ( pygame.Rect.colliderect( player_rect, coin_rect ) ):
        all_coins.del( coin )  # remove the coin from the coin-list  
        collect()

此代码提供了一个硬币解决方案,该解决方案的行数可能比现有代码少,但现在支持任何数量的硬币,并保护了代码免遭拼写错误的侵害。此外,如果需要更改冲突代码,则仅需要分析和修复一组逻辑。可以对Star个对象进行几乎相同的更改(甚至可以将类型存储到类似硬币的对象中,并同时用于两者)。

当然,此代码与已经存在的PyGame Sprite library的工作方式非常匹配。重构以使用精灵将是一个更好的更改。