Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.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
Java MySQL查询以获取球体中的行(X、Y、Z坐标)?_Java_Mysql_Minecraft - Fatal编程技术网

Java MySQL查询以获取球体中的行(X、Y、Z坐标)?

Java MySQL查询以获取球体中的行(X、Y、Z坐标)?,java,mysql,minecraft,Java,Mysql,Minecraft,我正在用bukkitapi制作一个名为Minecraft的游戏插件 我有一个名为的数据库表,其中包含以下字段:x整数,y整数,z整数。加固块是受保护的块,这意味着它不能被破坏 我正在使用EntityExplodeEvent检查TNT爆炸 我循环遍历event.blocklist(),并将每个块与表中的条目进行比较。如果存在,则使用event.blocklist()防止在爆炸中损坏加固块。移除 我可以通过获取每个坐标(x,y,z)的最小值和最大值,然后检查这两个数字之间的数据库行来实现这一点。问题

我正在用
bukkitapi
制作一个名为Minecraft的游戏插件

我有一个名为的数据库表,其中包含以下字段:
x整数
y整数
z整数
。加固块是受保护的块,这意味着它不能被破坏

我正在使用
EntityExplodeEvent
检查TNT爆炸

我循环遍历
event.blocklist()
,并将每个块与表中的条目进行比较。如果存在,则使用
event.blocklist()防止在爆炸中损坏加固块。移除

我可以通过获取每个坐标(x,y,z)的最小值和最大值,然后检查这两个数字之间的数据库行来实现这一点。问题是它是一个立方体。我应该检查一个球体。我该怎么做

注意:我知道select语句并不存在问题,因为我可以将返回的行与
event.blocklist()
进行比较,但我需要知道在以后生成update语句时如何进行比较

我之所以需要知道如何检查球体中的行,是因为最终我将向增强表添加一个名为
“耐久性整数”
的额外字段,该字段在每次爆炸后都会减小。由于爆炸是一个球体,更新查询应该只更新该球体中的行,而不是立方体

有人吗? 多谢各位

当前MySQL查询

"SELECT X, Y, Z FROM REINFORCEMENTS WHERE DURABILITY >= 1 " +
                "AND x<=? AND x>=? AND y<=? AND y>=? AND z<=? AND z>=? AND world=?");
“从耐久性>=1的钢筋中选择X、Y、Z”+
“x=?y=?z=?和world=?”;
完整代码

@EventHandler
    public void checkForExplosion(EntityExplodeEvent event){

        if(event.isCancelled()){
            return;
        }

        //Store blocks that are inside explosion's blast radius
        List<Block> blastRadiusBlocks = event.blockList();

        //If explosion occurs in mid air it returns 0 so no need to go any
        //further since there are no blocks inside the explosions radius
        if(blastRadiusBlocks.size() < 1){
            return;
        }

        HashMap<Coordinate, Block> affectedBlocks = new HashMap<Coordinate, Block>();

        //Initialize min & max X,Y,Z coordinates
        int smallestX = blastRadiusBlocks.get(0).getX();
        int largestX = smallestX;
        int smallestY = blastRadiusBlocks.get(0).getY();
        int largestY = smallestY;
        int smallestZ = blastRadiusBlocks.get(0).getZ();
        int largestZ = smallestZ;

        //World Name
        String worldName = blastRadiusBlocks.get(0).getWorld().getName();
        World world = this.myPlugin.getServer().getWorld(worldName);

        //Find min & max X,Y,Z coordinates
        for(int i = 0; i < blastRadiusBlocks.size(); i++){
            Block block = blastRadiusBlocks.get(i);
            int blockX = block.getX();
            int blockY = block.getY();
            int blockZ = block.getZ();

            if(blockX < smallestX){
                smallestX = blockX;
            }

            if(blockX > largestX){
                largestX = blockX;
            }

            if(blockY < smallestY){
                smallestY = blockY;
            }

            if(blockY > largestY){
                largestY = blockY;
            }

            if(blockZ < smallestZ){
                smallestZ = blockZ;
            }

            if(blockZ > largestZ){
                largestZ = blockZ;
            }

            //Instantiate Coordinate class passing in parameters
            Coordinate coordinate = new Coordinate(world, blockX, blockY, blockZ);
            //Put a new entry of type Coordinate as key and type Block as value
            affectedBlocks.put(coordinate, block);
        }

        try {
            //Query database for any reinforced blocks that may be in the blast radius
            //Reinforced blocks should have a durability > 0 (aka >= 1)
            PreparedStatement ask = this.conn.prepareStatement(
                "SELECT X, Y, Z FROM REINFORCEMENTS WHERE DURABILITY >= 1 " +
                "AND x<=? AND x>=? AND y<=? AND y>=? AND z<=? AND z>=? AND world=?");
            ask.setInt(1, largestX);
            ask.setInt(2, smallestX);
            ask.setInt(3, largestY);
            ask.setInt(4, smallestY);
            ask.setInt(5, largestZ);
            ask.setInt(6, smallestZ);
            ask.setString(7, worldName);
            ask.execute();
            ResultSet result = ask.getResultSet();

            //If there was some found, loop through each one
            while(result.next()){
                //Get X,Y,Z coords of reinforced block
                int x = result.getInt(1);
                int y = result.getInt(2);
                int z = result.getInt(3);

                //Pass in x, y, z of reinforced block into affectedBlocks HashMap to instantiate a Block
                Block protectedBlock = affectedBlocks.get(new Coordinate(world, x, y, z));
                //Then remove the protectedBlock from explosion list
                event.blockList().remove(protectedBlock);
            }

            result.close();
            ask.close();

        } catch (SQLException e) {
            System.err.println("Citadel - Select Reinforcement can't keep up (possibly too many explosions):\n" + e);
        }
}
@EventHandler
公共无效检查爆炸(EntityExplodeEvent事件){
if(event.isCancelled()){
返回;
}
//存储在爆炸爆炸半径内的块
List blastRadiusBlocks=event.blockList();
//如果爆炸发生在半空中,则返回0,因此无需进行任何操作
//此外,因为爆炸半径内没有障碍物
if(blastRadiusBlocks.size()<1){
返回;
}
HashMap affectedBlocks=新HashMap();
//初始化最小和最大X、Y、Z坐标
int smallestX=blastRadiusBlocks.get(0.getX();
int largestX=smallestX;
int smallestY=blastRadiusBlocks.get(0.getY();
int最大=最小;
int smallestZ=blastRadiusBlocks.get(0.getZ();
int largestZ=smallestZ;
//世界名称
字符串worldName=blastRadiusBlocks.get(0.getWorld().getName();
World World=this.myPlugin.getServer().getWorld(worldName);
//查找最小和最大X、Y、Z坐标
对于(int i=0;i最大X){
最大x=块x;
}
if(块状<小型){
小的=块状的;
}
如果(块状>最大){
最大=块状;
}
if(blockZlargestZ){
最大Z=块Z;
}
//实例化传递参数的坐标类
坐标坐标=新坐标(世界坐标、块X坐标、块Y坐标、块Z坐标);
//将“坐标”类型的新条目作为键,将“块”类型作为值
受影响的块。放置(坐标,块);
}
试一试{
//查询数据库中可能位于爆破半径内的任何加固砌块
//加固砌块的耐久性应大于0(aka>=1)
PreparedStatement ask=this.conn.PreparedStatement(
“从耐久性>=1的钢筋中选择X、Y、Z”+
“x=?y=?z=?和world=?”;
ask.setInt(1,最大值);
ask.setInt(2,smallestX);
ask.setInt(3,最大);
ask.setInt(4,smallestY);
ask.setInt(5,最大z);
ask.setInt(6,smallestZ);
ask.setString(7,世界名称);
ask.execute();
ResultSet result=ask.getResultSet();
//如果找到了一些,循环检查每一个
while(result.next()){
//得到加固块的X,Y,Z坐标
int x=result.getInt(1);
int y=result.getInt(2);
intz=result.getInt(3);
//将加固块的x、y、z传递到affectedBlocks HashMap以实例化块
Block protectedBlock=affectedBlocks.get(新坐标(world,x,y,z));
//然后从爆炸列表中删除protectedBlock
event.blockList().remove(protectedBlock);
}
result.close();
ask.close();
}捕获(SQLE异常){
System.err.println(“城堡-选择增援无法跟上(可能有太多爆炸):\n”+e);
}
}

如果球体的中心位于
x0,y0 z0
且半径为
r
,则需要:

select ... from ... where ((x-x0)*(x-x0)+(y-y0)*(y-y0)+(z-z0)*(z-z0) < r*r);
选择。。。从…起式中((x-x0)*(x-x0)+(y-y0)*(y-y0)+(z-z0)*(z-z0)
(这只是3d中的毕达哥拉斯)。

从中选择X、Y、Z
其中耐久性>=1
世界=?

(POW((X-?),2)+POW((Y-?),2)+POW((Z-?),2))可能作为相交球体的数学问题发布。查看并扩展第三个坐标,还有一些很好的优化,因此数据库可以使用索引排除边界外的任何点
SELECT X, Y, Z FROM REINFORCEMENTS 
WHERE DURABILITY >= 1 
AND world=?
AND (POW((X-?),2)+POW((Y-?),2)+POW((Z-?),2))<POW(?,2)