我有一艘射击激光的船。它从自身绘制一条线(mouseX,mouseY)。我怎样才能让船在完全相反的方向上加速,好像被推倒一样?
我一直在研究一些触发器和比率但是没有取得多大进展。加速度是恒定的,所以鼠标的距离无关紧要,只是方向。
我一直在尝试创建一个仅适用于范围(-4,4)中整数的向量,因为我无法让船以浮动速度在屏幕上移动,并且(-4) ,4)范围至少会给我...船舶移动的16个不同方向,但我希望这不是一个限制。
答案 0 :(得分:2)
没有涉及三角学,只有矢量。如果你从船的位置减去鼠标的位置
(shipX-mouseX, shipY-mouseY)
为您提供移动船舶的方向。将它乘以某个因子,将其四舍五入为整数,并将其添加到船舶的当前位置。您可能想要这样做几次,以提供一些连续的动作。此外,您可能希望因子变化:增加前几个刻度,然后减少到零。
答案 1 :(得分:0)
加速度矢量将是从鼠标光标到船的方向,远离鼠标位置 - 所以如果从鼠标到船的线是从角度θ到水平(逆时针θ是+ ve,顺时针是-ve),作用在船上的力F也会加速它。如果船具有质量M然后使用f = ma,则加速度A将是F / M. x轴的加速度为A * cos(theta),在y A * sin(theta)中 - 然后在每个时间间隔后使用v = u + at进行模拟。您将不得不使用浮点数学进行此计算。
答案 2 :(得分:0)
这是一个使用简单向量数学的完整示例。请注意评论。
import pygame
import math
# some simple vector helper functions, stolen from http://stackoverflow.com/a/4114962/142637
def magnitude(v):
return math.sqrt(sum(v[i]*v[i] for i in range(len(v))))
def add(u, v):
return [ u[i]+v[i] for i in range(len(u)) ]
def sub(u, v):
return [ u[i]-v[i] for i in range(len(u)) ]
def dot(u, v):
return sum(u[i]*v[i] for i in range(len(u)))
def normalize(v):
vmag = magnitude(v)
return [ v[i]/vmag for i in range(len(v)) ]
class Ship(object):
def __init__(self):
self.x, self.y = (0, 0)
self.set_target((0, 0))
self.org_speed = 0.9
self.speed = self.org_speed
self.laser = (None, 0)
@property
def pos(self):
return self.x, self.y
# for drawing, we need the position as tuple of ints
# so lets create a helper property
@property
def int_pos(self):
return map(int, self.pos)
@property
def target(self):
return self.t_x, self.t_y
@property
def int_target(self):
return map(int, self.target)
def set_target(self, pos):
self.t_x, self.t_y = pos
def update(self):
if self.speed < self.org_speed:
self.speed += min(self.org_speed, 0.3)
# if we won't move, don't calculate new vectors
if self.int_pos == self.int_target:
return
target_vector = sub(self.target, self.pos)
# a threshold to stop moving if the distance is to small.
# it prevents a 'flickering' between two points
if magnitude(target_vector) < 2:
return
# apply the ship's speed to the vector
move_vector = [c * self.speed for c in normalize(target_vector)]
# update position
self.x, self.y = add(self.pos, move_vector)
def draw(self, s):
pygame.draw.circle(s, (255, 0 ,0), self.int_pos, 5)
end, state = self.laser
if state > 0:
pygame.draw.line(s, (255, 255, 0 if state % 2 else 255), self.pos, end, 2)
self.laser = end, state - 1
def fire(self, pos):
self.speed = -min(5, magnitude(sub(pos, self.pos)) / 10.0)
self.laser = pos, 5
pygame.init()
quit = False
s = pygame.display.set_mode((300, 300))
c = pygame.time.Clock()
ship = Ship()
FIRE = pygame.USEREVENT
pygame.time.set_timer(FIRE, 2000)
while not quit:
quit = pygame.event.get(pygame.QUIT)
if pygame.event.get(FIRE):
ship.fire(pygame.mouse.get_pos())
ship.set_target(pygame.mouse.get_pos())
pygame.event.poll()
ship.update()
s.fill((0, 0, 0))
ship.draw(s)
pygame.display.flip()
c.tick(60)