首页 > 解决方案 > Pygame problem: how to execute conditional on collision?

问题描述

I have a problem with pygame and collision detection. The program I wrote should draw a rectangle on click, change alpha on mousover. These two work. But I am also trying to implement functionality that only executes if a rectangle already exists/if mouse is over an existing rectangle.

For now I tried to get the program not to draw a new marker/rectangle if it detects collision, but I can't think of a way to do that... The way I tried in my code example does not work, it only returns collision status for the last marker added...

I only started coding 2 Months ago, so maybe I am missing some fundamental idea regarding python. I tried to post as little of my code as possible without loosing the gist of what it does. Sorry if it is still too long.

So is there a way to get the functionality I want?

Thanks for any help!

import pygame


pygame.init()

clock = pygame.time.Clock()
clock.tick(20)

BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)

screen = pygame.display.set_mode((500, 500))
running = True


LEFT = 1



class Marker(pygame.sprite.Sprite):

  """
used to draw the marker at a given position
  """

  def __init__(self, x, y, key, function):
    pygame.sprite.Sprite.__init__(self)

    self.image = pygame.Surface((50, 50))
    self.image.fill(RED)
    self.image.set_alpha(50)

    self.rect = self.image.get_rect()
    self.rect.x = x
    self.rect.y = y

    self.function = function

  def check_click(self, mouse):
    if self.rect.collidepoint(mouse):
      self.image.set_alpha(200)
      return True

    if not self.rect.collidepoint(mouse):
      self.image.set_alpha(50)


  def collide_check(self, mouse):
    return self.rect.collidepoint(mouse)

  def get_function(self):
    return self.function


class Connections:

  def __init__(self):
    self.switch = False
    self.con_dict = {}
    self.key_dict = []

  def generate_key(self, position): #generates a dictionary key out of mouse position
    position_x, position_y = position
    instance_name = str(position_x) + str(position_y)
    return instance_name

  def add_entrance_or_exit(self, position): 
#sets marker/rectangle at mouse position(depending on switch state)
    if not self.switch:
      key = self.generate_key(position)
      self.key_dict.append(key)
      self.con_dict[key] = position
      pos_x, pos_y = position
      new_key = key + "_entrance"
      new_key = Marker(pos_x, pos_y, key, "entrance")
      all_sprites.add(new_key)
      self.switch = True
    else:
      key = self.key_dict[-1]
      old_pos = self.con_dict[key]
      pos_x, pos_y = position
      new_key = key + "_exit"
      new_key = Marker(pos_x, pos_y, key, "exit")
      all_sprites.add(new_key)
      self.con_dict[key] = [old_pos, position]
      self.switch = False


all_sprites = pygame.sprite.Group()

connections = Connections()

running = True


while running:
  collide = None
  for s in all_sprites:
    mouse_pos = pygame.mouse.get_pos()
    s.check_click(mouse_pos)
    collide = s.check_click(mouse_pos)

  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      running = False
    elif event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT:
      if collide == None:
        mouse = pygame.mouse.get_pos()
        connections.add_entrance_or_exit(mouse)

  screen.fill(BLACK)
  all_sprites.update()
  all_sprites.draw(screen)
  pygame.display.update()


pygame.quit()


标签: pythonpython-3.xpygame

解决方案


我会让碰撞检测成为所有碰撞的列表,然后你会为每个精灵得到一个布尔值(真或无)。然后如果 True 在列表中,则单击后无法执行代码(希望这是有道理的)

while running:
  collide = [] # collide is an empty list
  for s in all_sprites:
    mouse_pos = pygame.mouse.get_pos()
    s.check_click(mouse_pos)
    collide.append( s.check_click(mouse_pos) ) 
    # add whatever check_click returns to the list

  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      running = False
    elif event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT:
      if not True in collide: # if there was not a collision in the list
        mouse = pygame.mouse.get_pos()
        connections.add_entrance_or_exit(mouse)

  screen.fill(BLACK)
  all_sprites.update()
  all_sprites.draw(screen)
  pygame.display.update()

希望这可以帮助


推荐阅读