代码无功能,不兼容功能?

时间:2018-06-16 10:01:04

标签: python pygame

我正在尝试为我的A-Level最终项目学习PyGame,并且我已经开始使用Atari Breakout。我有一个球在球拍周围跳出的阶段。但是代码非常不整洁所以我想把它放到函数中。

代码无需函数:

import pygame, sys
from pygame.locals import *

pygame.init()
DISPLAYSURF = pygame.display.set_mode((1280, 720))
pygame.display.set_caption('Breakout')
padX = 310
padY = 680
dotX = 150
dotY = 150
dotMX = -1
dotMY = -1
loss = False

while loss != True:
    DISPLAYSURF.fill(pygame.Color(0,0,0))
    for event in pygame.event.get():

        if event.type == QUIT:
            pygame.quit()
            sys.exit()

        elif event.type == pygame.MOUSEMOTION:
            padX = event.pos[0]-75

        if padX < 3:
                padX = 3

        elif padX > 1127:
                padX = 1127

    pygame.draw.rect(DISPLAYSURF, pygame.Color(0, 0, 255),(padX, padY, 150, 30))

    dotX += dotMX
    dotY += dotMY

    if dotY >= 720 - 30:
        loss = True

    #hor colis
    if dotX <= 0 + 20:
        if dotMX == 1:
            dotMX = -1
        else:
            dotMX = 1
    elif dotX >= 1280 - 20:
        if dotMX == 1:
            dotMX = -1
        else:
            dotMX = 1
    #vert colis
    if dotY <= 0 - 20:
        if dotMY == 1:
            dotMY = -1
        else:
            dotMY = 1
    elif dotY >= 720 - 20:
        if dotMY == 1:
            dotMY = -1
        else:
            dotMY = 1
    #pad colis 
    if dotX >= padX and dotX <= padX + 150 and dotY == 665:
        if dotMY == 1:
            dotMY = -1
        else:
            dotMY = 1

    pygame.draw.circle(DISPLAYSURF, pygame.Color(255,0,0), (dotX, dotY), 20)

    pygame.display.update()

但是这里是它,但分为功能:

import pygame, sys
from pygame.locals import *
DISPLAYSURF = pygame.display.set_mode((1280, 720))


padX = 310
padY = 680
dotX = 150
dotY = 150
dotMX = -1
dotMY = -1
lives = 5


def main(padX, padY, dotX, dotY, dotMX, dotMY, lives):

    pygame.init()

    pygame.display.set_caption('Breakout')
    while lives != 0:
        DISPLAYSURF.fill(pygame.Color(0,0,0))
        for event in pygame.event.get():           
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEMOTION:
                padX = event.pos[0]-75

            if padX < 3:
                    padX = 3

            elif padX > 1127:
                    padX = 1127

        pygame.draw.rect(DISPLAYSURF, pygame.Color(0, 0, 255),(padX, padY, 150, 30))

        dotX += dotMX
        dotY += dotMY

        colis(dotX, dotY, dotMX, dotMY, padX, padY, lives) 


        pygame.display.update() 

def colis(dotX, dotY, dotMX, dotMY, padX, padY, lives):


    if dotY >= 720 - 30:
        lives -= 1

    #hor colis
    if dotX <= 0 + 20:
        if dotMX == 1:
            dotMX = -1
        else:
            dotMX = 1
    elif dotX >= 1280 - 20:
        if dotMX == 1:
            dotMX = -1
        else:
            dotMX = 1
    #vert colis
    if dotY <= 0 - 20:
        if dotMY == 1:
            dotMY = -1
        else:
            dotMY = 1
    elif dotY >= 720 - 20:
        if dotMY == 1:
            dotMY = -1
        else:
            dotMY = 1
    #pad colis 
    if dotX >= padX and dotX <= padX + 150 and dotY == 665:
        if dotMY == 1:
            dotMY = -1
        else:
            dotMY = 1
    pygame.draw.circle(DISPLAYSURF, pygame.Color(255,0,0), (dotX, dotY), 20)


main(padX, padY, dotX, dotY, dotMX, dotMY, lives)  

任何人都可以看到为什么它在分离成函数时不起作用?对不起,如果它是一个愚蠢的简单修复,我仍然缺乏python经验。 谢谢!

为了澄清,通过功能,球飞向左上方并消失!

3 个答案:

答案 0 :(得分:0)

我可以看到第二块cede的几个问题。第一个与格式有关。你有线,比如

self.tableWidget.setItem(...

这将不允许您编译代码,因为它受到不正确缩进的影响。 第二个问题是,你将一些变量传递给函数,在函数内修改它们,但你没有返回它们。

函数参数是名称。当您调用函数时,Python会将这些参数绑定到您传递的任何对象(通过调用方范围中的名称)。 对象可以是可变的(如列表)或不可变的(如Python中的整数,字符串)。

作为dotX,dotY,dotMX,todMY,padX,padY,生命是整数,你不能修改它们有副作用,它们需要从函数返回。 我建议创建一个类或使用一些数据结构来传递和返回所有必要的参数。

要快速检查,您可以通过在其末尾添加返回状态网络来修改if dotY >= 720 - 30 lives -= 1 功能,例如

colis

并将调用更改为return (dotX, dotY, dotMX, dotMY, padX, padY, lives) 函数中的函数,如下所示

main

在你明白了之后,你可以开始进一步的重构,因为我的更新不是那么优雅和干净。

答案 1 :(得分:0)

您正在将函数传递给函数(colis),在函数内部重新定义它们,但这些更改不会反映在函数之外(这就是Python的工作原理)。

最简单的更改只是返回colis中更改的三个变量,并将这些更改传播到main

def colis(dotX, dotY, dotMX, dotMY, padX, padY, lives):
    ...
    pygame.draw.circle(DISPLAYSURF, pygame.Color(255,0,0), (dotX, dotY), 20)

    return dotMX, dotMY, lives # This line

def main(padX, padY, dotX, dotY, dotMX, dotMY, lives):
    ...
        dotX += dotMX
        dotY += dotMY

        dotMX, dotMY, lives = colis(dotX, dotY, dotMX, dotMY, padX, padY, lives)  # This line

        pygame.display.update()

“更好”的方法(可能在未来)可能是为那些可以传递给{{1}的参数(例如DotPad)定义和实例化类对象。功能。

(完整代码)

colis

答案 2 :(得分:0)

好的,这是对您的代码的简单修复,您没有正确使用全局变量:

import pygame
import sys
from pygame.locals import *

DISPLAYSURF = pygame.display.set_mode((1280, 720))


padX = 310
padY = 680
dotX = 150
dotY = 150
dotMX = -1
dotMY = -1
lives = 5


def main():
    global padX, padY, dotX, dotY, dotMX, dotMY, lives

    pygame.init()

    pygame.display.set_caption('Breakout')
    while lives != 0:
        DISPLAYSURF.fill(pygame.Color(0, 0, 0))
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEMOTION:
                padX = event.pos[0] - 75

            if padX < 3:
                padX = 3

            elif padX > 1127:
                padX = 1127

        pygame.draw.rect(DISPLAYSURF, pygame.Color(
            0, 0, 255), (padX, padY, 150, 30))

        dotX += dotMX
        dotY += dotMY

        colis()

        pygame.display.update()


def colis():
    global padX, padY, dotX, dotY, dotMX, dotMY, lives

    if dotY >= 720 - 30:
        lives -= 1

    # hor colis
    if dotX <= 0 + 20:
        if dotMX == 1:
            dotMX = -1
        else:
            dotMX = 1
    elif dotX >= 1280 - 20:
        if dotMX == 1:
            dotMX = -1
        else:
            dotMX = 1
    # vert colis
    if dotY <= 0 - 20:
        if dotMY == 1:
            dotMY = -1
        else:
            dotMY = 1
    elif dotY >= 720 - 20:
        if dotMY == 1:
            dotMY = -1
        else:
            dotMY = 1
    # pad colis
    if dotX >= padX and dotX <= padX + 150 and dotY == 665:
        if dotMY == 1:
            dotMY = -1
        else:
            dotMY = 1
    pygame.draw.circle(DISPLAYSURF, pygame.Color(255, 0, 0), (dotX, dotY), 20)


if __name__ == "__main__":
    main()

这是你的代码有点重构,使用PEP8和更多OOP方法(有点):

import pygame
import sys
from pygame.locals import *


class Game():

    def __init__(self):
        self.pad_x = 310
        self.pad_y = 680
        self.dot_x = 150
        self.dot_y = 150
        self.dot_mx = -1
        self.dot_my = -1
        self.lives = 5

    def run(self):
        self.display = pygame.display.set_mode((1280, 720))
        pygame.init()
        pygame.display.set_caption('Breakout')

        while self.lives != 0:
            self.display.fill(pygame.Color(0, 0, 0))

            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                elif event.type == pygame.MOUSEMOTION:
                    self.pad_x = event.pos[0] - 75

                if self.pad_x < 3:
                    self.pad_x = 3

                elif self.pad_x > 1127:
                    self.pad_x = 1127

            pygame.draw.rect(self.display, pygame.Color(
                0, 0, 255), (self.pad_x, self.pad_y, 150, 30))

            self.dot_x += self.dot_mx
            self.dot_y += self.dot_my

            self.colis()

            pygame.display.update()

    def colis(self):
        if self.dot_y >= 720 - 30:
            self.lives -= 1

        # hor colis
        if self.dot_x <= 0 + 20:
            if self.dot_mx == 1:
                self.dot_mx = -1
            else:
                self.dot_mx = 1
        elif self.dot_x >= 1280 - 20:
            if self.dot_mx == 1:
                self.dot_mx = -1
            else:
                self.dot_mx = 1

        # vert colis
        if self.dot_y <= 0 - 20:
            if self.dot_my == 1:
                self.dot_my = -1
            else:
                self.dot_my = 1
        elif self.dot_y >= 720 - 20:
            if self.dot_my == 1:
                self.dot_my = -1
            else:
                self.dot_my = 1

        # pad colis
        if self.dot_x >= self.pad_x and self.dot_x <= self.pad_x + 150 and self.dot_y == 665:
            if self.dot_my == 1:
                self.dot_my = -1
            else:
                self.dot_my = 1

        pygame.draw.circle(self.display, pygame.Color(
            255, 0, 0), (self.dot_x, self.dot_y), 20)


if __name__ == "__main__":
    Game().run()