SDL 实现五子棋 GUI (一)

来源:互联网 发布:java编程手记 编辑:程序博客网 时间:2024/05/22 07:52
首先简短地说明一下, 原独立博客 www.codingtoro.com 到期后就停止了, 主要是发现自己还没有积累那么多可以拿出来分享, 自己的水平还很不够, 所以使用 CSDN 暂时作为博客.

好了废话不多说, 从高中开始就在想为什么不能自己创造一些好看的程序界面, 而只能天天面对 VB 6.0 的灰头土脸以及 CMD 的白底黑字. 说实话, 后来虽然知道 windows 下需要图形化编程可以学习 MFC, .NET, JAVA swing, QT 等等, 但我到现在这些都不会. 如果还要做游戏呢? 那对我来说就是不可能完成的任务了.

以前尝试过在 CMD 下实现一些界面, 比如

 

 

 

 

五子棋怎么办呢? 还是一样的在字符界面上画, 于是有

这里提供一下 windows 下 CMD 中勉强实现图形化的关键函数 (C/C++ 语言):

#include<stdio.h>#include<windows.h>#include<stdlib.h>#include<time.h>#include<conio.h>void gotoxy(int x,int y) /*gotoxy的替代函数*/{      COORD c;      c.X=x-1;      c.Y=y-1;      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);}int c;clock_t t1,t2;t1=t2=clock();//获得 clock_ticwhile (1){      if (((float)(t2-t1)/CLOCKS_PER_SEC>=0.1)&&kbhit())      {          //如果两个时间间隔相差超过 0.1 秒, kbhit() 在键盘按下后返回非零      //是一个非常好用的非阻塞函数, i.e 其调用不会类似 scanf, cin 一样      //让程序等待输入回车进行处理          printf("%c",getch());          t1=clock();      }      else      {          t2=clock();      }      fflush(stdin);//清空输入缓存}

 

由于这次要说的是五子棋的 GUI, 现提供一下如何实现字符界面的 CLI 绘制函数, 使用了两个字符宽的制表符:

void CLI::drawBoard(){    system("cls");    //first line    cout<<"  ╔";    for (int i=0;i<width-1;i++){        cout<<"═╦";    }    cout<<"═╗"<<endl;    //middle lines    for (int i=0;i<2*height-1;i++){        if (i%2==0){            //even-th line            cout<<setw(2)<<(i+1)/2+1<<"║";        }else{            //odd-th line            cout<<"  ╠";        }        for (int j=0;j<width-1;j++){            if (i%2==0){                //even-th line                if (board((i+1)/2+1,j+1)==PLAYER1){                    cout<<p1<<"║";                }                else if (board((i+1)/2+1,j+1)==PLAYER2){                    cout<<p2<<"║";                }                else if (mouseY==((i+1)/2+1) && mouseX==(j+1)){                    cout<<mouse<<"║";                }                else{                    cout<<"  ║";                }            }else{                //odd-th line                cout<<"═╬";            }        }        if (i%2==0){            //even-th line            if (mouseY==((i+1)/2+1) && mouseX==width){                cout<<mouse<<"║"<<endl;            }            else if (board((i+1)/2+1,width)==PLAYER1){                cout<<p1<<"║"<<endl;            }            else if (board((i+1)/2+1,width)==PLAYER2){                cout<<p2<<"║"<<endl;            }            else{                cout<<"  ║"<<endl;            }        }else{            //odd-th line            cout<<"═╣"<<endl;        }    }    //last line    cout<<"  ╚";    for (int i=0;i<width-1;i++){        cout<<"═╩";    }    cout<<"═╝"<<endl;    //last line's number    cout<<"    ";    for (int i=0;i<width;i++){        cout<<char('a'+i)<<"   ";    }    cout<<endl;    cout<<"Mouse: ( "<<char('a'+mouseX-1)<<", "<<mouseY<<" )"        <<"  PLAYER1: "<<board.counter_Player1        <<"  PLAYER2: "<<board.counter_Player2        <<"  EMPTY: "<<board.counter_EmptyPos        <<endl;}


那么在游戏中, 双方玩家下一颗棋子后, 调用 windows 下的系统命令(CMD 命令)再绘制一遍就行:

system("cls");cli.drawBoard();

注: 此处代码使用了 CLI 类的成员括号重载 board(row, col) 返回棋板上 (row, col) 位置棋子状态(空, PLAYER1, PLAYER2).

同学帮忙测试了一下, 说闪得慌. 这里简单解释一下为嘛会闪以及可能的解决办法:
由于 CMD 是字符界面, 所以绘制过程本质上是清空后再打印, 这个过程需要花费一定的时间(肉眼可见), 于是出现了空屏幕和完成屏幕的交替出现, 故曰"闪得慌".

如何解决? 抛开 GUI 不谈, 其实在图形显示方面, 一般采用双缓存机制, 即一块缓存保存当前屏幕上的内容, 另一块缓存在后台绘制将要展现的下一帧, 绘制好以后, 第二块缓存被复制到屏幕上, 第一块转后台绘制下一帧如此交替. 和输出字符的区别在于, 缓存复制到屏幕上是很快的, 现在的计算机肉眼看不出复制过程, 这样就不会闪了. 但是在 CMD 下怎么做呢? 我没实现过, 不过从王爽所写的《汇编语言》一书中可以了解到 CMD 有一段内存专门管理显示内容, 对这个部分内存的修改(通过 debug 程序)可以直接在屏幕上得到色块, ASCII 字符等. 所以可以从这方面入手, 创建一份和显示区同样大小的缓存(连续地址块), 交替呈现界面即可. 估计要使用到 C 语言内嵌汇编语言, 本人菜鸟, 不会!

那怎么办? 学习 MFC? .NET? 但是我的 AI 程序使用了诸如 vector, string 等 STL 内容, MFC 是否有对应的结构? .NET 似乎有相应的模板, 但是 .NET 构建在 CRL 上, 就写过的图论演示程序来说, 似乎运算速度比静态编译的程序还是慢一点点的.

于是引出 SDL, 我们下一篇再说. (SDL 主要用于写多媒体程序, 游戏是主要作品, 也可以用来写别的应用; 跨平台, 使用标准 C++ 就可以. 另一款轻量级引擎叫 HGE, 似乎学习研究的人更少一些.)

参考资料及一些名词:
MFC, http://en.wikipedia.org/wiki/Microsoft_Foundation_Class_Library
.NET, http://en.wikipedia.org/wiki/.NET_Framework
JAVA SWING, http://en.wikipedia.org/wiki/Swing_%28Java%29
QT, http://en.wikipedia.org/wiki/Qt_%28framework%29
GUI, http://en.wikipedia.org/wiki/Graphical_user_interface
CLI, http://en.wikipedia.org/wiki/Command-line_interface
CLR, http://en.wikipedia.org/wiki/Common_Language_Runtime
Assembly Language, http://en.wikipedia.org/wiki/Assembly_language
SDL, http://www.libsdl.org/
HGE, http://hge.relishgames.com/


原创粉丝点击