问题
I have collisions but I'd like my code to work so that when the bird touches the blocks, it print('x')
. It is doing that but not in the right place of the bird. Apologies for the long code but it is needed for it to run.
import random
import pygame
vec = pygame.math.Vector2
BLACK = (0,0,0)
RED = (255,0,0)
WIDTH = 500
HEIGHT = 400
pygame.init()
window = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Flappy Bird')
clock = pygame.time.Clock()
class Bird():
def __init__(self):
self.skin = pygame.image.load('bird2.png')
self.rect = self.skin.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
self.vx = 0
self.vy = 0
self.pos = vec(WIDTH / 2, HEIGHT / 2)
self.vel = vec(0, 0)
self.acc = vec(0, 0)
def update(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
window.fill(BLACK)
self.acc = vec(0, 0.7) #having 0.5 adds gravity
self.vy = 0
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
self.vel.y = -7
if keys[pygame.K_LEFT]:
self.acc.x = -0.5 #change to y to add vertical motion
if keys[pygame.K_RIGHT]:
self.acc.x = 0.5 #change to y to add vertical motion
#applys friction
self.acc.x += self.vel.x * -0.08 #FRICTION
#motion equations
self.vel += self.acc
self.pos += self.vel + 0.5 * self.acc
self.rect.center = self.pos
window.blit(self.skin, self.pos)
class Pipe():
def __init__(self,x,y):
self.image = pygame.Surface((50,60))
self.image.fill(RED)
self.rect = self.image.get_rect(topleft=(x,y))
self.pos = vec(x,y)
def blit_pipe(self):
window.blit(self.image, self.pos)
def border_check():
if (flappy.pos.y)+32 > HEIGHT: #this is the very top of the flappy
print("You are under\n")
pygame.quit()
quit()
if flappy.pos.y < 0:
print("You are over\n") #this is the very top of the flappy
pygame.quit()
quit()
pipey = Pipe(300,200)
pipey.blit_pipe()
pipey2 = Pipe(100,200)
pipey2.blit_pipe()
flappy = Bird()
window.blit(flappy.skin, flappy.pos)
while True:
border_check()
flappy.update()
pipey.blit_pipe()
pipey2.blit_pipe()
if flappy.rect.colliderect(pipey.rect):
print('x')
clock.tick(30)
pygame.display.update()
The bird looks like , and I would like the rect to be but in the game it works more like. I think the problem is that the rect has its center in the topleft but I don't know how to change it
回答1:
You need to blit the image at the top left coords of the rect. You can either set the center to self.pos
and pass the rect as the blit position (then pygame uses the top left coords),
self.rect.center = self.pos
window.blit(self.skin, self.rect)
or set the topleft
attribute to self.pos
, then you can still blit the image at the self.pos
:
self.rect.topleft = self.pos
window.blit(self.skin, self.pos)
回答2:
When drawing rectangles in pygame, the first 2 parameters are X and Y starting point, then the next 2 parameters are width and height. This will draw the rectangle form the top left corner. What you need to do, is have an image where the edge if the bird is the edge of the image. You can then do something like:
pygame.draw.rect(screen, red, [topLeftX, topLeftY, birdWidth, birdHeight])
An alternative, if you can't edit the picture, just use a +
sign for slight adjustment.
来源:https://stackoverflow.com/questions/47961345/why-is-the-pygame-rect-not-in-the-right-place