我想知道如何优化存储过程信息并在数据列表中访问特定元素。
例如,当我在我的世界中创建植被时,我告诉我的系统从0开始,得到10行的一行,然后它返回0并增加z位置以创建另一行。
通过在ArrayLists中存储位置,旋转,纹理和模型等数据来跟踪任何对象,以便在需要时在其他位置访问它们,例如:碰撞检测:
public void collision_ForestTree001() {
int modelID = 0;
while(treeXArray.size() != modelID && treeZArray.size() != modelID) {
// player and object bounds
float playerX = 0.15f;
float playerZ = 0.15f;
float objectX = 0.2f;
float objectZ = 0.2f;
// collision check
if((PlayerX)+playerX < treeXArray.get(modelID)-objectX ||
(PlayerX)-playerX > treeXArray.get(modelID)+objectX) {
collisionX = false;
} else {
collisionX = true;
}
if((PlayerZ)+playerZ < treeZArray.get(modelID)-objectZ ||
(PlayerZ)-playerZ > treeZArray.get(modelID)+objectZ) {
collisionZ = false;
} else {
collisionZ = true;
}
modelID++;
}
}
我想知道是否有更好的存储和访问数据的方式,因为使用ArrayLists访问信息似乎有点愚蠢,因为我必须逐个浏览元素才能找到所需的数据。谢谢你的帮助!
答案 0 :(得分:3)
如果每个森林的行为都是独立的,那么您的解决方案似乎并不那么糟糕。 如果要优化CPU并减少列表的迭代次数,可以使用一些与屏幕区域和林相关联的映射。 因此,根据玩家的位置,您将仅检查屏幕区域中与森林的碰撞。
编辑子问题:
欢迎你。我也喜欢游戏编程。享受:)
正如我在最初的消息中所说,如果每棵树的行为都是独立的,那么这是一个很好的方法。 独立的意思是当你的玩家接触到一棵树时,这棵树必须通过做一些小动作做出反应,你没有选择:你必须检查玩家所在地区的每棵树才能做出反应对于被触摸的树。
但是,如果当你的玩家触摸到一棵树时,树没有反应,只有玩家做出反应(例如通过阻止他),你可以将碰撞检测分解。因此,您可以考虑不应在用户所在的区域计算碰撞,而应在树木所在的整个区域进行计算。因此,您可以使用一个或多个矩形来覆盖树碰撞检测,并且您不必强制迭代列表。
答案 1 :(得分:1)
对于存储数据,我建议您创建一个类来表示将存储所有数据的每个植被对象。该对象称为实体。
public class Entity {
private double xCord;
private double yCord;
private double zCord;
//or in opengl you can use Vector3f() depending on your library
private double rotX;
private double rotY;
private double rotZ;
private Texture texture;
//assuming your model is represented by a class object
private Model model;
public Entity(double xC, double yC, double zC, double rX,
double rY, double rZ, Texture t, Model m) {
xCord = xC;
yCord = yC;
zCord = zC;
rotX = rX;
rotY = rY;
rotZ = rZ;
texture = t;
model = m;
}
public double getX(){
return xCord;
}
public double getY(){
return yCord;
}
public double getZ(){
return zCord;
}
public double getRotX(){
return rotX;
}
public double getRotY(){
return rotY;
}
public double getRotZ(){
return rotZ;
}
public Texture getTexture(){
return texture;
}
public Model getModel(){
return model;
}
}
然后,您可以将所有实体存储在一个arraylist中,您将遍历它以呈现每个实体。此外,您可以添加mutator方法来编辑实体,例如更改旋转或位置。同样为了获得最大效率,您可以使用距离公式来确定哪些实体处于渲染距离,并仅渲染和测试碰撞的实体。这可以加快程序的速度,因为渲染是几乎所有程序中最重的任务。
答案 2 :(得分:1)
既然您正在询问如何更好地做到这一点,那么这里有几个指针。
处理封装。我假设您每帧都调用此方法来更改collisionX和collisionZ的值(外部方法应该是不可变的)。这是糟糕的OOP。您应该将此方法传递给确定碰撞所需的参数,然后返回collisionX和collisionZ的状态。
初始化playerX / Z,对象X / Z在while循环范围之外。每次循环时都不需要创建新的变量。
进一步提取您的对象。将对象总区域的坐标存储在Map / Hashmap中的2d平面上。
通过定义较大的不太密集的碰撞检查来减少计算压力。例如。仅检查与上面建议的屏幕区域中的对象的碰撞,在网格区域中,或者如果您有复杂的对象形状,确定包裹整个碰撞对象的最小圆圈,对您的玩家角色执行相同操作,然后在两者之间进行距离检查他们各自的圈子中心。如果距离检查返回足够高的值,则只需跳过碰撞检查,如果没有,则使用更准确的碰撞检查。