Я хочу сделать игру с Pygame. Но моя стрела не может стрелять из правильного положения - PullRequest
1 голос
/ 29 января 2020

Python версия: 3.8.1

Система: Windows7 -32bit

см. Название, я хочу создать игру, но я столкнулся с проблемой. Игроки не отображаются в правильной позиции. Независимо от того, как изменяется позиция игрока, стрелка всегда будет стрелять из одной позиции. Я не использовал группу, потому что я считаю, что этого недостаточно для создания игры. Пожалуйста, помогите мне!

Есть код:

steve_vs_monsters.py

import pygame
from settings import Settings
import key_event
from steve import Steve
from update_screen import screen_update
from arrow import Arrow

def run_game():
    """ """
    --snip--
    #
    steve = Steve(a_settings,screen)
    arrow = Arrow(a_settings,screen,steve)
    #
    arrows = []

    #
    while True: 
        #
        key_event.check_events(steve,arrow,arrows)
        #
        update_screen(a_settings,screen,steve,arrow,arrows)

run_game()

arrow.py

import pygame

class Arrow():
    """ """
    def __init__(self,a_settings,screen,steve):
        """ """
        --snip--
        #
        self.rect.centerx = steve.rect.centerx
        self.rect.bottom = steve.rect.top
        self.rect.left = steve.rect.right
        #
        self.center = float(self.rect.centerx)

    def draw_arrow(self,arrows):
        """ """
        for a_arrow in arrows:
            self.screen.blit(self.image,a_arrow[0:2])

    def update_rect(self,steve,arrows):  
        for a_arrow in arrows:
            a_arrow[0] += float(self.a_settings.arrow_speed)

            if a_arrow[0] > self.screen_rect.right:
                arrows.remove(a_arrow)

update_screen.py

import pygame

def update_screen(a_settings,screen,steve,arrow,arrows):
    """ """
    screen.fill(a_settings.bg_color)
    steve.update_rect()
    arrow.update_rect(steve,arrows)
    steve.draw_steve()  
    arrow.draw_arrow(arrows)
    #
    pygame.display.flip()

key_event.py

import sys
import pygame

def check_keydown_events(event,steve,arrow,arrows):
    """ """
    if event.key == pygame.K_t:
        sys.exit()
    --snip--
    elif event.key==pygame.K_SPACE and len(arrows)<=4:
        arrows.append([arrow.center,arrow.rect.bottom,arrow.rect.left])

--snip--

def check_events(steve,arrow,arrows):
    """ """
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event,steve,arrow,arrows)
        --snip--

1 Ответ

1 голос
/ 30 января 2020

Похоже, код изначально создает один arrow, который занимает позицию из прямоугольника steve. Этот arrow затем используется в качестве базовой позиции для создания новых стрелок при нажатии K_SPACE.

Я думаю, что текущий прямоугольник steve должен использоваться для создания новый экземпляр Arrow, а не существующий экземпляр.

Например:

def check_keydown_events(event,steve,arrow,arrows):
    """ """
    if event.key == pygame.K_t:
        sys.exit()
    --snip--
    elif event.key==pygame.K_SPACE and len(arrows)<=4:
        #arrows.append( [arrow.center, arrow.rect.bottom, arrow.rect.left] )
        arrows.append( [steve.center, steve.rect.top, steve.rect.right] )

Таким образом, новая стрелка всегда создается там, где steve располагается теперь , а не позиционировано изначально.

Мне не понятно, почему при создании этого первого Arrow меняется верх / низ и лево / право, но я изменил код для использования этого метода тоже.

Лично я бы изменил класс Arrow так, чтобы он принимал координаты x и y и скорость как простые параметры:

class Arrow():
    """ """
    def __init__( self, arrow_image, x_pos, y_pos, speed ):
        self.image = arrow_image
        self.rect  = arrow_image.get_rect()
        self.speed = speed
        self.rect.centerx = x_pos
        self.rect.centery = y_pos

    def update( self ):
        self.rect.centerx += self.speed

    @staticmethod
    def draw_arrow_set( screen, all_arrows ):
        for a in all_arrows:
            screen.blit( a.image, a.rect )

    @staticmethod
    def update_arrow_set( all_arrows, screen_rect ):  
        for a in all_arrows:
            a.update()
            if ( a.rect.centerx > screen_rect.right ):
                all_arrows.remove( a )          # doesn't this cause problems? 

Тогда это более гибкий:

if ( steve_facing_left ):
    # facing left
    x_start = steve.rect.x    # start on Steve's left side
    arrows.append( Arrow( left_arrow_image, x_start, steve.rect.centery, -1 ) )
else:     
    # facing right
    x_start = steve.rect.x + steve.rect.width   # start on Steve's right side
    arrows.append( Arrow( right_arrow_image, x_start, steve.rect.centery, 1 ) )

А потом:

arrows.append( Arrow( super_arrow_image, x_start, y_start, 3 ) )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...