Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.10.2014, 01:45   #1
TrueOman
Новичок
Джуниор
 
Регистрация: 10.10.2011
Сообщений: 2
Радость Roguelike. Посмотрите код

Здравствуйте. Решил продолжить свое изучение C# на практике. Хочется написать небольшой рогалик. В общем - сейчас реализовал только до жути примитивный рендер карты из массива, и движение/столкновение персонажа("@").
Но вот чувствую что я пишу всё через задницу, и ничего "правильного" в моем коде нет.

Конкретные неувязки:
  1. Перемещение персонажа по карте. Всё осуществляется с помощью замены в массиве персонажа("@") с тем пустым местом(".") что находится по соседству в определенном направлении, и последующей очисткой экрана и рендерингом этого массива. Чувствую что можно поумнее это дело организовать.
  2. Проверка на столкновения. Перед движением персонажа в определенную сторону, проверяется - нет ли там стены("#"), если есть, то не двигаться, а просто перерисовать экран. Всё бы хорошо, но в будущем мне нужно будет "сталкиваться" не только со стенами, а так же с предметами которые можно будет поднять, с водой к примеру, и еще кучей всего. И несколько десятков if'ов в блоке кода каждого движения как-то бы вообще не хотелось. Как обрабатывать столкновения красиво?
  3. По скольку обрабатываю нажатия клавиш с помощью 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');
        }
    }
}
TrueOman вне форума Ответить с цитированием
Старый 28.10.2014, 19:52   #2
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

Мне Ваш код не понравился.
Во-первых, надо использовать декомпозицию, а у Вас всё в куче. А в декомпозированных объектах следить за уровнями доступа, временем жизни подэлементов.
Во-вторых, надо писать на "языке предметной области", т.е. в терминах сущностей для рогалика (работу их вычленить как раз при декомпозиции).
В-третьих, нужны абстракции, не привязывайтесь к консоли, киинпутам, символам, массивам и т.п. (оборачивайте по возможности все такие вещи - по идее при прохождении предыдущих этапов).
В-четвёртых, в рогалике обычно используют "слои", а у вас карта "плоская", когда герой стоит на клетке - она не является полом, а является героем, и это крест для любой интеракции в игре.
В-пятых, из-за непроработанных этапов 1-3 у Вас плодится копипаста и отсутствие гибкости.

Я бы, если собирался делать простой рогалик, начал бы минимум с чего-то такого (вложение). Хотя, конечно, там много чего ещё бы сделать, чтобы соответствовало моим же словам (этапам), как минимум, карту надо вынести в отдельный класс. Ответы на все 3 Ваших вопроса там есть, но их надо малость поискать.
Вложения
Тип файла: zip rl.zip (30.6 Кб, 43 просмотров)

Последний раз редактировалось phomm; 28.10.2014 в 19:55.
phomm вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Посмотрите мои код на Делфи (Азбука Морзе) darla1991 Помощь студентам 0 21.10.2012 15:02
Roguelike игра на WinAPI apromix Gamedev - cоздание игр: Unity, OpenGL, DirectX 1 20.08.2011 15:19
Посмотрите код! Spicus Visual C++ 6 30.01.2011 14:47
нужна Блок-схема... посмотрите код Настёна_19 Помощь студентам 0 26.12.2010 03:05
Посмотрите код Assemblerru Общие вопросы C/C++ 3 05.05.2010 17:57