가끔 실수로 git 명령어를 잘못쳐서 소스를 날려버리는 경우가 있다.

이를 대비해서 git에서는 자신이 친 명령어들의 History를 볼수 있고 reset을 이용하여 돌아 갈 수 있다.

 

예를 들어

마지막으로 한 리셋이 잘못되어서 소스 들이 다 날라갔다.

 

그리고 우리가 돌아가야 할 곳은

HEAD@{1} 위치 이다.

 

다음과 같이 명령어릴 치면, 마지막으로 명령어를 친 전 상태로 돌아온다.

 

 

고로, 명령어를 잘못 입력하였을 경우에는 reflog 와 reset을 활용해 보자!

 

 

 

'리눅스(ubuntu) > Git 관련' 카테고리의 다른 글

자주 사용하는 명령어  (0) 2019.06.13
특정 commit diff 보기  (0) 2018.07.30
git remote 관련  (0) 2018.07.12
쉘에 git 브랜치 표시하기  (0) 2018.05.03
git merge 돌리기  (0) 2018.03.27

3 에서 설명한 SDL 라이브러리의 그림을 제어하는 부분을 수정하여

코드에서 재사용 할 수 있도록 싱글톤 클래스로 만든다.

 

 

<TextureManager.h>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#ifndef __TEXTUREMANAGER__
#define __TEXTUREMANAGER__
 
#include <string>
#include <SDL.h>
#include <map>
 
class TextureManager
{
public:
 
    ~TextureManager();
 
    // singleton 객체 가저오기
    static TextureManager* Instance();
 
    // 이미지 로드 함수
    bool Load(const std::string parFileName, const std::string parId, SDL_Renderer* parPRenderer);
 
    // 우리가 원하는 좌표와 크기로 이미지를 그린다.
    void Draw(const std::string parId, int parX, int parY, int parWidth, int parHeight, SDL_Renderer* parPRenderer,
        SDL_RendererFlip parFlip = SDL_FLIP_NONE);
    // 에니메이션을 위해서 프레임을 이용한다.
    void DrawFrame(const std::string parId, int parX, int parY, int parWidth, int parHeight, int parCurrentRow, int parCurrentFrame,
        SDL_Renderer* parPRenderer, SDL_RendererFlip parFlip = SDL_FLIP_NONE);
 
private:
    // 외부에서 생성하지 못하도록 private에 넣는다.
    TextureManager();
 
private:
 
    // static signleton 객체
    static TextureManager* s_pInstance;
 
    // 텍스처를 제어하기위해 Map을 사용한다.
    std::map<std::string, SDL_Texture*> m_textureMap;
 
};
 
 
#endif // !__TEXTUREMANAGER__
 
 
 
cs

 

<TextureManager.cpp>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "TextureManager.h"
#include "SDL_image.h"
 
TextureManager* TextureManager::s_pInstance = 0;
 
TextureManager::TextureManager():
    m_textureMap()
{
}
 
TextureManager::~TextureManager()
{
}
 
TextureManager* TextureManager::Instance()
{
    if (s_pInstance == nullptr)
    {
        s_pInstance = new TextureManager();
        return s_pInstance;
    }
    return s_pInstance;
}
 
bool TextureManager::Load(const std::string parFileName, const std::string parId, SDL_Renderer* parPRenderer)
{
    // 테스트를 위해서 임의로 init에서 그림을 생성하겠다.
    // surface 생성
    SDL_Surface* pTmpSurface = IMG_Load(parFileName.c_str());
 
    if (pTmpSurface == nullptr)
    {
        return false;
    }
 
    // surface를 이용해 texture 생성
    SDL_Texture* pTexture = SDL_CreateTextureFromSurface(parPRenderer, pTmpSurface);
    // 사용한 surface 해제
    SDL_FreeSurface(pTmpSurface);
 
    if (pTexture != nullptr)
    {
        // map에 저장
        m_textureMap[parId] = pTexture;
        return true;
    }
 
    // 여기에 도달한다면 문제가 있는거임.
    return false;
}
 
void TextureManager::Draw(const std::string parId, int parX, int parY, int parWidth, int parHeight, SDL_Renderer* parPRenderer, SDL_RendererFlip parFlip)
{
    SDL_Rect srcRect;
    SDL_Rect destRect;
 
    srcRect.x = 0;
    srcRect.y = 0;
    srcRect.w = destRect.w = parWidth;
    srcRect.h = destRect.h = parHeight;
    destRect.x = parX;
    destRect.y = parY;
    SDL_RenderCopyEx(parPRenderer, m_textureMap[parId], &srcRect, &destRect, 00, parFlip);
}
 
void TextureManager::DrawFrame(const std::string parId, int parX, int parY, int parWidth, int parHeight, int parCurrentRow, int parCurrentFrame,
    SDL_Renderer* parPRenderer, SDL_RendererFlip parFlip)
{
    SDL_Rect srcRect;
    SDL_Rect destRect;
    srcRect.x = parWidth * parCurrentFrame;
    srcRect.y = parHeight * (parCurrentRow - 1);
    srcRect.w = destRect.w = parWidth;
    srcRect.h = destRect.h = parHeight;
    destRect.x = parX;
    destRect.y = parY;
    SDL_RenderCopyEx(parPRenderer, m_textureMap[parId], &srcRect, &destRect, 00, parFlip);
}
 
cs

 

이제는, 이 클래스를 이용하여, 그림을 로드하고 드로우 할 수 있다.

 

추가로

Game class 에 Prepare 함수를 추가한다.

또한 지난 시간에 추가하였던 SDL_Rect 변수와 SDL_Texture, SDL_Renderer 변수를 제거한다.

( Init() 에서 추가하였던 부분도 삭제한다. )

 

Prepare()에 다음과 같이 추가한다.

 

Main 에서 Prepare()를 추가한다.

 

 

마지막으로 Render()에 draw 부분을 넣는다.

 

 

결과 화면은 다음과 같다.

 

 

출처: SDL Game Development  Shaun Ross Mitchell 

'C++ > SDL' 카테고리의 다른 글

3. SDL 에서 그림 그리기.  (0) 2021.03.01
2. SDL Init의 함수화 및 클래스화  (0) 2021.03.01
1. Hello SDL (SDL 초기화)  (0) 2021.03.01

이 단원에서는 그림을 그리는 방법을 알아본다.

 

그림을 그리기 위해서는 다음과 같은 구조체들이 필요하다.

1
2
3
4
5
6
SDL_Window* m_pWindow;
SDL_Renderer* m_pRenderer;
 
SDL_Texture* m_pTexture; // the new SDL_Texture variable, 텍스처 변수
SDL_Rect m_sourceRectangle; // the first rectangle, 그림의 그리고자하는 그림의 본 좌표,크기
SDL_Rect m_destinationRectangle; // another rectangle, 그림이 그려지는 좌표, 크기
cs

 

물론, 그림을 그리기위해선 그림파일이 필요하다

여기에서는 assets 폴더를 만들고 그림을 넣겠다.

그림파일 이름은 "enemy.png" 로 하겠다.

 

코딩을 시작하기 전에 SDL에서 사용하는 SDL_LoadBMP() 함수를 이용한 방법은 제외하겠다.

게임에서는 BMP를 사용하는 일이 이제는 거의 없고 PNG를 사용하기 때문에 제외하였다.

 

코딩은 저번 단원을 이어서 시작한다. -> gamdekong.tistory.com/172?category=982747

 

Game.h 에 다음을 추가한다.

Game.cpp 에 Init 함수와 Render 함수에 다음과 같이 추가한다.

 

Init 함수

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
 
bool Game::Init(const char* parTitle, int parXPos, int parYpos, int parWidth, int parHeight, int parFlags)
{
    // attempt to initialize SDL
    if (SDL_Init(SDL_INIT_EVERYTHING) == 0)
    {
        std::cout << "SDL init success\n";
        // init the window
        m_pWindow = SDL_CreateWindow(parTitle, parXPos, parYpos,
            parWidth, parHeight, parFlags);
        if (m_pWindow != 0// window init success
        {
            std::cout << "window creation success\n";
            m_pRenderer = SDL_CreateRenderer(m_pWindow, -10);
            if (m_pRenderer != 0// renderer init success
            {
                std::cout << "renderer creation success\n";
                // 파란색 화면.
                SDL_SetRenderDrawColor(m_pRenderer, 00255255);
            }
            else
            {
                std::cout << "renderer init fail\n";
                return false// renderer init fail
            }
        }
        else
        {
            std::cout << "window init fail\n";
            return false// window init fail
        }
    }
    else
    {
        std::cout << "SDL init fail\n";
        return false// SDL init fail
    }
 
    std::cout << "init success\n";
    m_bRunning = true// everything inited successfully, start the main loop
 
 
    /////////////////////////////////////////////////////////////////////////////////////////////
 
    // 테스트를 위해서 임의로 init에서 그림을 생성하겠다.
    // surface 생성
    SDL_Surface* pTempSurface = IMG_Load("assets/enemy.png");
  
    // surface를 이용해 texture 생성
    m_pTexture = SDL_CreateTextureFromSurface(m_pRenderer, pTempSurface);
 
    // 사용한 surface 해제
    SDL_FreeSurface(pTempSurface);
 
 
    // 이제는 Texture를 이용해 그림을 그릴 준비가 끝났다.
 
    // 우리가 로드한 텍스처에서 그림의 크기를 가져온다.
    SDL_QueryTexture(m_pTexture, NULLNULL&m_sourceRectangle.w, &m_sourceRectangle.h);
 
    // 그림이 뿌려질 x,y좌표를 0으로 설정한다.
    m_destinationRectangle.x = m_sourceRectangle.x = 0;
    m_destinationRectangle.y = m_sourceRectangle.y = 0;
    // 본래 그림의 width, height 를 뿌려질 크기로 똑같이 설정.
    m_destinationRectangle.w = m_sourceRectangle.w;
    m_destinationRectangle.h = m_sourceRectangle.h;
    /////////////////////////////////////////////////////////////////////////////////////////////
 
    return true;
}
cs

 

Render 함수

1
2
3
4
5
6
7
8
9
10
11
void Game::Render()
{
    SDL_RenderClear(m_pRenderer); // clear the renderer to the draw color
 
    // RenderClear 와 RenderPresent 사이에 렌더링 할 부분을 넣는다.
    ////////////////////////////////////////////////////////////////////////////////////////
    SDL_RenderCopy(m_pRenderer, m_pTexture, &m_sourceRectangle, &m_destinationRectangle);
    ////////////////////////////////////////////////////////////////////////////////////////
 
    SDL_RenderPresent(m_pRenderer); // draw to the screen
}
cs

 

실행하기 위해선 다음의 dll파일이 필요하다. 라이브러리에 있다.

 

실행하면 다음과 같은 결과를 얻을 수 있다.

 

 

 

 

그림의 좌표와 크기를 변경해보자.

 

위와 같이 변경했을때 결과는 다음과 같다.

 

 

SourceRectangle 변경하면 다음과 같다

 

위와같이 변경하면 결과는 다음과 같다.

 

 

마지막으로 다음 함수를 이용하여 그림을 Flip 시킬 수 있다.

 

결과는 다음과 같다.

Flip Flag는 다음과 같다

 

 

 

 

출처: SDL Game Development,  Shaun Ross Mitchell 

+ Recent posts