几个月来我一直梦想着制作 Roguelike,不知为何,我固执的头脑不让我使用图书馆。如果不使用 stdio.h 以外的其他库,如何绘制地图并对其进行操作?
4 回答
C 不知道什么是“键盘”或“终端屏幕”。(奇怪的是,C 确实知道有些东西是什么,比如“语言环境”,但我们不要谈论它。)这意味着这些设备的任何书面功能本质上都是不可移植的。
尽管如此,虽然您可以在代码中做出一些务实的假设(例如,假设这stdin
是您的键盘和stdout
屏幕),但您将无法使用标准正确控制光标位置和文本颜色文本流。在 Linux 中,可以使用终端转义码来控制两者,但在 Windows 中这是不可能的——您必须为此使用控制台功能。此外,在 Linux 中,您仍然需要关心终端缓冲和其他复杂问题。最后,终端功能差异很大——典型的 Linux 终端比 Windows 控制台具有更多功能,后者无法显示粗体或斜体文本。
简而言之,标准文本流不适合创建交互式应用程序。最好的解决方案是创建一个隔离终端处理实现的小层,这样您以后可以决定如何最好地解决问题——例如,使用ncurses
或实现您自己的终端处理代码。
- 编写您自己的 ncurses(和 termcap)版本。
- 写下你的 Roguelike。
实际上,ncurses 是专门为允许类 Rogue 游戏的图形而编写的。
如果您想在不使用任何现有库的情况下做到这一点,您最终会慢慢地重新实现这些库。
我不建议在没有任何库的情况下用 C 语言编写 roguelike。对于任何需要图形控制的东西,无库 C 语言都非常弱。
在http://roguebasin.roguelikedevelopment.org/index.php?title=Main_Page上有一个很棒的 wiki 用于 roguelike 开发,其中包含许多关于算法和 roguelike 设计的页面。它还托管了许多 roguelikes,有些是开源的,有些是 C 语言的。我建议您阅读,尝试在自己的程序中重现,学习,阅读,尝试在自己的程序中重现,循环学习等。并且绝对使用它推荐的任何库(可能是某些版本的curses或ncurses,这是控制台流氓通常但并不总是使用的)
这取决于你想要的学位。
如果可以使用 Windows API,如何绘制地图。
准备地图
int map[15][20] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
准备打印功能
//used no double buffering and used putchar to make it simple void printAt(char c, int x, int y) { HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); COORD p = {x,y}; SetConsoleCursorPosition(h,p); putchar(c); }
包含标题
#include <windows.h> #include <stdio.h>
做主循环
int x = 10; int y = 10; //main loop while(1) { for(int cy=0;cy<15;cy++) { for(int cx=0;cx<20;cx++) { int cell = map[cy][cx]; if(cell == 0) printAt('.',cx,cy);//grass else if(cell == 1) printAt('T',cx,cy);//tree else if(cell == 2) printAt('?',cx,cy);//item } } printAt('@',x,y);//hero Sleep(500); x++;//simulate keypress }
如果您也想避免操作系统 API,请写入称为帧缓冲区的内存区域以在特定位置打印字符。并读取存储按键的称为键盘环形缓冲区的内存区域。但是,如果您想要这种方法,您可能需要设置通常称为裸机的环境。
粗体字是关键词。
如果您想要更多,您可能需要研究这些关键字。