在 Tilemap 类中,我使用矢量
然而,虽然为 next_tilemap 分配新值工作正常,但为 present_tilemap 对象分配值是错误的,因为向量
我将在这里发布我的代码,为了简化它,我将删除所有与我在问题中提出的问题无关的不相关部分。为了方便起见,我还会提供一个日志文件,记录每次迭代后的程序。
文件 Tilemap.hpp:
#pragma once
#ifndef Tilemap_hpp
#define Tilemap_hpp
#include <iostream>
#include <vector>
#include <SDL2/SDL.h>
using namespace std;
class Tilemap
{
private:
int tilemap_index;
int tilemap[18][32];
int number_of_platform = 0;
vector <SDL_Rect> platform_rects;
public:
Tilemap();
Tilemap(int index, int tilemap[18][32], int number, SDL_Rect platform[]);
~Tilemap();
int get_tilemap_index();
int get_tilemap(int x, int y);
void set_tilemap_index(int index);
void set_tilemap(int x, int y, int value);
int get_number_of_platform();
void set_number_of_platform(int number_of_platform);
void set_platform_rects(std::vector <SDL_Rect> platform_rects);
std::vector <SDL_Rect> get_platform_rects()
{
return platform_rects;
}
vector <SDL_Rect> update_platform_rects(Tilemap& tilemap, int tilemap_pos_x);
void create_platform_rects(int x, int y, int width, int height);
void update_platform_rects(int tilemap_pos_x);
};
#endif /* Tilemap_hpp */
文件 Tilemap.cpp:
#include "Tilemap.hpp"
Tilemap::Tilemap()
{
}
Tilemap::Tilemap(int index, int tilemap[18][32], int number, SDL_Rect platform[])
{
tilemap_index = index;
for (int i = 0; i < 18; i++)
{
for (int j = 0; j < 32; j++)
{
this->tilemap[i][j] = tilemap[i][j];
}
}
number_of_platform = number;
for (int i = 0; i < number; i++)
{
platform_rects.push_back(platform[i]);
}
}
Tilemap::~Tilemap()
{
}
int Tilemap::get_tilemap_index()
{
return tilemap_index;
}
int Tilemap::get_tilemap(int x, int y)
{
return tilemap[x][y];
}
void Tilemap::set_tilemap_index(int index)
{
tilemap_index = index;
}
void Tilemap::set_tilemap(int x, int y, int value)
{
tilemap[x][y] = value;
}
void Tilemap::create_platform_rects(int x, int y, int width, int height)
{
SDL_Rect platform_rect;
platform_rect.x = x;
platform_rect.y = y;
platform_rect.w = width;
platform_rect.h = height;
platform_rects.push_back(platform_rect);
}
void Tilemap::update_platform_rects(int tilemap_pos_x)
{
// di chuyển các platform sang trái với tốc độ speed
for (int i = 0; i < platform_rects.size(); i++)
{
platform_rects[i].x += tilemap_pos_x;
}
// xóa các platform ở phía bên trái màn hình
while (!platform_rects.empty() && platform_rects[0].x + platform_rects[0].w < 0)
{
platform_rects.erase(platform_rects.begin());
}
}
int Tilemap::get_number_of_platform()
{
return number_of_platform;
}
void Tilemap::set_number_of_platform(int number_of_platform)
{
this->number_of_platform = number_of_platform;
}
void Tilemap::set_platform_rects(std::vector<SDL_Rect> platform_rects)
{
this->platform_rects = platform_rects;
}
vector <SDL_Rect> Tilemap::update_platform_rects(Tilemap& tilemap, int tilemap_pos_x)
{
for (int i = 0; i < platform_rects.size(); i++)
{
platform_rects[i].x += tilemap_pos_x;
}
return platform_rects;
}
文件 Tilemap_data.hpp:
...
SDL_Rect def_platform_0 = {240, 400, 1000, 80};
SDL_Rect array_of_platforms_0[1] = {def_platform_0};
Tilemap Default_tilemap(0, tile_map_default, 1, array_of_platforms_0);
SDL_Rect tilemap1_platform_1 = {0, 280, 280, 40};
SDL_Rect tilemap1_platform_2 = {280, 240, 320, 40};
SDL_Rect tilemap1_platform_3 = {600, 360, 120, 40};
SDL_Rect tilemap1_platform_4 = {720, 560, 120, 40};
SDL_Rect tilemap1_platform_5 = {840, 480, 200, 40};
SDL_Rect tilemap1_platform_6 = {1040, 400, 240, 40};
SDL_Rect array_of_platforms_1[6] = {tilemap1_platform_1, tilemap1_platform_2, tilemap1_platform_3, tilemap1_platform_4, tilemap1_platform_5, tilemap1_platform_6};
Tilemap Tilemap_1(1, tile_map_1, 6, array_of_platforms_1)
(16 more...
To simplify, all 16 next Tilemap objects are copies of the Tilemap_1 object.)
文件main.cpp:
// Using SDL and standard IO
#include "Library.hpp"
#include <fstream>
// Screen dimension constants
const int SCREEN_WIDTH = 1280;
const int SCREEN_HEIGHT = 720;
Game *game = nullptr;
Player *player = nullptr;
int main(int argc, char *args[])
{
ofstream outfile;
outfile.open("log.txt");
int const FPS = 60;
int const frameDelay = 1000 / FPS;
player = new Player(320, 0, 1, -10, 0.5, 70, 90, false, false);
Texture_box player_texture(0, 0, player->get_width(), player->get_height(), player->get_x(), player->get_y(), player->get_width(), player->get_height());
Texture_box background(0, 0, 1280, 720, 0, 0, 1280, 720);
Texture_box next_background(0, 0, 1280, 720, 1280, 0, 1280, 720);
Texture_box sky(0, 0, 1280, 720, 0, 0, 1280, 720);
Texture_box plains(0, 0, 1280, 720, 0, 0, 1280, 720);
Texture_box next_plains(0, 0, 1280, 720, 1280, 0, 1280, 720);
Texture_box mountain(0, 0, 1280, 720, 0, 0, 1280, 720);
Texture_box next_mountain(0, 0, 1280, 720, 1280, 0, 1280, 720);
Texture_box cloud(0, 0, 1280, 720, 0, 0, 1280, 720);
Texture_box next_cloud(0, 0, 1280, 720, 1280, 0, 1280, 720);
Texture_box cloud_front(0, 0, 1280, 720, 0, 0, 1280, 720);
Texture_box next_cloud_front(0, 0, 1280, 720, 1280, 0, 1280, 720);
Texture_box cloud_behind(0, 0, 1280, 720, 0, 0, 1280, 720);
Texture_box next_cloud_behind(0, 0, 1280, 720, 1280, 0, 1280, 720);
Uint32 frameStart;
int frameTime;
game = new Game();
game->init("Sky Runner", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, false);
SDL_Texture *texture[50];
enum texture_type
{
BACKGROUND_SKY,
BACKGROUND_MOUNTAIN,
BACKGROUND_PLAINS,
BACKGROUND_CLOUD,
BACKGROUND_CLOUD_BEHIND,
BACKGROUND_CLOUD_FRONT,
CHARACTER,
MENU,
NEW_GAME,
INSTRUCTION,
SETTING,
QUIT,
INSTRUCTION_MENU,
};
game->loadTexture(texture[BACKGROUND_SKY], game->getRenderer(), "Image/Background/Sky.png");
game->loadTexture(texture[BACKGROUND_MOUNTAIN], game->getRenderer(), "Image/Background/mountain.png");
game->loadTexture(texture[BACKGROUND_PLAINS], game->getRenderer(), "Image/Background/plains_ground.png");
game->loadTexture(texture[BACKGROUND_CLOUD], game->getRenderer(), "Image/Background/cloud_1.png");
game->loadTexture(texture[BACKGROUND_CLOUD_BEHIND], game->getRenderer(), "Image/Background/cloud_behind.png");
game->loadTexture(texture[BACKGROUND_CLOUD_FRONT], game->getRenderer(), "Image/Background/cloud_front.png");
game->loadTexture(texture[CHARACTER], game->getRenderer(), "Image/Character/Character.png");
game->loadTexture(texture[MENU], game->getRenderer(), "Image/Menu/Menu/menu.png");
game->loadTexture(texture[NEW_GAME], game->getRenderer(), "Image/Menu/Menu/selected_start_button.png");
game->loadTexture(texture[INSTRUCTION], game->getRenderer(), "Image/Menu/Menu/selected_instruction_button.png");
game->loadTexture(texture[SETTING], game->getRenderer(), "Image/Menu/Menu/selected_setting_button.png");
game->loadTexture(texture[QUIT], game->getRenderer(), "Image/Menu/Menu/selected_quit_button.png");
Texture_box tilemap_texture(0, 0, 40, 40, 0, 0, 40, 40);
SDL_Texture *pT;
game->loadTexture(pT, game->getRenderer(), "Image/Background/test.png");
int present_tilemap_pos_x = 0;
int next_tilemap_pos_x = 1280;
const int speed = 5;
bool is_first_tilemap = true;
int present_tilemap_index = 0;
int next_tilemap_index = game->random_tilemap(18, game->getScore());
vector<SDL_Rect> present_platform_rects = platform_rects[0];
vector<SDL_Rect> next_platform_rects = platform_rects[next_tilemap_index];
Tilemap present_tilemap = array_of_tilemap[present_tilemap_index];
Tilemap next_tilemap = array_of_tilemap[next_tilemap_index];
present_platform_rects = array_of_tilemap[present_tilemap_index].update_platform_rects(present_tilemap, present_tilemap_pos_x);
next_platform_rects = next_tilemap.update_platform_rects(next_tilemap, next_tilemap_pos_x);
int count = 0;
game->render(game->getRenderer(), texture[BACKGROUND_SKY], sky.get_sourceRect(), sky.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_CLOUD], cloud.get_sourceRect(), cloud.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_CLOUD_BEHIND], cloud_behind.get_sourceRect(), cloud_behind.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_CLOUD_FRONT], cloud_front.get_sourceRect(), cloud_front.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_MOUNTAIN], mountain.get_sourceRect(), mountain.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_PLAINS], plains.get_sourceRect(), plains.get_destinationRect());
game->render(game->getRenderer(), texture[MENU], main_menu_screen_box.get_sourceRect(), main_menu_screen_box.get_destinationRect());
SDL_RenderPresent(game->getRenderer());
while (game->menu())
{
SDL_Event event;
SDL_PollEvent(&event);
switch (event.type)
{
case SDL_QUIT:
game->setRunning(false);
break;
case SDL_MOUSEMOTION:
int mouseX, mouseY;
SDL_GetMouseState(&mouseX, &mouseY);
if (isMouseInside(mouseX, mouseY, new_game_button))
{
game->render(game->getRenderer(), texture[NEW_GAME], main_menu_screen_box.get_sourceRect(), main_menu_screen_box.get_destinationRect());
SDL_RenderPresent(game->getRenderer());
}
else if (isMouseInside(mouseX, mouseY, quit_button))
{
game->render(game->getRenderer(), texture[QUIT], main_menu_screen_box.get_sourceRect(), main_menu_screen_box.get_destinationRect());
SDL_RenderPresent(game->getRenderer());
}
else if (isMouseInside(mouseX, mouseY, setting_button))
{
game->render(game->getRenderer(), texture[SETTING], main_menu_screen_box.get_sourceRect(), main_menu_screen_box.get_destinationRect());
SDL_RenderPresent(game->getRenderer());
}
else if (isMouseInside(mouseX, mouseY, instruction_button))
{
game->render(game->getRenderer(), texture[INSTRUCTION], main_menu_screen_box.get_sourceRect(), main_menu_screen_box.get_destinationRect());
SDL_RenderPresent(game->getRenderer());
}
else
{
game->render(game->getRenderer(), texture[MENU], main_menu_screen_box.get_sourceRect(), main_menu_screen_box.get_destinationRect());
SDL_RenderPresent(game->getRenderer());
}
break;
case SDL_MOUSEBUTTONDOWN:
// Kiểm tra xem người dùng đã click chuột vào nút nào
SDL_GetMouseState(&mouseX, &mouseY);
if (isMouseInside(mouseX, mouseY, new_game_button))
{
game->setPlaying(true);
game->setMenu(false);
}
if (isMouseInside(mouseX, mouseY, quit_button))
{
game->setMenu(false);
game->setRunning(false);
}
break;
}
}
while (game->playing())
{
frameStart = SDL_GetTicks64();
SDL_Event event;
SDL_PollEvent(&event);
switch (event.type)
{
case SDL_QUIT:
game->setPlaying(false);
game->setRunning(false);
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
game->setPlaying(false);
game->setRunning(false);
break;
case SDLK_UP:
player->set_jumping(true);
break;
case SDLK_RIGHT:
break;
}
default:
count++;
game->setScore(count / 10);
outfile << "Number of key event: " << count << endl;
outfile << "Your score: " << game->getScore() << endl;
present_platform_rects = present_tilemap.update_platform_rects(present_tilemap, -speed);
next_platform_rects = next_tilemap.update_platform_rects(next_tilemap, -speed);
player->player_jumping(*player);
player->set_falling(player->is_falling(*player, present_platform_rects, next_platform_rects));
player->player_falling(*player);
player_texture.set_destinationRect(player->get_x(), player->get_y(), player->get_width(), player->get_height());
present_tilemap_pos_x -= speed;
next_tilemap_pos_x -= speed;
break;
}
/*
game->Moving_background(texture[BACKGROUND_CLOUD], cloud, next_cloud, game->getRenderer(), speed - 4);
game->Moving_background(texture[BACKGROUND_CLOUD_BEHIND], cloud_behind, next_cloud_behind, game->getRenderer(), speed - 3);
game->Moving_background(texture[BACKGROUND_CLOUD_FRONT], cloud_front, next_cloud_front, game->getRenderer(), speed - 2);
game->Moving_background(texture[BACKGROUND_MOUNTAIN], mountain, next_mountain, game->getRenderer(), speed - 1);
game->Moving_background(texture[BACKGROUND_PLAINS], plains, next_plains, game->getRenderer(), speed);
*/
// Background render
game->render(game->getRenderer(), texture[BACKGROUND_SKY], sky.get_sourceRect(), sky.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_CLOUD], cloud.get_sourceRect(), cloud.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_CLOUD], next_cloud.get_sourceRect(), next_cloud.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_CLOUD_BEHIND], cloud_behind.get_sourceRect(), cloud_behind.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_CLOUD_BEHIND], next_cloud_behind.get_sourceRect(), next_cloud_behind.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_CLOUD_FRONT], cloud_front.get_sourceRect(), cloud_front.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_CLOUD_FRONT], next_cloud_front.get_sourceRect(), next_cloud_front.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_MOUNTAIN], mountain.get_sourceRect(), mountain.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_MOUNTAIN], next_mountain.get_sourceRect(), next_mountain.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_PLAINS], plains.get_sourceRect(), plains.get_destinationRect());
game->render(game->getRenderer(), texture[BACKGROUND_PLAINS], next_plains.get_sourceRect(), next_plains.get_destinationRect());
game->render(game->getRenderer(), texture[CHARACTER], player_texture.get_sourceRect(), player_texture.get_destinationRect());
// Tilemap render
if (is_first_tilemap || present_tilemap_pos_x <= -1280)
{
if (is_first_tilemap)
{
game->infinite_tilemap(array_of_tilemap, 18, tilemap_texture, pT, 0, next_tilemap_index, present_tilemap_pos_x, next_tilemap_pos_x, speed);
// present_platform_rects = platform_rects[present_tilemap_index];
if (present_tilemap_pos_x == -1280)
{
is_first_tilemap = false;
}
}
else
{
present_tilemap_index = next_tilemap_index;
next_tilemap_index = game->random_tilemap(18, game->getScore());
present_tilemap = array_of_tilemap[present_tilemap_index];
next_tilemap = array_of_tilemap[next_tilemap_index];
present_platform_rects.clear();
next_platform_rects.clear();
present_platform_rects.assign(platform_rects[present_tilemap_index].begin(), platform_rects[present_tilemap_index].end());
next_platform_rects = platform_rects[next_tilemap_index];
present_tilemap_pos_x = 0;
next_tilemap_pos_x = 1280;
present_platform_rects = present_tilemap.update_platform_rects(present_tilemap, present_tilemap_pos_x);
next_platform_rects = next_tilemap.update_platform_rects(next_tilemap, next_tilemap_pos_x);
}
}
game->drawing_tilemap(array_of_tilemap[present_tilemap_index], tilemap_texture, pT, present_tilemap_pos_x);
game->drawing_tilemap(array_of_tilemap[next_tilemap_index], tilemap_texture, pT, next_tilemap_pos_x);
SDL_RenderPresent(game->getRenderer());
frameTime = SDL_GetTicks64() - frameStart;
if (frameDelay > frameTime)
{
SDL_Delay(frameDelay - frameTime);
}
game->death_message(*player);
}
game->clean();
return 0;
}
文件log.txt文件:
Game start!
---------------------------------------------
Number of key event: 0
Present_tilemap_index: [0]
platform[0]_rect: 240 400 1000 80
Next_tilemap_index: [2]
next_platform[0]_rect: 1280 280 280 40
next_platform[1]_rect: 1560 240 320 40
next_platform[2]_rect: 1880 360 120 40
next_platform[3]_rect: 2000 560 120 40
next_platform[4]_rect: 2120 480 200 40
next_platform[5]_rect: 2320 400 240 40
---------------------------------------------
Number of key event: 1
Present_tilemap_index: [0]
platform[0]_rect: 235 400 1000 80
Next_tilemap_index: [2]
next_platform[0]_rect: 1275 280 280 40
next_platform[1]_rect: 1555 240 320 40
next_platform[2]_rect: 1875 360 120 40
next_platform[3]_rect: 1995 560 120 40
next_platform[4]_rect: 2115 480 200 40
next_platform[5]_rect: 2315 400 240 40
---------------------------------------------
Number of key event: 2
Present_tilemap_index: [0]
platform[0]_rect: 230 400 1000 80
Next_tilemap_index: [2]
next_platform[0]_rect: 1270 280 280 40
next_platform[1]_rect: 1550 240 320 40
next_platform[2]_rect: 1870 360 120 40
next_platform[3]_rect: 1990 560 120 40
next_platform[4]_rect: 2110 480 200 40
next_platform[5]_rect: 2310 400 240 40
---------------------------------------------
...
---------------------------------------------
Number of key event: 256
Present_tilemap_index: [0]
platform[0]_rect: -1040 400 1000 80
Next_tilemap_index: [2]
next_platform[0]_rect: 0 280 280 40
next_platform[1]_rect: 280 240 320 40
next_platform[2]_rect: 600 360 120 40
next_platform[3]_rect: 720 560 120 40
next_platform[4]_rect: 840 480 200 40
next_platform[5]_rect: 1040 400 240 40
---------------------------------------------
Number of key event: 257
Present_tilemap_index: [0]
platform[0]_rect: -1045 400 1000 80
Next_tilemap_index: [2]
next_platform[0]_rect: -5 280 280 40
next_platform[1]_rect: 275 240 320 40
next_platform[2]_rect: 595 360 120 40
next_platform[3]_rect: 715 560 120 40
next_platform[4]_rect: 835 480 200 40
next_platform[5]_rect: 1035 400 240 40
---------------------------------------------
//My note: after "keyevent 257, the condition for assigning the Tilemap objects (that I mentioned above) is satisfied.
---------------------------------------------
My note 2: If it works directly, the log must be:
Present_tilemap_index_after_update: [2]
platform[0]_rect: 0 280 280 40
platform[1]_rect: 280 240 320 40
platform[2]_rect: 600 360 120 40
platform[3]_rect: 720 560 120 40
platform[4]_rect: 840 480 200 40
platform[5]_rect: 1040 400 240 40
---------------------------------------------
The real result:
Present_tilemap_index_after_update: [2]
platform[0]_rect: 0 280 1000 40
platform[1]_rect: 280 240 -131965695 40
platform[2]_rect: 600 360 -1769019472 40
platform[3]_rect: 720 560 -131310329 40
platform[4]_rect: 840 480 5111881 40
platform[5]_rect: 1040 400 -131179259 40
---------------------------------------------
Number of key event: 258
Your score: 25
Player: 320 150 70 90
Player max height: 0
Falling: 0
Jumping: 0
Present_tilemap_index: [2]
platform[0]_rect: -5 280 1000 40
platform[1]_rect: 275 240 -131965695 40
platform[2]_rect: 595 360 -1769019472 40
platform[3]_rect: 715 560 -131310329 40
platform[4]_rect: 835 480 5111881 40
platform[5]_rect: 1035 400 -131179259 40
Next_tilemap_index: [13]
next_platform[0]_rect: 1275 280 280 40
next_platform[1]_rect: 1555 240 320 40
next_platform[2]_rect: 1875 360 120 40
next_platform[3]_rect: 1995 560 120 40
next_platform[4]_rect: 2115 480 200 40
next_platform[5]_rect: 2315 400 240 40
---------------------------------------------
...
我尝试了各种不同的方法,但结果还是一样。我哪里做错了?请帮我。如果您需要任何其他信息,我会提供。