Exemple #1
0
    //当单位配置中 keepdist = 1 时,攻击时将尽量保持与目标间的距离为自己的攻击距离
    public static void update_keep_atk_range(IBaseUnit sprite, long tm_elasped_s)
    {
        var pl = sprite.get_pack_data();
        if (pl.atking == null)
        {
            return;
        }

        if (sprite.has_state(pl_state_type.PST_CANT_MOVE))
        {
            // can't move
            return;
        }

        var gmap = sprite.gmap;

        if (gmap.has_sprite_by_iid(pl.atking.tar_iid))
        {
            //Utility.trace_err("monster["+this.mondata.iid+"] atking tar_iid[" + this.mondata.atking.tar_iid +"] cur tm[" +cur_clock_tm+"] last_trace_tm ["+ last_trace_target_tm +"] \n");

            var target = gmap.map_sprites[pl.atking.tar_iid];
            var tar_pl = target.get_pack_data();

            double dist_x = pl.x - tar_pl.x;
            double dist_y = pl.y - tar_pl.y;
            var dist2 = dist_x * dist_x + dist_y * dist_y;
            var dist = Math.Sqrt(dist2);
            var atk_rang2 = pl.atkrange * pl.atkrange;


            // 处于最佳攻击距离
            var best_atk_rang = pl.atkrange;
            if (dist.CompareTo(best_atk_rang) <= 0)
            {
                //Utility.trace_info("atk_trace stop:"+dist2+"="+atk_rang2+"\n");
                if (pl.moving != null)
                {
                    //// 停止移动
                    ////var cur_grid_pos  = {x=(pl.x/game_const.map_grid_pixel), y=(pl.y/game_const.map_grid_pixel)}
                    //var data = {tm=sys.clock_time()- pl.atking.trace_tm_left, iid=pl.iid, x=pl.x, y=pl.y, face=pl.face};
                    //// send stop move msg to clients
                    ////gmap.broadcast_map_rpc(10, data);
                    //sprite.broad_cast_zone_msg_and_self(10, data);

                    //delete pl.moving;
                    pl.moving = null;
                }
            }
            else
            {
                //if(dist > best_atk_rang)
                //{
                //    Utility.trace_info("atk_trace:"+dist+">"+best_atk_rang+"\n");
                //}
                //else if(dist < best_atk_rang)
                //{
                //    Utility.trace_info("atk_trace:"+dist+"<"+best_atk_rang+"\n");
                //}
                // 保持距离
                //var cur_pos = gmap.get_grid_by_pt(pl.x, pl.y);
                //var tar_pos = gmap.get_grid_by_pt(tar_pl.x, tar_pl.y);
                //var k = (best_atk_rang / dist);
                //var best_pos = {};
                //best_pos.x <- (tar_pos.x + (cur_pos.x - tar_pos.x) * k);
                //best_pos.y <- (tar_pos.y + (cur_pos.y - tar_pos.y) * k);

                // 计算和目标之间的角度atan(a),范围为[-PI/2, PI/2],为了获得整个圆周的范围,当(x<0)时角度为:PI+atan(a)
                /*      
                 *      |
                 * (-,-)|(+,-)
                 * -----O------>X
                 * (-,+)|(+,+)
                 *      |
                 *      \/Y
                 */
                double alpha = 0;
                if (dist != 0)
                {
                    alpha = Math.PI / 2;
                    if (dist_x != 0)
                    {
                        alpha = Math.Atan((dist_y / dist_x));
                        if (dist_x < 0)
                        {
                            alpha += Math.PI;
                        }
                    }
                    else if (dist_y < 0)
                    {
                        alpha = -Math.PI / 2;
                    }
                }
                //Utility.trace_info("atan("+dist_y+"/"+dist_x+"="+k+")="+alpha+"\n");
                // 在最佳攻击距离圈上选取最近可达点
                var new_pos = gmap.valpoint_on_round(tar_pl.x, tar_pl.y, best_atk_rang, alpha);
                if (new_pos != null)
                {
                    new_pos = gmap.get_grid_by_pt(new_pos.x, new_pos.y);
                    sprite._move_to(new_pos.x, new_pos.y);
                }
                //Utility.trace_info("keep range pos:("+tar_pos.x+","+tar_pos.y+","+best_atk_rang+")->("+new_pos.x+","+new_pos.y+")\n");
            }
        }
    }