从旋转枪
问题描述:
我的问题是连接到这个问题,发射子弹: 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
在正确的方向子弹的更新和芽但是从枪中心拍摄。如何将拍摄点移动到枪口?
答
下面是一个射击炮的例子。您只需将大炮的当前角度和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
答
我取得的成就,我需要以下几部件代码是一样的上面这是在代码解释一个很轻微的修改做。 @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
你是否将角度转换为弧度? –
我将度数转换为弧度,然后子弹以正确的方向射出,但仍然来自枪的相同位置。 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
请编辑您的文章并向我们展示一个我们可以运行的最小完整示例。 – skrx