Exemple #1
0
//���obj����Ұ�뾶,������Ұ����صĹ���Ԫ
static inline int32_t cal_blocks(struct map *m,struct point2D *pos,uint32_t view_radius,uint32_t *x1,uint32_t *y1,uint32_t *x2,uint32_t *y2)
{

	if(get_block_by_point(m,pos) == NULL)
		return -1;

	//�����view_radius���ڵ���С����
	struct point2D top_left,bottom_right;
	top_left.x = pos->x - view_radius;
	top_left.y = pos->y - view_radius;
	bottom_right.x = pos->x + view_radius;
	bottom_right.y = pos->y + view_radius;
	
	//�������,ʹ���γ�Ϊһ���ڵ�ͼ֮�ڵij�����
	if(top_left.x < m->top_left.x) top_left.x = m->top_left.x;
	if(top_left.y < m->top_left.y) top_left.y = m->top_left.y;
	if(bottom_right.x > m->bottom_right.x) bottom_right.x = m->bottom_right.x;
	if(bottom_right.y > m->bottom_right.y) bottom_right.y = m->bottom_right.y;
	
	struct map_block *_top_left = get_block_by_point(m,&top_left);
	struct map_block *_bottom_right = get_block_by_point(m,&bottom_right);
	*x1 = _top_left->x;
	*y1 = _top_left->y;
	*x2 = _bottom_right->x;
	*y2 = _bottom_right->y;
	return 0;
}
Exemple #2
0
//根据obj的视野半径,计算视野内相关的管理单元
static inline int32_t cal_blocks(struct map *m,struct point2D *pos,uint32_t view_radius,uint32_t *x1,uint32_t *y1,uint32_t *x2,uint32_t *y2)
{

	if(get_block_by_point(m,pos) == NULL)
		return -1;

	//计算包含view_radius在内的最小正方形
	struct point2D top_left,bottom_right;
	top_left.x = pos->x - view_radius;
	top_left.y = pos->y - view_radius;
	bottom_right.x = pos->x + view_radius;
	bottom_right.y = pos->y + view_radius;
	
	//规整坐标,使正方形成为一个在地图之内的长方形
	if(top_left.x < m->top_left.x) top_left.x = m->top_left.x;
	if(top_left.y < m->top_left.y) top_left.y = m->top_left.y;
	if(bottom_right.x > m->bottom_right.x) bottom_right.x = m->bottom_right.x;
	if(bottom_right.y > m->bottom_right.y) bottom_right.y = m->bottom_right.y;
	
	struct map_block *_top_left = get_block_by_point(m,&top_left);
	struct map_block *_bottom_right = get_block_by_point(m,&bottom_right);
	*x1 = _top_left->x;
	*y1 = _top_left->y;
	*x2 = _bottom_right->x;
	*y2 = _bottom_right->y;
	return 0;
}
Exemple #3
0
int32_t leave_map(struct map *m,struct aoi_object *o)
{
	struct map_block *block = get_block_by_point(m,&o->current_pos);
	if(!block)
		return -1;
	double_link_remove(&o->block_node);
	uint32_t radius = STAND_RADIUS;	
	if(o->view_radius > STAND_RADIUS)
	{
		radius = o->view_radius;
		double_link_remove(&o->super_node);
	}	
	uint32_t x1,y1,x2,y2;
	cal_blocks(m,&o->current_pos,radius,&x1,&y1,&x2,&y2);
	uint32_t y = y1;
	uint32_t x;
	for( ; y <= y2; ++y)
	{
		for( x=x1; x <= x2; ++x)
		{
			block_process_leave(m,get_block(m,y,x),o,1);
		}		
	}
	o->is_leave_map = 1;
	if(--o->watch_me_count == 0)
		m->all_aoi_objects[o->aoi_object_id] = NULL;			
}
Exemple #4
0
int32_t enter_map(struct map *m,struct aoi_object *o)
{
	struct map_block *block = get_block_by_point(m,&o->current_pos);
	if(!block)
		return -1;
	double_link_push(&block->aoi_objs,&o->block_node);
	m->all_aoi_objects[o->aoi_object_id] = o;
	uint32_t radius = STAND_RADIUS;	
	if(o->view_radius > STAND_RADIUS)
	{
		radius = o->view_radius;
		double_link_push(&m->super_aoi_objs,&o->super_node);
	}
	uint32_t x1,y1,x2,y2;
	cal_blocks(m,&o->current_pos,radius,&x1,&y1,&x2,&y2);
	uint32_t y = y1;
	uint32_t x;
	for( ; y <= y2; ++y)
	{
		for(x=x1 ; x <= x2; ++x)
		{
			block_process_enter(m,get_block(m,y,x),o);
		}		
	}
	o->last_update_tick = GetCurrentMs();
	o->is_leave_map = 0;
	
}
Exemple #5
0
int32_t leave_map(struct map *m,struct aoi_object *o)
{
	struct map_block *block = get_block_by_point(m,&o->current_pos);
	if(!block)
		return -1;
	dlist_remove(&o->block_node);
	uint32_t radius = STAND_RADIUS;	
	if(o->view_radius > STAND_RADIUS)
	{
		radius = o->view_radius;
		dlist_remove(&o->super_node);
	}	
	uint32_t x1,y1,x2,y2;
	x1 = y1 = x2 = y2 = 0;
	cal_blocks(m,&o->current_pos,radius,&x1,&y1,&x2,&y2);
	uint32_t y = y1;
	uint32_t x;
	for( ; y <= y2; ++y)
	{
		for( x=x1; x <= x2; ++x)
		{
			block_process_leave(m,get_block(m,y,x),o,1);
		}		
	}
	o->is_leave_map = 1;

	//自己离开自己的视野
	leave_me(m,o,o);
	return 0;			
}
Exemple #6
0
//将o移动到new_pos,并计算视野变化
void move_to(struct map *m,struct aoi_object *o,struct point2D *new_pos)
{
	struct point2D old_pos = o->current_pos;
	o->current_pos = *new_pos;
	struct map_block *old_block = get_block_by_point(m,&old_pos);
	struct map_block *new_block = get_block_by_point(m,new_pos);
	if(old_block != new_block)
		double_link_remove(&o->block_node);
		
	uint32_t radius = STAND_RADIUS;	
	if(o->view_radius > STAND_RADIUS)
		radius = o->view_radius;		
	//计算新旧管理区域
	uint32_t n_x1,n_y1,n_x2,n_y2;
	uint32_t o_x1,o_y1,o_x2,o_y2;
	cal_blocks(m,&old_pos,radius,&o_x1,&o_y1,&o_x2,&o_y2);
	cal_blocks(m,new_pos,radius,&n_x1,&n_y1,&n_x2,&n_y2);
	
	uint32_t y = n_y1;
	uint32_t x;
	for( ; y <= n_y2; ++y)
	{
		for( x = n_x1; x <= n_x2; ++x)
		{
			if(x >= o_x1 && x <= o_x2 && y >= o_y1 && y <= o_y2)
			{
				//无变化区域
				struct map_block *bl = get_block(m,y,x);
				struct aoi_object *cur = (struct aoi_object*)bl->aoi_objs.head.next;
				while(cur != (struct aoi_object*)&bl->aoi_objs.tail)
				{
					uint64_t distance = cal_distance_2D(new_pos,&cur->current_pos);
					if(o != cur)
					{
						if(o->view_radius >= distance && !is_set(&o->self_view_objs,cur->aoi_object_id))
							enter_me(m,o,cur);
						if(o->view_radius < distance && is_set(&o->self_view_objs,cur->aoi_object_id))
							leave_me(m,o,cur);
						if(cur->view_radius >= distance && !is_set(&cur->self_view_objs,o->aoi_object_id))
							enter_me(m,cur,o);
						if(cur->view_radius < distance && is_set(&cur->self_view_objs,o->aoi_object_id))
							leave_me(m,cur,o);
					}
					cur = (struct aoi_object *)cur->block_node.next;			
				}				
			}
			else
			{
				//新进入的区域
				block_process_enter(m,get_block(m,y,x),o);
			}
		}
	}
	if(old_block != new_block)
		double_link_push(&new_block->aoi_objs,&o->block_node);
	y = o_y1;
	for( ; y <= o_y2; ++y)
	{
		for(x = o_x1; x <= o_x2; ++x)
		{
			if(x >= n_x1 && x <= n_x2 && y >= n_y1 && y <= n_y2)
				continue;//这里不处理无变化区域
			block_process_leave(m,get_block(m,y,x),o,0);
		}		
	}
	o->last_update_tick = GetCurrentMs();
}
Exemple #7
0
//��o�ƶ���new_pos,��������Ұ�仯
void move_to(struct map *m,struct aoi_object *o,int32_t _x,int32_t _y)
{
	struct point2D new_pos = {_x,_y};
	struct point2D old_pos = o->current_pos;
	o->current_pos = new_pos;
	struct map_block *old_block = get_block_by_point(m,&old_pos);
	struct map_block *new_block = get_block_by_point(m,&new_pos);
	if(old_block != new_block)
		dlist_remove(&o->block_node);
		
	uint32_t radius = STAND_RADIUS;	
	if(o->view_radius > STAND_RADIUS)
		radius = o->view_radius;		
	//�����¾ɹ�������
	uint32_t n_x1,n_y1,n_x2,n_y2;
	uint32_t o_x1,o_y1,o_x2,o_y2;
	n_x1 = n_y1 = n_x2 = n_y2 = 0;
	o_x1 = o_y1 = o_x2 = o_y2 = 0;
	cal_blocks(m,&old_pos,radius,&o_x1,&o_y1,&o_x2,&o_y2);
	cal_blocks(m,&new_pos,radius,&n_x1,&n_y1,&n_x2,&n_y2);
	
	uint32_t y = n_y1;
	uint32_t x = 0;
	for( ; y <= n_y2; ++y)
	{
		for( x = n_x1; x <= n_x2; ++x)
		{
			if(x >= o_x1 && x <= o_x2 && y >= o_y1 && y <= o_y2)
			{
				//�ޱ仯����
				struct map_block *bl = get_block(m,y,x);
				struct aoi_object *cur = (struct aoi_object*)bl->aoi_objs.head.next;
				while(cur != (struct aoi_object*)&bl->aoi_objs.tail)
				{
					uint64_t distance = cal_distance_2D(&new_pos,&cur->current_pos);
					if(o != cur)
					{
						if(o->view_radius >= distance && !is_set(&o->self_view_objs,cur->aoi_object_id))
							enter_me(m,o,cur);
						else if(o->view_radius < distance && is_set(&o->self_view_objs,cur->aoi_object_id))
							leave_me(m,o,cur);
						
						if(cur->view_radius >= distance && !is_set(&cur->self_view_objs,o->aoi_object_id))
							enter_me(m,cur,o);
						else if(cur->view_radius < distance && is_set(&cur->self_view_objs,o->aoi_object_id))
							leave_me(m,cur,o);
					}
					cur = (struct aoi_object *)cur->block_node.next;			
				}				
			}
			else
			{
				//�½��������
				block_process_enter(m,get_block(m,y,x),o);
			}
		}
	}
	if(old_block != new_block)
		dlist_push(&new_block->aoi_objs,&o->block_node);
	y = o_y1;
	for( ; y <= o_y2; ++y)
	{
		for(x = o_x1; x <= o_x2; ++x)
		{
			if(x >= n_x1 && x <= n_x2 && y >= n_y1 && y <= n_y2)
				continue;//���ﲻ�����ޱ仯����
			block_process_leave(m,get_block(m,y,x),o,0);
		}		
	}
	o->last_update_tick = GetSystemMs64();
}