Исходные коды программ и игр

Программирование - работа и хобби

Исходник логической игры LinesK

Язык программирования C#

Описание исходного кода игры

Интерфейс логической игры LinesKИсходник написан на языке .NET C#. Графика приложения построена на базе графической библиотеки GDI+ и событии прорисовки окна OnPaint(...). Информационная графическая панель также выводит текст на поверхности GDI+, получая доступ к ней с помощью класса .NET Framework class Graphics

Для упрощения сопровождения кода исходник имеет модульную структуру, функциональность разделена на классы. Имеются модули настроек игры, сохранения настроек в двоичном формате и загрузка настроек из файла при запуске приложения.

Структура исходника

Исходник состоит из основных классов:
  • class FormMain - сборочный класс приложения. Размещает на себе игровое поле состоящее из 100 графических элементов. Обеспечивает взаимодействие с пользователем, читает настройки игры из файла и при закрытии приложения сохраняет настройки в файл.
  • class GraphItem - анимационный графический элемент. Образует ячейку с геометрической фигурой в центре. Обеспечивает анимацию активности, анимацию исчезновения и изменения цвета геометрической фигуры. Из объектов данного класса состоит игровое поле приложения.
  • class FormGameSetting - модальное окно настроек игры. Позволяет выбирать цвет и вид графической фигуры.
  • class FormPlayerName - модальное окно изменения имени игрока. В качестве иконки используется единица графического элемента
  • Модуль глобальных переменных и хранения настроек игры. Основные настройки игры сохраняются в файл в месте запуска приложения. Входят 3 класса - class Global, class GameSetting, class DataRecordsman
  • class FormEndGame - диалоговое окно окончания игры, оповещает пользователя об окончании игры и количестве набранных очков.

Анимационный графический элемент

Анимационный графический элементМодуль графического элемента class GraphItem представляет собой ячейку игрового поля. В центре графэлемента размещается цветная геометрическая фигура. Модуль показывает и скрывает фигуру, изменяет цвет и вид геометрической фигуры. Графэлемент также отвечает за анимацию фигур в режиме выбора и исчезновения при собирании в линию. Массив объектов класса GraphItem создает красочное игровое поле приложения.

Анимацию обеспечивают два таймера. Один таймер для визуальной активности выбранного элемента: происходит пульсация размеров геометрической фигуры. Второй таймер создаёт плавное исчезновение геометрических фигур при наборе линии из 5 и более элементов. Таймеры обеспечивают псевдомногопоточную работу приложения. Перерисовка графических элементов происходит без блокировки пользовательского интерфейса.

Листинг кода работы таймеров:
// Таймер активности (пульсирования) 
private Timer timerActive = new Timer();

// Таймер исчезновения
private Timer timerVanish = new Timer();

// Изменения размера сторон геометрического элемента 
// при пульсации и исчезновении.
private int deltaSize = 0;

/// <summary>
/// Координаты графэлемента.
/// </summary>
public Rectangle CellCoordinate;


int k = 1;
/// <summary>
/// Таймер активности периодически увеличивает и
/// уменьшает геометрическую фигуру,
/// создавая эффект активности.
/// </summary>
void TimerActive_Tick(object sender, EventArgs e)
{
    deltaSize += 1 * k;

    // Цикл уменьшения и увеличения размера
    // геометрической фигуры при пульсировании.
    if (deltaSize >= -2)
    {
                k = -1;
    }
    else if (deltaSize <= -7)
    {
        k = 1;
    }
    
    // Для экономии процессорных ресурсов
    // обновляем только прямоугольник 
    // графического элемента.
    Parent.Invalidate(CellCoordinate);
}

/// <summary>
/// Таймер исчезания, сначала графэлемент уменьшается,
/// а потом исчезает.
/// </summary>
void TimerVanish_Tick(object sender, EventArgs e)
{
    deltaSize += -2;

    if (deltaSize < -14)
    {
       timerVanish.Enabled = false;
       visible = false;
       vanish = false;

       // После того как геометрическая фигура стала невидимой,
       // возвращаем ей нормальные размеры.
       deltaSize = inflateSize;
    }

    // Для экономии процессорных ресурсов
    // обновляем только прямоугольник 
    // графического элемента.
    Parent.Invalidate(CellCoordinate);
}

Вывод графэлемента на поверхность GDI

Графический элемент class GraphItem рисуется на клиентской части родительского окна средствами GDI+. Для этого в классе есть специальный метод void Draw(Graphics g). Данным методом создаются ячейки с различными геометрическими фигурками. Графэлементы перерисовываются стандартно при генерировании события OnPaint родительским окном. И принудительно перерисовываются вызовом события OnPaint таймерами активности и исчезновения.

Краткий листинг метода рисования графэлемента:
/// <summary>
/// Рисование графики на поверхности окна приложения.
/// </summary>
/// <param name="g">Поверхность GDI+</param>
public void Draw(Graphics g)
{
    // Рисование ячейки, места для геометрической фигуры.
    g.FillRectangle(BrushCell(), CellCoordinate.X + 1,
    CellCoordinate.Y + 1, CellCoordinate.Width - 1, CellCoordinate.Height - 1);

    // При невидимой геометрической фигуре прорисовывается только квадрат ячейки.
    if (visible == false) return;

    // Вспомогательный квадрат для эффекта исчезания и эффекта 
    // активности в выбранном состоянии.
    Rectangle rectInflate = CellCoordinate;
    rectInflate.Inflate(deltaSize, deltaSize);

    ..............
   
    // Рисование текущей геометрической фигуры.
    switch (CurrentTypeGraphItem)
    {
        case TypeGraphItem.Ellipse:
            g.FillEllipse(pathBrush, rectInflate);
            break;
        case TypeGraphItem.Rectangle:
            g.FillRectangle(pathBrush, rectInflate);
            break;
        case TypeGraphItem.Rhombus:
            g.FillPolygon(pathBrush, pt);
            break;
    }
}
Листинг родительского метода события OnPaint:
private void FormMain_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;

    TextPanel(g);

    // Прорисовка графических элементов.
    for (int i = 0; i < Global.NumGraphItems; i++)
    {
        graphItems[i].Draw(g);
    }
}

BinaryFormatter для сохранения настроек

Класс BinaryFormatter для сохранения и чтения настроек используется BinaryFormatter упрощает процедуру сохранения объекта или группы объектов. Сохранение осуществляется в двоичном формате, достоинство такого формата - компактность и возможность сохранения объектов любой сложности, недостаток - невозможность непосредственного редактирования сохраненного файла.


// Сохранение настроек в файл .ini
void ToFileIni()
{
    string filePath = Application.StartupPath + "\\settings.lin";
    FileStream fileStream = File.Create(filePath);
 
    BinaryFormatter bf = new BinaryFormatter();
 
    for (int i = 0; i < GameSet.DRH.Length; i++)
    {
         GameSet.DRH[i].CurrentPlayer = false;
    }
    bf.Serialize(fileStream, GameSet);
    fileStream.Close();
}
 
// Чтение настроек из файла  .ini
void FromFileIni()
{
    FileStream fileStream = null;
    string filePath = Application.StartupPath + "\\settings.lin";
 
    FileInfo fi = new FileInfo(filePath);
    if (fi.Exists == false) return;
 
    fileStream = File.OpenRead(filePath);
    BinaryFormatter bf = new BinaryFormatter();
    GameSet = (GameSetting)bf.Deserialize(fileStream);
     
               .............
               
    Array.Sort(GameSet.DRH, new SortRecordHolders());
     
    fileStream.Close();        
}

List<T> для проверки последовательностей

Для проверок последовательностей из 5 и более геометрических фигур в исходнике применяется класс List появившийся в .NET Framework 2.0. Данный список удобен тем, что может содержать любые типы объектов, имеет простые процедуры добавления, удаления элементов, сортировки и при извлечении элементов не требуется приведения типов. На практике List очень удобный универсальный динамический массив.


bool HideGraphItems()
{
    List<bool> listBool = new List<bool>();
    listBool.Add(CheckColumn());
    listBool.Add(CheckRow());
    listBool.Add(CheckDiagonal());
    listBool.Add(CheckDiagonal2());
 
    for (int i = 0; i < listBool.Count; i++)
    {
        if (listBool[i] == true) return true;
    }
 
    return false;
}

Инструменты для работы с исходником

Среда программирования MS Visual Studio 2019, Visual Studio Core. Блокнот и компилятор C#.

Файл загрузки Размер Кол-во загрузок
sourcelinesk_vs16.zip 💾 738Кбайт 5987