【问题标题】:Pygame Game Development shoot functionalityPygame 游戏开发拍摄功能
【发布时间】:2019-05-06 18:51:27
【问题描述】:

我的问题是如何在我的游戏中提高我的射击功能。我正在尝试使其到达玩家可以朝其移动方向射击的位置(例如向上、向下、向左、向右)以及在移动时射击和在空闲时射击。

玩家和导弹都是使用 pygame 形状的矩形,以便我更容易理解游戏开发背后的逻辑。

def player(px,py):
    pygame.draw.rect(gameWindow,black,[px,py,30,30])

def missile(mx,my):
    pygame.draw.rect(gameWindow,black,[mx,my,10,10])

这里是游戏代码,有助于更好地理解我在说什么。我注释掉的小部分是我尝试过的。我目前只将它设置为从其初始起点向左移动的 x 方向。

import pygame #####IMPORTING PYGAME MODULE###########################

pygame.init() #####INITIALIZING PYGAME##################################

gameWindow = pygame.display.set_mode((800,600)) ###Screen Width and Height###

clock = pygame.time.Clock() ## FRAMES PER SECOND ##

white = (255,255,255)
black = (0,0,0)
red = (255,0,0) 


def player(px,py):
    pygame.draw.rect(gameWindow,black,[px,py,30,30])

def missile(mx,my):
    pygame.draw.rect(gameWindow,black,[mx,my,10,10])

def enemies():
    return


def gameloop():
    px = 700
    py = 300

    mx = 700
    my = 300

    px_change = 0
    py_change = 0

    mx_change = 0
    my_change = 0

    gameExit = False

    while not gameExit:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    mx_change = -10
                if event.key == pygame.K_RIGHT:
                    mx_change = 10
                if event.key == pygame.K_UP:
                    my_change = -10
                if event.key == pygame.K_DOWN:
                    my_change = 10

                if event.key == pygame.K_SPACE: 
                    mx_change = -6
                #if event.key == pygame.K_SPACE and pygame.K_RIGHT:
                    #mx_change = 6


                if event.key == pygame.K_LEFT:
                    px_change = -10
                if event.key == pygame.K_RIGHT:
                    px_change = 10
                if event.key == pygame.K_UP:
                    py_change = -10
                if event.key == pygame.K_DOWN:
                    py_change = 10

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                    px_change = 0
                if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                    py_change = 0

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                    mx_change = 0
                    mx = px
                if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                    my_change = 0
                    my = py
                if event.key == pygame.K_SPACE:
                    mx_change = 0
                    my_change = 0
                    mx = px
                    my = py


        px += px_change
        py += py_change

        mx += mx_change
        my += my_change

        gameWindow.fill(white)

        player(px,py)
        missile(mx,my)
        pygame.display.update()

        clock.tick(100)

    pygame.quit()
    quit()
gameloop()

【问题讨论】:

  • 我不知道你为什么用按键来改变导弹的位置。它应该自行改变位置 - 始终沿选定方向移动。
  • 您可以使用pygame.Rect() 来保持玩家和导弹的位置和大小。 Rect() 可用于draw(..., missille_rect)blit(..., missille_rect) 并具有检查碰撞的功能player_rect.colliderect(missille_rect)
  • 添加了整个代码以便更好地理解问题。
  • 当你按下空格键时,你应该创建导弹并设置它的方向,而不是用其他键改变它。并且不要在 KEYUP SPACE 时重置它。您应该在一段时间或几帧后杀死/删除/重置它,这样它就不会取决于玩家的位置。
  • 我认为你应该阅读一些关于真正基本游戏架构的文章/tuts。从我的角度来看,您的代码毫无意义。

标签: python pygame


【解决方案1】:

我建议为您的播放器和导弹使用不同的对象。按照您现在的设置方式,只能有 1 个玩家和 1 个导弹。只有 1 名玩家可能很好,但 1 枚导弹会使游戏变得乏味。我建议使用一个类,比如这个简单的例子:

class Projectile():
    def init(self,x,y,vx,vy):
        self.x = x
        self.y = y
        self.vx = vx
        self.vy = vy
    def update(self): 
        self.x += self.vx
        self.y += self.vy

现在您有了课程,您可以开始做伟大的事情了!想让空格键发射一枚新导弹而不是在屏幕上移动一枚导弹? ezpz!您所需要的只是一个要跟踪的导弹对象列表,例如my_missile_list

if event.key == pygame.K_SPACE: 
      my_missile_list.append(Projectile(px,py,missile_x_velocity,missile_y_velocity))

这会根据输入的位置和速度创建 Projectile 类的全新实例。

最后,我们需要让所有这些导弹移动!这就是类定义使我们的生活更轻松的地方!每帧一次,我们只需要更新子弹:

for b in my_missile_list: 
    b.update()

在这里使用类还有更多好处,但这是一个开始。如果您通读本文并进行一些更改,您的游戏将更像您正在寻找的那样运行。

【讨论】:

  • 感谢胡格的帮助。我需要阅读更多关于类的内容,以更好地了解它们在游戏开发中的用途。有什么建议吗?
  • 我不知道特定于游戏开发的资源,但是关于 Python 类的官方文档在这里:docs.python.org/3/tutorial/classes.html 除此之外,我建议练习,一旦你掌握了使用它们的类的窍门,成为第二天性。任何时候您想要某个对象(射弹、墙壁、敌人)的多个副本时,一个类将是保存这些对象所需的所有信息的好方法。
【解决方案2】:

你应该只在你KEYDOWN空格时设置missille,而不是用其他键来改变它。玩家可能有变量direction,所以当它停留时你会知道它在看哪个方向,并且你会知道向哪个方向移动导弹。

import pygame

# --- constants --- (UPPER_CASE_NAMES)

WHITE = (255,255,255)
BLACK = (0,0,0)
RED   = (255,0,0) 

# --- classes --- (CamelCaseNames)

# empty

# --- functions ---- (lower_case_names_

def player(screen, x, y):
    pygame.draw.rect(screen, BLACK, (x, y, 30, 30))

def missile(screen, x, y):
    pygame.draw.rect(screen, RED, (x, y, 10, 10))

def enemies():
    pass

def gameloop(screen):
    px = 700
    py = 300

    mx = 700
    my = 300

    px_change = 0
    py_change = 0
    p_direction = 'left'

    mx_change = 0
    my_change = 0
    #m_direction = 'left'

    game_exit = False
    clock = pygame.time.Clock() ## FRAMES PER SECOND ##

    while not game_exit:

        # --- events ---

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_exit = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    px_change = -10
                    p_direction = 'left'
                if event.key == pygame.K_RIGHT:
                    px_change = 10
                    p_direction = 'right'
                if event.key == pygame.K_UP:
                    py_change = -10
                    p_direction = 'top'
                if event.key == pygame.K_DOWN:
                    py_change = 10
                    p_direction = 'down'

                if event.key == pygame.K_SPACE:
                    mx = px
                    my = py
                    if p_direction == 'left':
                        mx_change = -16
                        my_change = 0
                    elif p_direction == 'right':
                        mx_change = 16
                        my_change = 0
                    elif p_direction == 'top':
                        mx_change = 0
                        my_change = -16
                    elif p_direction == 'down':
                        mx_change = 0
                        my_change = 16

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                    px_change = 0
                if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                    py_change = 0

        # --- changes/updates ---

        px += px_change
        py += py_change

        mx += mx_change
        my += my_change

        # --- draws ----

        screen.fill(WHITE)

        player(screen, px, py)
        missile(screen, mx, my)
        pygame.display.update()

        # --- FPS ---

        clock.tick(30)

# --- main ---

pygame.init()

screen = pygame.display.set_mode((800,600))

gameloop(screen)

pygame.quit()
#quit()

您应该使用pygame.Rect() 而不是px, pymx,my - 它可以用于draw()blit(),并且它具有检查冲突的方法。

【讨论】:

  • 不错,但如果你在射击前先移动,它不会跟随玩家。
  • 那么,为了让导弹继续朝某个方向发射并发射多枚导弹,我必须实现类?
  • 我不知道你想导弹跟随玩家。我认为它应该朝着自己的方向发展,这是你的问题。
  • 要拥有许多导弹,您必须将它们列在清单上。当每枚导弹都是类的实例或至少是带有参数的字典/列表时,这会更容易。 PyGame 有 pygame.sprite.Sprite 类,它具有有用的功能 - 您可以将所有精灵保留在 pygame.sprite.Group() 中并检查与其他组的碰撞并自动删除“被杀死”的项目。您还可以使用一个命令来绘制组中的所有项目。所有这些都使代码更短。
猜你喜欢
  • 1970-01-01
  • 2016-02-08
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多