2015-10-16 65 views
0

我有一艘可以拍攝激光的船。它從它自己畫出一行(mouseX,mouseY)。我怎麼才能讓船的反方向加速,好像被推倒了一樣?如何讓對象以恆定速度直接遠離鼠標運行

我一直在努力通過一些觸發和比率,但沒有取得很大進展。加速度是恆定的,所以鼠標到底有多遠並不重要,只是方向。

我一直主要致力於嘗試創建一個只能在範圍(-4,4)範圍內使用整數的向量,因爲我無法讓浮標以浮動速度在屏幕上移動,而( - 4,4)範圍至少會給我...船舶移動的16個不同方向,儘管我希望這不是一個限制。

回答

2

沒有涉及三角函數,只是矢量。如果你把減去鼠標的位置從船上

(shipX-mouseX, shipY-mouseY) 

,讓你在移動的船的方向的位置。將其乘以某個因子,將其舍入爲整數,然後將其添加到船的當前位置。你可能想要這樣做幾次,以提供一些連續的動作。此外,您可能希望因素有所不同:增加前幾個滴答,然後減少到零。

+0

嗯...是啊..完蛋了。我遇到了麻煩,在我的頭上連接點,它的這麼簡單的混亂。非常感謝。 – dyllandry

0

加速度矢量將從鼠標光標到船的方向,遠離鼠標位置 - 因此,如果從鼠標到船的線在角度θ與水平線之間(其中逆時針θ是+ ve,順時針是-ve),作用在船上的力F也會加速它。如果船的質量爲M,則使用f = ma,則加速度A爲F/M。 x軸的加速度爲A * cos(theta),y A * sin(theta) - 然後在每個時間間隔後使用v = u + at來進行模擬。你將不得不使用浮點數學來計算。

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) 

enter image description here

相關問題