2017-10-21 164 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