2017-10-21 189 views
1

我正在尝试在pygame中创建一个赛车游戏。我想要这样,当汽车离开赛道时,速度会减慢。我试图通过让另一个精灵是轨道轮廓,当汽车接触到这个精灵,它会减速。这不起作用,我不知道为什么。有一个更好的方法吗?pygame中的Sprite面具碰撞问题

Img是汽车图像

Back是赛道

BackHit是大纲

我收到此错误代码:

Traceback (most recent call last): File "C:\Users\Daniella\Desktop\Python\Games\game.py", line 75, in if pygame.sprite.collide_mask(Img, BackHit): File "C:\Users\Daniella\AppData\Roaming\Python\Python36\site-packages\pygame\sprite.py", line 1470, in collide_mask xoffset = right.rect[0] - left.rect[0] AttributeError: 'pygame.Surface' object has no attribute 'rect'

这是代码:

import pygame 

Width = 800 
Height = 600 

Black = (0, 0, 0) 
White = (255, 255, 255) 
Red = (255, 0, 0) 
Green = (0, 255, 0) 
Blue = (0, 0, 255) 
Yellow = (255, 255, 0) 
BackColour = (198, 151, 107) 

pygame.init() 
GameDisplay = pygame.display.set_mode((Width, Height)) 
pygame.display.set_caption("A bit Racey") 
Clock = pygame.time.Clock() 

Img = pygame.image.load("download.png") 
ImgWidth = 46 
ImgHeight = 68 
Img = pygame.transform.scale(Img, (ImgWidth, ImgHeight)) 

Back = pygame.image.load("back1.png") 
BackWidth = Width*4 
BackHeight = Height*4 
Back = pygame.transform.scale(Back, (BackWidth, BackHeight)) 

BackHit = pygame.image.load("back1 hit1.png") 
BackHitWidth = Width*4 
BackHitHeight = Height*4 
BackHit = pygame.transform.scale(BackHit, (BackHitWidth, BackHitHeight)) 

def Car(): 
    GameDisplay.blit(Img, (400-ImgWidth/2, 300-ImgHeight/2)) 

def Background(X, Y): 
    GameDisplay.blit(Back, (X, Y)) 

def BackgroundHit(X, Y): 
    GameDisplay.blit(BackHit, (X, Y)) 

X = (Width*0.45) 
Y = (Height*0.5) 

XChange = 0 
YChange = 0 

Changer = 1 

Crashed = False 

while not Crashed: 
    for Event in pygame.event.get(): 
     if Event.type == pygame.QUIT: 
      Crashed = True 
     elif Event.type == pygame.KEYDOWN: 
      if Event.key == pygame.K_LEFT: 
       Img = pygame.transform.rotate(Img, -90) 
       XChange = 5/Changer 
      elif Event.key == pygame.K_RIGHT: 
       Img = pygame.transform.rotate(Img, 90) 
       XChange = -5/Changer 
      elif Event.key == pygame.K_UP: 
       Img = pygame.transform.rotate(Img, 0) 
       YChange = 5/Changer 
      elif Event.key == pygame.K_DOWN: 
       Img = pygame.transform.rotate(Img, 180) 
       YChange = -5/Changer 
     if Event.type == pygame.KEYUP: 
      if Event.key == pygame.K_LEFT or Event.key == pygame.K_RIGHT: 
       XChange = 0 
      elif Event.key == pygame.K_UP or Event.key == pygame.K_DOWN: 
       YChange = 0 
    if pygame.sprite.collide_mask(Img, BackHit): 
     Changer = 2 
    Y += YChange 
    X += XChange 
    GameDisplay.fill(White) 
    BackgroundHit(X, Y) 
    Background(X, Y) 
    Car() 
    pygame.display.update() 
    Clock.tick(200) 

pygame.quit() 
quit() 
+0

'pygame.sprite.collide_mask'与'pygame.Sprite's不是'pygame.Surface's一起使用。你知道如何使用'pygame.Sprite'类吗?如果没有,请查看此[教程](http://programarcadegames.com/index.php?chapter=introduction_to_sprites&lang=en#section_13)。或者,您可以创建[来自曲面的遮罩](http://renesd.blogspot.com/2017/03/pixel-perfect-collision-detection-in.html)。 – skrx

+0

我的意思是'pygame.sprite.Sprite'而不是'pygame.Sprite'。 – skrx

回答

0

下面是一个小例子,向您展示如何使用pygame.mask.from_surfacepygame.Mask.overlap进行像素完美碰撞检测。

import pygame as pg 

# Transparent surfaces with a circle and a triangle. 
circle_surface = pg.Surface((60, 60), pg.SRCALPHA) 
pg.draw.circle(circle_surface, (30, 90, 200), (30, 30), 30) 
triangle_surface = pg.Surface((60, 60), pg.SRCALPHA) 
pg.draw.polygon(triangle_surface, (160, 250, 0), ((30, 0), (60, 60), (0, 60))) 


def main(): 
    screen = pg.display.set_mode((640, 480)) 
    clock = pg.time.Clock() 

    # Use `pygame.mask.from_surface` to get the masks. 
    circle_mask = pg.mask.from_surface(circle_surface) 
    triangle_mask = pg.mask.from_surface(triangle_surface) 

    # Also create rects for the two images/surfaces. 
    circle_rect = circle_surface.get_rect(center=(320, 240)) 
    triangle_rect = triangle_surface.get_rect(center=(0, 0)) 

    done = False 

    while not done: 
     for event in pg.event.get(): 
      if event.type == pg.QUIT: 
       done = True 
      elif event.type == pg.MOUSEMOTION: 
       triangle_rect.center = event.pos 

     # Now calculate the offset between the rects. 
     offset_x = triangle_rect.x - circle_rect.x 
     offset_y = triangle_rect.y - circle_rect.y 

     # And pass the offset to the `overlap` method of the mask. 
     overlap = circle_mask.overlap(triangle_mask, (offset_x, offset_y)) 
     if overlap: 
      print('The two masks overlap!', overlap) 

     screen.fill((30, 30, 30)) 
     screen.blit(circle_surface, circle_rect) 
     screen.blit(triangle_surface, triangle_rect) 

     pg.display.flip() 
     clock.tick(30) 


if __name__ == '__main__': 
    pg.init() 
    main() 
    pg.quit() 

要为背景创建遮罩或跟踪你需要创建一个额外的图像,要么离开轨道透明或区里的车应该减速,然后检查车的碰撞跟踪或与外部区域。在这里,我检查一下绿色三角形是否与“轨道”(蓝线)相碰撞,然后在您的游戏中,如果它不与轨道相撞,则会减慢车速。

import pygame as pg 


bg_surface = pg.Surface((640, 480), pg.SRCALPHA) 
pg.draw.lines(
    bg_surface, (30, 90, 200), True, 
    ((60, 130), (300, 50), (600, 200), (400, 400), (150, 300)), 
    12) 
triangle_surface = pg.Surface((60, 60), pg.SRCALPHA) 
pg.draw.polygon(triangle_surface, (160, 250, 0), ((30, 0), (60, 60), (0, 60))) 


def main(): 
    screen = pg.display.set_mode((640, 480)) 
    clock = pg.time.Clock() 

    bg_mask = pg.mask.from_surface(bg_surface) 
    triangle_mask = pg.mask.from_surface(triangle_surface) 

    bg_rect = bg_surface.get_rect(center=(320, 240)) 
    triangle_rect = triangle_surface.get_rect(center=(0, 0)) 

    done = False 

    while not done: 
     for event in pg.event.get(): 
      if event.type == pg.QUIT: 
       done = True 
      elif event.type == pg.MOUSEMOTION: 
       triangle_rect.center = event.pos 

     offset_x = triangle_rect.x - bg_rect.x 
     offset_y = triangle_rect.y - bg_rect.y 

     overlap = bg_mask.overlap(triangle_mask, (offset_x, offset_y)) 
     if overlap: 
      print('The two masks overlap!', overlap) 

     screen.fill((30, 30, 30)) 
     screen.blit(bg_surface, bg_rect) 
     screen.blit(triangle_surface, triangle_rect) 

     pg.display.flip() 
     clock.tick(30) 


if __name__ == '__main__': 
    pg.init() 
    main() 
    pg.quit() 
+0

这个实例的问题在于我的背景精灵,汽车应该放慢速度,这不是一个简单的形状,它围绕着赛道,所以我不能使用x和y坐标。感谢您的帮助:) –

+0

我已经添加了一些蓝色线条代表曲目的例子。 – skrx