为什么Python返回Rect样式对象错误

时间:2015-01-17 20:57:56

标签: python python-2.7 python-3.x pygame ipython

import time,random
import pygame
global swidth,sheight,screen,background

pygame.init()
inf=pygame.display.Info()
swidth=int(inf.current_w)
sheight=int(inf.current_h)

screen=pygame.display.set_mode((swidth,sheight),pygame.FULLSCREEN)
background=pygame.color.Color(0,0,0,255)
screen.fill(background)

def puttext(surf,pos,text,font,size,color,flag):
    fontrend=pygame.font.Font(font,size)
    textrend=fontrend.render(text,1,color)
    if flag=="center":
        textpos=textrend.get_rect()
        textpos.center=surf.get_rect().center
    elif flag == "left":
        textpos=(surf.get_rect().left+2,surf.get_rect().top)
    elif flag=="right":
        textpos=(surf.get_rect().right-textrend.get_rect().width-2,surf.get_rect().top)
    else:
        textpos=pos
    surf.blit(textrend,textpos)

class paddle():
    def __init__(self,posx,posy,velx,vely,width,height,color):
        self.posx=posx
        self.posy=posy
        self.velx=velx
        self.vely=vely
        self.width=width
        self.height=height
        self.color=color
        self.ltime=time.time()
    def move(self):
        global swidth,sheight,screen,background
        ttime=self.ltime
        self.ltime=time.time()
        diff=self.ltime-ttime
        #Handle collisions
        newx=self.posx+self.velx*(diff)
        newy=self.posy+self.vely*(diff)
        #check for paddle collisions
        if newy<0:  #hit ceiling
            self.posy=0
        elif newy+self.height>sheight:
            self.posy=sheight-self.height
        else:
            self.posy=newy
            self.posx=newx
    def setvelx(self,vel):
        self.velx=vel
    def setvely(self,vel):
        self.vely=vel
    def getvelx(self):
        return self.velx
    def getvely(self):
        return self.vely
    def erase(self,surf):
        global swidth,sheight,screen,background
        pygame.draw.rect(surf,background,pygame.rect.Rect(self.posx,self.posy,self.width,self.height),0)
    def draw(self,surf):
        pygame.draw.rect(surf,self.color,pygame.rect.Rect(self.posx,self.posy,self.width,self.height),0)

class arrow():
    def __init__(self,posx,posy,velx,vely,color,height,width,thisgame):
        self.posx=posx
        self.posy=posy
        self.velx=velx
        self.vely=vely
        self.color=color
        self.height=height
        self.width=width
        self.ltime=time.time()
        self.text="It's Clobberin' Time!"
        self.game=thisgame # game object for this arrow
    def move(self):
        ttime=self.ltime
        self.ltime=time.time()
        diff=self.ltime-ttime
        #Handle collisions
        newx=self.posx+self.velx*(diff)
        newy=self.posy+self.vely*(diff)
        #check for collisions
        #handle collisions
        #if newy>=sheight: #past the edge
            #newy=2*(sheight)-newy
            #self.vely=self.vely*(-1)
        #elif newy<0:
            #newy=-1*newy
            #self.vely=self.vely*(-1)
        if newx+self.width>=self.game.player2.paddle.posx: #possibly hit right paddle
            padx=self.game.player2.paddle.posx
            padtop=self.game.player2.paddle.posy
            padbot=self.game.player2.paddle.posy+self.game.player2.paddle.height
            padvelx=self.game.player2.paddle.velx
            padvely=self.game.player2.paddle.vely
            dt=(padx-self.posx-self.height)/(self.velx+.00001)
            padtop=padtop+padvely*dt
            padbot=padbot+padvely*dt
            newy=self.posy+self.vely*dt
            if newy>=padtop and newy<=padbot:
                #newx=2*(padx)-newx
                #self.velx=self.velx*10
                #self.vely=self.vely+self.game.player2.paddle.vely/2
                self.game.player1.score=self.game.player1.score+1
        if newx+self.width<=self.game.player1.paddle.posx+self.game.player1.paddle.width: #possibly hit left paddle
            padx=self.game.player1.paddle.posx+self.game.player1.paddle.width
            padtop=self.game.player1.paddle.posy
            padbot=self.game.player1.paddle.posy+self.game.player1.paddle.height
            padvelx=self.game.player1.paddle.velx
            padvely=self.game.player1.paddle.vely
            dt=(-padx+self.posx)/(self.velx+.00001)
            padtop=padtop+padvely*dt
            padbot=padbot+padvely*dt
            newarrowy=self.posy+self.vely*dt
            if newy>=padtop and newy<=padbot:
                #newx=2*(padx)-newx
                self.velx=self.velx*10
                self.vely=self.vely+self.game.player1.paddle.vely/2
                self.game.player2.score=self.game.player2.score+1
        if newx>=swidth: #past the edge
            self.velx=self.velx*10
        elif newx<=0:
            self.velx=self.velx*10
            self.posx=newx
            self.posy=newy
    def setvelx(self,vel):
        self.velx=vel
    def setvely(self,vel):
        self.vely=vel
    def getvelx(self):
        return self.velx
    def getvely(self):
        return self.vely
    def erase(self,surf):
        global swidth,sheight,background
        #pygame.draw.rect(surf,background,pygame.Rect(self.posx-9,self.posy-39,200,50),0)
        pygame.draw.rect(surf,background,pygame.Rect(self.posx,self.posy,self.width,self.height),0)
    def draw(self,surf):
        pygame.draw.rect(surf,self.color,pygame.Rect(self.posx,self.posy,self.width,self.height),0)
        #puttext(screen,(self.posx-9,self.posy-39),self.text,None,30,(255,255,255,255),None)

class player():
    def __init__(self,name,number):
        global swidth,sheight,screen,background
        self.name=name
        self.number=number
        self.score=0
        if number==1:
            self.paddle=paddle(5,random.randint(0,sheight-50),0,0,5,50,(255,0,0,255))
        if number==2:
            self.paddle=paddle(swidth-10,random.randint(0,sheight-50),0,0,5,50,(0,255,0,255))
    def get_score(self):
        return self.score

class scoreboard():
    def __init__(self,width,height,color,game):
        self.width=width
        self.height=height
        self.color=color
        self.game=game
        self.board=pygame.surface.Surface((self.width,self.height))
        self.board=self.board.convert_alpha()
        self.fps=0
    def ptext(self,x,y,text,surf,color):
        puttext(surf,(x,y),text,None,20,color,"None")
    def draw(self):
        self.board.fill(self.color)
        self.ptext(5,5,"Player 1:   "+str(self.game.player1.get_score()),self.board,(220,220,100,150))
        self.ptext(5,20,"Player 2:   "+str(self.game.player2.get_score()),self.board,(220,220,100,150))
        self.ptext(5,35,"FPS:   "+str(self.fps),self.board,(220,220,100,150))
        screen.blit(self.board,(int(swidth/2)-int(self.width/2),0))
    def erase(self):
        pygame.draw.rect(screen,(0,0,0,0),pygame.rect.Rect(int(swidth/2)-int(self.width/2),0,self.width,self.height),0)

class game():
    def __init__(self):
        self.arrows=[]
        self.player1=player("bob",1)
        self.player2=player("fred",2)
        self.score=scoreboard(150,60,(0,0,255,50),self)
        self.gameloop()
    def gameloop(self):
        global swidth,sheight,screen,background
        t1=time.time()
        cnt=0
        ttot=0
        paddlespeed=300
        puttext(screen,(0,0),"IT'S CLOBBERIN' TIME!",None,50,(255,255,255,255),"center")
        pygame.display.flip()
        screen.fill(background)
        time.sleep(2)
        while True:
            pygame.event.pump()
            keysup=pygame.event.get(pygame.KEYUP)
            keysdown=pygame.event.get(pygame.KEYDOWN)
            pygame.event.get()
            if len(keysup)>0:
                for a in keysup:
                    if a.key == pygame.K_ESCAPE:
                        exit()
                    if a.key==pygame.K_UP:
                        self.player2.paddle.vely=self.player2.paddle.vely+paddlespeed
                    if a.key==pygame.K_DOWN:
                        self.player2.paddle.vely=self.player2.paddle.vely-paddlespeed
                    if a.key==pygame.K_a:
                        self.player1.paddle.vely=self.player1.paddle.vely+paddlespeed
                    if a.key==pygame.K_z:
                        self.player1.paddle.vely=self.player1.paddle.vely-paddlespeed
                    if a.key==pygame.K_RIGHT:
                        self.player2.paddle.velx=self.player2.paddle.velx-paddlespeed
                    if a.key==pygame.K_LEFT:
                        self.player2.paddle.velx=self.player2.paddle.velx+paddlespeed
                    #if a.key==pygame.K_q:
                        #self.arrows.append(arrow(self.player1.paddle.width,self.player1.paddle.posy+.5*self.player1.paddle.height,150,0,pygame.color.Color(255,255,28,255),0,75,self))
                    #if a.key==pygame.K_p:
                        #self.arrows.append(arrow(self.player2.paddle.posx,self.player2.paddle.posy+.5*self.player2.paddle.height,-150,0,pygame.color.Color(255,255,28,255),0,75,self))
            if len(keysdown)>0:
                for a in keysdown:
                    if a.key==pygame.K_UP:
                        self.player2.paddle.vely=self.player2.paddle.vely-paddlespeed
                    if a.key==pygame.K_DOWN:
                        self.player2.paddle.vely=self.player2.paddle.vely+paddlespeed
                    if a.key==pygame.K_a:
                        self.player1.paddle.vely=self.player1.paddle.vely-paddlespeed
                    if a.key==pygame.K_z:
                        self.player1.paddle.vely=self.player1.paddle.vely+paddlespeed
                    if a.key==pygame.K_RIGHT:
                        self.player2.paddle.velx=self.player2.paddle.velx+paddlespeed
                    if a.key==pygame.K_LEFT:
                        self.player2.paddle.velx=self.player2.paddle.velx-paddlespeed
                    if a.key==pygame.K_q:
                        self.arrows.append(arrow(self.player1.paddle.width+5,self.player1.paddle.posy+.5*self.player1.paddle.height,200,0,pygame.color.Color(255,255,28,255),0,75,self))
                    if a.key==pygame.K_p:
                        self.arrows.append(arrow(self.player2.paddle.posx-75,self.player2.paddle.posy+.5*self.player2.paddle.height,-200,0,pygame.color.Color(255,255,28,255),0,75,self))


#           time.sleep(.1)
            self.score.erase()
            self.player1.paddle.erase(screen)
            self.player2.paddle.erase(screen)
            for x in self.arrows:
                x.erase(screen)
                x.move()
            self.player1.paddle.move()
            self.player2.paddle.move()

            ttot=time.time()-t1+ttot            
            if ttot>1:
                self.score.fps=cnt
                cnt=0
                ttot=0
            t1=time.time()
            cnt=cnt+1

            for x in self.arrows:
                x.draw(screen)
            self.player1.paddle.draw(screen)
            self.player2.paddle.draw(screen)
            self.score.draw()
            pygame.display.flip()


    game()


Traceback (most recent call last):
    line 270, in <module>
        game()
    line 186, in __init__
        self.gameloop()
    line 263, in gameloop
        x.draw(screen)
    line 144, in draw
        pygame.draw.rect(surf,self.color,pygame.Rect(self.posx,self.posy,self.width,self.height),0)
TypeError: Argument must be rect style object

我不明白为什么Python会返回此错误。如果在语法的上下文中分析,则行144是正确的。这个论点似乎是格式正确的。代码结构中是否有任何错误,可能是第144行与其他行之间的交互?

1 个答案:

答案 0 :(得分:1)

pygame.draw.rect(surf,self.color,pygame.Rect(self.posx,self.posy,self.width,self.height),0)

这一定是;

pygame.draw.rect(surf,self.color,(self.posx,self.posy,self.width,self.height),0)

您正在尝试将rectstyle对象放入rect coords中。有效语法是;

a= where you want to draw your rect, it's a surface object,screen
b= RGB color of rect
c=coordinates in a tuple
pygame.draw.rect(a,b,c)

c=coordinates in a tuple实际上意味着,

(x,y,wx,hy)
x= x coordinate of your rectangle
y= y corrdinate of your rectangle
wx= the lenght of x coord of your rectangle. If `x` is bigger,your rectangle is bigger.
hx= the height of y coord of your rectangle. If `y` is bigger, your rectangle is bigger.