pygame碰撞无法正确更改状态

时间:2019-01-23 13:19:08

标签: python debugging pygame collision-detection collision

冲突无法按我希望的方式工作。我想要这样,以便每当您击中一条船时,您都将返回到MENUSTATE,并且每当您击中一条鱼时,图像就会消失并且游戏会继续运行。根据我的尝试,只要两个对象仍在碰撞,游戏就会在船撞后返回MENUSTATE,但完成后将返回GAMESTATE。我如何拥有它,使其在与船相撞后永久停留在MENUSTATE中?当与人相撞而游戏仍在运行时,我将如何删除鱼图像?

图像和SFX:https://mega.nz/fm/zHohiSJD

import pygame
import random
import os

os.environ['SDL_VIDEO_WINDOW_POS'] = "%d, %d" % (0, 20)  # positions the game tab to the top left portion of the monitor
pygame.init()  # initializes pygame
pygame.display.set_caption("Biomagnification ")
SIZE = W, H = 400, 700  # determining the screen size of the game
screen = pygame.display.set_mode(SIZE)  # creating a display surface
clock = pygame.time.Clock()  # creating a clock

# RGB colours
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
BACKGROUND = (94, 194, 222)
STRIPE = (60, 160, 190)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREY = (80, 80, 80)


MENUSTATE = 0
INFOSTATE = 1
GAMESTATE = 2
# variables
x1 = 30  # desired X position for the left dolphin/hitbox
x2 = 330  # desired X position for the right dolphin/hitbox
lane1 = 30
lane2 = 130
lane3 = 230
lane4 = 330
y = 530  # desired y value of the hitbox
width, height = (40, 64)  # width and height of the hitbox

toggle1 = 0  # toggle for left dolphin
toggle2 = 0  # toggle for right dolphin

target_x1 = 30
target_x2 = 330
vel_x = 10  # speed at which the dolphins move

# fonts
menuFont = pygame.font.SysFont('impact', 60)
titleFont = pygame.font.SysFont('Impact', 40)
textFont = pygame.font.SysFont('Calibri', 16)
text2Font = pygame.font.SysFont('Calibri', 20)

# method to blit text, taken from my university assignment 2
def blit_text(surface, string, pos, font, color=pygame.Color('black')):
   words = [word.split(' ') for word in string.splitlines()]  # 2D array where each row is a list of words.
   space = font.size(' ')[0]  # The width of a space.
   max_width, max_height = surface.get_size()
   x, y = pos
   for line in words:
       for word in line:
           word_surface = font.render(word, 0, color)
           word_width, word_height = word_surface.get_size()
           if x + word_width >= max_width:
               x = pos[0]  # Reset the x.
               y += word_height  # Start on new row.
           surface.blit(word_surface, (x, y))
           x += word_width + space
       x = pos[0]  # Reset the x.
       y += word_height  # Start on new row.


def drawScene():
   screen.fill(BACKGROUND)  # fills the background with the colour ((94, 194, 222)
   pygame.draw.polygon(screen, STRIPE, ((200, 700), (300, 700), (400, 600), (400, 500)))  # draws the different coloured stripes
   pygame.draw.polygon(screen, STRIPE, ((0, 700), (100, 700), (400, 400), (400, 300)))
   pygame.draw.polygon(screen, STRIPE, ((0, 500), (0, 600), (400, 200), (400, 100)))
   pygame.draw.polygon(screen, STRIPE, ((0, 300), (0, 400), (400, 0), (300, 0)))
   pygame.draw.polygon(screen, STRIPE, ((0, 100), (0, 200), (200, 0), (100, 0)))
   pygame.draw.line(screen, WHITE, (100, 0), (100, 700), 2)  # draws the white separating lines in the background
   pygame.draw.line(screen, WHITE, (200, 0), (200, 700), 6)
   pygame.draw.line(screen, WHITE, (300, 0), (300, 700), 2)

def drawMenu(button, mouseX, mouseY):
   st = MENUSTATE
   screen.fill(BACKGROUND)
   pygame.draw.polygon(screen, STRIPE, ((300, 700), (400, 700), (400, 600)))  # draws the different coloured stripes
   pygame.draw.polygon(screen, STRIPE, ((0, 100), (0, 0), (100, 0)))
   string = "biomagnification"
   blit_text(screen, string, (52, 80), titleFont, BLACK)
   playRect = pygame.Rect(W // 3, (H // 4) + 30, W // 3, H // 10)
   pygame.draw.rect(screen, STRIPE, playRect)
   string = "play"
   blit_text(screen, string, (146, 200), menuFont, BLACK)
   infoRect = pygame.Rect(W // 3, (H // 2.5) + 30, W // 3, H // 10)
   pygame.draw.rect(screen, STRIPE, infoRect)
   string = "info"
   blit_text(screen, string, (152, 307), menuFont, BLACK)
   quitRect = pygame.Rect(W // 3, (H // 1.81) + 30, W // 3, H // 10)
   pygame.draw.rect(screen, STRIPE, quitRect)
   string = "quit"
   blit_text(screen, string, (148, 410), menuFont, BLACK)
   if button == 1:
       if playRect.collidepoint(mouseX, mouseY) == True:
           st = GAMESTATE
       elif infoRect.collidepoint(mouseX, mouseY) == True:
           st = INFOSTATE
       elif quitRect.collidepoint(mouseX, mouseY) == True:
           pygame.quit()
   pygame.display.update()
   return st

def drawInfo(button, mouseX, mouseY):
   st = INFOSTATE
   screen.fill(BACKGROUND)
   pygame.draw.polygon(screen, STRIPE, ((300, 700), (400, 700), (400, 600)))  # draws the different coloured stripes
   pygame.draw.polygon(screen, STRIPE, ((0, 100), (0, 0), (100, 0)))
   string = "biomagnification:"
   blit_text(screen, string, (50, 80), titleFont, BLACK)
   textRect = pygame.Rect(0, (H // 4) + 30, W, H // 3)
   pygame.draw.rect(screen, STRIPE, textRect)
   string = "the process by which a compound increases its concentration in the tissues of organisms as it travels up the food chain."
   blit_text(screen, string, (20, 135), textFont, BLACK)
   string = "Magnesium, an element commonly found in E-Waste increases its concentration in tissue as it travels up the food chain."
   blit_text(screen, string, (20, 230), textFont, BLACK)
   string = "Score is measured in PPM (parts per million) of Mg."
   blit_text(screen, string, (20, 300), textFont, BLACK)
   string = "• Eat fish to increase your PPM of Mg!"
   blit_text(screen, string, (20, 340), text2Font, BLACK)
   string = "• Dodge fishing boats!"
   blit_text(screen, string, (20, 380), text2Font, BLACK)
   text2Rect = pygame.Rect(0, (H // 1.65) + 30, W, H // 5)
   pygame.draw.rect(screen, STRIPE, text2Rect)
   string = "Controls"
   blit_text(screen, string, (165, 465), text2Font, BLACK)
   string = "A - Switch Left Lane"
   blit_text(screen, string, (130, 495), textFont, BLACK)
   string = "D - Switch Right Lane"
   blit_text(screen, string, (130, 520), textFont, BLACK)
   string = "ESC - Main Menu"
   blit_text(screen, string, (130, 545), textFont, BLACK)
   backRect = pygame.Rect(W // 3, 612, W // 3, H // 10)
   pygame.draw.rect(screen, STRIPE, backRect)
   string = "back"
   blit_text(screen, string, (139, 610), menuFont, BLACK)
   if button == 1:
       if backRect.collidepoint(mouseX, mouseY) == True:
           st = MENUSTATE
   pygame.display.update()
   return st

# dolphin spritesheet
mainsheet = pygame.image.load("mainsheetSmall.png").convert()  # load in the spritesheet
sheetSize = mainsheet.get_size()  # gets the size of the spritesheet
horiz_cells = 36  # number of horizontal frames/cells in the spritesheet
vert_cells = 1  # number of vertical frames/cells in the spritesheet
cell_width = int(sheetSize[0] / horiz_cells)  # determining the width of each cell
cell_height = int(sheetSize[1] / vert_cells)  # determing the height of each cell

cellList = []  # creates a list for all the cells
for vert in range(0, sheetSize[1], cell_height):
   for horz in range(0, sheetSize[0], cell_width):
       surface = pygame.Surface((cell_width, cell_height))
       surface.blit(mainsheet, (0, 0),
                    (horz, vert, cell_width, cell_height))
       colorkey = surface.get_at((0, 0))  # gets the colour at O, 0 (white)
       surface.set_colorkey(colorkey)  # removes all the white from the spritesheet, making the background transparent
       cellList.append(surface)  # appends to the list of cells (cellList)

cellPosition = 0  # determines which frame is playing. Starts at 0


speed = 4
# 1st pair of boats
boat = pygame.image.load("boat.png").convert_alpha()
boatX = random.choice([lane1, lane2, lane3, lane4])
if boatX == lane1:
   boatX2 = random.choice([lane3, lane4])
elif boatX == lane2:
   boatX2 = random.choice([lane3, lane4])
else:
   boatX2 = random.choice([lane1, lane2])
boatY = -100

# 2nd pair of boats
boatX3 = random.choice([lane1, lane2, lane3, lane4])
if boatX3 == lane1:
   boatX4 = random.choice([lane3, lane4])
elif boatX3 == lane2:
   boatX4 = random.choice([lane3, lane4])
else:
   boatX4 = random.choice([lane1, lane2])
boatY2 = -450

# 1st pair of fish
fish1 = pygame.image.load("fishBlue.png").convert_alpha()
fish2 = pygame.image.load("fishOrange.png").convert_alpha()
fish = random.choice([fish1, fish2])
fishX = random.choice([lane1, lane2, lane3, lane4])
if fishX == lane1:
   fishX2 = random.choice([lane3, lane4])
elif fishX == lane2:
   fishX2 = random.choice([lane3, lane4])
else:
   fishX2 = random.choice([lane1, lane2])
fishY = -800

# 2nd pair of fish
fishX3 = random.choice([lane1, lane2, lane3, lane4])
if fishX3 == lane1:
   fishX4 = random.choice([lane3, lane4])
elif fishX3 == lane2:
   fishX4 = random.choice([lane3, lane4])
else:
   fishX4 = random.choice([lane1, lane2])
fishY2 = -1150


# main loop
running = True
state = MENUSTATE
button = mx = my = 0
while running:
   clock.tick(60)  # makes the game tick 60 frames per second

   for event in pygame.event.get():
       if event.type == pygame.QUIT:
           running = False
       if event.type == pygame.MOUSEBUTTONDOWN:
           mx, my = pygame.mouse.get_pos()
           button = pygame.mouse.get_pressed()[0]

       if event.type == pygame.KEYDOWN:
           if event.key == pygame.K_ESCAPE:  # detects if the user presses the ESC key
               pygame.quit()
           elif event.key == pygame.K_a:  # detects if the user presses the A key
               pygame.mixer.music.load('percussiveHit.mp3')
               pygame.mixer.music.play()
               toggle1 += 1  # adds 1 to toggle1
               if toggle1 % 2 == 1:  # if toggle1 mod 2 equals 1
                   target_x1 += 100  # add 100 to the target position
               else:
                   target_x1 -= 100  # if toggle1 mod 2 does not equal 1, subtract 100 from the target position making it the original of 30
           elif event.key == pygame.K_d:  # detects if the user presses the D key
               pygame.mixer.music.load('percussiveHit.mp3')
               pygame.mixer.music.play()
               toggle2 += 1  # adds 1 to toggle2
               if toggle2 % 2 == 1:  # if toggle2 mod 2 equals 1
                   target_x2 -= 100  # subtract 100 the to target position
               else:
                   target_x2 += 100  # if toggle2 mod 2 does not equal 1, add 100 to the target position making it the original of 330
   if x1 < target_x1:
       x1 = min(x1 + vel_x, target_x1)
   else:
       x1 = max(x1 - vel_x, target_x1)

   if x2 < target_x2:
       x2 = min(x2 + vel_x, target_x2)
   else:
       x2 = max(x2 - vel_x, target_x2)

   if cellPosition < len(cellList) - 1:
       cellPosition += 1
   else:
       cellPosition = 0

   boatY += speed
   if boatY > H + 625:
       boatX = random.choice([lane1, lane2, lane3, lane4])
       if boatX == lane1:
           boatX2 = random.choice([lane3, lane4])
       elif boatX == lane2:
           boatX2 = random.choice([lane3, lane4])
       else:
           boatX2 = random.choice([lane1, lane2])
       boatY = -100

   boatY2 += speed
   if boatY2 > H + 100:
       boatX3 = random.choice([lane1, lane2, lane3, lane4])
       if boatX3 == lane1:
           boatX4 = random.choice([lane3, lane4])
       elif boatX3 == lane2:
           boatX4 = random.choice([lane3, lane4])
       else:
           boatX4 = random.choice([lane1, lane2])
       boatY2 = -625

   fishY += speed
   if fishY > H + 275:
       fishX = random.choice([lane1, lane2, lane3, lane4])
       if fishX == lane1:
           fishX2 = random.choice([lane3, lane4])
       elif fishX == lane2:
           fishX2 = random.choice([lane3, lane4])
       else:
           fishX2 = random.choice([lane1, lane2])
       fishY = -450

   fishY2 += speed
   if fishY2 > H + 450:
       fishX3 = random.choice([lane1, lane2, lane3, lane4])
       if fishX3 == lane1:
           fishX4 = random.choice([lane3, lane4])
       elif fishX3 == lane2:
           fishX4 = random.choice([lane3, lane4])
       else:
           fishX4 = random.choice([lane1, lane2])
       fishY2 = -275
       if speed < 11:
           speed *= 1.1
   def drawGame():
       st = GAMESTATE
       dolphin1Rect = pygame.Rect((x1, y), (width, height))
       pygame.draw.rect(screen, GREEN, (x1, y, width, height))# hitbox of left dolphin
       dolphin2Rect = pygame.Rect((x2, y), (width, height))
       pygame.draw.rect(screen, GREEN, (x2, y, width, height))  # hitbox of right dolphin
       drawScene()  # draws the scene (background, lane-lines, etc)
       # players
       screen.blit(cellList[cellPosition], (x1 + 4, y - 1))  # the left dolphin
       screen.blit(cellList[cellPosition], (x2 + 4, y - 1))  # the right dolphin

       boat1Rect = pygame.Rect((boatX + 3, boatY + 14), (34, 81))
       pygame.draw.rect(screen, GREEN, boat1Rect)
       boat2Rect = pygame.Rect((boatX2 + 3, boatY + 14, 34, 81))
       pygame.draw.rect(screen, GREEN, boat2Rect)
       boat3Rect = pygame.Rect((boatX3 + 3, boatY2 + 14, 34, 81))
       pygame.draw.rect(screen, GREEN, boat3Rect)
       boat4Rect = pygame.Rect((boatX4 + 3, boatY2 + 14, 34, 81))
       pygame.draw.rect(screen, GREEN, boat4Rect)

       fish1Rect = pygame.Rect((fishX, fishY), (40, 40))
       pygame.draw.rect(screen, GREEN, fish1Rect)
       fish2Rect = pygame.Rect((fishX2, fishY, 40, 40))
       pygame.draw.rect(screen, GREEN, fish2Rect)
       fish3Rect = pygame.Rect((fishX3, fishY2, 40, 40))
       pygame.draw.rect(screen, GREEN, fish3Rect)
       fish4Rect = pygame.Rect((fishX4, fishY2, 40, 40))
       pygame.draw.rect(screen, GREEN, fish4Rect)

       screen.blit(boat, (boatX, boatY))
       screen.blit(boat, (boatX2, boatY))
       screen.blit(boat, (boatX3, boatY2))
       screen.blit(boat, (boatX4, boatY2))
       screen.blit(fish, (fishX, fishY))
       screen.blit(fish, (fishX2, fishY))
       screen.blit(fish, (fishX3, fishY2))
       screen.blit(fish, (fishX4, fishY2))
       boatList = [boat1Rect, boat2Rect, boat3Rect, boat4Rect]
       collideToggle = 0
       if pygame.Rect.collidelist(dolphin1Rect, boatList) > -1:
           st = MENUSTATE
       if pygame.Rect.collidelist(dolphin2Rect, boatList) > -1:
           st = MENUSTATE
       if dolphin1Rect.colliderect(fish1Rect) == False and fishY > y:
           st = MENUSTATE
       elif dolphin2Rect.colliderect(fish1Rect) == False and fishY > y:
           st = MENUSTATE
       elif dolphin1Rect.colliderect(fish2Rect) == False and fishY > y:
           st = MENUSTATE
       elif dolphin2Rect.colliderect(fish2Rect) == False and fishY > y:
           st = MENUSTATE
       elif dolphin1Rect.colliderect(fish3Rect) == False and fishY2 > y:
           st = MENUSTATE
       elif dolphin2Rect.colliderect(fish3Rect) == False and fishY2 > y:
           st = MENUSTATE
       elif dolphin1Rect.colliderect(fish4Rect) == False and fishY2 > y:
           st = MENUSTATE
       elif dolphin2Rect.colliderect(fish4Rect) == False and fishY2 > y:
           st = MENUSTATE
       return st
       pygame.display.update()


   if state == MENUSTATE:
       state = drawMenu(button, mx, my)
   elif state == GAMESTATE:
       state = drawGame()
       pygame.display.update()
   elif state == INFOSTATE:
       drawInfo(button, mx, my)
   else:
       running = False

0 个答案:

没有答案