我目前正在使用 C++。我需要制作一个数字捕手游戏,因此必须同时做两件事
- 移动角色
- 数字不断从顶部下降。
此外,我需要一次抛出多个数字。我怎样才能同时做所有这些事情?
你是基于一个非常错误的前提。这并不要求同时做任何这样的事情。你所要做的就是做每一件事然后更新。你需要一本关于非常基本的游戏架构的书。
我相信你需要从你的项目开始,同时向别人学习。基本上,您不需要同时执行所有这些操作,如果您在后台同时执行这些操作,没人会注意,您只需要在将结果呈现给用户之前完成所有操作。
我将从其他提倡研究游戏编程的答案中稍微详细说明一下,并提供一些基本的见解。
程序的主要任务是循环(直到游戏结束,或者玩家累了),并且在每次迭代时:
您不必按此顺序执行此操作,游戏应该运行得足够快,以使一切看起来都在同时发生。
游戏的状态实际上是游戏中所有元素的状态:
可能存在管理所有这些对象的规则、针对不同对象的不同规则、对象之间的交互等等。您可以在引擎中编写这些规则,并确保所有对象都得到更新。最简单的方法是遍历所有对象列表并一一更新。
渲染基本上是遍历所有对象并根据它们的状态(颜色、位置等)在屏幕上绘制它们(如果它们可见)。
轮询输入就是:验证玩家是否使用键盘、鼠标、触摸屏或您希望处理的任何其他输入设备进行了输入。
在您的项目中,您的对象列表将只是下降字符的列表,主要规则是重力(或以恒定速度向下移动到屏幕底部),输入是键盘。
如果您希望游戏以文本模式运行,主要障碍将是移动光标、获得非阻塞输入、清除屏幕。在 UNIX 上,查找提供所有必要功能的curses库。
鉴于游戏的简单性,您的程序肯定会运行得非常快,因此您需要在循环中包含一个小的休眠期。但是,最好具有一致的帧速率(至少 30hz),这样您就可以测量完成工作所花费的时间,并让进程在剩余时间内休眠以达到一个循环的正确时间。
最后一件事:不要为这个项目研究线程或并发编程,这无济于事。在大多数图形设置中,渲染必须由单个线程完成,并且您最终会进行大量同步,除非您使用线程之间的消息传递(这将是一个有趣的练习,但保留在版本 2 中)。
如果您在 Windows 上,则代码:
/* The Matrix falling numbers */
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
using namespace std;
#define KB_UP 72
#define KB_DOWN 80
#define KB_LEFT 75
#define KB_RIGHT 77
#define KB_ESCAPE 27
#define KB_F8 66
/* Variables*/
char screen_buffer[2000]={' '};
int y_coord[2000]={0};
int x=0, y=0,dy=0;
int XMAX=77;
int YMAX=23;
int KB_code=0;
bool QuitGame=false;
int platformX=35, platformY=23;
/* function prototypes*/
void gotoxy(int x, int y);
void clrscr(void);
void setcolor(WORD color);
void simple_keyboard_input();
void draw_falling_numbers();
void draw_platform();
/* main */
int main(void)
{
/* generate random seed */
srand ( time(NULL) );
/* generate random number*/
for(int i=0;i<XMAX;i++) y_coord[i]= rand() % YMAX;
while(!QuitGame)
{
/* simple keyboard input */
simple_keyboard_input();
/* draw falling numbers */
draw_falling_numbers();
}
/* restore text color */
setcolor(7);
clrscr( );
cout<<" \n";
cout<<" \nPress any key to continue\n";
cin.ignore();
cin.get();
return 0;
}
/* functions */
void draw_falling_numbers()
{
for(x=0;x<=XMAX;x++)
{
/* generate random number */
int MatixNumber=rand() % 2 ;
/* update falling number */
y_coord[x]=y_coord[x]+1;
if (y_coord[x]>YMAX) y_coord[x]=0;
/* draw dark color */
setcolor(2);
gotoxy(x ,y_coord[x]-1); cout<<" "<<MatixNumber<<" ";
/* draw light color */
setcolor(10);
gotoxy(x ,y_coord[x]); cout<<" "<<MatixNumber<<" ";
}
/* wait some milliseconds */
Sleep(50);
//clrscr( );
}
void draw_platform()
{
setcolor(7);
gotoxy(platformX ,platformY);cout<<" ";
gotoxy(platformX ,platformY);cout<<"ÜÜÜÜÜÜ";
setcolor(7);
Sleep(5);
}
void simple_keyboard_input()
{
if (kbhit())
{
KB_code = getch();
//cout<<"KB_code = "<<KB_code<<"\n";
switch (KB_code)
{
case KB_ESCAPE:
QuitGame=true;
break;
case KB_LEFT:
//Do something
platformX=platformX-4;if(platformX<3) platformX=3;
break;
case KB_RIGHT:
//Do something
platformX=platformX+4;if(platformX>74) platformX=74;
break;
case KB_UP:
//Do something
break;
case KB_DOWN:
//Do something
break;
}
}
}
void setcolor(WORD color)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color);
return;
}
void gotoxy(int x, int y)
{
static HANDLE hStdout = NULL;
COORD coord;
coord.X = x;
coord.Y = y;
if(!hStdout)
{
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
}
SetConsoleCursorPosition(hStdout,coord);
}
void clrscr(void)
{
static HANDLE hStdout = NULL;
static CONSOLE_SCREEN_BUFFER_INFO csbi;
const COORD startCoords = {0,0};
DWORD dummy;
if(!hStdout)
{
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hStdout,&csbi);
}
FillConsoleOutputCharacter(hStdout,
' ',
csbi.dwSize.X * csbi.dwSize.Y,
startCoords,
&dummy);
gotoxy(0,0);
}
在某些情况下,我们需要调用多个功能。这就是线程发挥作用的地方。例如,在 Windows 上,您可以使用CreateThreadEx
函数同时调用多个函数。但是您必须处理线程的复杂性。
阅读有关线程的文章,您将了解其基本概念。
研究将包括使用 openmp 或 pthreads 的并发编程方法。我建议使用 openmp 的唯一原因是,如果你的时间有限,它很容易学习,并且在某种程度上 pthreads 也很容易让你理解。此外,了解您使用的平台也会有所帮助,以便每个人都以更具体的方式回答问题。