我是pygame的新手,正在尝试创建我的第一个pygame项目。这是一个2D平台化侧面滚动器,而我的子弹对象存在多个问题。
import pygame
import math, random, sys, time
from pygame.locals import *
pygame.init()
jump = False
jump_offset = 0
jump_height = 250
k = pygame.key.get_pressed()
#Window Settings
w = 1280
h = 720
half_w = w /2
half_h = h /2
AREA = w*h
#Defining colours
BLACK = ( 0, 0, 0)
WHITE = ( 255, 255, 255)
#Initialising the window
display = pygame.display.set_mode((w,h))
pygame.display.set_caption("Platformer")
Clock = pygame.time.Clock()
FPS = 300
def events():
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
def do_jumping():
global jump_height
global jump
global jump_offset
if jump:
jump_offset += 3
if jump_offset >= jump_height:
jump = False
elif jump_offset > 0 and jump == False:
jump_offset -= 3
bg = pygame.image.load("background.png").convert()
bgWidth, bgHeight = bg.get_rect().size
stageWidth = bgWidth*2
stagePosX = 0
startScrollPosX = half_w
circleRadius = 25
circlePosX = circleRadius
pPosX = circleRadius
pPosY = 602
pVelX = 0
playersprite = pygame.image.load("playerSprite.png").convert_alpha()
playersprite = pygame.transform.scale(playersprite, (130,130))
bullets = []
bulletSprite = pygame.image.load("Bullet1.png").convert_alpha()
bulletSprite = pygame.transform.scale(bulletSprite, (20,10))
#------------------------MAIN PROGRAM LOOP------------------------#
next_bullet_time = 0
bullet_delay = 300
while True:
current_time = pygame.time.get_ticks()
events()
do_jumping()
k = pygame.key.get_pressed()
if k[K_RIGHT]:
pVelX = 2
if k[K_LEFT]:
pVelX = -2
if k[K_UP] and jump == False and jump_offset == 0:
jump = True
if not k[K_RIGHT] and not k[K_LEFT]:
pVelX = 0
if k[K_SPACE]:
if current_time > next_bullet_time:
next_bullet_time = current_time + bullet_delay
bullets.append([circlePosX+30, pPosY-20 - jump_offset])
pPosX += pVelX
if pPosX > stageWidth - circleRadius-25: pPosX = stageWidth - circleRadius-25
if pPosX < circleRadius+55:pPosX = circleRadius+55
if pPosX < startScrollPosX: circlePosX = pPosX
elif pPosX > stageWidth - startScrollPosX: circlePosX = pPosX - stageWidth + w
else:
circlePosX = startScrollPosX
stagePosX += -pVelX
for b in range(len(bullets)):
bullets[b][0] += 2
for bullet in bullets[:]:
if bullet[0] < 0:
bullets.remove(bullet)
rel_x = stagePosX % bgWidth
display.blit(bg,(rel_x - bgWidth, 0))
if rel_x < w:
display.blit(bg, (rel_x, 0))
for bullet in bullets:
display.blit(bulletSprite, pygame.Rect(bullet[0], bullet[1], 0, 0,))
display.blit(playersprite, (int(circlePosX-80),pPosY-100 - jump_offset))
pygame.display.update()
Clock.tick(FPS)
display.fill(BLACK)
答案 0 :(得分:0)
- 屏幕随着玩家的移动而滚动,子弹离开屏幕,尽管具有删除功能,但子弹会在2/3分钟后重新出现在屏幕上(朝拍摄方向)。
这是由整数溢出引起的。项目符号离开屏幕左侧之后,项目符号将永远不会从列表bullets
中删除。项目符号的x坐标不断增加,直到溢出为止。因此,x坐标的值从可能的最高值切换到可能的最低值。这导致子弹稍后再次“出现”在屏幕右侧。
项目符号离开屏幕后,从列表bullets
中删除项目符号:
w = display.get_width()
for b in [b for b in bullets if b[0] < 0 or b[0] > w]:
bullets.remove(b)
- 子弹运动与玩家的运动相关联,因此当玩家向后移动时,所有子弹对象也向后移动相同的数量,从而产生了它们已经停止的错觉。作为最近的新手,我不确定如何解决这些问题。任何建议将不胜感激。
移动子弹时必须补偿滚动量。注意每一帧的滚动距离,并将其添加到项目符号位置:
pPosX += pVelX
scroll = 0
if pPosX > stageWidth - circleRadius-25: pPosX = stageWidth - circleRadius-25
if pPosX < circleRadius+55:pPosX = circleRadius+55
if pPosX < startScrollPosX: circlePosX = pPosX
elif pPosX > stageWidth - startScrollPosX: circlePosX = pPosX - stageWidth + w
else:
circlePosX = startScrollPosX
stagePosX += -pVelX
scroll = -pVelX
for b in range(len(bullets)):
bullets[b][0] += 2 + scroll
但是请注意,玩家的速度,因此滚动和子弹的速度都相等。这导致外观,如果玩家向前移动,则子弹停滞不前,因为子弹和玩家以相同的速度向前移动。