SDL2 遊戲開發日記(一)

SDL2 遊戲開發日記(一)

SDL的基礎教程請戳這裏

創建遊戲窗口

開發工具:VC++ 2013

新建項目 --> Win32 控制檯應用程序

窗口類:

使用單例模式

窗口標題如果要顯示中文,要把字符串轉成UTF8編碼

#pragma once
#include <SDL.h>
#include <SDL_ttf.h>
#include <SDL_image.h>
#include <string>
using namespace std;
#define theGame SDLGame::Instance()
#define DEFAULT_FPS 60
class SDLGame{
private:	
	int mFrameTime = 1000 / DEFAULT_FPS;
	SDL_Window *mWindow = NULL;	
	SDL_Renderer *mRenderer = NULL;
	SDL_Event mEvent;
	bool IsRunning;
	SDLGame(){
		IsRunning = true;
	}
	SDLGame(const SDLGame &){}
	void operator=(const SDLGame &){}
public:	
	static SDLGame &Instance(){
		static SDLGame instance;
		return instance;
	}	
	~SDLGame(){}
	void setFPS(int fps){
		mFrameTime = 1000 / fps;
	}
	bool Init(string title,int x,int y,int width,int height){
		do{
			if (SDL_Init(SDL_INIT_EVERYTHING)){
				printf("SDL_Init error:%s\n", SDL_GetError());
				break;
			}
			if (TTF_Init()){
				printf("TTF_Init error:%s\n", SDL_GetError());
				break;
			}
			int imageFlags = IMG_INIT_PNG;
			if (!(IMG_Init(imageFlags) & imageFlags)){				
				printf("IMG_Init error:%s\n",SDL_GetError());
				break;
			}
			mWindow = SDL_CreateWindow(title.c_str(), x, y, width, height, SDL_WINDOW_SHOWN);
			if (mWindow == NULL){
				printf("SDL_CreateWindow error:%s\n",SDL_GetError());
				break;
			}
			mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
			if (mRenderer == NULL){
				printf("SDL_CreateRenderer error:%s\n", SDL_GetError());
				break;
			}
			IsRunning = true;
			return true;
		} while (0);
		IsRunning = false;
		return false;
	}
	SDL_Renderer *getRenderer(){
		return mRenderer;
	}
	void Run(){
		while (IsRunning)
		{
			int start = SDL_GetTicks();
			while (SDL_PollEvent(&mEvent)){
				if (mEvent.type == SDL_QUIT){
					IsRunning = false;
				}
			}
			SDL_SetRenderDrawColor(mRenderer, 0x00, 0x00, 0x00, 0xFF);
			SDL_RenderClear(mRenderer);
			//
			//繪圖
			//
			SDL_RenderPresent(mRenderer);
			int remaining_time = mFrameTime - (SDL_GetTicks() - start);
			if (remaining_time > 0){
				SDL_Delay(remaining_time);
			}
		}
		if (mRenderer != NULL)
			SDL_DestroyRenderer(mRenderer);
		if (mWindow != NULL)
			SDL_DestroyWindow(mWindow);		
		IMG_Quit();
		TTF_Quit();
		SDL_Quit();
	}
	void Destroy(){
		IsRunning = false;
	}
};

字符串轉UTF8函數:

//
std::string wcharToUTF8(wchar_t *str){
	std::string strOutUTF8;
	int n = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
	char * str2 = new char[n];
	WideCharToMultiByte(CP_UTF8, 0, str, -1, str2, n, NULL, NULL);
	strOutUTF8 = str2;
	delete[]str2;
	str2 = NULL;
	return strOutUTF8;
}
//
std::string charToUTF8(char *str)
{
	std::string strUTF8 = "";
	WCHAR * str1;
	int n = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
	str1 = new WCHAR[n];
	MultiByteToWideChar(CP_ACP, 0, str, -1, str1, n);
	strUTF8 = wcharToUTF8(str1);
	delete[]str1;
	str1 = NULL;	
	return strUTF8;
}

int _tmain(int argc, _TCHAR* argv[])
{
	std::string title = charToUTF8("中文標題");
	theGame.Init(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT);
	theGame.Run();
	return 0;
}

隱藏控制檯黑窗口

1、代碼中加入:

#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )

2、主函數 _tmain 改爲 main

3、在SDL_main.h中 108 - 110 行註釋掉main的宏定義。

三步缺一不可,否則報錯:

錯誤	1	error LNK2019: 無法解析的外部符號 _main,該符號在函數 ___tmainCRTStartup 中被引用	
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章