2017-02-16 17 views
1

我的問題是連接到這個問題,發射子彈: rotating gun with restricted movement從旋轉槍

什麼計算你需要做的就是子彈從槍口射擊?下面

def gun_radar(self): 

    for p in self.gameobjects: 

     if "R" in p.name or "L" in p.name: 

      if abs(p.rect.centerx - self.hero.rect.centerx) < p.radar and abs(p.rect.centery - self.hero.rect.centery) < p.radar: # if hero within radar 

       p.vec_to_target = pygame.math.Vector2(self.hero.rect.center) - p.rect.center 
       p.direction = p.orig_direction.rotate(p.current_angle) 
       p.orientation = p.vec_to_target.dot(p.direction) 

       if p.orientation > 2: 
        p.current_angle += 1 
       elif p.orientation < -2: 
        p.current_angle -= 1 

       p.current_angle = p.clamp(p.current_angle, p.clamp_min, p.clamp_max) 

       p.gun_rotate(-p.current_angle) 

       self.blt_timer -= 1 #count down the timer. when zero calculate vector and add bullet to fired_blts 

       if self.blt_timer<= 0: 
        w, h = p.rect.center 
        angle_in_rad = p.current_angle * (math.pi)/180 
        w = w + math.cos(angle_in_rad) 
        h = h + math.sin(-angle_in_rad) 
        bullet = Bombullet(bulletimage, w, h) 


        bullet.xvel = bullet.speed * math.cos(angle_in_rad) 
        bullet.yvel = bullet.speed * math.sin(angle_in_rad) 

        bullet.rect.x += bullet.xvel 
        bullet.rect.y += bullet.yvel 

        self.fired_blts.add(bullet) 
        self.blt_timer = 100 

我的代碼時給出的英雄來它被激活的槍從槍中心子彈芽的圓形區域內。

我移動子彈與

def move(self): 

     self.rect.x += self.xvel 

     self.rect.y += self.yvel 
     print self.rect.x, self.rect.y, self.life 
     self.life -= 1 

在正確的方向子彈的更新和芽但是從槍中心拍攝。如何將拍攝點移動到槍口?

+0

你是否將角度轉換爲弧度? –

+0

我將度數轉換爲弧度,然後子彈以正確的方向射出,但仍然來自槍的相同位置。 rect.midright。修改後的代碼W = W + math.cos(angle_in_rad) H = H + math.sin(angle_in_rad) 子彈= Bombullet(bulletimage,W,H) bullet.xvel = bullet.speed * math.cos( angle_in_rad) bullet.yvel = bullet.speed * math.sin(angle_in_rad) – emorphus

+0

請編輯您的文章並向我們展示一個我們可以運行的最小完整示例。 – skrx

回答

1

下面是一個射擊炮的例子。您只需將大炮的當前角度和rect.center傳遞給新創建的子彈,然後在__init__方法中旋轉其圖像和速度矢量。

import math 
import pygame as pg 
from pygame.math import Vector2 


pg.init() 
screen = pg.display.set_mode((640, 480)) 
FONT = pg.font.Font(None, 24) 
BLACK = pg.Color('black') 
BG_COLOR = pg.Color('darkseagreen4') 


class Bullet(pg.sprite.Sprite): 

    def __init__(self, pos, angle): 
     super(Bullet, self).__init__() 
     self.image = pg.Surface((20, 11), pg.SRCALPHA) 
     pg.draw.rect(self.image, pg.Color('grey11'), [0, 0, 13, 11]) 
     pg.draw.polygon(
      self.image, pg.Color('grey11'), [(13, 0), (20, 5), (13, 10)]) 
     self.image = pg.transform.rotate(self.image, -angle) 
     self.rect = self.image.get_rect(center=pos) 
     # To apply an offset to the start position, 
     # create another vector and rotate it as well. 
     offset = Vector2(80, 0).rotate(angle) 
     # Use the offset to change the starting position. 
     self.pos = Vector2(pos) + offset 
     self.velocity = Vector2(5, 0) 
     self.velocity.rotate_ip(angle) 

    def update(self): 
     self.pos += self.velocity 
     self.rect.center = self.pos 


def main(): 
    clock = pg.time.Clock() 
    # The cannon image and rect. 
    surf = pg.Surface((40, 22), pg.SRCALPHA) 
    surf.fill(pg.Color('grey27')) 
    pg.draw.rect(surf, pg.Color('grey11'), [30, 6, 10, 10]) 
    orig_surf = surf 
    rect = surf.get_rect(center=(320, 240)) 
    angle = 0 # Angle of the cannon. 
    # Add bullets to this group. 
    bullet_group = pg.sprite.Group() 

    playing = True 
    while playing: 
     for event in pg.event.get(): 
      if event.type == pg.QUIT: 
       playing = False 
      if event.type == pg.MOUSEBUTTONDOWN: 
       if event.button == 1: # Left button fires bullet. 
        # Fire a bullet from cannon center with current angle. 
        bullet_group.add(Bullet(rect.center, angle)) 

     bullet_group.update() 
     # Find angle to target (mouse pos). 
     x, y = Vector2(pg.mouse.get_pos()) - rect.center 
     angle = math.degrees(math.atan2(y, x)) 
     # Rotate the cannon image. 
     surf = pg.transform.rotate(orig_surf, -angle) 
     rect = surf.get_rect(center=rect.center) 

     # Draw 
     screen.fill(BG_COLOR) 
     bullet_group.draw(screen) 
     screen.blit(surf, rect) 
     txt = FONT.render('angle {:.1f}'.format(angle), True, BLACK) 
     screen.blit(txt, (10, 10)) 
     pg.draw.line(
      screen, pg.Color(150, 60, 20), rect.center, pg.mouse.get_pos(), 2) 
     pg.display.update() 

     clock.tick(30) 

if __name__ == '__main__': 
    main() 
    pg.quit() 

您也可以使用math.cos和sin來計算偏移量。

run = math.cos(math.radians(angle)) * 80 
rise = math.sin(math.radians(angle)) * 80 
offset = run, rise 
+0

我已經編輯了答案,以演示如何用另一個矢量來抵消開始位置。 – skrx

+0

答案接受。 – emorphus

1

我取得的成就,我需要以下幾部件代碼是一樣的上面這是在代碼解釋一個很輕微的修改做。 @skrx答案和Nick A.的評論幫助我實現了這一點。

def gun_radar(self): 

    for p in self.gameobjects: 

     if "R" in p.name or "L" in p.name: 

      if abs(p.rect.centerx - self.hero.rect.centerx) < p.radar and abs(p.rect.centery - self.hero.rect.centery) < p.radar: # if hero within radar 

       p.vec_to_target = pygame.math.Vector2(self.hero.rect.center) - p.rect.center 
       p.direction = p.orig_direction.rotate(p.current_angle) 
       p.orientation = p.vec_to_target.dot(p.direction) 

       if p.orientation > 2: 
        p.current_angle += 1 
       elif p.orientation < -2: 
        p.current_angle -= 1 

       p.current_angle = p.clamp(p.current_angle, p.clamp_min, p.clamp_max) 

       p.gun_rotate(-p.current_angle) 

       p.timer -= 1 #count down the timer. when zero calculate vector and add bullet to fired_blts 

       if p.timer<= 0: 

        w, h = p.rect.center 

        # adjust for the distance fromm the gun center to the gun muzzle 

        w = w + math.cos(math.radians(p.current_angle)) * 28 
        h = h + math.sin(math.radians(p.current_angle)) * 28 
        bullet = Bombullet(bulletimage, w, h) # create the bullet 

        # calculate the velocity 

        bullet.xvel = bullet.speed * math.cos(math.radians(p.current_angle)) 
        bullet.yvel = bullet.speed * math.sin(math.radians(p.current_angle)) 

        self.fired_blts.add(bullet) 

        p.timer = 100