2011-11-19 59 views
3
import pygame 
import random 

red = [255,0,0] 
green = [0,255,0] 
blue = [0,0,255] 
white = [255,255,255] 
black = [0,0,0] 
UP = [0,-1] 
DOWN = [0,1] 
LEFT = [-1,0] 
RIGHT = [1,0] 
NOTMOVING = [0,0] 
#constants end 
#classes 
class collidable: 
    x = 0 
    y = 0 
    w = 0 
    h = 0 
    rect = pygame.Rect(x,y,w,h) 
    color = [0,0,0] 
    def __init__(self,x,y,w,h,color): 
     self.x = x 
     self.y = y 
     self.w = w 
     self.h = h 
     self.color = color 
     self.rect = pygame.Rect(x,y,w,h) 
    def draw(self): 
     pygame.draw.rect(screen,self.color,[self.x,self.y,self.w,self.h],6) 

class player: 
    x = 0 
    y = 0 
    speed = 0 
    rect = pygame.Rect(x,y,x+20,y+20) 
    def __init__(self,x,y,speed): 
     self.x = x 
     self.y = y 
     self.speed = speed 
     self.rect = pygame.Rect(self.x,self.y,self.x+20,self.y+20) 
    def draw(self): 
     if player_moving==LEFT: 
     pygame.draw.polygon(screen,black,[(self.x-10,self.y),(self.x+10,self.y-10),(self.x+10,self.y+10)]) 
     elif player_moving==RIGHT: 
      pygame.draw.polygon(screen,black,[(self.x+10,self.y),(self.x-10,self.y-10),(self.x-10,self.y+10)]) 
     elif player_moving==UP: 
      pygame.draw.polygon(screen,black,[(self.x,self.y-10),(self.x+10,self.y+10),(self.x-10,self.y+10)]) 
     elif player_moving==DOWN: 
      pygame.draw.polygon(screen,black,[(self.x,self.y+10),(self.x+10,self.y-10),(self.x-10,self.y-10)]) 
     else: 
      pygame.draw.rect(screen,black,pygame.Rect(self.x-10,self.y-10,20,20),6) 
    def setpos(self,x,y): 
     self.x = x 
     self.y = y 
    def move(self,direction): 
     self.x = self.x + direction[0]*self.speed 
     self.y = self.y + direction[1]*self.speed 
#classes end 

#globals 
pygame.init() 
screenSize = [800,600] 
screenBGColor = white 
screen=pygame.display.set_mode(screenSize) 
pygame.display.set_caption("Move the Block") 
player = player(screenSize[0]/2,screenSize[1]/2,9) 
collidables = [] 
clock=pygame.time.Clock() 
for i in range(10): 
    collidables.append(collidable(random.randrange(0,screenSize[0]),random.randrange(0,screenSize[1]),random.randrange(10,200),random.randrange(10,200),blue)) 

running = True 
#globals end 

#functions 
def render(): 
    screen.fill(screenBGColor) 
    clock.tick(60) 
    player.draw() 
    for c in collidables: 
     c.draw() 
    pygame.display.flip() 
def tick():           #----------------HERE 
    for c in collidables: 
     if player.rect.colliderect(c.rect): 
      player_moving = NOTMOVING 
      print("hit") 
    player.move(player_moving) 

#functions end 

#main loop 
while running==True: 
    for event in pygame.event.get(): 
     if event.type==pygame.QUIT: 
      running = False 
     if event.type==pygame.KEYDOWN: 
      if event.key==pygame.K_LEFT: 
       player_moving = LEFT 
      if event.key==pygame.K_RIGHT: 
       player_moving = RIGHT 
      if event.key==pygame.K_UP: 
       player_moving = UP 
      if event.key==pygame.K_DOWN: 
       player_moving = DOWN 
     else: 
      player_moving = NOTMOVING 
    tick() 
    render() 
#main loop end 

pygame.quit() 

我試圖做一個簡單的碰撞檢測來禁用玩家移動時觸摸可碰撞對象。但是,在可能發生碰撞的地方,碰撞總是被觸發。我不知道爲什麼玩家不移動,如果玩家的中心距離可戰鬥的邊界10個像素,這個代碼只能阻止移動。我相信這種方法是錯誤的,但我想不出任何其他的螯合碰撞方式。(python + pygame)與rects碰撞檢測

+0

您是否在閱讀本書:http://inventwithpython.com/? –

+1

真的,你希望我們爲你調試程序嗎? :o – mac

+0

對不起,我不是那個意思。我相信代碼是錯誤的,我需要更好的方法來檢測碰撞。我的帖子缺乏,因爲我的互聯網如此緩慢,當我不小心打進輸入發送,它並沒有取消。 – Kroltan

回答

1

好吧,所以,基本上,你是真的。你的計劃是好的,但是:

    在pygame的文檔
  • : 矩形=(POSX,波西,寬度,高度)

所以,你的代碼(差異):

- self.rect = pygame.Rect(self.x,self.y,self.x+20,self.y+20) 
+ self.rect = pygame.Rect(self.x,self.y,self.20,self.20) 

而且還有:

def move(self,direction): 
     self.x = self.x + direction[0]*self.speed 
     self.y = self.y + direction[1]*self.speed 
+  self.rect = pygame.Rect(self.x,self.y,self.20,self.20) 

你的代碼還有一個小問題。例如,在tick()函數中,使用player_moving,但在第一次迭代中,該變量不存在。

的代碼(運行):

import pygame 
import random 

red = [255,0,0] 
green = [0,255,0] 
blue = [0,0,255] 
white = [255,255,255] 
black = [0,0,0] 
UP = [0,-1] 
DOWN = [0,1] 
LEFT = [-1,0] 
RIGHT = [1,0] 
NOTMOVING = [0,0] 
#constants end 
#classes 
class collidable: 
    x = 0 
    y = 0 
    w = 0 
    h = 0 
    rect = pygame.Rect(x,y,w,h) 
    color = [0,0,0] 
    def __init__(self,x,y,w,h,color): 
     self.x = x 
     self.y = y 
     self.w = w 
     self.h = h 
     self.color = color 
     self.rect = pygame.Rect(x,y,w,h) 
    def draw(self): 
     pygame.draw.rect(screen,self.color,[self.x,self.y,self.w,self.h],6) 

class player: 
    x = 0 
    y = 0 
    speed = 0 
    rect = pygame.Rect(x,y,20,20) 
    def __init__(self,x,y,speed): 
     self.x = x 
     self.y = y 
     self.speed = speed 
     self.rect = pygame.Rect(self.x,self.y,20,20) 
    def draw(self): 
     if player_moving==LEFT: 
       pygame.draw.polygon(screen,black,[(self.x-10,self.y),(self.x+10,self.y-10),(self.x+10,self.y+10)]) 
     elif player_moving==RIGHT: 
      pygame.draw.polygon(screen,black,[(self.x+10,self.y),(self.x-10,self.y-10),(self.x-10,self.y+10)]) 
     elif player_moving==UP: 
      pygame.draw.polygon(screen,black,[(self.x,self.y-10),(self.x+10,self.y+10),(self.x-10,self.y+10)]) 
     elif player_moving==DOWN: 
      pygame.draw.polygon(screen,black,[(self.x,self.y+10),(self.x+10,self.y-10),(self.x-10,self.y-10)]) 
     else: 
      pygame.draw.rect(screen,black,pygame.Rect(self.x-10,self.y-10,20,20),6) 
    def setpos(self,x,y): 
     self.x = x 
     self.y = y 
    def move(self,direction): 
     self.x = self.x + direction[0]*self.speed 
     self.y = self.y + direction[1]*self.speed 
     self.rect = pygame.Rect(self.x,self.y,20,20) 
#classes end 

#globals 
pygame.init() 
screenSize = [800,600] 
screenBGColor = white 
screen=pygame.display.set_mode(screenSize) 
pygame.display.set_caption("Move the Block") 
player = player(screenSize[0]/2,screenSize[1]/2,9) 
collidables = [] 
clock=pygame.time.Clock() 
for i in range(10): 
    collidables.append(collidable(random.randrange(0,screenSize[0]),random.randrange(0,screenSize[1]),random.randrange(10,200),random.randrange(10,200),blue)) 

running = True 
#globals end 
player_moving = NOTMOVING 
#functions 
def render(): 
    screen.fill(screenBGColor) 
    clock.tick(60) 
    player.draw() 
    for c in collidables: 
     c.draw() 
    pygame.display.flip() 
def tick(player_moving):           #----------------HERE 
    for c in collidables: 
     if player.rect.colliderect(c.rect): 
      player_moving = NOTMOVING 
      print("hit"+str(c.rect)+" with "+str(player.rect)) 
    player.move(player_moving) 

#functions end 

#main loop 
while running==True: 
    for event in pygame.event.get(): 
     if event.type==pygame.QUIT: 
      running = False 
     if event.type==pygame.KEYDOWN: 
      if event.key==pygame.K_LEFT: 
       player_moving = LEFT 
      if event.key==pygame.K_RIGHT: 
       player_moving = RIGHT 
      if event.key==pygame.K_UP: 
       player_moving = UP 
      if event.key==pygame.K_DOWN: 
       player_moving = DOWN 
     else: 
      player_moving = NOTMOVING 
    tick(player_moving) 
    render() 
#main loop end 

pygame.quit() 
2

你鑽研所謂的AABB(軸對齊包圍盒)。你在你的角色周圍設置一個可以檢測周圍物體的盒子。

這裏有一些資源,可以幫助你找出到底是怎麼回事,以及技巧,以幫助您更好地實現它們:

http://www.gamasutra.com/view/feature/3426/when_two_hearts_collide_.php

http://www.gamefromscratch.com/post/2012/11/26/GameDev-math-recipes-Collision-detection-using-an-axis-aligned-bounding-box.aspx

Other Various platforming implementations

閱讀在這些!我在碰撞檢測方面掙扎了一段時間,這些確實有幫助。

+0

+1的真棒資源!=] – Adriano