Roguelike. Движение персонажа, проверить реализацию кода - C#
Формулировка задачи:
Здравствуйте. Решил продолжить свое изучение C# на практике. Хочется написать небольшой рогалик. В общем - сейчас реализовал только до жути примитивный рендер карты из массива, и движение/столкновение персонажа("@").
Но вот чувствую что я пишу всё через задницу, и ничего "правильного" в моем коде нет.
Конкретные неувязки:
- Перемещение персонажа по карте. Всё осуществляется с помощью замены в массиве персонажа("@") с тем пустым местом(".") что находится по соседству в определенном направлении, и последующей очисткой экрана и рендерингом этого массива. Чувствую что можно поумнее это дело организовать.
- Проверка на столкновения. Перед движением персонажа в определенную сторону, проверяется - нет ли там стены("#"), если есть, то не двигаться, а просто перерисовать экран. Всё бы хорошо, но в будущем мне нужно будет "сталкиваться" не только со стенами, а так же с предметами которые можно будет поднять, с водой к примеру, и еще кучей всего. И несколько десятков if'ов в блоке кода каждого движения как-то бы вообще не хотелось. Как обрабатывать столкновения красиво?
- По скольку обрабатываю нажатия клавиш с помощью ReadKey(), всё что ввожу с клавиатуры - выводится на экран. Нельзя ли просто обрабатывать нажатия клавиш без вывода иных на экран?
// Управление - 8,6,2,4 на нумпаде.
using System;
namespace Roguelike
{
class Program
{
public static void mapRender(char[,] map) //Очищает и рендерит карту;
{
Console.Clear();
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 7; j++)
{
Console.Write(map[i, j]);
}
Console.WriteLine();
}
}
static void Main(string[] args)
{
int heroX = 3; //Задаем координаты персонажа
int heroY = 2;
char[,] map =
{
{'#','#','#','#','#','#','#'},
{'#','.','.','.','.','.','#'},
{'#','.','.','.','.','.','#'},
{'#','.','.','.','.','.','#'},
{'#','#','#','#','#','#','#'}
};
map[heroY, heroX] = '@'; //Ставим персонажа на карту
mapRender(map); //Рендерим
ConsoleKeyInfo keypress;
do
{
keypress = Console.ReadKey();
if (keypress.KeyChar == '8') //Движение вверх
{
if (map[heroY - 1, heroX] != '#') //Провяем нет ли стены там, куда мы будем двигаться
{
map[heroY, heroX] = '.';
map[heroY - 1, heroX] = '@';
heroY--;
mapRender(map);
}
else mapRender(map);
}
if (keypress.KeyChar == '6') //Движение вправо
{
if (map[heroY, heroX + 1] != '#')
{
map[heroY, heroX] = '.';
map[heroY, heroX + 1] = '@';
heroX++;
mapRender(map);
}
else mapRender(map);
}
if (keypress.KeyChar == '2') //Движение вниз
{
if (map[heroY + 1, heroX] != '#')
{
map[heroY, heroX] = '.';
map[heroY + 1, heroX] = '@';
heroY++;
mapRender(map);
}
else mapRender(map);
}
if (keypress.KeyChar == '4') //Движение влево
{
if (map[heroY, heroX - 1] != '#')
{
map[heroY, heroX] = '.';
map[heroY, heroX - 1] = '@';
heroX--;
mapRender(map);
}
else mapRender(map);
}
} while (keypress.KeyChar != 'Q');
}
}
}Решение задачи: «Roguelike. Движение персонажа, проверить реализацию кода»
textual
Листинг программы
// Управление - 8,6,2,4 на нумпаде.
using System;
namespace Roguelike
{
class Program
{
static int OffsetX = 20;
static int OffsetY = 3;
public static void firstDraw(char[,] map) //Очищает и рендерит карту;
{
Console.Clear();
for (int y = 0; y < 5; y++)
for (int x = 0; x < 7; x++)
putCh(map[y, x], y, x);
}
private static void putCh(char ch, int y, int x)
{
Console.SetCursorPosition(OffsetX + x, OffsetY + y);
Console.Write(ch);
}
static char[,] map =
{
{'#','#','#','#','#','#','#'},
{'#','.','.','.','.','.','#'},
{'#','.','.','.','.','.','#'},
{'#','.','.','.','.','.','#'},
{'#','#','#','#','#','#','#'}
};
static int heroX = 3; //Задаем координаты персонажа
static int heroY = 2;
static void Main(string[] args)
{
map[heroY, heroX] = '@'; //Ставим персонажа на карту
firstDraw(map); //Рендерим
ConsoleKeyInfo keypress;
do
{
keypress = Console.ReadKey(true);
switch (keypress.KeyChar)
{
case 'w': move(0, -1); break;
case 's': move(0, 1); break;
case 'd': move(1, 0); break;
case 'a': move(-1, 0); break;
default:
break;
}
} while (keypress.KeyChar != 'q');
}
private static void move(int dx, int dy)
{
if (map[heroY + dy, heroX + dx] == '#') return; //Провяем нет ли стены там, куда мы будем двигаться
map[heroY, heroX] = '.';
putCh('.', heroY, heroX);
heroY += dy; heroX += dx;
map[heroY, heroX] = '@';
putCh('@', heroY, heroX);
}
}
}