Первая ошибка, которую вы совершаете здесь, это попытка разделить пули влево и пули вправо. Должен быть только один массив маркеров, где записи - это позиция маркера, а затем вы используете их положение, чтобы определить, идут ли они вправо или влево. Это легко, так как вы уже определили две клавиши, одну для стрельбы влево и одну для стрельбы вправо. «Хитрая» часть обрабатывает то, что происходит, когда пуля покидает мир: я принял решение сделать так, чтобы они полностью исчезли, а это означает, что каждый раз, когда кто-то покидает экран, пули становится на одну единицу меньше. Я реализовал это, перебирая каждую пулю и «вытягивая их назад», то есть следующая перезаписывает текущую.
Вторая ошибка - основа рендеринга, которую вы используете. Итерации по циклу for, пока вы не наткнетесь на то, что хотите нарисовать, не очень устойчивы. Чтобы исправить это, я ввел массив символов, в котором мы храним все, что хотим нарисовать (игрок, маркеры и '-'), а затем рендеринг - это всего лишь один printf.
Я также взял на себя смелость заставить игру работать только при вводе, так как это меня не смущает. Также изменил ключи на asdf, так как это более эргономично для меня.
#include <stdio.h>
#include <string.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <conio.h>
int main() {
bool exit = false;
int PlayerPosition = 33;
const int MaxBullets = 50;
int Bullets[MaxBullets] = {};
int CurrentBullets = 0;
CONSOLE_SCREEN_BUFFER_INFO csbi;
int columns, rows;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
const int WIDTH = columns;//info->dwSize.X;
char* RenderLine = (char*) HeapAlloc(
GetProcessHeap(), HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, columns + 1
);
// Initial render
for (int i = 0; i < WIDTH; i++) {
RenderLine[i] = '-';
}
RenderLine[PlayerPosition] = 'x';
printf(RenderLine);
do {
//Process input
char ch = getch();
if (ch) {
switch (ch) {
case 'a': {
if (PlayerPosition > 0) {
RenderLine[PlayerPosition] = '-';
RenderLine[--PlayerPosition] = 'x';
}
break;
}
case 'f': {
if (PlayerPosition < WIDTH - 1) {
RenderLine[PlayerPosition] = '-';
RenderLine[++PlayerPosition] = 'x';
}
break;
}
case 'd': {
if (CurrentBullets < MaxBullets) {
RenderLine[PlayerPosition + 1] = '>';
Bullets[CurrentBullets++] = PlayerPosition + 1;
}
break;
}
case 's': {
if (CurrentBullets < MaxBullets) {
RenderLine[PlayerPosition - 1] = '<';
Bullets[CurrentBullets++] = PlayerPosition - 1;
}
break;
}
case 27: exit = true; break; // press escape
}
//Render
printf(RenderLine);
//Move bullets
for (int i = 0; i < CurrentBullets; i++) {
if (Bullets[i] > PlayerPosition) { // move right
RenderLine[Bullets[i]] = '-';
if (Bullets[i] == (WIDTH - 1)) { // a bullet has left the screen on the right
Bullets[i] = Bullets[--CurrentBullets];
} else {
RenderLine[++Bullets[i]] = '>';
}
} else if (Bullets[i] < PlayerPosition) { // move right
RenderLine[Bullets[i]] = '-';
if (Bullets[i] == 0) { // a bullet has left the screen on the left
Bullets[i] = Bullets[--CurrentBullets];
} else {
RenderLine[--Bullets[i]] = '<';
}
}
}
}
} while (!exit);
}