如何为程序中的所有形状创建一个点击框以及检测碰撞的方法



我对python和模块pygame相当陌生。我最近还开始了一个小项目的工作,游戏的目的是,如果一个圆圈碰到了"玩家"(正方形(,那么游戏就会结束或出现一条消息,说你放松了(仍在努力解决点击框问题,所以仍在考虑之后该怎么办(。我遇到的问题是,我很难创建一种检测命中框碰撞的方法,每次我试图测试命中框是否碰撞时,它都不会起作用,所以如果有人能告诉我如何创建类和命中框,另一种方法,甚至如何修复我的代码,使其不会与播放器类碰撞。谢谢你的任何帮助,我可能会得到。

这是代码(如果我在试图找到解决方案时不断删除和添加内容,我会感到非常抱歉,如果我做了不恰当的事情,我也会感到抱歉,这是我的第一个问题(。

import pygame
import random
pygame.init()
width, height = 800, 800
hbox, vbox = 15, 15
rect = pygame.Rect(500, 600, hbox, vbox)
velocity = (0, 0)
frames = 40
ball_size = 12
white = (255, 255, 255)
black = (0, 0, 0)
hp = 100
screen = pygame.display.set_mode((width, height))

pygame.display.set_caption("Space Invaders")
icon = pygame.image.load('ufo.png')
pygame.display.set_icon(icon)
is_blue = True

clock = pygame.time.Clock()

class Ball:

def __init__(self):
self.x = 0
self.y = 0
self.change_x = 0
self.change_y = 0
self.hitbox = (self.x + 1, self.y + 2, 31, 57)

def make_ball():
ball = Ball()
Ball.hitbox = ball.hitbox
ball.x = random.randrange(ball_size, width - ball_size)
ball.y = random.randrange(ball_size, height - ball_size)
ball.change_x = random.randrange(-2, 3)
ball.change_y = random.randrange(-2, 3)
return ball

ball_list = []
ball = make_ball()
ball_list.append(ball)

class player(object):
def __init__(self, ):
self.x = rect.x
self.y = rect.y
self.box_width = hbox
self.box_hieght = vbox
self.speed = move
player.hitbox = (self.x + 1, self.y + 11, 29, 52)
def draw(self, is_blue):
if is_blue:
color = (0, 128, 255)
else:
color = (255, 100, 0)
if event.type == pygame.KEYDOWN and event.key == pygame.K_c:
is_blue = not is_blue
Player = player
Player = pygame.draw.rect(screen, color, rect)
def move(self):
surface = pygame.Surface((100, 100))
keys = pygame.key.get_pressed()
if keys[pygame.K_LSHIFT] or keys[pygame.K_RSHIFT]:
move = 8
else:
move = 4
if keys[pygame.K_w]:
rect.y -= move
if rect.y < 0:
rect.y = 0
if keys[pygame.K_s]:
rect.y += move
if rect.y > height - hbox:
rect.y = height - vbox
if keys[pygame.K_a]:
rect.x -= move
if rect.x < 0:
rect.x = 0
if keys[pygame.K_d]:
rect.x += move
if rect.x > width - hbox:
rect.x = width - hbox

running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
# Space bar! Spawn a new ball.
if event.key == pygame.K_SPACE:
ball = make_ball()
ball_list.append(ball)
if rect.x == ball.x and rect.y == ball.y:
hp -100
if hp == 0:
pygame.quit()

if event.type == pygame.KEYDOWN and event.key == pygame.K_c:
is_blue = not is_blue
surface = pygame.Surface((100, 100))
keys = pygame.key.get_pressed()
if keys[pygame.K_LSHIFT] or keys[pygame.K_RSHIFT]:
move = 8
else:
move = 4
if keys[pygame.K_w]:
rect.y -= move
if rect.y < 0:
rect.y = 0
if keys[pygame.K_s]:
rect.y += move
if rect.y > height - hbox:
rect.y = height - vbox
if keys[pygame.K_a]:
rect.x -= move
if rect.x < 0:
rect.x = 0
if keys[pygame.K_d]:
rect.x += move
if rect.x > width - hbox:
rect.x = width - hbox

screen.fill((0, 0, 0))
if is_blue:
color = (0, 128, 255)
else:
color = (255, 100, 0)
color_2 = (255, 0, 0)
for ball in ball_list:
ball.x += ball.change_x
ball.y += ball.change_y
if ball.y > height - ball_size or ball.y < ball_size:
ball.change_y *= -1
if ball.x > width - ball_size or ball.x < ball_size:
ball.change_x *= -1

screen.fill(black)

for ball in ball_list:
pygame.draw.circle(screen, white, [ball.x, ball.y], ball_size)

Rectangle = pygame.draw.rect(screen, color, rect)

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

` 

通常,我建议使用pygame.sprite.Spritepygame.sprite.Group,但我将向您展示一个更接近当前代码的解决方案。

创建一个Ball类,该类可以移动和绘制球对象。该类具有类型为pygame.Rect.rect属性,而不是属性.x.y,并且也可以用于"hitbox">
矩形在实例方法move():中更新

class Ball:
def __init__(self):
x = random.randrange(ball_size, width - ball_size)
y = random.randrange(ball_size, height - ball_size)
self.change_x, self.change_y = 0, 0
while self.change_x == 0 and self.change_y == 0:
self.change_x = random.randrange(-2, 3)
self.change_y = random.randrange(-2, 3)
self.rect = pygame.Rect(x-ball_size, y-ball_size, ball_size*2, ball_size*2)
def move(self):
self.rect = self.rect.move(self.change_x, self.change_y)
if self.rect.right >= height or self.rect.left < 0:
self.change_x *= -1
if self.rect.bottom >= width or self.rect.top <= 0:
self.change_y *= -1
def draw(self, surface): 
pygame.draw.circle(surface, white, self.rect.center, ball_size)
def make_ball():
ball = Ball()
return ball

在主应用程序循环中,球可以在for-循环中移动和绘制,碰撞测试可以通过.colliderect():进行

hits = 0
running = True
while running:
# [...]
for ball in ball_list:
if ball.rect.colliderect(rect):
hits += 1
print("hit " + str(hits))   
# [...]
for ball in ball_list:
ball.move()
screen.fill(black)
for ball in ball_list:
ball.draw(screen)
Rectangle = pygame.draw.rect(screen, color, rect)
pygame.display.flip()
clock.tick(30)

最新更新