Как сделать так, чтобы пули выглядели так, как будто они выходят из пистолета? - PullRequest
8 голосов
/ 26 мая 2020

enter image description hereenter image description hereI am having an issue where my bullets dont look like they are coming out of my gun they look like they are coming out of the players body ВИДЕО как вы можете видеть на видео, он стреляет где-то в другом месте, или это пистолет, то же самое для левой стороны, он хорошо стреляет, поднимаясь вверх, но стреляет плохо, когда падает ВИДЕО

enter image description here

I tried angeling my gun to 120 but what happens is everything good works for the right side not for the left side ВИДЕО как вы видите, это просто сбои

мой класс снаряда

class projectile(object):
   def __init__(self, x, y, dirx, diry, color):
       self.x = x
       self.y = y
       self.dirx = dirx
       self.diry = diry
       self.slash = pygame.image.load("round.png")
       self.slash = pygame.transform.scale(self.slash,(self.slash.get_width()//2,self.slash.get_height()//2))
       self.rect  = self.slash.get_rect()
       self.rect.topleft = ( self.x, self.y )
       self.speed = 18
       self.color = color
       self.hitbox = (self.x + -18, self.y, 46,60)



как мой снаряды добавляют


        if event.type == pygame.MOUSEBUTTONDOWN:           
                    
                    # this is for the bullets
            if len(bullets) < 3:
                if box1.health > 25:
                    mousex, mousey = pygame.mouse.get_pos()

                    playerman.isJump = True
                    start_x, start_y = playerman.x - 30, playerman.y  - 65
                    mouse_x, mouse_y = event.pos

                    dir_x, dir_y = mouse_x - start_x, mouse_y - start_y
                    distance = math.sqrt(dir_x**2 + dir_y**2)
                    if distance > 0:
                        new_bullet = projectile(start_x, start_y, dir_x/distance, dir_y/distance, (0,0,0))
                        bullets.append(new_bullet)
                

                # this is displaying the bullets for the player            
    for bullet in bullets[:]:
        bullet.move()
        if bullet.x < 0 or bullet.x > 900 or bullet.y < 0 or bullet.y > 900:
            bullets.pop(bullets.index(bullet))


    def draw(self,drawX,drawY):
 
        self.rect.topleft =  (drawX,drawY)
 
            # the guns hitbox
 
            # rotatiing the gun
        dx = self.look_at_pos[0] - self.rect.centerx
        dy = self.look_at_pos[1] - self.rect.centery 
            
        angle = (190/math.pi) * math.atan2(-dy, dx)
      
        gun_size = self.image.get_size()
        pivot = (8, gun_size[1]//2)
            
 
        blitRotate(window, self.image, self.rect.center, pivot, angle)

        if((angle > 90 or angle < -90) and self.gunDirection != "left"):
            self.gunDirection = "left"
            self.image = pygame.transform.flip(self.image, False, True)
        if((angle < 90 and angle > -90) and self.gunDirection != "right"):
            self.gunDirection = "right"
            self.image = pygame.transform.flip(self.image, False, True)





мой полный класс оружия

 
class handgun():
    def __init__(self,x,y,height,width,color):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.color = color
        self.rect = pygame.Rect(x,y,height,width)
 
 
        # LOL THESE IS THE HAND
        self.shootsright = pygame.image.load("hands.png")
        self.image = self.shootsright
        self.rect  = self.image.get_rect(center = (self.x, self.y))
        self.look_at_pos = (self.x, self.y)
 
        self.isLookingAtPlayer = False
        self.look_at_pos = (x,y)
            
 
 
 
        self.hitbox = (self.x + -18, self.y, 46,60)

 
        self.gunDirection = "right"
    def draw(self,drawX,drawY):
 
        self.rect.topleft =  (drawX,drawY)
 
            # the guns hitbox
 
            # rotatiing the gun
        dx = self.look_at_pos[0] - self.rect.centerx
        dy = self.look_at_pos[1] - self.rect.centery 
            
        angle = (120/math.pi) * math.atan2(-dy, dx)
      
        gun_size = self.image.get_size()
        pivot = (8, gun_size[1]//2)
            
 
        blitRotate(window, self.image, self.rect.center, pivot, angle)

        if((angle > 90 or angle < -90) and self.gunDirection != "left"):
            self.gunDirection = "left"
            self.image = pygame.transform.flip(self.image, False, True)
        if((angle < 90 and angle > -90) and self.gunDirection != "right"):
            self.gunDirection = "right"
            self.image = pygame.transform.flip(self.image, False, True)




    def lookAt( self, coordinate ):
            
        self.look_at_pos = coordinate
 
 
 
white = (255,255,255)
handgun1 = handgun(300,300,10,10,white)




how my images are blitted





```def blitRotate(surf, image, pos, originPos, angle):
 
        # calcaulate the axis aligned bounding box of the rotated image
    w, h = image.get_size()
    sin_a, cos_a = math.sin(math.radians(angle)), math.cos(math.radians(angle)) 
    min_x, min_y = min([0, sin_a*h, cos_a*w, sin_a*h + cos_a*w]), max([0, sin_a*w, -cos_a*h, sin_a*w - cos_a*h])
 
        # calculate the translation of the pivot 
    pivot        = pygame.math.Vector2(originPos[0], -originPos[1])
    pivot_rotate = pivot.rotate(angle)
    pivot_move   = pivot_rotate - pivot
 
        # calculate the upper left origin of the rotated image
    origin = (pos[0] - originPos[0] + min_x - pivot_move[0], pos[1] - originPos[1] - min_y + pivot_move[1])
 
        # get a rotated image
    rotated_image = pygame.transform.rotate(image, angle)
 
        # rotate and blit the image
    surf.blit(rotated_image, origin)
 

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

мой полный код скрипт

1 Ответ

9 голосов
/ 09 августа 2020

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

Пример

Это довольно хороший пример поиска 2 точек, но обратите внимание, что остальные 2 точки являются зеркальными. (это можно исправить, но я не стал беспокоиться)

Адаптировано из - Как вы можете повернуть изображение вокруг центра поворота в Pygame

And From - Поворот точки относительно другой точки в градусах python

Онлайн-среда IDE - https://repl.it/@ikoursh / отслеживание

import pygame
import math
import time


def rotate(origin, point, angle):
    """
    Rotate a point counterclockwise by a given angle around a given origin.
    """
    angle = math.radians(angle)
    ox, oy = origin
    px, py = point

    qx = ox + math.cos(angle) * (px - ox) - math.sin(angle) * (py - oy)
    qy = oy + math.sin(angle) * (px - ox) + math.cos(angle) * (py - oy)
    return [qx, qy]


def blitRotate(surf, image, pos, originPos, angle):
    # calculate the axis aligned bounding box of the rotated image
    w, h = image.get_size()
    sin_a, cos_a = math.sin(math.radians(angle)), math.cos(math.radians(angle))
    min_x, min_y = min([0, sin_a * h, cos_a * w, sin_a * h + cos_a * w]), max(
        [0, sin_a * w, -cos_a * h, sin_a * w - cos_a * h])

    # calculate the translation of the pivot
    pivot = pygame.math.Vector2(originPos[0], -originPos[1])
    pivot_rotate = pivot.rotate(angle)
    pivot_move = pivot_rotate - pivot

    # calculate the upper left origin of the rotated image
    origin = (
        round(pos[0] - originPos[0] + min_x - pivot_move[0]), round(pos[1] - originPos[1] - min_y + pivot_move[1]))

    box_rel = [[0, 0], [w, 0], [w, -h], [0, -h]]
    box_n_rotate = [rotate(originPos, p, -angle) for p in box_rel]  # crete a box with negative rotation
    for i in range(len(box_n_rotate)):
        box_n_rotate[i][0] += pos[0] - originPos[0]
        box_n_rotate[i][1] += pos[1] - originPos[1]

    for c in box_n_rotate[:2]:
        pygame.draw.circle(screen, (0, 255, 0), [round(c[i]) for i in range(len(c))], 5)

    # get a rotated image
    rotated_image = pygame.transform.rotate(image, angle)

    # rotate and blit the image
    surf.blit(rotated_image, origin)


pygame.init()
size = (400, 400)
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()

image = pygame.image.load('boomerang64.png')
pivot = (48, 21)

angle, frame = 0, 0
done = False
while not done:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
    screen.fill(0)

    pos = (200 + math.cos(frame * 0.05) * 100, 200 + math.sin(frame * 0.05) * 50)
    blitRotate(screen, image, pos, pivot, angle)

    pygame.draw.line(screen, (0, 255, 0), (pos[0] - 20, pos[1]), (pos[0] + 20, pos[1]), 3)
    pygame.draw.line(screen, (0, 255, 0), (pos[0], pos[1] - 20), (pos[0], pos[1] + 20), 3)
    pygame.display.flip()
    frame += 1
    angle += 1
    # time.sleep(0.2)

pygame.quit()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...