まえがき
30年以上にわたり、ビデオゲームは、ゲームプレイやグラフィック機能から、高度な人工知能システムや、開発者が提供する素材に対するユーザーの認識まで、積極的に開発されてきました。 Esportsは、数百万ドルの賞金と10億ドルの売り上げを誇る本格的なスポーツです。 また、ビデオゲーム業界自体は常に勢いを増しており、エンターテインメント業界で最も現金と大規模な支店の1つです。 そしてこれらすべてに、人類はオシロスコープで発売された「テニス」の最も原始的な実装から来ました。
新入生として、C / C ++の基本的なコンソール機能の研究の一環として、プレイヤーがより速く考え、ゲームと継続的にやり取りし、プレイヤーが何らかの種類で解釈できるシンプルなグラフィック部分を必要とする「クラシック」ASCIIゲームをプログラムすることが可能です三次元画像。
そのような決定の視覚的な原始性にもかかわらず、それらは確かに古い学校のゲームに対するノスタルジーをプレイヤーに引き起こします。
ひらめき
モノクロディスプレイを搭載した携帯電話の市場に登場した夜明けには、ノキアのデバイスに組み込まれた「スペースインパクト」というゲームが目立ちました。 彼女は当時のセルの限られた能力に完全に適合しました。 携帯電話へのシンプルなゲームの導入後、デバイスの販売が急増し、モバイルゲームが徐々に人気を博し、今では「アダルト」AAAプロジェクトの業界と完全に競合しています。
「スペースインパクト」は、2000年代初頭の実行の容易さと人気のため、私の最初のゲームの基礎でした。
スペースインベーダーの機能
まず第一に、プログラムの軽さ。 実行可能ファイルは100 kb未満で、Visual C ++を搭載したWindows OSを実行しているほとんどすべてのコンピューターで意図したとおりに機能します。
次に、移植性-ソースコードを数分でPOSIXシステムに変換できるため、UNIXおよびMacオペレーティングシステムでの操作性が確保され、いくつかの機能を置き換えて適切なコンパイラーでプログラムを再構築するだけです。
3番目の利点-プログラムは移植性があり、追加のファイルを必要としません。 必要に応じて、追加ファイルはすべて、実行可能ファイルの場所ディレクトリに自動的に作成されます。
説明や使用手順を必要としない、最もシンプルで直感的なインターフェイス。
- メインメニューは4つの項目で構成されており、キーボードの矢印を使用して選択できます。
- アイテム「ゲーム」-2つのポイントのメニューを開きます。
- サブアイテム「新しいゲーム」-新しいゲームセッションを開始します。
- 「続行」サブアイテム-最後に保存したゲームをバイナリファイルから実行可能ファイルディレクトリにロードし、受信したデータを使用してゲームセッションを開始します。
- ヘルプ項目-アプリケーションとその説明を操作するための手順。 キーボードの矢印を押してスクロールします。
- 「Hall of Fame」アイテムはゲームセッションリーダーのリストであり、バイナリファイルから実行可能ファイルディレクトリにロードされ、コンソールにフォーマットされた形式で表示されます。
- 「終了」項目-アプリケーションを終了します。
- ダイナミックな速度で左に移動する「世界」。 「World」には、1〜2文字の太さのランダムフィールドが上下にあります。 また、フィールド間のランダムに表示される「スペースデブリ」は、プレーヤーの障害となる記号「¤」で表示されます。
- ウィンドウの左端に押されているのは「宇宙船」です。 船は、キーボードの上下矢印を使用して移動します。スペースバーを押すと、発射体が放出され、タッチすると「スペースデブリ」が破壊されます。
- コンソール上部の「ダッシュボード」には、走行距離、現在の速度、残りの試行回数が表示されます。
Space Invaderはどのように機能しますか?
アプリケーションが起動すると、スプラッシュスクリーンアニメーションが表示されます。 これは、200msごとに変化する6つの事前にフォーマットされた文字配列で構成されています。
スクリーンセーバーの開始-最終スライド
次に、パラメーター1(整数)を使用したメインメニュー機能へのアピールです。 この関数は、強調表示された山括弧で囲まれたメニューを表示し、入力パラメーターと一致する番号のメニュー項目を表示します。 メニュー4の各項目の入力パラメーターは、それぞれ1から4まで変えることができます。下矢印を押すと、入力パラメーターが4未満の場合、増分入力パラメーターに再帰的にアクセスします。選択したメニュー項目に対応する機能の呼び出しを入力します。
void StartMenu(int switcher) { system("cls"); switch (switcher) { case 1: cout << "\n\n\n << ! >>\n\n !\n\n \n\n "; break; case 2: cout << "\n\n\n !\n\n << ! >>\n\n \n\n "; break; case 3: cout << "\n\n\n !\n\n !\n\n << >>\n\n "; break; case 4: cout << "\n\n\n !\n\n !\n\n \n\n << >>"; break; } int choice = _getch(); if (choice == 224) choice = _getch(); if (choice == 72) if (switcher != 1) StartMenu(switcher - 1); else StartMenu(4); if (choice == 80) if (switcher != 4) StartMenu(switcher + 1); else StartMenu(1); if (choice == 13 || choice == 32) { if (switcher == 1) GameMenu(1); if (switcher == 2) Help(0); if (switcher == 3) TopChart(); if (switcher == 4) _exit(0); } }
メインメニュー(機能への入力はパラメーター1で実行されます)
「ゲーム」項目に対応する機能にアクセスすると、機能が似ている機能が起動しますが、2つの項目しか選択できません。 したがって、入力パラメーターは1または2になります。矢印(上または下)のいずれかを押すと、数値を「反対」に変更するだけで済みます。 最も最適化されたオプションは、3から入力パラメーターを減算することです(3-1 = 2、3-2 = 1)。
void GameMenu(int switcher) { system("cls"); if (switcher == 1) cout << "\n\n\n\n\n << ! >>\n\n !"; else cout << "\n\n\n\n\n !\n\n << ! >>"; int choice = _getch(); if (choice == 224) choice = _getch(); if (choice == 72 || choice == 80) GameMenu(3 - switcher); if (choice == 27) StartMenu(1); if (choice == 13 || choice == 32) Game(switcher); }
追加メニュー(機能への入力はパラメーター1で実行されます)
ここで重要なのは、ゲームプロセスです。 サブアイテム「新しいゲーム」を選択すると、新しいゲームセッションが開始されます。 14行50列の次元の2次元配列が作成されます。 最初の行はダッシュボードの下で強調表示されます。 最初のデバイスは移動したキロメートル数で、コンソールの更新数に等しくなります(最初は80msごとにコンソールが更新され、更新ごとにこのパラメーターは25に達するまで減少します)。
int odometerBuf = odometer, odometerDigitLength; for (odometerDigitLength = 0; odometerBuf != 0; odometerBuf /= 10, odometerDigitLength++);// for (int i = odometerDigitLength, odometerBuf = odometer; i >= 0; i--, scr[0][i] = odometerBuf % 10 + '0', odometerBuf /= 10);// scr[0][odometerDigitLength++] = ''; scr[0][odometerDigitLength++] = '';// "" odometer++;//
2番目のデバイスである現在の速度は、1000 /コンソールの更新速度という式です。 速度は1秒あたりのキロメートルで測定されます。 したがって、最初は船は12 km / sの速度で動き、しばらくすると40 km / sのマークに達します。
speed = 1000 / timer;// int speedBuf = speed; for (int i = 42; speed != 0; i--, scr[0][i] = speed % 10 + '0', speed /= 10);// scr[0][42] = ''; scr[0][43] = ''; scr[0][44] = '/'; scr[0][45] = '';// "/"
3番目のデバイスには、残りの試行回数(最初は3回)が表示されます。試行は「&」記号で表示されます。
for (int i = 50; lifes > 0; i--, lifes--, scr[0][i] = '&');
ゲームセッションの開始時のダッシュボード
最後の2行と同様に、次の2行はゲームのフィールドです。 フィールド装飾はランダムに選択され、3文字またはスペースで構成されます。 極端な線は常に完全に塗りつぶされ、2番目と最後の1つは、これらの文字が他の文字から「成長」する場所でのみスペースと異なる文字を含みます。
char borderSymbols[] = { '†', '‡', '¤', ' ' }; for (int aboveBelow = 0; aboveBelow < 50; aboveBelow++)// (2 + 2) { scr[1][aboveBelow] = borderSymbols[rand() % 3]; if (scr[1][aboveBelow] == '‡') scr[2][aboveBelow] = '¤'; scr[13][aboveBelow] = borderSymbols[rand() % 3]; if (scr[13][aboveBelow] == '‡') scr[12][aboveBelow] = '¤'; }
ゲームセッションの開始時のダッシュボードとフィールド
左端に押されたプレイスペースの中心線には、プレイヤーがコントロールしなければならない宇宙船が描かれています。
scr[6][0] = '\\'; scr[6][1] = '\\';// scr[7][0] = '3'; scr[7][1] = '='; scr[7][2] = '='; scr[8][0] = '/'; scr[8][1] = '/';
上矢印と下矢印で制御できます。
if (_kbhit())// { control = _getch();// if (control == 224) control = _getch(); } if (control == 72)// if (scr[2][0] == '\\' || scr[3][0] == '\\' && scr[2][0] == '¤' || scr[3][1] == '\\' && scr[2][1] == '¤')// - if (lifes > 1) { cout << '\a'; lifes--; weaponPos = 7; GameStart(scr, lifes, &timer); Sleep(1000); } else GameOver(odometer); else { for (int i = 2; i < 13; i++)// for (int j = 0; j < 49; j++) if (scr[i][j] == '3' || scr[i][j] == '\\' || scr[i][j] == '=' || scr[i][j] == '/') { scr[i - 1][j] = scr[i][j]; scr[i][j] = ' '; } weaponPos--; } if (control == 80)// if (scr[12][0] == '/' || scr[11][0] == '/' && scr[12][0] == '¤' || scr[11][1] == '/' && scr[12][1] == '¤')// - if (lifes > 1) { cout << '\a'; lifes--; weaponPos = 7; GameStart(scr, lifes, &timer); Sleep(1000); } else GameOver(odometer); else { for (int i = 12; i >= 2; i--)// for (int j = 0; j < 49; j++) if (scr[i][j] == '3' || scr[i][j] == '\\' || scr[i][j] == '=' || scr[i][j] == '/') { scr[i + 1][j] = scr[i][j]; scr[i][j] = ' '; } weaponPos++; }
上矢印を2回押すことによる船の位置
視覚化から離れて、船と一緒に、船の「バレル」を担当する配列要素を上下にシフトすることは注目に値します。 したがって、スペースバーを押すことでシェルを解放できます。
ただし、フィールドもシェルも移動しないため、ゲームプレイを「復活」させるために、画面再描画タイマーの期限が切れると、「ワールド」は1列左に移動し、シェルは1列右に移動します。 プレイヤーが望む場合を除き、船はそのままです。 しかし、再描画後、空の列が1つ表示されます。フィールドと「スペースデブリ」をランダムに入力します。これらは、船の砲弾やサイドバンパーで落とすことができます。
for (int i = 1; i < 14; i++)// "" for (int j = 0; j < 49; j++) { if (scr[i][j] == '\\' && scr[i][j + 1] == '¤' || scr[i][j] == '=' && scr[i][j + 1] == '¤' || scr[i][j] == '/' && scr[i][j + 1] == '¤') if (lifes > 1) { cout << '\a'; lifes--; weaponPos = 7; GameStart(scr, lifes, &timer); Sleep(1000); } else GameOver(odometer); if (scr[i][j] != '3' && scr[i][j] != '\\' && scr[i][j] != '=' && scr[i][j] != '/' && scr[i][j] != '-' && scr[i][j + 1] != '-') scr[i][j] = scr[i][j + 1]; if (scr[i][j] == '¤') scr[i][j + 1] = ' '; } for (int i = 1; i < 14; i++)// for (int j = 48; j >= 0; j--) if (scr[i][j] == '-') if (j != 48) { scr[i][j + 1] = '-'; scr[i][j] = ' '; } else scr[i][j] = ' '; char borderSymbols[] = { '†', '‡', '¤', ' ' }; scr[2][49] = ' ';// scr[1][49] = borderSymbols[rand() % 3]; if (scr[1][49] == '‡') scr[2][49] = '¤'; scr[12][49] = ' '; scr[13][49] = borderSymbols[rand() % 3]; if (scr[13][49] == '‡') scr[12][49] = '¤'; for (int i = 3; i < 12; i++)// { if (rand() % 10 == 1) scr[i][49] = '¤'; }
この瞬間に船が上下に移動すると、バンパーのおかげで、宇宙破片は船に損傷を与えることなく破壊されます
現時点で下向きの矢印で破片をかわさないと、船は壊れます
船から発射される砲弾は、航路のすべてを一掃するように設計されています。 その結果、1つのシェルを発射すると、1行で廊下がクリアされます。
ただし、フィールドはスペースデブリに似た材料で構成されていますが、チッパーで破壊することはできません。 船のあらゆる部分が野原と接触すると、必然的に崩壊します。 宇宙船の前面へのスペースデブリの侵入と同様。 ダッシュボードのそのような瞬間に少なくとも1つの「試行」の指定がある場合-ゲームは最初からやり直しているように見えますが、スコアを保持して1つの「試行」を失います。 速度は初期値の12km / sにリセットされます。
プレイヤーが「クラッシュ」し、それ以上の試行がなかった場合、ゲームセッションは終了し、プレイヤーは結果を「殿堂」に保存するために自分の名前を入力するよう求められます。
結果を「名誉の殿堂」に保存するためにプレイヤーに名前を入力するという申し出
アプリケーションは2つのファイルを処理します。
- 「TopChart.bin」は、リーダーボードを保存するためのバイナリファイルです。 データは構造に保存されます(プレイヤーのニックネーム、アカウント、ゲームセッションの完了日)。 ゲームが終了すると、データはファイルの最後に追加されます。 アイテムを「名誉の殿堂」と呼ぶと、ファイルは読み取り用に開かれ、編集することができます。 次に、構造の動的配列が宣言され、そこにファイルからデータがコピーされます。その後、配列が並べ替えられ、コンソールに表示されるようにフォーマットされます(配列に13個の結果が含まれる場合、結果の最大数は12で、最後は並べ替え後に破棄されます)。 次に、ファイルは結果構造の配列で上書きされ、その後配列が破棄されます。
- 「CurrentSave.bin」は、保存したゲームを保存するためのバイナリファイルです。 「ゲーム」アイテムの「続行」サブアイテムを開始するときに読み取りのために呼び出されます。 1つの不完全なゲームセッションを復元するためのデータが含まれる場合があります。船の船首、走行距離、残りの試行回数、画面上のオブジェクトの位置を含む行番号。 このデータを使用して、不完全なものを正確に繰り返すゲームセッションが形成されます。 不当なプレイを避けるために、ファイルからセッションをロードするとき、ファイルは削除されます。 ゲーム中にEscキーを押すと、このファイルが作成され、ゲームセッションをさらに続行するために必要なすべてのデータが書き込まれます。
メインメニュー項目「ヘルプ」は、0〜22のパラメーターを受け取る機能で、入力パラメーターから50文字の次の12行を表示します。 管理は、上矢印と下矢印を使用して再帰的に実行されます。
void Help(int switcher) { system("cls"); cout << ": / | : ESCAPE\n"; char arr[1800] = { " – / – ENTER – ESCAPE / – / – , – ESCAPE – , . . . – . 40 /. , , . , « » ( «&»), 3. – ESCAPE. , «!». . ! Svjatoslav Laskov – AUTHOR Igor Marchenko – COACH National Technical University «Kharkiv Polytechnic Institute» 2016" }; for (int i = 0, buf = switcher; i < 13; i++) { for (int j = buf * 50; j < buf * 50 + 50; j++) cout << arr[j]; if (i != 12) cout << endl; buf++; } int controller = _getch();// if (controller == 224)// controller = _getch();// if (controller == 72)// if (switcher > 0) Help(switcher - 1); else Help(0); if (controller == 80)// if (switcher < 22) Help(switcher + 1); else Help(22); if (controller == 27)// Escape StartMenu(2); }
メインメニュー項目「終了」-アプリケーションを終了します。
•メニューでの管理
oアイテム間を移動する-上/下矢印
oアイテムを選択-スペースバーまたはENTER
o前のメニューに戻る-ESCAPE
•ゲーム管理
o上/下に移動-上/下矢印
oショットを作成する-スペースバー
oメニューに戻り、ゲームを保存します-ESCAPE
•ブリーフィング
あなたは宇宙嵐に巻き込まれた宇宙船のパイロットです。 可能な限りクラッシュして飛行する必要はありません。
船には動的制御が装備されています。 速く飛ぶほど、船はより鋭く回転します。 船は自動的に徐々に40 km / sに加速します。
船に組み込まれた磁気銃とサイドバンパーの助けを借りて、スペースデブリを撃ち落とすことができます。
船を制御する場合、走行距離、現在の速度、および残りの「ロールバックセル」の数(「&」記号で表示)が計器パネルに表示されます。最初は3つです。
ゲームを停止する場合は、ESCAPEを押してください。 ゲームは保存され、「続行」アイテムを使用してアプリケーションを再起動した後でもゲームを続行できます。
メインメニューでは、名誉パイロットの表を見ることができます。 そこにいる権利を手に入れよう!
まとめ
個人的には、特に標準コンソールはゲーム用ではなく情報を表示するように設計されているため、このようなささいなプロジェクトを開発することから多くの喜びを得ました。 このため、アプリケーションを実行するコンピューターに関係なく、フレームレートは非常に制限されます。
また、ユーザーのキーストロークに対するより正確な反応のために、アプリケーションを複数のスレッドに分割したかったのですが、次のC ++プロジェクトでスレッドを実装します。
#include "conio.h" #include "windows.h" #include "ctime" #include <iostream> using namespace std; struct player// , - { char name[7]; int score; int mday; int mon; int year; }; struct save// , { int weaponPos; int timer; int odometer; int lifes; char scr[14][50]; }; void ScreenOutput(char scr[14][50])// { system("cls"); for (int i = 0; i < 14; i++) { for (int j = 0; j < 50; j++) cout << scr[i][j]; if (i != 13) cout << endl; } } // void StartMenu(int switcher);//, , "" "" void GameMenu(int switcher);// void GameStart(char scr[14][50], int lifes, int *timer);//, void Game(int var);// void GameOver(int score);//, , void Help(int switcher);// void TopChart();// " " - void Help(int switcher) { system("cls"); cout << ": / | : ESCAPE\n"; char arr[1800] = { " – / – ENTER – ESCAPE / – / – , – ESCAPE – , . . . – . 40 /. , , . , « » ( «&»), 3. – ESCAPE. , «!». . ! Svjatoslav Laskov – AUTHOR Igor Marchenko – COACH National Technical University «Kharkiv Polytechnic Institute» 2016" }; for (int i = 0, buf = switcher; i < 13; i++) { for (int j = buf * 50; j < buf * 50 + 50; j++) cout << arr[j]; if (i != 12) cout << endl; buf++; } int controller = _getch();// if (controller == 224)// controller = _getch();// if (controller == 72)// if (switcher > 0) Help(switcher - 1); else Help(0); if (controller == 80)// if (switcher < 22) Help(switcher + 1); else Help(22); if (controller == 27)// Escape StartMenu(2); } void StartMenu(int switcher) { system("cls"); switch (switcher) { case 1: cout << "\n\n\n << ! >>\n\n !\n\n \n\n "; break; case 2: cout << "\n\n\n !\n\n << ! >>\n\n \n\n "; break; case 3: cout << "\n\n\n !\n\n !\n\n << >>\n\n "; break; case 4: cout << "\n\n\n !\n\n !\n\n \n\n << >>"; break; } int choice = _getch(); if (choice == 224) choice = _getch(); if (choice == 72) if (switcher != 1) StartMenu(switcher - 1); else StartMenu(4); if (choice == 80) if (switcher != 4) StartMenu(switcher + 1); else StartMenu(1); if (choice == 13 || choice == 32) { if (switcher == 1) GameMenu(1); if (switcher == 2) Help(0); if (switcher == 3) TopChart(); if (switcher == 4) _exit(0); } } void GameMenu(int switcher) { system("cls"); if (switcher == 1) cout << "\n\n\n\n\n << ! >>\n\n !"; else cout << "\n\n\n\n\n !\n\n << ! >>"; int choice = _getch(); if (choice == 224) choice = _getch(); if (choice == 72 || choice == 80) GameMenu(3 - switcher); if (choice == 27) StartMenu(1); if (choice == 13 || choice == 32) Game(switcher); } void GameStart(char scr[14][50], int lifes, int *timer) { for (int i = 0; i < 14; i++)// for (int j = 0; j < 50; j++) scr[i][j] = ' '; for (int i = 50; lifes > 0; i--, lifes--, scr[0][i] = '&'); *timer = 80; char borderSymbols[] = { '†', '‡', '¤', ' ' }; for (int aboveBelow = 0; aboveBelow < 50; aboveBelow++)// (2 + 2) { scr[1][aboveBelow] = borderSymbols[rand() % 3]; if (scr[1][aboveBelow] == '‡') scr[2][aboveBelow] = '¤'; scr[13][aboveBelow] = borderSymbols[rand() % 3]; if (scr[13][aboveBelow] == '‡') scr[12][aboveBelow] = '¤'; } scr[6][0] = '\\'; scr[6][1] = '\\';// scr[7][0] = '3'; scr[7][1] = '='; scr[7][2] = '='; scr[8][0] = '/'; scr[8][1] = '/'; } void GameOver(int score) { system("cls"); player newPlayer;// newPlayer.score = score;// cout << " !\n " << score << " .\n\n(, )\n( 6 )\n \n : "; cin.getline(newPlayer.name, 7);// time_t timeCur; time(&timeCur); struct tm * timeCurStruct = localtime(&timeCur); newPlayer.mday = timeCurStruct->tm_mday;// newPlayer.mon = timeCurStruct->tm_mon; newPlayer.year = timeCurStruct->tm_year; FILE *topChart; fopen_s(&topChart, "TopChart.bin", "ab+"); fwrite(&newPlayer, 1, sizeof(player), topChart);// fclose(topChart); TopChart(); } void TopChart() { FILE *topChart; fopen_s(&topChart, "TopChart.bin", "rb+"); system("cls"); if (topChart == NULL)// { system("cls"); cout << " ."; Sleep(1000); system("cls"); cout << " .."; Sleep(1000); system("cls"); cout << " ..."; Sleep(1000); cout << "\n , ."; _getch(); StartMenu(3); } fseek(topChart, 0L, SEEK_END); int playerAmount = ftell(topChart) / sizeof(player); player *temp = new player[playerAmount]; fseek(topChart, 0L, SEEK_SET); for (int i = 0; i < playerAmount; i++)// fread(&temp[i], 1, sizeof(player), topChart); fclose(topChart); for (int i = 1; i < playerAmount; i++)// if (temp[i].score > temp[i - 1].score) { player tempAlone; strcpy(tempAlone.name, temp[i].name); tempAlone.score = temp[i].score; tempAlone.mday = temp[i].mday; tempAlone.mon = temp[i].mon; tempAlone.year = temp[i].year; strcpy(temp[i].name, temp[i - 1].name); temp[i].score = temp[i - 1].score; temp[i].mday = temp[i - 1].mday; temp[i].mon = temp[i - 1].mon; temp[i].year = temp[i - 1].year; strcpy(temp[i - 1].name, tempAlone.name); temp[i - 1].score = tempAlone.score; temp[i - 1].mday = tempAlone.mday; temp[i - 1].mon = tempAlone.mon; temp[i - 1].year = tempAlone.year; if (i > 1) i -= 2; else i = 0; } if (playerAmount > 12) playerAmount = 12; cout << "№ " << "" << '\t' << "" << '\t' << "" << endl;// for (int i = 0; i < playerAmount; i++) { cout << i + 1 << ')' << '\t' << temp[i].name << '\t' << temp[i].score << '\t'; if (temp[i].mday / 10 == 0) cout << '0' << temp[i].mday; else cout << temp[i].mday; cout << ' '; switch (temp[i].mon) { case 0: cout << ""; break; case 1: cout << ""; break; case 2: cout << ""; break; case 3: cout << ""; break; case 4: cout << ""; break; case 5: cout << ""; break; case 6: cout << ""; break; case 7: cout << ""; break; case 8: cout << ""; break; case 9: cout << ""; break; case 10: cout << ""; break; case 11: cout << ""; break; } cout << ' ' << 1900 + temp[i].year << endl; } fopen_s(&topChart, "TopChart.bin", "wb+"); for (int i = 0; i < playerAmount; i++)// fwrite(&temp[i], 1, sizeof(player), topChart); fclose(topChart); delete[] temp; _getch(); StartMenu(3); } int main() { setlocale(LC_ALL, "Rus");// system("mode con cols=51 lines=14");// system("title Space Invader");// system("color 0A");// (0- ; - ) HANDLE hCons = GetStdHandle(STD_OUTPUT_HANDLE);// CONSOLE_CURSOR_INFO cursor = { 100, false };// 1 100 ; false\true - SetConsoleCursorInfo(hCons, &cursor);// int timer = 200; cout << " (____/(__) \\_/\\_/ \\___)(____)\n\n\n\n\n\n\n\n\n\n\n __ __ _ _ _ __ ____ ____ ____\n ( )( ( \\/ )( \\ / _\\ ( \\( __)( _ \\";// Sleep(timer); system("cls"); cout << " \\___ \\ ) __// \\( (__ ) _)\n (____/(__) \\_/\\_/ \\___)(____)\n\n\n\n\n\n\n\n\n __ __ _ _ _ __ ____ ____ ____\n ( )( ( \\/ )( \\ / _\\ ( \\( __)( _ \\\n )( / /\\ \\/ // \\ ) D ( ) _) ) /";// Sleep(timer); system("cls"); cout << " / ___)( _ \\ / _\\ / __)( __)\n \\___ \\ ) __// \\( (__ ) _)\n (____/(__) \\_/\\_/ \\___)(____)\n\n\n\n\n\n\n __ __ _ _ _ __ ____ ____ ____\n ( )( ( \\/ )( \\ / _\\ ( \\( __)( _ \\\n )( / /\\ \\/ // \\ ) D ( ) _) ) /\n (__)\\_)__) \\__/ \\_/\\_/(____/(____)(__\\_)";// Sleep(timer); system("cls"); cout << " ____ ____ __ ___ ____\n / ___)( _ \\ / _\\ / __)( __)\n \\___ \\ ) __// \\( (__ ) _)\n (____/(__) \\_/\\_/ \\___)(____)\n\n\n\n\n __ __ _ _ _ __ ____ ____ ____\n ( )( ( \\/ )( \\ / _\\ ( \\( __)( _ \\\n )( / /\\ \\/ // \\ ) D ( ) _) ) /\n (__)\\_)__) \\__/ \\_/\\_/(____/(____)(__\\_)";// Sleep(timer); system("cls"); cout << "\n ____ ____ __ ___ ____\n / ___)( _ \\ / _\\ / __)( __)\n \\___ \\ ) __// \\( (__ ) _)\n (____/(__) \\_/\\_/ \\___)(____)\n\n\n __ __ _ _ _ __ ____ ____ ____\n ( )( ( \\/ )( \\ / _\\ ( \\( __)( _ \\\n )( / /\\ \\/ // \\ ) D ( ) _) ) /\n (__)\\_)__) \\__/ \\_/\\_/(____/(____)(__\\_)";// Sleep(timer); system("cls"); cout << "\n\n ____ ____ __ ___ ____\n / ___)( _ \\ / _\\ / __)( __)\n \\___ \\ ) __// \\( (__ ) _)\n (____/(__) \\_/\\_/ \\___)(____)\n __ __ _ _ _ __ ____ ____ ____\n ( )( ( \\/ )( \\ / _\\ ( \\( __)( _ \\\n )( / /\\ \\/ // \\ ) D ( ) _) ) /\n (__)\\_)__) \\__/ \\_/\\_/(____/(____)(__\\_)";// cout << '\a'; Sleep(10 * timer);// StartMenu(1); return 0; } void Game(int var) { int weaponPos;// int timer;// int odometer;// , int lifes;// char control = '&';// int shotPause = 4;// ( ) int speed;// char scr[14][50]; if (var == 1) { weaponPos = 7;// odometer = 1;// , lifes = 3;// GameStart(scr, lifes, &timer); } else// { FILE *saveBin; fopen_s(&saveBin, "CurrentSave.bin", "rb"); if (!saveBin) { system("cls"); cout << " ."; Sleep(1000); system("cls"); cout << " .."; Sleep(1000); system("cls"); cout << " ..."; Sleep(1000); Game(1); } fread(&weaponPos, 1, sizeof(int), saveBin); timer = 80; fread(&odometer, 1, sizeof(int), saveBin); fread(&lifes, 1, sizeof(int), saveBin); fread(&scr, 14 * 50, sizeof(char), saveBin); fclose(saveBin); remove("CurrentSave.bin"); } while (true) { int odometerBuf = odometer, odometerDigitLength; for (odometerDigitLength = 0; odometerBuf != 0; odometerBuf /= 10, odometerDigitLength++);// for (int i = odometerDigitLength, odometerBuf = odometer; i >= 0; i--, scr[0][i] = odometerBuf % 10 + '0', odometerBuf /= 10);// scr[0][odometerDigitLength++] = ''; scr[0][odometerDigitLength++] = '';// "" odometer++;// speed = 1000 / timer;// int speedBuf = speed; for (int i = 42; speed != 0; i--, scr[0][i] = speed % 10 + '0', speed /= 10);// scr[0][42] = ''; scr[0][43] = ''; scr[0][44] = '/'; scr[0][45] = '';// "/" if (_kbhit())// { control = _getch();// if (control == 224) control = _getch(); } if (control == 13 && shotPause == 4 || control == 32 && shotPause == 4)// { scr[weaponPos][3] = '-'; shotPause = 0; } if (shotPause < 4)// shotPause++; if (control == 27)// { FILE *saveBin; fopen_s(&saveBin, "CurrentSave.bin", "wb"); fwrite(&weaponPos, 1, sizeof(int), saveBin); fwrite(&odometer, 1, sizeof(int), saveBin); fwrite(&lifes, 1, sizeof(int), saveBin); fwrite(&scr, 14 * 50, sizeof(char), saveBin); fclose(saveBin); GameMenu(2); } if (control == 72)// if (scr[2][0] == '\\' || scr[3][0] == '\\' && scr[2][0] == '¤' || scr[3][1] == '\\' && scr[2][1] == '¤')// - if (lifes > 1) { cout << '\a'; lifes--; weaponPos = 7; GameStart(scr, lifes, &timer); Sleep(1000); } else GameOver(odometer); else { for (int i = 2; i < 13; i++)// for (int j = 0; j < 49; j++) if (scr[i][j] == '3' || scr[i][j] == '\\' || scr[i][j] == '=' || scr[i][j] == '/') { scr[i - 1][j] = scr[i][j]; scr[i][j] = ' '; } weaponPos--; } if (control == 80)// if (scr[12][0] == '/' || scr[11][0] == '/' && scr[12][0] == '¤' || scr[11][1] == '/' && scr[12][1] == '¤')// - if (lifes > 1) { cout << '\a'; lifes--; weaponPos = 7; GameStart(scr, lifes, &timer); Sleep(1000); } else GameOver(odometer); else { for (int i = 12; i >= 2; i--)// for (int j = 0; j < 49; j++) if (scr[i][j] == '3' || scr[i][j] == '\\' || scr[i][j] == '=' || scr[i][j] == '/') { scr[i + 1][j] = scr[i][j]; scr[i][j] = ' '; } weaponPos++; } for (int i = 1; i < 14; i++)// "" for (int j = 0; j < 49; j++) { if (scr[i][j] == '\\' && scr[i][j + 1] == '¤' || scr[i][j] == '=' && scr[i][j + 1] == '¤' || scr[i][j] == '/' && scr[i][j + 1] == '¤') if (lifes > 1) { cout << '\a'; lifes--; weaponPos = 7; GameStart(scr, lifes, &timer); Sleep(1000); } else GameOver(odometer); if (scr[i][j] != '3' && scr[i][j] != '\\' && scr[i][j] != '=' && scr[i][j] != '/' && scr[i][j] != '-' && scr[i][j + 1] != '-') scr[i][j] = scr[i][j + 1]; if (scr[i][j] == '¤') scr[i][j + 1] = ' '; } for (int i = 1; i < 14; i++)// for (int j = 48; j >= 0; j--) if (scr[i][j] == '-') if (j != 48) { scr[i][j + 1] = '-'; scr[i][j] = ' '; } else scr[i][j] = ' '; char borderSymbols[] = { '†', '‡', '¤', ' ' }; scr[2][49] = ' ';// scr[1][49] = borderSymbols[rand() % 3]; if (scr[1][49] == '‡') scr[2][49] = '¤'; scr[12][49] = ' '; scr[13][49] = borderSymbols[rand() % 3]; if (scr[13][49] == '‡') scr[12][49] = '¤'; for (int i = 3; i < 12; i++)// { if (rand() % 10 == 1) scr[i][49] = '¤'; } ScreenOutput(scr);// if (control != '&')//"" control = '&'; if (timer > 25)// timer--; Sleep(timer);// } }
.exe : Space Invader .
PS: , .