简单的跨平台程序






2.41/5 (7投票s)
如何编写一个允许简单游戏在 Linux 和 Windows 上运行的程序
引言
我最初使用Microsoft Visual Studio IDE中的Visual Basic编写了我的数独程序的代码。这会将程序限制在Windows平台。为了让代码能够成功地在Windows和Linux上运行,我决定利用C和C++语言的跨平台性。我将程序抽象为一系列函数,这些函数可以与本地GUI工具包进行接口。GUI接口只需要一些按钮、一个图像框和鼠标位置。它只用于调用核心C或C++程序中的函数。在Windows上,我仍然使用Visual Basic IDE来提供GUI。这些函数是通过将C++核心编译成托管程序集DLL来提供的。在Linux上,我使用Glade来开发GUI及相关代码。这些函数被直接添加到GUI代码中。数独的图像使用了Windows BMP文件格式的未压缩位图文件。这可以在Windows和Linux中显示。它也可以直接用于生成程序所需的各种图像。
图像生成
Visual Basic程序sudoku_bmp用于生成程序核心代码使用的起始图像。它是使用Visual Basic 2008 Express Edition编写的。运行此程序会显示一个显示数独起始图像的窗口。遗憾的是,我们无法直接访问BMP文件图像...
Dim soduku As New Bitmap(10, 10)
'generate the graphics as per sudoku_bmp program
soduku.Save("soduku.bmp")
...因为所有的位图都以PNG文件格式存储。PNG使用复杂的无损压缩,我们无法在颜色字节级别直接使用它。我们可以进行屏幕截图,然后使用绘图类程序进行必要的裁剪,以生成24位每像素的start.bmp文件。
下面是使用BMP文件格式的1x1黑色像素的字节列表:00000000 42 4D 3A 00 00 00 00 00-00 00 36 00 00 00 28 00 BM:.......6...(. 00000010 00 00 01 00 00 00 01 00-00 00 01 00 18 00 00 00 ................ 00000020 00 00 04 00 00 00 13 0B-00 00 13 0B 00 00 00 00 ................ 00000030 00 00 00 00 00 00 接下来是数据 00 00-00 00 .......... 前两个字节BM,接下来的两个字节是文件大小(小端序)H003A = 58字节。接下来的6个字节是零。H36小端序的54字节=头大小。接下来是尺寸01x01等,包括H18=24位每像素。每行的数据向上取整以使其成为偶数。00 00 00,填充字节为00,数据是反向的,即BGR。
start.bmp的宽度为573像素,高度为598像素。文件有一个54字节的头,像素数据以栅格排列存储。每条水平线的数据为573 x 3字节,加上一个填充字节=1720字节。有598条线,总计1028614字节。当图像在屏幕上显示时,顶行对应于文件中存储的最后一行。

start.bmp包含运行数独程序所需的所有独立图像。
核心程序
核心程序是用C++编写的,用于Windows。它是使用Visual C++ 2008 Express Edition编写的。核心功能相同,但为Linux进行了简化为C。它是通过在Linux中使用文本编辑器修改C++.cpp和.h文件来编写的。GUI接口使用的函数是
sudoku(); //constructor to get the main image
//and extract the images for the Sudoku program
void userselect(int x,int y, int number); //user selects number
void stepback(); //go back one step in the solution
void highlight(int x, int y); //change the pencil number to yellow
void randomgame(int level); //start hard, medium or easy game
void solveexisting(); //solve existing Sudoku
void startenter(); //start Sudoku at from step 0
核心程序有以下全局变量
char *mainimage = new char[1028614]; //allocate memory as needed -dynamic
// won't be pushed on stack which is set at about 1M
char selectnumber[10][10800]; //error(0) and selected(1-9) numbers
char pencilnumber[2][10][1200]; //blank(0) and pencil(1-9) numbers
//dim [0] is pencil...dim[1] is select pencil
char sudokuarray[82][3][3][3][3][3][3]; //0 to 81 steps in solution
//x large..y large..x small..y small..x number..y number
int sudokustep =0; //step counter used in all solutions as current step
int yellow[2] = {27,27}; //x-y record of pencilnumbers highlighted
程序启动时,我们加载主图像
fstream inclientfile ("start.bmp",ios::binary); //1,028,614 bytes in file
inclientfile.read(mainimage,1028614 ); //read raw bytes to the array
然后,我们从mainimage
数组中提取铅笔数字和选择数字的图像。这些图像随后在核心程序中用于生成显示游戏进度的图像。每一步,新的图像都会被存储
ofstream outClientFile( "copy.bmp", ios::binary ); // copy the file
outClientFile.write(mainimage,1028614 ); //write raw bytes to the array
然后,GUI会在其窗口的图像框中显示新图像。
Windows
Visual C++程序sudokudll用于生成托管程序集DLL。使用VC++2008 Express打开项目文件并生成解决方案,以编译sudokudll.dll。Visual Basic程序MySudoku
引用此DLL。此程序用于生成程序的GUI窗口。随着程序中每一步的进展,我们都会更新窗口上的图像
Dim st As Stream = File.Open("copy.bmp", FileMode.Open, FileAccess.Read)
PictureBox1.Image = Image.FromStream(st)
st.Dispose()
使用VB2008 Express打开项目文件并生成MySudoku
,以编译.exe文件。
Linux
程序Glade3
用于生成数独核心的GUI窗口。随着程序中每一步的进展,我们都会更新窗口上的图像
gtk_image_set_from_file(image1, "copy.bmp");
打开文件MySudoku.glade,然后选择生成以创建GUI的代码。打开一个终端窗口,并在拥有.glade文件的目录中输入:./autogen.sh
。这将为我们提供用户GUI窗口的所有代码。将src_add_replace中的所有文件复制并使用“全部替换”粘贴到src文件夹中。将终端切换到src目录,然后键入“make
”以编译Linux可执行文件。