xyyzzjw 发表于 2023-5-21 23:38:56

雷霆战机中发射子弹y坐标定位错误

本帖最后由 xyyzzjw 于 2023-5-21 23:45 编辑

问题是    雷霆战机中发射子弹时    子弹x坐标能跟随飞机变化,而y坐标总是在屏幕的上方,不会随飞机位置变化而变化(定位错误)

"雷霆战机" # 新功能 :发射子弹
import pygame
import random
import copy
from pygame.locals import *
import time

#地图
class GameBackground:
    image1=None
    image2=None
    main_scene=None
    y1=None
    y2=None

    #初始化地图
    def __init__(self,scene):
      #加载图片
      self.image1=pygame.image.load("./images/bg.png")
      self.image2=copy.copy(self.image1)
      self.main_scene=scene
      self.main_scene_h=self.main_scene.get_height()

      self.y1=0
      self.y2=-self.main_scene_h    # self.y2=-self.main_scene.get_size

    #计算要绘制地图图片的坐标
    def action(self):
      self.y1=self.y1+1
      self.y2+=1
      if self.y1>=self.main_scene_h:
            self.y1=0
      if self.y2>=0:
            self.y2=-self.main_scene_h

    #绘制地图的两张图片
    def draw(self):
      self.main_scene.blit(self.image1,(0,self.y1))
      self.main_scene.blit(self.image2,(0,self.y2))

#子弹
class Bullet:
    speed=10
    x=None
    y=None
    width=None
    height=None

    def __init__(self,x,y,w,h):
      self.x=x
      self.y=y
      self.width=w
      self.height=h

    def move(self):
      self.y=-self.speed
#飞机
class Plane:
    x=None
    y=None
    images=[]
    main_scene=None
    speed=8
    style=0
    width=None
    height=None

    shoot_frequency=0
    bullet_image=None
    bullets=[]

    def __init__(self,scene):
      #加载飞机三种飞行状态的图片
      self.images.append(pygame.image.load("./images/plane1.jpg"))
      self.images.append(pygame.image.load("./images/plane2.jpg"))
      self.images.append(pygame.image.load("./images/plane3.jpg"))
      self.main_scene=scene
      self.rect=self.main_scene.get_rect()
      #飞机的初始坐标
      self.x=self.rect//2-self.images.get_width()//2
      self.y=600
      self.width=self.images.get_width()
      self.height=self.images.get_height()
      #加载飞机子弹图片
      self.bullet_image=pygame.image.load("./images/bullet.jpg").convert()
      self.bullet_rect=self.bullet_image.get_rect()

    #发射子弹
    def shoot(self):
      if self.shoot_frequency%15==0:
            bullet_x=self.x+self.images.get_width()//2-self.bullet_image.get_width()//2
            bullet_y=self.y-self.bullet_rect.height+10#bullet_y=self.y-self.bullet_image.get_height()+10
            b_w=self.bullet_image.get_width()
            b_h=self.bullet_image.get_height()
            self.bullets.append(Bullet(bullet_x,bullet_y,b_w,b_h))
      self.shoot_frequency+=1
      if self.shoot_frequency>15:
            self.shoot_frequency=0

    #绘制子弹
    def drawBullet(self):
      for b in self.bullets:
            b.move()
            self.main_scene.blit(self.bullet_image,(b.x,b.y))
            if b.y<0:
                self.bullets.remove(b)
    #向上
    def moveUp(self):
      if self.y>0:
            self.y-=self.speed

    #向下
    def moveDown(self):
      if self.y+self.images.get_height()<self.rect:
            self.y+=self.speed

    #向左
    def moveLeft(self):
      if self.x>0:
            self.x-=self.speed

    #向右
    def moveRight(self):
      if self.x+self.images.get_width()<self.rect:
            self.x+=self.speed

    #绘制飞机
    def draw(self):
      self.main_scene.blit(self.images,(self.x,self.y))
#主场景
class MainScene:








    def __init__(self):
      self.sft=60
      self.running = True
      self.clock=pygame.time.Clock()
      self.size=(398,651)
      self.scene=pygame.display.set_mode((self.size,self.size))
      pygame.display.set_caption("雷霆战机")
      self.map=GameBackground(self.scene)
      #创建飞机对象
      self.plane=Plane(self.scene)



    #绘制
    def draw_elements(self):
      self.map.draw()#绘制背景
      self.plane.draw()#绘制飞机
      self.plane.drawBullet()#绘制飞机子弹

    #计算元素坐标和生成元素
    def action_elements(self):
      self.map.action()

    #处理事件
    def handle_event(self):
      for event in pygame.event.get():
            #检测键盘事件
            if event.type==pygame.KEYUP:
                #检测松开的按键方向
                if event.key==K_LEFT or event.key==K_RIGHT:
                  self.plane.style=0
            if event.type==pygame.QUIT:
                self.running=False

    #碰撞检测
    def detect_conlision(self):
      pass


    #按键处理
    def key_pressed(self):
      #获取按下按键信息
      key_pressed=pygame.key.get_pressed()

      if key_pressed:
            self.plane.moveUp()
      if key_pressed:
            self.plane.moveDown()
      if key_pressed:
            self.plane.style=1
            self.plane.moveLeft()
      if key_pressed:
            self.plane.style=2
            self.plane.moveRight()

      if key_pressed:
            self.plane.shoot()


    #主循环,主要处理各种事件
    def run_scene(self):

      while self.running:
            self.clock.tick(self.sft)
            self.action_elements()
            self.draw_elements()
            self.handle_event()
            self.detect_conlision()
            self.key_pressed()
            pygame.display.update()
#创建主场景
mainScene=MainScene()

#开始游戏
mainScene.run_scene()


isdkz 发表于 2023-5-21 23:44:26

看起来你的子弹移动代码存在一些问题,特别是在Bullet类的move方法中。你的move方法将子弹的y坐标减去了速度,但这会使子弹向屏幕上方移动。根据你的代码,这应该是正确的行为(子弹从飞机处发射,向上移动)。

然而,你在move方法中使用了负号,这将导致子弹向屏幕的下方移动,这可能不是你预期的行为。我将改正这个问题。在此之外,我还会在子弹类中加入一个屏幕边界检查,以防止子弹飞出屏幕。

你应该将Bullet类的move方法改成以下这样:

def move(self):
    self.y -= self.speed# 减去速度,使子弹向上移动


还有,你需要注意在飞机类Plane中的drawBullet方法。在此方法中,你应该检查每个子弹是否已经飞出屏幕。如果子弹已经飞出屏幕,那么应该从子弹列表中移除。你可以通过比较子弹的y坐标和0来完成此操作。

我将drawBullet方法改为以下这样:

def drawBullet(self):
    for b in self.bullets:
      b.move()
      self.main_scene.blit(self.bullet_image, (b.x, b.y))
      if b.y + b.height < 0:# 如果子弹已经飞出屏幕,则移除
            self.bullets.remove(b)


现在,你的子弹应该能正确向上飞行,并且当它们飞出屏幕时,会被正确移除。

歌者文明清理员 发表于 2023-5-21 23:48:28

子弹y坐标定位错误,应该将Bullet类中move()方法中的
self.y=-self.speed
改为
self.y-=self.speed
这样每次移动时y坐标会减小而不是直接变为负数,就能够跟随飞机位置变化了。

xyyzzjw 发表于 2023-5-21 23:54:11

谢谢各位大姥的解答。你们的帮助问题已解决了。花了一个晚上找不出问题。
页: [1]
查看完整版本: 雷霆战机中发射子弹y坐标定位错误