SDL2角色移动角度异常:无法匹配旋转网格的30°移动求助
等距网格角色移动匹配问题
我绘制了一个向右旋转π/6(30°)的网格以实现深度效果,希望角色(Sprite)能沿网格方块移动。根据三角函数逻辑,左右移动应遵循π/6角度,上下移动应遵循π/3角度,但实际右移仅对应约20°,无法和网格对齐。多次测试仍无法解决,特来求助。
当前代码如下:
#include <stdio.h> #include <stdbool.h> #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <math.h> #include "graphique.h" #include "../constantes.h" #define GRID_ROWS 15 #define GRID_COLS 12 #define CELL_WIDTH (WINDOW_WIDTH / GRID_COLS) #define CELL_HEIGHT (WINDOW_HEIGHT / GRID_ROWS) #define CELL_RATIO (CELL_HEIGHT / CELL_WIDTH) typedef struct { float x; float y; } Point; int graphicGame(int joueur) { if (SDL_Init(SDL_INIT_EVERYTHING)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error in init: %s", SDL_GetError()); exit(-1); } atexit(SDL_Quit); if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error in image init: %s", IMG_GetError()); exit(-1); } atexit(IMG_Quit); SDL_Window *window; window = SDL_CreateWindow("JETAGAME", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN); if (!window) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error in window init: %s", SDL_GetError()); exit(-1); } SDL_Renderer *renderer; renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if (!renderer) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error in renderer init: %s", SDL_GetError()); exit(-1); } SDL_Surface *playerSpriteSurface = IMG_Load("src/Graphique/Sprites/sprite.png"); if (!playerSpriteSurface) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error in player sprite surface init: %s", IMG_GetError()); exit(-1); } SDL_Texture *playerSpriteTexture = SDL_CreateTextureFromSurface(renderer, playerSpriteSurface); if (!playerSpriteTexture) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error in player sprite texture init: %s", SDL_GetError()); exit(-1); } SDL_FreeSurface(playerSpriteSurface); int playerSpriteFullWidth, playerSpriteFullHeight; if (SDL_QueryTexture(playerSpriteTexture, NULL, NULL, &playerSpriteFullWidth, &playerSpriteFullHeight)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error in query texture: %s", SDL_GetError()); exit(-1); } int playerSpriteWidth = playerSpriteFullWidth / 4; int playerSpriteHeight = playerSpriteFullHeight / 4; SDL_Event event; bool running = true; int offset = 0; double playerX = 3.5, playerY = 3.5; int direction = 0; double angleHorizontal = M_PI / 6; double angleVertical = M_PI / 6; double Cx = WINDOW_WIDTH / 2; double Cy = WINDOW_HEIGHT / 2; while (running) { if (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: running = false; break; case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_DOWN: playerX -= cos(M_PI/3); playerY += sin(M_PI/3); offset += 1; offset %= 4; direction = 0; break; case SDLK_UP: playerX += cos(M_PI/2.5); playerY -= sin(M_PI/2.5); offset += 1; offset %= 4; direction = 1; break; case SDLK_LEFT: playerX -= cos(M_PI/6); playerY -= sin(M_PI/6); offset += 1; offset %= 4; direction = 2; break; case SDLK_RIGHT: playerX += cos(M_PI/6); playerY += sin(M_PI/6); offset += 1; offset %= 4; direction = 3; break; } break; case SDL_KEYUP: offset = 0; break; } SDL_Color const BACKGROUND_COLOR = {.r = 0xFF, .g = 0xE6E6E6, .b = 0xFF, .a = SDL_ALPHA_OPAQUE}; if (SDL_SetRenderDrawColor(renderer, BACKGROUND_COLOR.r, BACKGROUND_COLOR.g, BACKGROUND_COLOR.b, BACKGROUND_COLOR.a)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error in set render draw color: %s", SDL_GetError()); } if (SDL_RenderClear(renderer)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error in render clear: %s", SDL_GetError()); } SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); for (int i = 0; i <= GRID_ROWS; ++i) { double y = i * (WINDOW_HEIGHT / GRID_ROWS); double x1 = 0; double y1 = y; double x2 = WINDOW_WIDTH; double y2 = y; double Rx1 = (x1 - Cx) * cos(angleHorizontal) - (y1 - Cy) * sin(angleHorizontal) + Cx; double Ry1 = (x1 - Cx) * sin(angleHorizontal) + (y1 - Cy) * cos(angleHorizontal) + Cy; double Rx2 = (x2 - Cx) * cos(angleHorizontal) - (y2 - Cy) * sin(angleHorizontal) + Cx; double Ry2 = (x2 - Cx) * sin(angleHorizontal) + (y2 - Cy) * cos(angleHorizontal) + Cy; SDL_RenderDrawLine(renderer, (int)Rx1, (int)Ry1, (int)Rx2, (int)Ry2); } for (int j = 0; j <= GRID_COLS; ++j) { double x = j * (WINDOW_WIDTH / GRID_COLS); double x1 = x; double y1 = 0; double x2 = x; double y2 = WINDOW_HEIGHT; double Rx1 = (x1 - Cx) * cos(angleVertical) - (y1 - Cy) * sin(angleVertical) + Cx; double Ry1 = (x1 - Cx) * sin(angleVertical) + (y1 - Cy) * cos(angleVertical) + Cy; double Rx2 = (x2 - Cx) * cos(angleVertical) - (y2 - Cy) * sin(angleVertical) + Cx; double Ry2 = (x2 - Cx) * sin(angleVertical) + (y2 - Cy) * cos(angleVertical) + Cy; SDL_RenderDrawLine(renderer, (int)Rx1, (int)Ry1, (int)Rx2, (int)Ry2); // Lignes verticales } SDL_Rect playerSpriteRect = {.x = offset * playerSpriteWidth, .y = direction * playerSpriteHeight, .w = playerSpriteWidth, .h = playerSpriteHeight}; SDL_Rect playerDestRect = {.x = playerX * CELL_WIDTH, .y = playerY * CELL_HEIGHT, .w = playerSpriteWidth, .h = playerSpriteHeight}; if (SDL_RenderCopy(renderer, playerSpriteTexture, &playerSpriteRect, &playerDestRect)) SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error in render copy: %s", SDL_GetError()); SDL_RenderPresent(renderer); } } return 0; }
- 尝试使用π/6的实际效果:

- 期望实现的效果:

内容的提问来源于stack exchange,提问作者EleZen
相关产品推荐
相关产品推荐

