[實戰]C++加Lua加SDL來重寫龍神錄彈幕遊戲(1):準備

        自學程序加工作好幾年了,是時候來練個手了(不算用引擎開發遊戲)。之前Google學習資料的時候,找到一個彈幕射擊遊戲的教程,稍微瞄了眼,還挺不錯的,但用的是封裝的DxLib庫,這就不開心了,後面就沒看了。學習DirectX也有年頭了,覺得是時候可以練習下,但不打算用DirectX來開發,打算用最近剛學習的SDL或者SFML來開發。

        爲了加大難度,就打算採用C++加Lua的方式來開發,不用第3方庫,全部自己手寫導出到Lua這邊,加深一下自己對C++和Lua的通信原理。

PS:之前有人聯繫我說,說看不懂,還說只有寫的人能看懂,還有讓我幫你來做功能的。我就奇了怪了,你自己基礎不到位,怪作者,爲啥不怨一下你自己不努力呢?

準備工作
        IDE用的是Visual Stuido 2019,這個下載就不介紹了,版本很新,一直在推薦更新╮(╯▽╰)╭。接下來準備lua源碼和SDL庫。

Lua準備工作

        去lua官網(https://www.lua.org/download.html)下載源代碼。

        新建一個Visual Stuido空工程,空工程名爲Lua,將剛纔下的lua源碼解壓,解壓得到lua-5.3.5文件夾,將lua-5.3.5文件夾中的子文件夾src文件夾整個拷貝到剛建Lua空工程目錄下。在Solution Explorer(解決方案管理器)窗口選擇Lua工程,然後在Solution Explorer窗口的工具欄上點擊Show All Files按鈕。

        然後就會看到剛纔拷貝過來的src文件夾。然後選擇src文件夾,右鍵點擊Include In Project(包含到工程中),然後在src文件中找到lua.c和luac.c文件,右鍵點擊Exclude In Project(從工程中排除)。

        右鍵Lua工程,點擊屬性按鈕,先將EXE工程改成靜態庫工程。

        接着修改Output Directory(輸出目錄)和Intermediate Directory(中間目錄),也可以不改,用默認的也可以,主要是這樣鏈接Lua庫比較方便。
Output Directory(輸出目錄):$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\
Intermediate Directory(中間目錄):$(SolutionDir)bin-int\$(Platform)\$(Configuration)\$(ProjectName)\


        然後右鍵Lua工程編譯得到Lua.lib。Lua這邊的準備工作就已經完成了,接下來就是測試。
        接着在同一個Solution下新建一個Visual Stuido空工程,空工程名爲Ryuujinn(日語名爲龍(りゅう)(
ryuu)神(じん)(jinn))。右鍵Ryuujinn工程添加新文件夾,命名爲Source,再在Source目錄下添加新文件Main.cpp(這個就不需要列出具體步驟吧)。

        現在需要做的事,是鏈接Lua庫來測試。首先右鍵Ryuujinn工程,點擊屬性按鈕,修改Output Directory和Intermediate Directory,改成跟Lua工程一樣的,這個步驟上面有,就不再介紹了。
        點擊屬性面板中左側的C/C++按鈕,選擇General(一般),然後在右側的Additional Include Directories(附加的包含目錄)中添加Include;$(SolutionDir)Lua\Src;Include指的是我等下會再建一個Include文件夾目錄,$(SolutionDir)Lua\Src指的是之前創建Lua工程下的拷貝過來的lua源碼目錄。


        接着點擊屬性面板中左側的Linker(鏈接器)按鈕,選擇General(一般),然後在右側的Additional Library Directories(附加的庫目錄)中添加$(SolutionDir)bin\$(Platform)\$(Configuration)\Lua\;這個$(SolutionDir)bin\$(Platform)\$(Configuration)\Lua\就是前面Lua工程中Output Directory的目錄。之前說修改Output Directory和Intermediate Directory的方便就在這個地方。如果沒有修改的話,就需要自己去定位到靜態庫的生成目錄。


        好了,鏈接Lua庫的大部分工作做完了,開始測試是否可以調用Lua。在之前添加的Main.cpp中添加如下代碼:

// 引入lua需要的頭文件
extern "C"
{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}

// 鏈接Lua工程生成的靜態庫
#pragma comment(lib, "Lua.lib")

#include <iostream>

int main()
{
	// 創建虛擬棧
	lua_State* L = luaL_newstate();
	// 引入lua的標準庫,不然調用print會報錯,可以註釋掉代碼,查看報錯
	luaL_openlibs(L);

	// 很簡單的lua代碼,輸出Hello, lua
	const char* strLuaScript = R"(
	print("Hello, lua")
	)";

	// 執行lua代碼
	int result = luaL_dostring(L, strLuaScript);
	if (LUA_OK != result)
		std::cout << lua_tostring(L, -1) << std::endl;
	else
	{

	}

	// 關閉虛擬棧
	lua_close(L);

	system("pause");
	return 0;
}


        代碼中註釋很多,就不一一解釋了,如果想要仔細瞭解C++調用Lua,可以通過百度和Google搜索文章看,也可以通過搜視頻看,國內有一個還可以,但是需要付費,也不貴(60多),但我就不列出具體網址了,國外的我在看,講的很不錯,英文不錯的可以看下,網址在這裏,需要科學上網,最近有個測試的酷鳥瀏覽器是可以科學上網看的(用過,比較差,經常打不開,或者看到一半就掛了,勉強能用)
        如果輸出了Hello, lua就說明lua配置沒有問題。lua配置就到此結束了,接下來就是SDL的配置了。

SDL準備工作

        去SDL官網(https://www.libsdl.org/download-2.0.php)下載Development Libraries。還需SDL的擴展庫SDL_Image,去該網址下載(https://www.libsdl.org/projects/SDL_image/)Development Libraries。

        將下載的2個文件都解壓,放到自己喜歡的硬盤下,接下來配置環境變量,因爲我存放到D盤下,文件名爲_SDL2-2.0.10和_SDL2_image-2.0.5,因此我的環境變量是
SDL_IncludePath: "D:_SDL2-2.0.10\include"
SDL_LibraryPath: "D:_SDL2-2.0.10\lib"
SDL_Image_IncludePath: "D:_SDL2_image-2.0.5\include"
SDL_Image_LibraryPath: "D:_SDL2_image-2.0.5\lib"


        win7只能截成這樣了,win10的話就會好一點。環境變量生效的話需要重啓Visual Studio 2019,如果不生效,就關閉explorer.exe,再不行就重啓電腦就OK。
        跟之前配置Lua一樣,在Ryuujinn工程的屬性面板上添加剛配置好的環境變量就OK:Additional Include Directories(附加的包含目錄)再添加$(SDL_IncludePath);$(SDL_Image_IncludePath)。


Additional Library Directories(附加的庫目錄)就需要特殊處理下,要根據平臺來處理:
32位(Win32)添加$(SDL_LibraryPath)\x86;$(SDL_Image_LibraryPath)\x86;


64位(x64)添加$(SDL_LibraryPath)\x64;$(SDL_Image_LibraryPath)\x64;


        還需要一步處理,也是需要根據平臺來,在Ryuujinn工程的屬性面板點擊左側的Build Events(編譯事件),接着點擊Build Events下方的Pre-Build Evnet(預編譯事件),在屬性面板右側的Command Line(命令行)中點擊,會彈出Edit(編輯)按鈕,點擊後會彈出一個窗口,接下來填入需要處理的命令。


32位(Win32)添加
XCOPY "$(SDL_LibraryPath)\x86\*.dll" "$(TargetDir)" /D /K /Y
XCOPY "$(SDL_Image_LibraryPath)\x86\*.dll" "$(TargetDir)" /D /K /Y


64位(x64)添加
XCOPY "$(SDL_LibraryPath)\x64\*.dll" "$(TargetDir)" /D /K /Y
XCOPY "$(SDL_Image_LibraryPath)\x64\*.dll" "$(TargetDir)" /D /K /Y


        這2句命令的主要功能就是將之前下載下來的SDL和SDL_Image目錄中的DLL拷貝到Ryuujinn工程的生成目錄中而已。
SDL配置也已經結束了,接下來在之前Lua測試代碼中添加SDL測試代碼來測試:
新的Main.cpp:

// 引入lua需要的頭文件
extern "C"
{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}

// 鏈接Lua工程生成的靜態庫
#pragma comment(lib, "Lua.lib")

#define SDL_MAIN_HANDLED

// 引入SDL需要的頭文件
#include <SDL.h>
#include <SDL_image.h>

// 鏈接SDL靜態庫
#pragma comment(lib, "SDL2.lib")
#pragma comment(lib, "SDL2main.lib")
#pragma comment(lib, "SDL2_image.lib")

#include <iostream>

int main()
{
	// 創建虛擬棧
	lua_State* L = luaL_newstate();
	// 引入lua的標準庫,不然調用print會報錯,可以註釋掉代碼,查看報錯
	luaL_openlibs(L);

	// 很簡單的lua代碼,輸出Hello, lua
	const char* strLuaScript = R"(
	print("Hello, lua")
	)";

	// 執行lua代碼
	int result = luaL_dostring(L, strLuaScript);
	if (LUA_OK != result)
		std::cout << lua_tostring(L, -1) << std::endl;
	else
	{

	}

	// 關閉虛擬棧
	lua_close(L);

	if (0 != SDL_Init(SDL_INIT_EVERYTHING))
		return -1;

	int flags = 0;
	SDL_Window* pWindow = SDL_CreateWindow("Test", 100, 100, 500, 500, flags);
	if (!pWindow)
		return -1;

	SDL_Renderer* pRenderer = SDL_CreateRenderer(pWindow, -1, 0);
	SDL_SetRenderDrawColor(pRenderer, 255, 255, 255, 255);
	if (!pRenderer)
		return -1;

	while (1);
	SDL_DestroyWindow(pWindow);
	SDL_DestroyRenderer(pRenderer);
	SDL_Quit();

	system("pause");
	return 0;
}

        彈出如下窗口,就說明SDL配置成功,但新加的代碼是沒有測試SDL_Image的配置是否成功的,因爲基本差不多,但是要加測試代碼,就不是這麼一點了,還得找資源就有點麻煩了,可以自行上網搜索添加代碼測試。


        如果有下圖編譯失敗的,看是不是這個錯誤,這個錯誤的原因是SDL修改了main函數(#define main    SDL_main),這個可以在SDL_main.h頭文件中可以查看,解決這個錯誤有多個方法,這邊就採取最簡單的,看是不是沒有添加#define SDL_MAIN_HANDLED,或者這個是否在#include <SDL.h>之前。

        好了,Lua和SDL的配置大體完成了,可以舒一口氣了。

源碼下載地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章