Why am I getting this error: “Invalid rectstyle ar

2019-02-26 15:21发布

问题:

I am currently making a game in python where a ball hits a group of boxes. I have loaded an image of a grass that I wanted the boxes to stand on, the grass image is 600 by 151 pixels. So far I have all the boxes and the ball appearing perfectly however, What is not working currently is when I try to load the image and display it so that the boxes can stand on the grass image instead of falling off.

import pygame
from pygame.locals import *
from pygame.color import *
import pymunk as pm
from pymunk import Vec2d
import sys
from random import randint

def to_pygame(p):
    """Small hack to convert pymunk to pygame coordinates"""
    return int(p[0]), int(-p[1]+600)


def add_box(space, size, pos, mass=1.0):
    # pos is a Vec2d object
    points = [(-size, -size), (-size, size), (size,size), (size, -size)]
    moment = pm.moment_for_poly(int(mass), points, (0,0))

    body = pm.Body(mass, moment)
    body.position = pos

    shape = pm.Poly(body, points, (0,0))
    shape.friction = 1
    space.add(body,shape)

    return shape

def draw_box(screen, box):
    ps = box.get_points()
    ps.append(ps[0])
    ps = map(to_pygame, ps)
    pygame.draw.polygon(screen, THECOLORS["blue"], ps, 3)


def main():
    pygame.init()
    screen = pygame.display.set_mode((600, 600))
    pygame.display.set_caption("Piling boxes")
    clock = pygame.time.Clock()

    boxes = []
    x = 170
    y = 120
    space = pm.Space()
    space.gravity = (0.0, -100.0)

    ### ground
    body = pm.Body()
    shape = pm.Segment(body, (150,100), (450,100), .0)
    shape.friction = 4.4
    space.add(shape)

    for i in range(5):
        # what is the mass of the box?
        mass = randint(1,3)
        # what size is the box?
        size = randint(10, 35)
        # calculate its position & hold it in a Vec2d

        #x = x + size + 10
        y = y + size
        pos = Vec2d(x,y)

        box = add_box(space, size, pos, mass)
        boxes.append(box)

    while 1:
        clock.tick(15)
        space.step(1/30.0)

        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit(0)
            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit(0)

        screen.fill(THECOLORS["white"])
        test_image = pygame.image.load("grass.png")

        screen.blit(test_image, to_pygame((450,100)), to_pygame((150,100)),3)


        for i in range(len(boxes)):
            draw_box(screen, boxes[i])

        pygame.display.flip()


if __name__ == '__main__':
    main()

回答1:

No traceback or error log so it is a bit hard to identify the point of the error, an educated guess would be that you are passing Rectstyle arguments incorrectly somewhere. Please see the documentation for pygame.Rect on how to pass Rectstyle args correctly.

pygame.Rect(left, top, width, height): return Rect
pygame.Rect((left, top), (width, height)): return Rect
pygame.Rect(object): return Rect


回答2:

The problem is

screen.blit(test_image, to_pygame((450,100)), to_pygame((150,100)),3)

To blit a surface to to screen, a valid blit is:

screen.blit(test_image, (450,100))

So you want:

screen.blit(test_image, to_pygame((450,100)))

Note: The extra args make me think maybe you're trying to use a source rect argument, to use a tileset. But in that case you wouldn't convert world to screen coords twice. Just on destination, not source.

If you do want the spritesheet/tileset, then out How do you select a sprite image from a sprite sheet in python? and Pygame.org/cookbook/SpriteSheet



回答3:

The third argument in blit is the source area argument, should be a rectangle, not coordinates:

screen.blit(test_image, to_pygame((450,100)), to_pygame((150,100)),3)

Perhaps you want this:

screen.blit(test_image, to_pygame((450,100)), pygame.Rect((0,0), (150,100)), 3)


回答4:

The problem is because your call to screen.blit is incorrect. See here.

The call could be

screen.blit(test_image, to_pygame((450,100)))

or perhaps if you wanted to use the area argument,

screen.blit(test_image, to_pygame((450,100)), pygame.Rect((0,0), (150,100)), 3)

Also, you are loading guess.png in every loop, instead move it out of the while loop, your code will perform better.



标签: python pygame