현재 SDL을 배우고 있으며 Pacman 게임을 만들려고합니다. 엄청난 양의 코드로 인해 수렁에 빠지지 않도록 단계별로 시도하고 있습니다.SDL에서 움직이지 않는 이미지 렌더링
지금까지 빈 창을 만들고 그 위에 Pacman 이미지를 렌더링했습니다. 나는 화살표 키를 누르고 Pacman을 창 주위로 움직일 수있다. 저는 Pacman 이미지가 RenderCopy를 사용하여 창에 blit하는 SDL_Texture로 저장되도록 설정했습니다. 사용자가 화살표를 누를 때마다 이미지의 좌표를 이동하고 전체 이미지를 다시 렌더링합니다. 이것은 잘 작동합니다. 그러나 이제 팩맨이 먹을 수있는 점들을 화면에 표시하고 싶습니다. 그러나 도트 이미지를로드하여 팩맨과 함께 화면에 blit하는 새로운 텍스처로 저장할 경우 Pacman을 이동할 때마다 점이 깜박이고 팩맨과 함께 지워지고 다시 렌더링되기 때문에 점으로 깜박입니다.
제 질문은이 "깜박임"을 어떻게 피합니까? 어떻게 든 나머지 화면을 렌더링하지 않고도 Pacman 만 렌더링 할 수 있습니까? 아니면 다른 방법이 있습니까? 배경에서 나중에 미로를 만들려고 할 때도 같은 문제가 생길 것입니다. 렌더링 할 때마다 깜박 거리지 않는 정적 배경을 만드는 방법은 무엇입니까?
아래 코드는 지금까지입니다. 거기에 나쁜 형식의 코드가 있다면 용서해주십시오. 제가 말했듯이, 저는 SDL (C++에 익숙하지 않은)을 배우기 시작했습니다. 그래서 "결코 그렇게하지 말아야합니다!" 거기 가지의 종류, 나는 :)
#include <iostream>
#include <SDL2/SDL.h>
using namespace std;
const int WINDOW_HEIGHT = 480;
const int WINDOW_WIDTH = 640;
const int MOVE_WIDTH = 10;
int main(int argc, const char * argv[])
{
SDL_Window* mainWindow = NULL; //To hold the main window
SDL_Renderer* renderer = NULL; //To hold the renderer
SDL_Rect targetRect; //Rectangle to which pacman image will be drawn
SDL_Surface* bmpSurface = NULL; //To hold bmp image
SDL_Texture* bmpTexture = NULL; //To hold bmp image
//Initialize SDL and check for errors
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
cout << "ERROR: could not initialize SDL." << endl;
}
//Create a window
mainWindow = SDL_CreateWindow("BAM", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, 0);
if (mainWindow == NULL)
{
cout << "ERROR: could not initialize mainWindow." << endl;
}
//Initialize renderer
renderer = SDL_CreateRenderer(mainWindow, -1, SDL_RENDERER_ACCELERATED);
//Load image and store in an SDL_Surface
bmpSurface = SDL_LoadBMP("/Users/billgrenard/Desktop/Programs/SDL/SDL_KeyPresses/SDL_KeyPresses/pacman_closed.bmp");
if (bmpSurface == NULL)
{
cout << "ERROR: could not load bmp file." << endl;
}
//Convert surface to texture for rendering
bmpTexture = SDL_CreateTextureFromSurface(renderer, bmpSurface);
if (bmpTexture == NULL)
{
cout << "ERROR: could not convert bmp surface." << endl;
}
SDL_FreeSurface(bmpSurface);
//Define rectangle where pacman image is to be blitted
targetRect.w = 30;
targetRect.h = 30;
targetRect.x = (WINDOW_WIDTH/2) - (targetRect.w/2);
targetRect.y = (WINDOW_HEIGHT/2) - (targetRect.h/2);
//Main game loop
while (1)
{
SDL_Event e;
if (SDL_PollEvent(&e))
{
//Quit when user x's out the window
if (e.type == SDL_QUIT)
{
break;
}
//If user presses a key enter switch statement
else if(e.type == SDL_KEYDOWN)
{
switch (e.key.keysym.sym) {
//If user presses up arrow and the resulting move is inside the window, then move the Pacman's position
case SDLK_UP:
if (targetRect.y - MOVE_WIDTH > 0)
{
targetRect.y -= MOVE_WIDTH;
}
break;
//If user presses down arrow and the resulting move is inside the window, then move the Pacman's position
case SDLK_DOWN:
if (targetRect.y + MOVE_WIDTH < (WINDOW_HEIGHT - targetRect.w))
{
targetRect.y += MOVE_WIDTH;
}
break;
//If user presses right arrow and the resulting move is inside the window, then move the Pacman's position
case SDLK_RIGHT:
if (targetRect.x + MOVE_WIDTH < (WINDOW_WIDTH - targetRect.w))
{
targetRect.x += MOVE_WIDTH;
}
break;
//If user presses left arrow and the resulting move is inside the window, then move the Pacman's position
case SDLK_LEFT:
if (targetRect.x - MOVE_WIDTH > 0)
{
targetRect.x -= MOVE_WIDTH;
}
break;
default:
break;
}
}
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, bmpTexture, NULL, &targetRect);
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(mainWindow);
SDL_DestroyTexture(bmpTexture);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0;
}
EDIT 그것을 지적하는 사람을 이해할 것 : 대답에서 RASER의 의견에, 여기에 내가 PollEvent의 예를 볼 수있는 링크입니다 : 사용 http://wiki.libsdl.org/SDL_CreateRenderer?highlight=%28%5CbCategoryAPI%5Cb%29%7C%28SDLFunctionTemplate%29
어떻게 점을 렌더링하고 있습니까? – raser
도트 이미지를로드하고 새 텍스처에 저장했습니다. 그런 다음 동일한 렌더러를 사용하여 두 번째 RenderCopy (RenderCopy 직후에 Pacman 이미지에 사용한)를 호출했지만 도트 텍스처를 렌더링하고 다른 targetRect를 사용했습니다. 코드에서 이미 가지고있는 동일한 RenderPresent 함수를 유지했습니다. 도트와 팩맨을 렌더링하십시오. – wgrenard
허. 나는 지금 그렇게 할 수 있는지를보기 위해 시험을 썼다. 팩맨이 점들 또는 점들과 함께 깜박입니까? – raser