bool MapZone::IsInsideZone(float pos_x, float pos_y) const { uint16 x = (uint16)GetFloatInteger(pos_x); uint16 y = (uint16)GetFloatInteger(pos_y); // Verify each section of the zone and check if the position is within the section bounds. for (vector<ZoneSection>::const_iterator i = _sections.begin(); i != _sections.end(); ++i) { if (x >= i->left_col && x <= i->right_col && y >= i->top_row && y <= i->bottom_row) { return true; } } return false; }
int16 ContextZone::_IsInsideZone(MapObject* object) { // NOTE: argument is not NULL-checked here for performance reasons uint16 x = (uint16)GetFloatInteger(object->GetXPosition()); uint16 y = (uint16)GetFloatInteger(object->GetYPosition()); // Check each section of the zone to see if the object is located within for (uint16 i = 0; i < _sections.size(); i++) { if (x >= _sections[i].left_col && x <= _sections[i].right_col && y >= _sections[i].top_row && y <= _sections[i].bottom_row) { return i; } } return -1; }
bool MapZone::_ShouldDraw(const ZoneSection& section) { MapMode *map = MapMode::CurrentInstance(); // If the context is not in one of the active context, don't display it. if (!(_active_contexts & map->GetCurrentContext())) return false; MapRectangle rect; rect.top = section.top_row; rect.bottom = section.bottom_row; rect.left = section.left_col; rect.right = section.right_col; // Determine if the sprite is off-screen and if so, don't draw it. if (!MapRectangle::CheckIntersection(rect, map->GetMapFrame().screen_edges)) return false; // Determine the center position coordinates for the camera float x_pos, y_pos; // Holds the final X, Y coordinates of the camera float x_pixel_length, y_pixel_length; // The X and Y length values that coorespond to a single pixel in the current coodinate system float rounded_x_offset, rounded_y_offset; // The X and Y position offsets of the object, rounded to perfectly align on a pixel boundary // TODO: the call to GetPixelSize() will return the same result every time so long as the coordinate system did not change. If we never // change the coordinate system in map mode, then this should be done only once and the calculated values should be saved for re-use. // However, we've discussed the possiblity of adding a zoom feature to maps, in which case we need to continually re-calculate the pixel size x_pos = rect.left + (rect.right - rect.left) / 2; y_pos = rect.top + (rect.bottom - rect.top); hoa_video::VideoManager->GetPixelSize(x_pixel_length, y_pixel_length); rounded_x_offset = FloorToFloatMultiple(GetFloatFraction(x_pos), x_pixel_length); rounded_y_offset = FloorToFloatMultiple(GetFloatFraction(y_pos), y_pixel_length); x_pos = static_cast<float>(GetFloatInteger(x_pos)) + rounded_x_offset; y_pos = static_cast<float>(GetFloatInteger(y_pos)) + rounded_y_offset; // Move the drawing cursor to the appropriate coordinates for this sprite hoa_video::VideoManager->Move(x_pos - map->GetMapFrame().screen_edges.left, y_pos - map->GetMapFrame().screen_edges.top); return true; }
void MapMode::_UpdateMapFrame() { // Determine the center position coordinates for the camera // Holds the final X, Y coordinates of the camera float camera_x = _camera->GetXPosition(); float camera_y = _camera->GetYPosition(); if(_camera_timer.IsRunning()) { camera_x += (1.0f - _camera_timer.PercentComplete()) * _delta_x; camera_y += (1.0f - _camera_timer.PercentComplete()) * _delta_y; } // Actual position of the view, either the camera sprite or a point on the camera movement path uint16 current_x = GetFloatInteger(camera_x); uint16 current_y = GetFloatInteger(camera_y); // NOTE: Would the map mode coordinate system be able to dynamically change, allow this to be recomputed, // and used as the multiple of the current camera tile offset. if (_pixel_length_x <= 0.0f || _pixel_length_y <= 0.0f) VideoManager->GetPixelSize(_pixel_length_x, _pixel_length_y); // std::cout << "the ratio is: " << _pixel_length_x << ", " << _pixel_length_y << " for resolution: " // << VideoManager->GetScreenWidth() << " x " << VideoManager->GetScreenHeight() << std::endl; // NOTE: The offset is corrected based on the map coord sys pixel size, to avoid glitches on tiles with transparent parts // and black edges. The size of the edge would have a variable size and look like vibrating when scrolling // without this fix. float current_offset_x = vt_utils::FloorToFloatMultiple(GetFloatFraction(camera_x), _pixel_length_x); float current_offset_y = vt_utils::FloorToFloatMultiple(GetFloatFraction(camera_y), _pixel_length_y); // Determine the draw coordinates of the top left corner using the camera's current position _map_frame.tile_x_offset = 1.0f - current_offset_x; if(IsOddNumber(current_x)) _map_frame.tile_x_offset -= 1.0f; _map_frame.tile_y_offset = 2.0f - current_offset_y; if(IsOddNumber(current_y)) _map_frame.tile_y_offset -= 1.0f; // The starting row and column of tiles to draw is determined by the map camera's position _map_frame.tile_x_start = (current_x / 2) - HALF_TILES_ON_X_AXIS; _map_frame.tile_y_start = (current_y / 2) - HALF_TILES_ON_Y_AXIS; _map_frame.screen_edges.top = camera_y - HALF_SCREEN_GRID_Y_LENGTH; _map_frame.screen_edges.bottom = camera_y + HALF_SCREEN_GRID_Y_LENGTH; _map_frame.screen_edges.left = camera_x - HALF_SCREEN_GRID_X_LENGTH; _map_frame.screen_edges.right = camera_x + HALF_SCREEN_GRID_X_LENGTH; // Check for boundary conditions and re-adjust as necessary so we don't draw outside the map area // Usually the map centers on the camera's position, but when the camera becomes too close to // the edges of the map, we need to modify the drawing properties of the frame. // Reinit map corner check members _camera_x_in_map_corner = false; _camera_y_in_map_corner = false; // Determine the number of rows and columns of tiles that need to be drawn _map_frame.num_draw_x_axis = TILES_ON_X_AXIS + 1; _map_frame.num_draw_y_axis = TILES_ON_Y_AXIS + 1; // Camera exceeds the left boundary of the map if(_map_frame.tile_x_start < 0) { _map_frame.tile_x_start = 0; _map_frame.tile_x_offset = vt_utils::FloorToFloatMultiple(1.0f, _pixel_length_x); _map_frame.screen_edges.left = 0.0f; _map_frame.screen_edges.right = SCREEN_GRID_X_LENGTH; _map_frame.num_draw_x_axis = TILES_ON_X_AXIS; _camera_x_in_map_corner = true; } // Camera exceeds the right boundary of the map else if(_map_frame.tile_x_start + TILES_ON_X_AXIS >= _tile_supervisor->_num_tile_on_x_axis) { _map_frame.tile_x_start = static_cast<int16>(_tile_supervisor->_num_tile_on_x_axis - TILES_ON_X_AXIS); _map_frame.tile_x_offset = vt_utils::FloorToFloatMultiple(1.0f, _pixel_length_x); _map_frame.screen_edges.right = static_cast<float>(_object_supervisor->_num_grid_x_axis); _map_frame.screen_edges.left = _map_frame.screen_edges.right - SCREEN_GRID_X_LENGTH; _map_frame.num_draw_x_axis = TILES_ON_X_AXIS; _camera_x_in_map_corner = true; } // Camera exceeds the top boundary of the map if(_map_frame.tile_y_start < 0) { _map_frame.tile_y_start = 0; _map_frame.tile_y_offset = vt_utils::FloorToFloatMultiple(2.0f, _pixel_length_y); _map_frame.screen_edges.top = 0.0f; _map_frame.screen_edges.bottom = SCREEN_GRID_Y_LENGTH; _map_frame.num_draw_y_axis = TILES_ON_Y_AXIS; _camera_y_in_map_corner = true; } // Camera exceeds the bottom boundary of the map else if(_map_frame.tile_y_start + TILES_ON_Y_AXIS >= _tile_supervisor->_num_tile_on_y_axis) { _map_frame.tile_y_start = static_cast<int16>(_tile_supervisor->_num_tile_on_y_axis - TILES_ON_Y_AXIS); _map_frame.tile_y_offset = vt_utils::FloorToFloatMultiple(2.0f, _pixel_length_y); _map_frame.screen_edges.bottom = static_cast<float>(_object_supervisor->_num_grid_y_axis); _map_frame.screen_edges.top = _map_frame.screen_edges.bottom - SCREEN_GRID_Y_LENGTH; _map_frame.num_draw_y_axis = TILES_ON_Y_AXIS; _camera_y_in_map_corner = true; } // Update parallax effects now that map corner members are up to date if(_camera_timer.IsRunning()) { // Inform the effect supervisor about camera movement. float duration = (float)_camera_timer.GetDuration(); float time_elapsed = (float)SystemManager->GetUpdateTime(); float x_parallax = !_camera_x_in_map_corner ? _delta_x * time_elapsed / duration / SCREEN_GRID_X_LENGTH * VIDEO_STANDARD_RES_WIDTH : 0.0f; float y_parallax = !_camera_y_in_map_corner ? _delta_y * time_elapsed / duration / SCREEN_GRID_Y_LENGTH * VIDEO_STANDARD_RES_HEIGHT : 0.0f; GetEffectSupervisor().AddParallax(x_parallax, y_parallax); GetIndicatorSupervisor().AddParallax(x_parallax, y_parallax); } // Comment this out to print out map draw debugging info about once a second // static int loops = 0; // if (loops == 0) { // printf("--- MAP DRAW INFO ---\n"); // printf("Rounded offsets: [%f, %f]\n", current_offset_x, current_offset_y); // printf("Starting row, col: [%d, %d]\n", _map_frame.starting_row, _map_frame.starting_col); // printf("# draw rows, cols: [%d, %d]\n", _map_frame.num_draw_rows, _map_frame.num_draw_cols); // printf("Camera position: [%f, %f]\n", camera_x, camera_y); // printf("Tile draw start: [%f, %f]\n", _map_frame.tile_x_start, _map_frame.tile_y_start); // printf("Edges (T,B,L,R): [%f, %f, %f, %f]\n", _map_frame.screen_edges.top, _map_frame.screen_edges.bottom, // _map_frame.screen_edges.left, _map_frame.screen_edges.right); // } // // if (loops >= 60) // loops = 0; // else // ++loops; } // void MapMode::_UpdateMapFrame()
float GetFloatFraction(float value) { return (value - GetFloatInteger(value)); }