Pygame多子弹问题

2024-04-16 10:25:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我是pygame场景的新手,正在尝试创建我的第一个pygame项目。这是一个二维平台侧滚动,我有我的子弹对象多个问题。你知道吗

  1. 子弹只能朝一个方向移动
  2. 当玩家移动时屏幕会滚动,子弹会离开屏幕,尽管有移除功能,但子弹会在2/3分钟后重新出现在屏幕上(按方向射击)。你知道吗
  3. 子弹的移动与玩家的移动相关联,这样当玩家向后移动时,所有的子弹物体也会向后移动相同的量,给人一种他们已经停止的错觉。 作为一个新手,我真的不知道如何着手解决这些问题。如有任何建议,我们将不胜感激。你知道吗

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)

Tags: eventgetiftimedisplaypygameoffsetjump
1条回答
网友
1楼 · 发布于 2024-04-16 10:25:43
  1. The screen scrolls as the player moves, and bullets go off the screen and despite having a remove feature, the bullets reappear on the screen (in direction shot) 2/3 minutes later.

这是由整数溢出引起的。在项目符号离开左侧屏幕之后,项目符号永远不会从列表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)
  1. The bullet movement is linked to the player movement such that when the player moves back, all bullet objects also move back by the same amount, giving the illusion that they have stopped. Being recently new I am not really sure how to go about fixing these issues. Any suggestions will be greatly appreciated.

移动项目符号时必须补偿滚动量。注意每帧中的滚动距离,并将数量添加到项目符号位置:

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

但是请注意,播放器的速度,因此滚动和子弹的速度是相等的。如果玩家向前移动,子弹就会静止不动,因为子弹和玩家以相同的速度向前移动。你知道吗

相关问题 更多 >