从一组对象中创建vector2形式? [英] Create a vector2 formation out of a group of objects?

查看:79
本文介绍了从一组对象中创建vector2形式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hey Codeproject,



我不确定如何说出问题,因为我不确定这究竟是什么。无论如何,为了快速达到目的,我有一个实体(玩家,船只,诸如此类)的列表,我发送到特定点使用:



 GoToTarget(实体实体,Ve​​ctor2位置)
{
Entity.GoToPosition(Vector2);
}





这种方法的问题在于它们最终会到达同一个地方并堆叠在每个顶部其他。现在我通常会说添加碰撞​​会解决这个问题,但它看起来并不整齐 - 而且它也不会发生在我的游戏中(不是这不是作业,因为我不做作业。)



这就是为什么我问如何让它们成为一个阵型,形成一种他们将被命令在目标位置旁边的方式 - 如()帝国时代2 [ ^ ]



我不想要任何花哨的形式,因为在这个阶段对我来说是无关紧要的。我只想要它们的实体列表由目标的来源格式化。



编辑:



假设我们有八个实体。我们想要两行,这意味着每行有四行:

  int 行=  2 ; 

for int i = 0 ; i< rows; i ++)

for int x = 0 ; x< Entities.Count / rows; x ++)
{
// 此时我们知道有两行,X的结果最多为4。

位置= parOrigin - ((Entities.Count / 2 * new Vector2(Entities [i] .Size.X ,i * Entities [i] .Size.Y))+ new Vector2(Entities [i] .Size.X, 0 )* i);
实体[Entities.Count / Rows * i + x] .GoToTarget(Position);
}
}



- 我认为这是解决方案吗?在我脑海里感觉像这样。任何评论?



编辑(15-5-2016):

使用当前给出的唯一答案我仍然遇到问题按矩形排序。他们中的一些仍然堆叠在一起。



我尝试过:



以下是伪代码,用于解释我尝试进行简单编码。



Vector2 parTarget = MousePosition;

Vector2 parOrigin = parTarget;



for(int i = 0; i< entities.count;> {

parTarget = parOrigin - (( Entities.Count / 2 * new Vector2(Entities [i] .Size.X,0))+ new Vector2(Entities [i] .Size.X,0)* i);



if(Entities [i] .Selected)

{

Entities [i] .GoToPosition(parTarget);

}

}



你很可能用伪语言读这个应该用直线发送它们作为原点,但这个不会形成矩形,因此会将它们展开整个地图,我不希望这样。



我希望矩形尽可能小但我不知道怎么做仅使用一维for循环来完成此操作。我对数学不是很好,所以如果这很明显我会道歉 - 我在这里学习。

解决方案

找出最合适的方块,您可以使用以下内容:



  //  这将计算适合 
// 最可能的矩形。
int columnCount =( int )(Math.Ceiling(Math.Sqrt(Entities.Count)));

// 如果单位数不是,则行数可能小于列数
// 精确的正方形。此外,最后一行可能不完整。
int rowCount =(Entities.Count + columnCount - 1 )/ columnCount;

// 找出所需的网格大小(如果所有实体都不需要此步骤
// 大小相同。)
// 注意:如果实体为空,这些行将抛出异常。
int xSize = Entities.Max(e => e.Size.X);
int ySize = Entities.Max(e => e.Size.Y);

// 这是网格的左上角,它是居中的on
// parTarget。
Vector2 gridCornerOffset = parTarget
+ new Vector2(-xSize * columnCount / 2 , - ySize * rowCount / 2 );

// 将每个实体发送到目标位置。
for int i = 0 ; i < Entities.Count; ++ i)
{
int gridX = i%columnCount;
int gridY = i / columnCount;

Vector2 position = gridCornerOffset
+ new Vector2(xSize * gridX,ySize * gridY);

实体[i] .GoToTarget(position);
}





编辑:如果您想要形成矩形,可以将第一行更改为以下内容:



  //  这是所需矩形的宽高比。 
double r = 2 ; // 2:1矩形

int columnCount =( int )(Math.Round(r * Math.Sqrt(Entities.Count / r)));


Hey Codeproject,

I wasn't sure how to phrase the question as I am not sure what this is exactly called. Anyways, to quickly get to the point I have a list of entities (players, ships, whatnot) that I send to a specific point using:

GoToTarget(Entity Entity, Vector2 Position)
{
  Entity.GoToPosition(Vector2);
}



The problem with this method is that they will eventually all get to the same place and stack on top of each other. Now I'd usually say that adding collisions would solve this problem, but it does not look neat - and neither is it suppose to happen in my game (no this is not a homework assignment because I do not do homework.)

So that's why I asked how to make them in a "formation", formation being a way they will be ordered next to the target position - as can be seen in ()Age of Empires 2[^]

I don't want any fancy formations, because that to me is irrelevant at this stage. I just want them list of entities to be formated by the origin that is "Target".

Edit:

Assuming we have eight entities. We want two rows, meaning there's four on each row:

int Rows = 2;

for(int i =0; i<rows; i++)  

  for(int x=0; x <Entities.Count / rows; x++) 
{ 
// At this point we know that there's two rows, and the result of X is a maximum of 4.
     
     Position = parOrigin  - ((Entities.Count / 2 * new Vector2(Entities[i].Size.X, i * Entities[i].Size.Y)) + new Vector2(Entities[i].Size.X, 0) * i);
     Entities[Entities.Count / Rows * i + x].GoToTarget(Position);
  } 
}


-- I think this is the solution? Feels like it in my head. Any comments?

Edit (15-5-2016):
Using the only answer currently given I still have problems getting them all to sort in a rectangle. Some of them still stack on top of each other.

What I have tried:

The following is pseudo code to explain my attempt at making a simple formation.

Vector2 parTarget = MousePosition;
Vector2 parOrigin = parTarget;

for(int i =0; i<entities.count;>{
parTarget = parOrigin - ((Entities.Count / 2 * new Vector2(Entities[i].Size.X, 0)) + new Vector2(Entities[i].Size.X, 0) * i);

if(Entities[i].Selected)
{
Entities[i].GoToPosition(parTarget);
}
}

As you can most likely read this in pseudo language should send them in a straight line having target as origin, but this does not give a rectangle formation and will thus spread them out over the entire map, and I do not want that.

I want the rectangle to be as small as necessary but I have no idea how to do this with only a one dimensional for loop. I'm not very good with math, so if this is obvious I do apologize - I am here to learn.

解决方案

To figure out the best-fitting square, you can use something like the following:

// This will compute the number of columns needed to fit all the units in the
// squarest rectangle possible.
int columnCount = (int)(Math.Ceiling(Math.Sqrt(Entities.Count)));

// The number of rows may be less than columns if the number of units is not
// an exact square. Also, the last row may be incomplete.
int rowCount = (Entities.Count + columnCount - 1) / columnCount;

// Figure out the grid size needed (this step is not necessary if all entities 
// are the same size.)
// NOTE: These lines will throw an exception if Entities is empty.
int xSize = Entities.Max(e=>e.Size.X); 
int ySize = Entities.Max(e=>e.Size.Y); 

// This is the top-left corner of the grid, which is to be centered on
// parTarget.
Vector2 gridCornerOffset = parTarget
    + new Vector2(-xSize * columnCount / 2, -ySize * rowCount / 2);

// Send each entity to its position at the target.
for(int i = 0; i < Entities.Count; ++i)
{
    int gridX = i % columnCount;
    int gridY = i / columnCount;
	
    Vector2 position = gridCornerOffset
		+ new Vector2(xSize * gridX, ySize * gridY);
		
    Entities[i].GoToTarget(position);
}



EDIT: If you instead want a rectangle formation, you can change the first line to the following:

// This is the width to height ratio of the desired rectangle.
double r = 2; // for 2:1 rectangle

int columnCount = (int)(Math.Round(r * Math.Sqrt(Entities.Count / r)));


这篇关于从一组对象中创建vector2形式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆