控制台下的贪吃蛇,俄罗斯方块,扫雷,黑白棋什么的有太多了。
今天我就将我做的控制台下的“超级玛丽”共享出来大家看看,新人开发的游戏,并没有特地学习游戏开发,可能不太符合规范,望见谅。
来,看下截图。
这是一个更真实的(我觉得)超级玛丽世界。
这是第一大关,即以超级玛丽为主角去闯关,一路消灭蘑菇怪,最终历经千辛万险通过此关,赢得美眉公主的青睐。关卡包括两小节自己制作的地图,然后后面的就是随机生成的啦,随机的话当然要有一定的简单算法让能过关啦。。。
蘑菇怪被杀从一开始就被人们认同并一直延续到现在。但这对蘑菇怪是不公平的,人家蘑菇怪只是在那里无聊地两边走来走去,就要被虐杀?
哪里有压迫,哪里就有反抗。伟人说过,“枪杆子里出政权”。然后,蘑菇怪就引进魂斗罗的科技,学习人族的上古体术。逆袭。
就是用蘑菇怪通一次第一关的图,。。然后,竟然也得到了美眉公主的青睐。
可怕!
都说倾城祸国,说的就是游戏里的公主吧!
因为三角恋,哦, 因为民族血恨,种族之争,超级玛丽跟蘑菇怪进行最man的对决,什么?你说猜拳?不,实打实的干啊!
第三关是玩家控制超级玛丽跟弱AI电脑蘑菇怪(的确弱得可以)生死决战。
基本就是这样啦!可惜只能看图,很多东西无法表现出来!
可以去看看我的项目,运行试试看。github链接:https://github.com/UltramanGaia/SuperMario
下面我来整理下我的模块吧,以后同学们要用的话可以参考下。
//隐藏光标
#include <Windows.h>
void hideCursor()
{
CONSOLE_CURSOR_INFO cursor_info = { 1,0 };
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
//更换handle可以隐藏指定缓冲区的光标
//移动光标到x,y
#include <Windows.h>
void gotoxy(int x, int y)
{
COORD coord; // 坐标
coord.X = x; coord.Y = y; // 坐标变量赋x , y
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); //移动光标到坐标(x,y)
}
//移动光标到x,y打印c,颜色color
#include <Windows.h>
void gotoxyAndPutchar(int x, int y, char c, int color)//移动光标到x,y打印c
{
if (x >= 0 && x <= MX && y >= 0 && y <= MY)
{
gotoxy(x, y);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
putchar(c);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x07);
}
}
//隐藏滚动条
#include <Windows.h>
void remove_scrollbar()
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(handle, &info);
COORD new_size =
{
info.srWindow.Right - info.srWindow.Left + 1,
info.srWindow.Bottom - info.srWindow.Top + 1
};
SetConsoleScreenBufferSize(handle, new_size);
}
//设置字体大小模式
#include <Windows.h>
void setFontSizeMode(int n)
{
typedef BOOL(WINAPI *PROCSETCONSOLEFONT)(HANDLE, DWORD);//
PROCSETCONSOLEFONT SetConsoleFont; //设置字体大小要用
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
HMODULE hKernel32 = GetModuleHandle("kernel32");
SetConsoleFont = (PROCSETCONSOLEFONT)GetProcAddress(hKernel32, "SetConsoleFont");
SetConsoleFont(hConsole, n);
/*字体大小模式如下(不同电脑可能不同,自己尝试下)
x? y? 模式
3 3 0
4 4 1
5 5 2
6 6 3
8 8 4
16 16 5
5 5 6
6 6 7
7 7 8
8 8 9
16 16 10
*/
}
SetConsoleDisplayMode(GetStdHandle(STD_OUTPUT_HANDLE), CONSOLE_FULLSCREEN_MODE, 0);//全屏
system("mode con cols=300 lines=300"); //设置控制台行列
//双缓冲
#include <Windows.h>
HANDLE hStdout, hNewScreenBuffer; //两个句柄 , 对应两个缓冲区
CHAR_INFO chiBuffer[MY*MX]; //[MY][MX];用于储存从标准缓冲区到新缓冲区的字符
// 创建一个句柄 指向STDOUT ,从那里copy数据到新建的缓冲区
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
// 创建一个新缓冲区 , 数据copy到这里
hNewScreenBuffer = CreateConsoleScreenBuffer(
GENERIC_READ | // 读/写 权限
GENERIC_WRITE,
FILE_SHARE_READ |
FILE_SHARE_WRITE, // 共享
NULL, // 默认安全属性
CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE
NULL); // reserved; must be NULL
//使显示的是新建的缓冲区
SetConsoleActiveScreenBuffer(hNewScreenBuffer);
//传输标准缓冲区中的画面到显示的缓冲区,我做成了函数
void copyToBuffer(HANDLE SHandle, int STop, int SLeft, int SBottom, int SRight, HANDLE DHandle, int DTop, int DLeft, int DBottom, int DRight)//S开头的是Sourse,D开头的是Destination
{
// 设置源方框
SMALL_RECT srctReadRect; //从源缓冲区截取的方框
srctReadRect.Top = STop;
srctReadRect.Left = SLeft;
srctReadRect.Bottom = SBottom - 1;
srctReadRect.Right = SRight - 1;
//设置临时储存的数组的大小,多少行,多少列
COORD coordBufSize;
coordBufSize.Y = SBottom - STop;
coordBufSize.X = SRight - SLeft;
//设置临时缓冲开始装入的开始位置
COORD coordBufCoord;
coordBufCoord.X = 0;
coordBufCoord.Y = 0;
//从屏幕拷贝“块”到临时储存的数组
ReadConsoleOutput(
SHandle, // screen buffer to read from
chiBuffer, // buffer to copy into
coordBufSize, // col-row size of chiBuffer
coordBufCoord, // top left dest. cell in chiBuffer
&srctReadRect); // screen buffer source rectangle
// 设置目标方框
SMALL_RECT srctWriteRect; //写到新缓冲区的方框
srctWriteRect.Top = DTop;
srctWriteRect.Left = DLeft;
srctWriteRect.Bottom = DBottom - 1;
srctWriteRect.Right = DRight - 1;
//从临时储存的数组拷贝“块”到屏幕目标缓冲区
WriteConsoleOutput(
DHandle, // screen buffer to write to
chiBuffer, // buffer to copy from
coordBufSize, // col-row size of chiBuffer
coordBufCoord, // top left src cell in chiBuffer
&srctWriteRect); // dest. screen buffer rectangle
}
#include <Windows.h>
#define CMD_LEFT 1 //方向键的宏定义
#define CMD_RIGHT 2
#define CMD_UP 4
#define CMD_DOWN 8
#define CMD_SHOOT 16
#define CMD_ESC 32
//获取按键信息
int GetCommand()
{
int temp = 0;
if (GetAsyncKeyState('A') & 0x8000)
temp |= CMD_LEFT;
if (GetAsyncKeyState('D') & 0x8000)
temp |= CMD_RIGHT;
if ((GetAsyncKeyState('W') & 0x8000) || (GetAsyncKeyState('K') & 0x8000))
temp |= CMD_UP;
if (GetAsyncKeyState('S') & 0x8000)
temp |= CMD_DOWN;
if (GetAsyncKeyState('J') & 0x8000)
temp |= CMD_SHOOT;
if (GetAsyncKeyState(VK_ESCAPE) & 0x8000)
temp |= CMD_ESC;
return temp;
}
//调用时,这是非阻塞的,而且一次可以获取多个按键的状态
if (_kbhit())
{
ch = GetCommand();
if (ch&CMD_LEFT)
{
//...
}
if (ch&CMD_RIGHT)
{
//...
}
if ((ch&CMD_UP))
{
//...
}
if (ch&CMD_DOWN)
{
//...
}
if (ch&CMD_ESC)
{
//...
}
if (ch & CMD_SHOOT )
{
//...
}
//可以用clock来控制游戏的帧速
#include<time.h>
#include <Windows.h>
clock_t t1, t2;
t1 = clock();
while(1)
{
do
{
t2 = clock();
} while (t2 - t1 < 50);
t1 = clock();
}
可能会出点问题,可以参考我的项目,链接github链接:https://github.com/UltramanGaia/SuperMario