Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何让对象以恒定速度直接从鼠标上跑开_Python_Vector_Pygame_Trigonometry - Fatal编程技术网

Python 如何让对象以恒定速度直接从鼠标上跑开

Python 如何让对象以恒定速度直接从鼠标上跑开,python,vector,pygame,trigonometry,Python,Vector,Pygame,Trigonometry,我有一艘发射激光的船。它从自身到(mouseX,mouseY)绘制一条线。我怎么能让船在完全相反的方向加速,就像被向后推一样 我一直在研究一些trig和ratio,但进展不大。加速度是恒定的,所以鼠标的距离无关紧要,只是方向 我主要致力于创建一个只适用于(-4,4)范围内整数的向量,因为我不能让飞船以浮动速度在屏幕上移动,(-4,4)范围至少会给我。。。飞船移动的16个不同方向,尽管我不希望这成为一个限制。加速度向量将在从鼠标光标到飞船的方向上,远离鼠标位置-因此,如果鼠标到飞船的直线与水平线成

我有一艘发射激光的船。它从自身到(mouseX,mouseY)绘制一条线。我怎么能让船在完全相反的方向加速,就像被向后推一样

我一直在研究一些trig和ratio,但进展不大。加速度是恒定的,所以鼠标的距离无关紧要,只是方向


我主要致力于创建一个只适用于(-4,4)范围内整数的向量,因为我不能让飞船以浮动速度在屏幕上移动,(-4,4)范围至少会给我。。。飞船移动的16个不同方向,尽管我不希望这成为一个限制。

加速度向量将在从鼠标光标到飞船的方向上,远离鼠标位置-因此,如果鼠标到飞船的直线与水平线成角度θ(逆时针θ为+ve,顺时针为-ve),作用在船上使其加速的力F也是如此。如果船的质量为M,则使用f=ma,加速度A将为f/M。x轴上的加速度为A*cos(θ),y轴上的加速度为A*sin(θ)-然后在每个时间间隔后使用v=u+,用于模拟。您必须使用浮点数学进行此计算。

不涉及三角函数,只涉及向量。如果你用鼠标从船的位置减去鼠标的位置

(shipX-mouseX, shipY-mouseY)

这给了你移动飞船的方向。将其乘以某个因子,四舍五入为整数,然后将其添加到船舶的当前位置。你可能想这样做几次,给一些连续的运动。此外,您可能希望该因子有所不同:增加前几个刻度,然后减小到零

下面是一个使用简单向量数学的完整示例。请注意这些评论

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)
导入pygame
输入数学
#一些简单的向量辅助函数,从http://stackoverflow.com/a/4114962/142637
def量级(v):
返回math.sqrt(范围(len(v))中i的和(v[i]*v[i]))
def添加(u,v):
返回[u[i]+v[i]表示范围内的i(len(u))]
def接头(u、v):
返回[u[i]-v[i]表示范围内的i(len(u))]
def点(u,v):
范围(len(u))内i的返回和(u[i]*v[i]
def正常化(v):
vmag=震级(v)
返回[v[i]/vmag(len(v))]
船舶类别(对象):
定义初始化(自):
self.x,self.y=(0,0)
self.set_目标((0,0))
self.org_速度=0.9
self.speed=self.org\u speed
self.laser=(无,0)
@财产
def位置(自身):
返回self.x,self.y
#对于绘图,我们需要位置作为int的元组
#因此,让我们创建一个helper属性
@财产
def int_位置(自身):
返回映射(内部、自身位置)
@财产
def目标(自我):
返回self.t_x,self.t_y
@财产
def int_目标(自身):
返回映射(int,self.target)
def设置_目标(自身、位置):
self.t_x,self.t_y=pos
def更新(自我):
如果self.speed0:
pygame.draw.line(255,255,如果状态为%2,则为0,否则为255),self.pos,end,2)
self.laser=结束,状态-1
def火灾(自身,位置):
自速度=-min(5,量级(子位置,自位置))/10.0
self.laser=pos,5
pygame.init()
退出=错误
s=pygame.display.set_模式((300300))
c=pygame.time.Clock()
ship=ship()
FIRE=pygame.USEREVENT
pygame.time.set_定时器(FIRE,2000)
不退出时:
quit=pygame.event.get(pygame.quit)
如果pygame.event.get(火灾):
ship.fire(pygame.mouse.get_pos())
ship.set_目标(pygame.mouse.get_pos())
pygame.event.poll()
ship.update()
s、 填充((0,0,0))
船上绘图(s)
pygame.display.flip()
c、 勾选(60)

嗯。。。是的。。就这样。。我很难把我脑海中的点点滴滴联系起来,因为它太简单了,太令人困惑了。多谢。