私は現在C++で作業しています。ナンバーキャッチャーゲームを作る必要があるため、2つのことを同時に行う必要があります
- 動くキャラクター
- 上から連続して落ちてくる数字。
さらに、一度に複数の数字を投げる必要があります。これらすべてを同時に行うにはどうすればよいですか?
あなたは非常に誤った前提に基づいています。これは、そのようなことを同時に行う必要はありません。あなたがしなければならないのは、それぞれのことをしてから更新することだけです。非常に基本的なゲーム アーキテクチャに関する本を入手する必要があります。
プロジェクトから始めて、同時に他の人から学ぶ必要があると思います。基本的に、すべてを同時に行う必要はありません。内部で同時に行う場合、誰も見ていません。ユーザーに結果を提示する前にすべてを行う必要があります。
複数の機能を呼び出す必要がある場合があります。そして、それがスレッド化が機能する場所です。たとえば、Windows では、関数を使用CreateThreadEx
して複数の関数を同時に呼び出すことができます。ただし、スレッド化の複雑さに対処する必要があります。
スレッド化に関する記事を読めば、その基本的な概念を理解できます。
ゲームプログラミングの研究を提唱する他の回答から少し詳しく説明し、基本的な洞察を提供します。
プログラムの主なタスクは、(ゲーム オーバーになるまで、またはプレイヤーが疲れるまで) ループすることであり、反復ごとに次のようになります。
この順序でこれを行う必要はありません。ゲームは、すべてが同時に起こっているように見えるように十分に速く実行する必要があります。
ゲームの状態は、実際にはゲームの一部であるすべての要素の状態です。
これらすべてのオブジェクト、オブジェクトごとの異なるルール、オブジェクト間の相互作用などを管理するルールが存在する場合があります。エンジンでこれらのルールをコーディングし、すべてのオブジェクトが更新されるようにするのはあなた次第です。最も簡単な方法は、すべてのオブジェクト リストを繰り返し処理し、1 つずつ更新することです。
レンダリングとは、基本的にすべてのオブジェクトを調べて、それらの状態 (色、位置など) に応じて (オブジェクトが表示されている場合) 画面に描画することです。
ポーリング入力とは、プレイヤーがキーボード、マウス、タッチスクリーン、または処理したいその他の入力デバイスを使用して何らかの入力を行ったかどうかを確認することです。
あなたのプロジェクトの場合、オブジェクト リストは落下する文字のリストだけになり、主なルールは重力 (または画面の下部を下る一定の速度) であり、入力はキーボードです。
ゲームをテキスト モードで実行したい場合、主なハードルはカーソルの移動、非ブロック入力の取得、画面のクリアです。UNIX では、必要なすべての機能を提供するcursesライブラリを探します。
ゲームは単純なので、プログラムは非常に高速に実行されるので、ループに短いスリープ期間を含める必要があります。ただし、一貫したフレームレート (少なくとも 30hz) を使用することをお勧めします。そのため、作業にかかる時間を測定し、残りの時間はプロセスをスリープさせて、1 つのループの正しい時間に達することができます。
最後に 1 つ: このプロジェクトのスレッドや並行プログラミングを調べないでください。役に立ちません。レンダリングは、ほとんどのグラフィック セットアップで 1 つのスレッドで実行する必要があり、スレッド間のメッセージングを使用しない限り、多くの同期を実行することになります (これは興味深い演習ですが、バージョン 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);
}
openmp または pthread の使用を含む並行プログラミング方法を検討してください。私が openmp をお勧めする唯一の理由は、時間が限られている場合でも簡単に習得できることと、pthreads も頭を包み込むのがある程度簡単だからです。また、誰もがより具体的な方法で質問に答えられるように、使用しているプラットフォームを知っておくと役立ちます.