2016-12-30 3 views
1

До сих пор я сравнивал массивы с одной переменной, например. позиция игрока:Как сравнить массивы (не точные совпадения)

for position in ships: 
    if player_location_x > position[0]-100 and player_location_x < position[0]+100 and player_location_y > position[1]-100 and player_location_y < position[1]+100: 
     #Do something (e.g. draw bullets between the two locations) 

Как бы это расширить, чтобы сравнить значения самих массивов, например. сравнивая значения x и y «кораблей», чтобы проверить их расстояние друг к другу, а также сравнивая значения x и y между «судами» и «more_ships»?

ships = numpy.array([ 
           [ 
            shuttle_class.npc_x[0], 
            shuttle_class.npc_y[0], 
            shuttle_class.img,  
            shuttle_class.hp 
           ], 

           [ 
            shuttle_class.npc_x[1], 
            shuttle_class.npc_y[1], 
            shuttle_class.img,  
            shuttle_class.hp 
           ], 

           [ 
            shuttle_class.npc_x[2], 
            shuttle_class.npc_y[2], 
            shuttle_class.img,  
            shuttle_class.hp 
           ] 
        ]) 

more_ships = numpy.array([ 
           [ 
            shuttle_class.npc_x[3], 
            shuttle_class.npc_y[3], 
            shuttle_class.img,  
            shuttle_class.hp 
           ], 

           [ 
            shuttle_class.npc_x[4], 
            shuttle_class.npc_y[4], 
            shuttle_class.img,  
            shuttle_class.hp 
           ], 

           [ 
            shuttle_class.npc_x[5], 
            shuttle_class.npc_y[5], 
            shuttle_class.img,  
            shuttle_class.hp 
           ] 
         ]) 
+0

Одним из улучшений, которые вы можете сделать, является использование квадрантов, так что каждый раз, когда что-то движется, вы пересчитываете свою позицию, что довольно дешево, а затем, чтобы проверить расстояние, вам нужно только проверить объекты, которые находятся в той же секции сетки как вы. Может быть, лучше с numpy, но по тому, как вы это делали в данный момент, я знаю, что делаю это до того, как это дает огромное увеличение скорости :) – Peter

+0

Правильно ли я понимаю ваш вопрос: у вас есть корабли (массивы x1, y1) и more_ships (массивы x2, y2), и для каждой возможной комбинации вы хотите попарно «x1-x2» и «y1-y2»? – VBB

+0

@VBB Да, это правильно – pytheron

ответ

1

Начнем с двух массивов x1, y1 для судов. Вы хотите создать каждое попарное расстояние с x2, y2. Скажем, ради обсуждения, что у вас есть 5 кораблей и еще 3 корабля. Поэтому мы используем Numpy meshgrid:

xx1, xx2 = np.meshgrid(x1, x2) # both these are 3x5 arrays 
yy1, yy2 = np.meshgrid(y1, y2) 
dx = xx1 - xx2 # np.abs(xx1 - xx2) if you want just absolute values 
dy = yy1 - yy2 

Теперь вы можете использовать np.where, чтобы получить окончательный список:

sel = np.where((dx <= d_max) & (dy <= d_max)) 

Сель является 2xn массив. Значения представляют собой индексы точек n, удовлетворяющих условию.


EDIT: добавление образец кода в соответствии с просьбой ОП.

import matplotlib.pyplot as plt 
import numpy as np 

sx = np.array([0, 250, 500]) 
sy = np.array([100, 100, 100]) 
mx = np.array([1000, 0]) 
my = np.array([0,0]) 
plt.scatter(sx, sy) 
plt.scatter(mx, my, c='r', marker='o') 
plt.grid() 

У нас есть три корабля (s), и два more_ships (m).

xx1, xx2 = np.meshgrid(sx, mx) 
yy1, yy2 = np.meshgrid(sy, my) 

Рассмотрим это немного: np.shape(xx1) является (2,3). Первый индекс относится к m (больше судов), а второй относится к s.

dx = np.abs(xx1 - xx2) 
dy = np.abs(yy1 - yy2) 
d_max = 200.0 
sel = np.where((dx <= d_max) & (dy <= d_max)) 
print sel 

Вы увидите, что у sel есть два массива. Первый массив относится к индексам для первой оси (m), а второй относится к (s). В этом случае массивы имеют значения 1 и 0, что означает, что more_ships[1] находится в пределах 200 пикселей от ships[0].

Если изменить sx к np.array([0, 250, 1000]) тогда sel будет array([0, 1]), array([2, 0]) - что означает more_ships[0] находится в 200 пикселей ships[2] и more_ships[1] рядом ships[0].

+0

Большое спасибо за ваш ответ. Извините, но я попытался реализовать это, и я не могу окунуться в то, что вы здесь написали, - сможете ли вы продемонстрировать пример, используя метод pygame.draw.line, чтобы нарисовать линию между любыми два корабля с расстоянием 200 пикселей? – pytheron

+0

200 пикселей или меньше как по оси x, так и по оси y * – pytheron

Смежные вопросы