pygame掩码冲突发生在错误区域

5gfr0r5j  于 2021-08-20  发布在  Java
关注(0)|答案(0)|浏览(186)

我以前问过这个问题,有人告诉我,面罩需要一个位置才能正确检测碰撞。有了这个建议,我就能够修改代码,使其正常工作。然而,激光激活的第一帧将移除它不应该接触的小行星。我看了其他的问题,仍然感到困惑


# Written by: Theo

# Date: December 2020 - July 2021

# 

# Version 1: an endless runner game where the player

# controls a ship traveling through space, dodging obstacles

import pygame
import math
import time
import random
import RiftObstacles

global ship
global rot_ship
global shipX
global moonMask

pygame.init()
FPS = 100
clock = pygame.time.Clock()
size = pygame.display.Info()
WIDTH = 1000
HEIGHT = 1000
pygame.display.set_caption('Parallax Nebula')
screen = pygame.display.set_mode((WIDTH, HEIGHT))

########## Rift Variables

ship = pygame.image.load("Images/Rift/Ship.PNG")
ship = pygame.transform.scale(ship, (85, 125))
rot_ship = ship
shipX = 450
shipY = 700

A1 = pygame.image.load("Images/Rift/Asteroids/1.PNG")
A1 = pygame.transform.scale(A1, (100, 100))
A1 = pygame.Surface.convert_alpha(A1)

A2 = pygame.image.load("Images/Rift/Asteroids/2.PNG")
A2 = pygame.transform.scale(A2, (100, 100))
A2 = pygame.Surface.convert_alpha(A2)

A3 = pygame.image.load("Images/Rift/Asteroids/3.PNG")
A3 = pygame.transform.scale(A3, (100, 100))
A3 = pygame.Surface.convert_alpha(A3)

A4 = pygame.image.load("Images/Rift/Asteroids/4.PNG")
A4 = pygame.transform.scale(A4, (100, 100))
A4 = pygame.Surface.convert_alpha(A4)

A5 = pygame.image.load("Images/Rift/Asteroids/5.PNG")
A5 = pygame.transform.scale(A5, (100, 100))
A5 = pygame.Surface.convert_alpha(A5)

A6 = pygame.image.load("Images/Rift/Asteroids/6.PNG")
A6 = pygame.transform.scale(A6, (100, 100))
A6 = pygame.Surface.convert_alpha(A6)

A7 = pygame.image.load("Images/Rift/Asteroids/7.PNG")
A7 = pygame.transform.scale(A7, (100, 100))
A7 = pygame.Surface.convert_alpha(A7)

A8 = pygame.image.load("Images/Rift/Asteroids/8.PNG")
A8 = pygame.transform.scale(A8, (100, 100))
A8 = pygame.Surface.convert_alpha(A8)

A9 = pygame.image.load("Images/Rift/Asteroids/9.PNG")
A9 = pygame.transform.scale(A9, (100, 100))
A9 = pygame.Surface.convert_alpha(A9)

A10 = pygame.image.load("Images/Rift/Asteroids/10.PNG")
A10 = pygame.transform.scale(A10, (100, 100))
A10 = pygame.Surface.convert_alpha(A10)

A11 = pygame.image.load("Images/Rift/Asteroids/11.PNG")
A11 = pygame.transform.scale(A11, (100, 100))
A11 = pygame.Surface.convert_alpha(A11)

A12 = pygame.image.load("Images/Rift/Asteroids/12.PNG")
A12 = pygame.transform.scale(A12, (60, 100))
A12 = pygame.Surface.convert_alpha(A12)

F1 = pygame.image.load("Images/Rift/Fuel/1.PNG")
F1 = pygame.transform.scale(F1, (150, 150))

F2 = pygame.image.load("Images/Rift/Fuel/2.PNG")
F2 = pygame.transform.scale(F2, (150, 150))

F3 = pygame.image.load("Images/Rift/Fuel/3.PNG")
F3 = pygame.transform.scale(F3, (150, 150))

F4 = pygame.image.load("Images/Rift/Fuel/4.PNG")
F4 = pygame.transform.scale(F4, (150, 150))

F5 = pygame.image.load("Images/Rift/Fuel/5.PNG")
F5 = pygame.transform.scale(F5, (150, 150))

F6 = pygame.image.load("Images/Rift/Fuel/6.PNG")
F6 = pygame.transform.scale(F6, (150, 150))

comet = pygame.image.load("Images/Rift/Comet.PNG")
comet = pygame.transform.scale(comet, (80, 250))

moon = pygame.image.load("Images/Rift/Moon - WIP.PNG")
moon = pygame.transform.smoothscale(moon, (1200, 1200))
moon = pygame.Surface.convert_alpha(moon)
moonMask = pygame.mask.from_surface(moon)

angle = 0
lasers = []
stretch = []
for i in range(60):
    laserImg = pygame.image.load("Images/Rift/Laser/"+str(i+1)+".PNG")
    laserImg = pygame.Surface.convert_alpha(laserImg)
    stretchTemp = int(15*math.cos(math.pi*i/30))
    stretch.append(50 - stretchTemp)
    laserImg = pygame.transform.scale(laserImg, (50-stretchTemp, 1050))
    lasers.append(laserImg)

angle = 0

RiftBG = pygame.image.load("Images/Rift/Background/BG.PNG")
RiftBG = pygame.Surface.convert_alpha(RiftBG)
RiftBG = pygame.transform.smoothscale(RiftBG, (1000, 1000))

# Transparent comet warning

def warning(surface, color, rect):
    shape_surf = pygame.Surface(pygame.Rect(rect).size, pygame.SRCALPHA)
    pygame.draw.rect(shape_surf, color, shape_surf.get_rect())
    surface.blit(shape_surf, rect)

# Moving the ship

def moveShip(shipX, X, angle):
    if (X >= 0 and shipX > 100) or (X <= 0 and shipX < 800):
        shipX -= X    
    else:
        shipX -= X
        angle -= (X*speed)/11

    rot_ship = pygame.transform.rotate(ship, angle)
    return(shipX, rot_ship, angle)

# Pulling ship towards the middle of the screen

def riftpull(shipX, angle, rot_ship):
    if shipX < 440:
        if angle > -25:
            angle -= 0.1 * speed
        else:
            angle += 0.1 * speed
        shipX, rot_ship, angle = moveShip(shipX, (angle/2.5), angle)

    elif shipX > 460:
        if angle < 25:
            angle += 0.1 * speed
        else:
            angle -= 0.1 * speed
        shipX, rot_ship, angle = moveShip(shipX, (angle/2.5), angle)

    elif 440 < shipX < 460:
        if abs(angle) > 1:
            angle = angle/1.2
        else:
            angle = 0
        shipX, rot_ship, angle = moveShip(shipX, (angle/2.5), angle)
    return shipX, angle, rot_ship  

# Ship Travel through the rift

def rift():
    global ship
    global rot_ship
    global shipX
    global speed
    global moon
    global moonOutline
    global moonMask
    global distance
    speed = 5
    angle = 0
    laserOn = 2*FPS
    laserAnimation = int(FPS/30)
    laserFrame = 0
    distanceTimer = 0
    delay = FPS
    laserMode = False
    crash = False
    key = pygame.key.get_pressed()
    wallX = 470
    wallY = [-1000, -3000]

    rocks = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12]
    fuel = [F1, F2, F3, F4, F5, F6]
    numRock, rockX, rockY, numComet, cometX, cometY, numMoon, moonX, moonY, moonScale, numFuel, fuelX, fuelY = RiftObstacles.path()
    rockType = []
    rockAngle = []  
    rockAngle2 = []
    rockRot = []
    for i in range(numRock):
        rockType.append(random.choice(rocks))
        rockAngle.append(random.uniform(-0.2,0.2))
        rockAngle2.append(rockAngle[i])

    fuelType = []
    fuelAngle = []
    fuelAngle2 = []
    fuelRot = []
    for i in range(numFuel):
        fuelType.append(random.choice(fuel))
        fuelAngle.append(random.uniform(-0.2,0.2))
        fuelAngle2.append(fuelAngle[i])

    warningWidth = []
    for i in range(numComet):
        warningWidth.append(10)

    endRift = False
    while endRift == False:
        screen.blit(RiftBG, (0,0))

        #Displaying obstacles       
        for i in range(numRock):
            rockRot.append(pygame.transform.rotate(rockType[i], rockAngle2[i]))
            screen.blit(rockRot[i], (rockX[i], rockY[i]))

        for i in range(numComet):
            screen.blit(comet, (cometX[i], cometY[i]))
            if -2000 < cometY[i] < HEIGHT:
                warningHEIGHT = HEIGHT - cometY[i]
                cometWarning = pygame.Rect(cometX[i]+40 - warningWidth[i]/2, cometY[i]+100, warningWidth[i], warningHEIGHT)
                if warningWidth[i] < 78:
                    warningWidth[i] += 1.5
                warning(screen, (250, 200, 3, 127), (cometWarning))

        for i in range(numFuel):
            fuelRot.append(pygame.transform.rotate(fuelType[i], fuelAngle2[i]))
            screen.blit(fuelRot[i], (fuelX[i], fuelY[i]))

        if laserMode == True:
            laserOn -= 1
            if laserOn <= 0:
                laserMode = False

            rot_laser = pygame.transform.rotate(lasers[laserFrame], angle)
            laserAnimation -= 1
            if -1 < laserAnimation < 1:
                laserAnimation = FPS/30
                if laserFrame < 59:
                    laserFrame += 1
            laserRect = rot_laser.get_rect()
            if angle == 0:
                correction = 50*math.sin((angle*math.pi)/180)
                laserRect.midbottom = (shipX + 42 - correction, shipY+100)

            elif angle <= 1:
                correction = angle*9
                laserRect.midbottom = (shipX + 50 - correction, shipY+100)

            else:
                correction = angle*7
                laserRect.midbottom = (shipX + 30 - correction, shipY+100)

            screen.blit(rot_laser, laserRect)

        if laserMode == False:
            laserOn = 180
            laserFrame = 0

        for i in range(numMoon):
            moon = pygame.transform.smoothscale(moon, (int(100*moonScale[i]), int(100*moonScale[i])))
            screen.blit(moon, (moonX[i], moonY[i]))

        #Ship Movement                
        screen.blit(rot_ship, (int(shipX), shipY))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT or event.key == pygame.K_a:
                    key = 'left'
                elif event.key == pygame.K_RIGHT or event.key == pygame.K_d:
                    key = 'right'

                #Activating the laser
                elif event.key == pygame.K_SPACE:
                    if laserMode == False:
                        laserMode = True

                else:
                    key = 'up'

            if event.type == pygame.KEYUP:
                key = 'up'

        if key == 'left':
            if angle < 35 and shipX > 50:
                angle += 0.2*speed

            shipX, rot_ship, angle = moveShip(shipX, (angle/2.5), angle)

        elif key == 'right':
            if angle > -35 and shipX < 850:
                angle -= 0.2*speed

            shipX, rot_ship, angle = moveShip(shipX, (angle/2.5), angle)

        elif key == 'up':
            shipX, angle, rot_ship = riftpull(shipX, angle, rot_ship)

        #Collision detection
        shipRect = pygame.Rect(shipX, shipY, 85, 125)
        shipMask = pygame.mask.from_surface(rot_ship)
        if laserMode == True:
            rot_laser = pygame.transform.rotate(lasers[laserFrame], angle)
            if angle == 0:
                correction = 50*math.sin((angle*math.pi)/180)
                laserRect.midbottom = (shipX + 42 - correction, shipY+100)

            elif angle <= 1:
                correction = angle*9
                laserRect.midbottom = (shipX + 50 - correction, shipY+100)

            else:
                correction = angle*7
                laserRect.midbottom = (shipX + 30 - correction, shipY+100)
            laserMask = pygame.mask.from_surface(rot_laser)

        remove = []
        for i in range(numRock):
            rockRect = pygame.Rect(rockX[i], rockY[i], 100, 100)
            if laserMode == True:
                if rockRect.colliderect(laserRect):
                    rockMask = pygame.mask.from_surface(rockRot[i])
                    offset_x = laserRect.x - rockRect.x
                    offset_y = laserRect.y - rockRect.y
                    laserHit = rockMask.overlap(laserMask, (offset_x, offset_y))
                    if laserHit:
                        remove.append(i)

            if rockRect.colliderect(shipRect):
                rockMask = pygame.mask.from_surface(rockRot[i])
                offset_x = shipRect.x - rockRect.x
                offset_y = shipRect.y - rockRect.y
                crash = rockMask.overlap(shipMask, (offset_x, offset_y))

        for i in range(len(remove)):
                numRock -= 1
                rockX.pop(remove[i])
                rockY.pop(remove[i])
                rockType.pop(remove[i])
                rockAngle.pop(remove[i])
                rockAngle2.pop(remove[i])
                rockRot.pop(remove[i])

        remove = []                    
        for i in range(numComet):
            cometRect = pygame.Rect(cometX[i], cometY[i], 80, 250)
            if cometRect.colliderect(shipRect):
                cometMask = pygame.mask.from_surface(comet)
                offset_x = shipRect.x - cometRect.x
                offset_y = shipRect.y - cometRect.y
                crash = cometMask.overlap(shipMask, (offset_x, offset_y))

        remove = []        
        for i in range(numMoon):
            moonRect = pygame.Rect(moonX[i], moonY[i], int(100*moonScale[i]), int(100*moonScale[i]))
            if int(50*moonScale[i]+60)**2 >= ((shipX+40 - moonX[i]-int(50*moonScale[i]))**2 + (shipY+100 - moonY[i]-int(50*moonScale[i]))**2) and not crash:
                moonMask = pygame.mask.from_surface(moon)
                offset_x = shipRect.x - moonRect.x
                offset_y = shipRect.y - moonRect.y
                crash = moonMask.overlap(shipMask, (offset_x, offset_y))

        remove = []
        for i in range(numFuel):
            fuelRect = pygame.Rect(fuelX[i], fuelY[i], 100, 100)
            if fuelRect.colliderect(shipRect):
                fuelMask = pygame.mask.from_surface(fuelRot[i])
                offset_x = shipRect.x - fuelRect.x
                offset_y = shipRect.y - fuelRect.y
                fuelHit = fuelMask.overlap(shipMask, (offset_x, offset_y))
                if fuelHit:
                    remove.append(i)

        for i in range(len(remove)):
            numFuel -= 1
            fuelX.pop(remove[i])
            fuelY.pop(remove[i])
            fuelType.pop(remove[i])
            fuelAngle.pop(remove[i])
            fuelAngle2.pop(remove[i])
            fuelRot.pop(remove[i])

        remove = []           
        #Moves objects down screen
        rockRot = []
        fuelRot = []
        for i in range(numRock):
            rockY[i] += speed
            rockAngle2[i] += rockAngle[i]

        for i in range(numMoon):
            moonY[i] += speed

        for i in range(numComet):
            cometY[i] += speed * 5
            if cometY[i] > HEIGHT:
                 warningWidth[i] = 10

        for i in range(numFuel):
            fuelY[i] += speed
            fuelAngle2[i] += fuelAngle[i]

        #Choosing a new path      
        rockPassed = HEIGHT+1
        cometPassed = HEIGHT+1
        moonPassed = HEIGHT+1
        if len(rockY) != 0:
            rockPassed = rockY[-1]
        if len(cometY) != 0:
            cometPassed = cometY[-1]
        if len(moonY) != 0:
            moonPassed = moonY[-1]
        if rockPassed > HEIGHT and cometPassed > HEIGHT and moonPassed > HEIGHT:
            numRock, rockX, rockY, numComet, cometX, cometY, numMoon, moonX, moonY, moonScale, numFuel, fuelX, fuelY = RiftObstacles.path()
            rockType = []
            rockAngle = []
            rockAngle2 = []
            rockRot = []
            fuelType = []
            fuelAngle = []
            fuelAngle2 = []
            fuelRot = []
            for i in range(numRock):
                rockType.append(random.choice(rocks))
                rockAngle.append(random.uniform(-0.2,0.2))
                rockAngle2.append(rockAngle[i])

            for i in range(numFuel):
                fuelType.append(random.choice(fuel))
                fuelAngle.append(random.uniform(-0.2,0.2))
                fuelAngle2.append(fuelAngle[i])

            warningWidth = []
            for i in range(numComet):
                warningWidth.append(10)

        #Shows that collision between the ship works with obstacles
        if crash:
            #print('crash')
            crash = False

        pygame.display.update()
        clock.tick(FPS)

distance = 0
active = True
while active:
    rift()

pygame.quit()

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题