我以前问过这个问题,有人告诉我,面罩需要一个位置才能正确检测碰撞。有了这个建议,我就能够修改代码,使其正常工作。然而,激光激活的第一帧将移除它不应该接触的小行星。我看了其他的问题,仍然感到困惑
# 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()
暂无答案!
目前还没有任何答案,快来回答吧!