如何从2D世界坐标转换为2D屏幕坐标?

时间:2019-12-26 21:44:14

标签: c++ 2d rendering sdl game-development

我正在使用SDL设计一个基于2D Platformer Tile的游戏。从世界坐标转换为屏幕坐标时遇到麻烦。我将(0,0)定义为屏幕和世界的左上角,将(x,y)定义为右下角。

目前,我正在像这样存储地图数据:

"." is an air tile

"#" is a grass tile

"i" is an iron tile

"p" is a wooden plank tile

"c" is the top layer of the ice

"b" is the bottom layers of the ice

...iiiiii...pppppp..cccccc...........................................
...iiiiii...pppppp..b....b...........................................
...iiiiii...p....p..b....b...........................................
...iiiiii...p....p..b....b...........................................
...iiiiii...p....p..b....b...........................................
...iiiiii...p....p..b....b...........................................
...iiiiii...p....p..bbbbbb...........................................
...iiiiii...pppppp..bbbbbb...........................................
...iiiiii...pppppp..bbbbbb...........................................
...iiiiii...pppppp..bbbbbb...........................................
...iiiiii...pppppp..bbbbbb...........................................
...iiiiii...pppppp..bbbbbb...........................................
#####################################################################
.....................................................................
.....................................................................
.....................................................................
.....................................................................
.....................................................................
.....................................................................
.....................................................................
.....................................................................
.....................................................................
.....................................................................
.....................................................................
....................................................................#

我正在这样加载地图,其中左上角为(0,0):

typedef struct Tile {
    char texture_id;
    int x;
    int y;
} Tile;

Map::Map(std::string raw_map_data) {
    // Initialize private variables
    this->unparsed_map_data= raw_map_data;

    // Split the map data into a std::vector<std::string> based off of newlines
    std::vector<std::string> map_data_split = split_string(raw_map_data, "\n");

    // Next, convert the map data to a vector Tile structs
    int cur_x = 0;
    int cur_y = 0;
    std::vector<Tile> tiles_processed;
    Tile tile;
    for (size_t i = 0; i < map_data_split.size(); i++) {
        for (size_t j = 0; j < map_data_split[i].size(); j++) {
            tile.x = cur_x;
            tile.y = cur_y;
            tile.texture_id = map_data_split[i][j];
            tiles_processed.push_back(tile);
            cur_x += TILE_WIDTH;
        }
        cur_x = 0;
        cur_y += TILE_HEIGHT;
    }
    this->tiles_parsed = tiles_processed;
    //std::reverse(this->tiles_parsed.begin(), this->tiles_parsed.end());
    DebugTiles(this->tiles_parsed); // DEBUG: used to print tiles to find errors
}

我已将相机坐标设置为窗口左上角的世界坐标。此外,播放器永远不会离开屏幕的中心。此外,我正在使用的从世界坐标到屏幕坐标的转换如下: screen coordinates = camera coordinates - world coordinates of tile

void Camera::Render(std::vector<Tile> tiles_to_render, SDL_Texture* player_texture) {
    // Render the scene
    for (size_t i = 0; i < tiles_to_render.size(); i++) {
        if (tiles_to_render[i].texture_id != '.') {
            // world_pos_tl is an SDL_Rect containing the camera coordinates
            SDL_Rect dstrect = {this->world_pos_tl.x - tiles_to_render[i].x, this->world_pos_tl.y - tiles_to_render[i].y, TILE_WIDTH, TILE_HEIGHT};
            SDL_RenderCopy(this->renderer, this->textures[tiles_to_render[i].texture_id], NULL, &dstrect);
        }
    }


    // Render the character (always in center of screen)
    SDL_Rect player_dstrect = {(WIDTH / 2) - TILE_WIDTH, (HEIGHT / 2) - TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT};
    SDL_RenderCopy(this->renderer, player_texture, NULL, &player_dstrect);
}

但是,当我编译并运行时,随着世界旋转270度,我得到以下结果。

运行代码的结果:

rendered image

1 个答案:

答案 0 :(得分:0)

特别感谢“ One Lone Coder”不和谐服务器上的 Gorbit99 为我解决了这个问题。

问题在于,该位置应该是屏幕位置=世界位置-摄像头位置。的原因是,当您向左移动对象并且摄像头静止不动时,该对象应该向左移动。但是,如果摄像头向左移动并且物体静止不动,则看起来应该像物体向右移动。

旁注:我过多地使用了关键字this,因为它仅用于在函数中的变量与类成员具有相同名称且您要指定所需的变量时使用使用类成员。因此,实际上,应该很少使用关键字this