2017-01-07 9 views
-2

Я сделал простую 2D-игру, но когда герой стреляет, некоторые из пуль двигаются быстрее других, особенно пули, которые выходят из углов героя (форма героя - простая коробка).Как контролировать скорость пуль?

Вот как я написал код съемки (я написал эту строку, чтобы убедиться, что пули идут в правильном направлении). Я использую Python 3.5.2.

Запустите код и стремитесь случайным образом повсюду, и вы увидите, что некоторые из них быстрее.

import pygame 
from pygame.locals import* 
import os 
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (0,25) 
pygame.init() 
x=pygame.display.set_mode((1360,705)) 
clock = pygame.time.Clock() 
kx=[] 
ky=[] 
kx1=[] 
ky1=[] 
while True : 
    x.fill((0,0,0)) 
    for event in pygame.event.get(): 
       if event.type==QUIT : 
        pygame.quit() 
        quit() 
       if event.type== pygame.MOUSEBUTTONDOWN and event.button == 1: 
        xvx=pygame.mouse.get_pos() 
        xa=(int(xvx[0])) 
        ya=(int(xvx[1])) 
        wox=(xa-680) 
        woy=(ya-352) 
        ox=wox/70 
        oy=woy/70 
        while True : 
         if xa >= 700 or xa <=660 or ya>=372 or ya<=332 : 
           xa=xa-ox 
           ya=ya-oy 
         else : 
           break 
        pygame.draw.line(x,(255,150,100),(xa,ya),(680,352)) 
        kx.append(xa-1) 
        ky.append(ya-1) 
        kx1.append(680) 
        ky1.append(352) 
    for i in range (len(kx)): 
      wox=(kx[i]-kx1[i]) 
      woy=(ky[i]-ky1[i]) 
      ox=wox/20 
      oy=woy/20 
      kx[i]=kx[i]+ox 
      ky[i]=ky[i]+oy 
      kx1[i]=kx1[i]+ox 
      ky1[i]=ky1[i]+oy 
      pygame.draw.rect(x,(250,250,250),(kx[i],ky[i],2,2)) 
    pygame.display.update() 
    clock.tick(60) 
+2

Вы можете добавить некоторые значимые имена переменных, пожалуйста, как сейчас это трудно понять, что происходит –

+0

КСТАТИ: если у вас есть ' MOUSEBUTTONDOWN', тогда у вас есть позиция мыши в 'event.pos', и вам не нужно' pygame.mouse.get_pos() '. Оба дают позицию как целочисленные значения, поэтому вам не нужно использовать 'int()' - 'xa, ya = event.pos' – furas

ответ

4

Ваш текущий код, по-видимому, использует положение мыши, когда вы нажимаете его, чтобы определить скорость. Еще один щелчок приводит к более быстрому выстрелу. Но похоже, что вы хотите, чтобы положение мыши определяло направление выстрела, при этом все пуль получали такую ​​же скорость.

Это работа по нормализации вектора!

Вы можете преобразовать вектор положения, который вы вычисляете, вычитая позицию щелчка из положения символа в единичный вектор, разделив его на свою длину. Затем вы можете умножить единичный вектор на желаемую скорость.

попробовать что-то вроде этого:

if event.type== pygame.MOUSEBUTTONDOWN and event.button == 1: 
    xvx=pygame.mouse.get_pos() 
    click_x = int(xvx[0]) - 680 # get relative position of the click 
    click_y = int(xvx[1]) - 352 
    distance = math.sqrt(click_x**2 + click_y**2) 
    unit_x = click_x/distance   # make a unit vector 
    unit_y = click_y/distance 
    BULLET_SPEED = 20 # this constant could be defined elsewhere 
    velocity_x = unit_x * BULLET_SPEED  # make the velocity vector 
    velocity_y = unit_y * BULLET_SPEED 
    pygame.draw.line(x, (255, 150, 100), 
         (680, 352), (680+velocity_x, 352+velocity_y)) 
    kx.append(680 + velocity_x) 
    ky.append(352 + velocity_y) 
    kx1.append(680) 
    ky1.append(352) 

Я использовал более осмысленные имена переменных, поэтому мы надеемся, что код легче понять, чем оригинал с его чрезмерно скупых именами. Вы можете немного сократить количество операций, если хотите, объединив некоторые из последовательных операций в одну комбинированную операцию на одной строке (например, нет необходимости в том, чтобы переменные unit_x и unit_y существовали, вы могли перейти прямо к velocity_x и velocity_y путем умножения на скорость в то же время вы делите на distance).

Обратите внимание, что я оставил kx/ky и kx1/ky1 списки, как они были, но могли бы сделать больше смысла хранить компоненты скорости пули в kx1/ky1 вместо сохранения прежнего положения (так как вы все равно вычитаете позиции, чтобы получить скорость).

Вы также можете рассмотреть возможность создания класса Bullet для хранения позиции и скорости пули вместе в одном объекте, а не с несколькими параллельными списками.

+0

@OP pygame имеет [pygame.math.Vector2] (http://pygame.org/ docs/ref/math.html # pygame.math.Vector2), который имеет методы 'distance_to()' и 'normalize()' - поэтому позже вы можете писать код @Blckknght короче. – furas

0

@Blckknght проблема descibed, я только показать, как сделать это с pygame.math.Vector2

BTW: вместо 4 списков kx, ky, kx1, ky1 я использую один bullets и хранить всю информацию в виде списка [position, speed] где position и speedVector2, поэтому они сохраняются как float, а значения округлены до целого числа, только когда pygame рисует объекты.

position += speed 

или

position.x += speed.x 
position.y += speed.y 

Полный код:

#!/usr/bin/env python3 

import pygame 
import os 

# --- constants --- 

WIDTH = 1360 
HEIGHT = 705 

BLACK = (0, 0, 0) 
WHITE = (250, 250, 250) 

BULLET_SPEED = 5 

# --- classes --- 

#empty 

# --- functions --- 

#empty 

# --- main --- 

# - init - 

os.environ['SDL_VIDEO_WINDOW_POS'] = '0, 25' 

pygame.init() 

screen = pygame.display.set_mode((WIDTH, HEIGHT)) 

# - objects - 

bullets = [] 

# center of screen as Vector2 
#center = pygame.math.Vector2(WIDTH//2, HEIGHT//2) 
center = pygame.math.Vector2(screen.get_rect().center) 

# - mainloop - 

clock = pygame.time.Clock() 

while True: 
    screen.fill(BLACK) 

    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      pygame.quit() 
      quit() 

     if event.type== pygame.MOUSEBUTTONDOWN: 
      if event.button == 1: 

       # get vector from center to mouse position 
       vector = event.pos - center 
       # `center` is `Vector2` so `vector` will be `Vector2` too 
       #print(type(vector)) 

       # normalize 
       normal = vector.normalize() 

       # create speed vector 
       speed = normal * BULLET_SPEED 

       # move object (first move 5 times bigger then next moves) 
       pos = center + (speed * 5) 

       #pygame.draw.line(screen, (255,150,100), (pos.x, pos.y), (center.x, center.y)) 
       pygame.draw.line(screen, (255,150,100), pos, center) 

       # remeber position and speed as one object 
       bullets.append([pos, speed]) 

    # - draws - 

    for pos, speed in bullets: 
     # move 
     pos += speed 

     # draw 
     pygame.draw.rect(screen, WHITE, (pos.x, pos.y, 2, 2)) 

    pygame.display.update() 

    # - speed - 

    clock.tick(60) 

# - end - 
+0

спасибо, что это было очень полезно Я новичок в изучении python и программирования (началось всего несколько месяцев назад) , так что я не понял, что в коде есть что-то, что я могу читать, чтобы понять ваш код больше? как что-нибудь читать и понимать больше игровой математики? –

+0

У меня нет места для всей информации. Я многому научился из многих мест и книг много лет - я даже не помню эти места и книги. – furas

+0

В Интернете есть так много учебников, видеоурок и книг. то есть. см. [Программные аркадные игры с Python и Pygame] (http://programarcadegames.com/), или, возможно, [GameDev.net] (https://www.gamedev.net/) – furas

 Смежные вопросы

  • Нет связанных вопросов^_^