我正在创建一个游戏,玩家在网格上移动并躲避岩石,但是我检测碰撞的代码似乎无效。
import pygame
from pygame.locals import *
import random
pygame.init()
xSize = 500
ySize = 500
win = pygame.display.set_mode((xSize, ySize), RESIZABLE)
pygame.display.set_caption('Grid Game: Featuring Sad Blue Circle')
grid = pygame.image.load('gr.png').convert()
clock = pygame.time.Clock()
rockWait = 1000
rock_spawn_ev = pygame.USEREVENT
class player(object):
def __init__(self):
self.right = [pygame.image.load('right_%s.png' % frame) for frame in range(1, 9)]
self.x = 109
self.y = 109
self.frameCount = 0
self.rect = pygame.Rect(self.x, self.y, 32, 32) #rect for collision
def draw(self, win):
if self.frameCount + 1 >= 40:
self.frameCount = 0
win.blit(self.right[self.frameCount//5], (self.x, self.y))
self.frameCount +=1
self.rect = pygame.Rect(self.x, self.y, 32, 32) #update rect position
class rock(object):
def __init__(self, vel):
self.rock = pygame.image.load('rock.png')
self.vel = vel
self.ran = random.randint(0, 3)
self.ran2 = random.randint(1, 10) * 50 - 41
if self.ran > 1:
self.x = 550
self.y = 550
else:
self.x = -50
self.y = -50
rocks.append(self)
self.rect = pygame.Rect(self.x, self.y, 32, 32) #rect for collision
def draw(self, win):
if self.ran == 0: #top to bottom
self.y += self.vel
win.blit(self.rock, (self.ran2, self.y))
if self.ran == 2: #bottom to top
self.y -= self.vel
win.blit(self.rock, (self.ran2, self.y))
if self.ran == 1: #left to right
self.x += self.vel
win.blit(self.rock, (self.x, self.ran2))
if self.ran == 3: #right to left
self.x -= self.vel
win.blit(self.rock, (self.x, self.ran2))
self.rect = pygame.Rect(self.x, self.y, 32, 32) #update rect position
def rgw():
win.blit (grid, (0,0))
player.draw(win)
for rock in rocks:
rock.draw(win)
colliding = player.rect.colliderect(rock.rect)
if colliding:
print('collide') #nothing happens, even when touching rock
pygame.display.update()
pygame.time.set_timer(rock_spawn_ev, rockWait)
player = player()
rocks = []
run = True
while run:
clock.tick(60)
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
run = False
if event.type == rock_spawn_ev:
rock(6)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP and player.y > 9:
player.y -= 50
elif event.key == pygame.K_DOWN and player.y < ySize - 41:
player.y += 50
elif event.key == pygame.K_LEFT and player.x > 9:
player.x -= 50
elif event.key == pygame.K_RIGHT and player.x < xSize - 41:
player.x += 50
rgw()
pygame.quit()
我认为colliding = player.rect.colliderect(rock.rect)
应该在碰到一块岩石时返回True
,但是"collide"
永远不会被打印出来,在此for循环中:
for rock in rocks:
rock.draw(win)
colliding = player.rect.colliderect(rock.rect)
if colliding:
print('collide') #nothing happens, even when touching rock
我知道for循环本身可以工作,因为正在绘制岩石
class player(object):
def __init__(self):
self.x = 109
self.y = 109
self.rect = pygame.Rect(self.x, self.y, 32, 32) #rect for collision
def draw(self, win):
self.rect = pygame.Rect(self.x, self.y, 32, 32) #update rect position
class rock(object):
def __init__(self):
rocks.append(self)
self.rect = pygame.Rect(self.x, self.y, 32, 32) #rect for collision
def draw(self, win):
self.rect = pygame.Rect(self.x, self.y, 32, 32) #update rect position
player = player()
rocks = []
def rgw():
win.blit (grid, (0,0))
player.draw(win)
for rock in rocks:
rock.draw(win)
colliding = player.rect.colliderect(rock.rect)
if colliding:
print('collide') #nothing happens, even when touching rock
pygame.display.update()
答案 0 :(得分:2)
首先,在(self.x, self.y)
位置没有绘制岩石,但是在(self.ran2, self.y)
和(self.x, self.ran2)
位置绘制了岩石
我建议创建围绕来自相应pygame.Surface
对象的对象的矩形。使用get_rect()
生成具有图像大小的pygame.Rect
对象,并通过关键字参数(self.rect = self.rock.get_rect(topleft = (self.x, self.ran2))
)设置位置,或使用pygame.Surface.blit
返回的矩形。例如:
class player(object):
# [...]
def draw(self, win):
# [...]
self.rect = win.blit(self.right[self.frameCount//5], (self.x, self.y))
class rock(object):
# [...]
def draw(self, win):
# [...]
self.rect = win.blit(self.rock, (self.x, self.ran2))
由于在类rock
中在位置(self.ran2, self.y)
和(self.x, self.ran2)
上绘制了2个岩石,所以您必须设置2个不同的矩形对象:
class rock(object):
# [...]
def draw(self, win):
# [...]
self.rect_1 = win.blit(self.rock, (self.ran2, self.y))
# [...]
self.rect_2 = win.blit(self.rock, (self.x, self.ran2))
您必须进行2次碰撞测试:
def rgw():
win.blit (grid, (0,0))
player.draw(win)
for rock in rocks:
rock.draw(win)
colliding = player.rect.colliderect(rock_1.rect) or player.rect.colliderect(rock_2.rect)
if colliding:
print('collide') #nothing happens, even when touching rock
pygame.display.update()