Загрузка...

Игра на C#

Тема в разделе C# создана пользователем AshotOneShot 5 ноя 2020. 1926 просмотров

  1. AshotOneShot
    AshotOneShot Автор темы 5 ноя 2020 долбаеб 18 10 фев 2017
    Здарова пацаны. В общем, обратился ко мне друг на днях, с просьбой написать ему игру(гонки) для шараги, почесал я репу и согласился, за символические 500 рублей сделать ему этот шедевр(за который он между прочим получил 2 пятерки:roflanPoker:).
    Потратил я на это:
    • 2 кружки кофе(nescafe gold barista)
    • 3 сижки(Philip Morris exotic mix)
    • 3 часа своего не драгоценного времени
    Не знаю, кому это может потребоваться, но надеюсь кому-то пригодятся мои труды
    Ладно, хватит разглагольствовать, перейдем к тому как я это реализовал.

    1. Создаем проект winForms

    2. Создаем сразу несколько форм с меню, гаражом и собсна с игрой(Form1, garage, game)

    [IMG]
    [IMG]
    [IMG]

    На форму с главным меню кидаем:
    • 3 Кнопки (Играть, Гараж, Выход)
    • Лэйбл с названием игры
    И переходим к коду.
    На кнопку выхода сразу вешаем:
    Код
    Application.Exit();
    Думаю, объяснять что это значит не надо
    На кнопку "Гараж" вешаем функцию вызова формы с гаражом(у меня она называется garage):
    Код
    garage Garage = new garage();
    Garage.Show();
    А, еще один момент, надо перейти в класс Program.cs и добавить туды переменную для хранения пути до выбранной машины. Код:
    Код

    public static class Info
    {
    public static string Car_model { get; set; } // переменная для хранения пути до картинки с машиной
    }
    Перейдем на форму с гаражом. На нее кидаем:
    • лэйбл с надписью "Выбери машину:"
    • 2 pictureBox'a с модельками машины(они будут в конце статьи), называем их car1 и car2
    Два раза клиаем по обоим пиктуреБоксам, чтобы создать событие на клик по ним.
    В событие клика первого pictureBox'a пишем данный код:
    Код
    Info.Car_model = "res/car01.png"; // присвоение значения пути до первой модели машины(тут надо указать путь до картинки)
    DialogResult result = MessageBox.Show("Вы выбрали первую машину, покинуть гараж?", "Гараж", MessageBoxButtons.YesNo, MessageBoxIcon.Question); // вывод диалогового окна
    if (result == DialogResult.Yes) // если ответ да
    {
    this.Close(); // закрытие формы
    }
    Второго:
    Код
    Info.Car_model = "res/car02.png"; // присвоение значения пути до второй модели машины
    DialogResult result = MessageBox.Show("Вы выбрали вторую машину, покинуть гараж?", "Гараж", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
    if (result == DialogResult.Yes)
    {
    this.Close();
    }
    Переходим обратно на первую форму (которая с меню) и на событие клика кнопки играть вешаем это:
    Код
     if (Info.Car_model != null) // проверка переменной в которой хранится путь до картинки с машиной
    {
    game Game = new game();
    Game.Show(); // Открытие формы с игрой
    this.Hide(); // Скрытие формы с меню, чтобы не мешала
    }
    else // если в ней нет значения
    {
    MessageBox.Show("Сначала выбери машину в гараже"); // выводим сообщение с ошибкой
    }
    Теперь открываем форму с игрой.
    В настройках формы, в поле BackgoundImage подгружаем картинку с дорогой (все ресурсы внизу).
    Кидаем три(3) pictureBox'a, и называем их player и enemy и finish
    на пиктуреБокс с финишем вешаем картинку с финишной полосой
    Так же на нее кидаем 6 таймеров, Interval ставим 10. Называем их так:
    [IMG]
    Кидаем Label, в котором пишем:
    и в поле name пишем

    Все, форму настроили, переходим к коду. Влетаем в него с ноги и сразу же добавляем либу Drawing:
    Код
    using System.Drawing;
    и пока форма в ахуе, объявляем переменные:
    Код
    Image player_img; // переменная с картинкой машины игрока
    int playerspeed = 10; // переменная со скоростью игрока
    int enemyspeed = 5; // переменная со скоростью противника
    bool pause = true; // переменная паузы
    Image enemy_img; // переменная с картинкой машины противника
    Random rnd = new Random(); // рандом
    Так, переменные объявили, теперь идем public game() и там пишем:
    Код
    player_img = new Bitmap(Info.Car_model); // берем из переменной Car_model путь до картинки с машиной
    player.Image = player_img; // присваиваем объекту player(pictureBox) картинку с машиной
    enemy_img = new Bitmap($"res/car0{rnd.Next(1, 5)}.png"); // выбираем рандомную картинку для машины противника
    enemy.Image = enemy_img; // присваиваем рандомную картинку объекту enemy
    Дальше прописываем код для каждого таймера:
    Код
     private void move_left_timer_Tick(object sender, EventArgs e) // таймер движения вперед (вправо)
    {
    if (player.Left < 1460) // проверка, чтобы игрок не заезжал за рамки трассы
    {
    player.Left += playerspeed; // Двигаем picuteBox с игроком
    }
    }


    private void move_up_timer_Tick(object sender, EventArgs e) // таймер движения влево (вверх)
    {
    if (player.Top > 210) // проверка, чтобы игрок не заезжал за рамки трассы
    {
    player.Top -= playerspeed; // Двигаем picuteBox с игроком
    }
    }

    private void move_down_timer_Tick(object sender, EventArgs e) // таймер движения вправо (вниз)
    {
    if (player.Top < 470) // проверка, чтобы игрок не заезжал за рамки трассы
    {
    player.Top += playerspeed; // Двигаем picuteBox с игроком
    }
    }
    private void enemy_move_timer_Tick(object sender, EventArgs e)
    {
    enemy.Left += enemyspeed + rnd.Next(2, 8); // движение противника, с рандомом
    }
    private void finish_timer_Tick(object sender, EventArgs e) // таймер проверки пересечения финиша или столкновения игрока с врагом
    {
    if (player.Bounds.IntersectsWith(finish.Bounds)) // проверка пересечения игрока линии финиша
    {
    move_right_timer.Stop(); // останавливаем таймер движения вперед(вправо)
    enemy_move_timer.Stop(); // останавливаем таймер движения противника
    pause = true; // ставим паузу
    pause_label.Text = "Поздравляю! Вы выиграли";
    pause_label.Show(); // меняем надпись лэйбла и выводим его

    }
    if (enemy.Bounds.IntersectsWith(finish.Bounds)) // проверка пересечения врага линии финиша
    {
    enemy_move_timer.Stop();
    pause = true;
    pause_label.Text = "Увы, но вы проиграли";
    pause_label.Show();
    }
    if (player.Bounds.IntersectsWith(enemy.Bounds)) // проверка столкновения игрока с врагом
    {
    enemy_move_timer.Stop();
    pause = true;
    pause_label.Text = "Вы врезались, машина сломана";
    pause_label.Show();
    }
    }
    Переходим в конструктор формы, в настройках формы находим события KeyDown и KeyUp, нажимаем на них 2 раза
    [IMG]

    В KeyDown Пишем обработчик нажатия клавиш:
    [CODE]if (e.KeyCode == Keys.Space) // если нажата клавиша Space
    {
    if (pause) //проверяем переменную pause, если истина то:
    {
    pause = false; // меняем на ложь
    pause_label.Hide(); //скрываем лэйбл паузы
    Thread.Sleep(1000); // задержка в одну секунду, чтобы игрок успел сориентироваться
    enemy_move_timer.Start(); // запускаем таймер с движением противника
    finish_timer.Start();
    }
    else // если ложь, то:
    {
    pause = true; // меняем на истину
    pause_label.Show(); // показываем лэйбл паузы
    enemy_move_timer.Stop();
    finish_timer.Stop();
    }
    }
    if (!pause) // проверяем стоит ли игры на паузе, если нет то:
    {
    if (e.KeyCode == Keys.Up || e.KeyCode == Keys.W) // проверяем если нажата клавиша вверх или W
    {
    move_right_timer.Start(); // запускаем таймер движения вперед(вправо)
    }
    if (e.KeyCode == Keys.Left || e.KeyCode == Keys.A) // если нажата клавиша влево или A
    {
    move_up_timer.Start(); // запускаем таймер движения влево(вверх)
    }
    if (e.KeyCode == Keys.Right || e.KeyCode == Keys.D) // если нажата клавиша вправо или D
    {
    move_down_timer.Start(); // запускаем таймер движения вправо(вниз)
    }
    }[/CODE]В KeyUp это:
    [CODE] if (e.KeyCode == Keys.Up || e.KeyCode == Keys.W) // если отпущена клавиша вверх или W
    {
    move_right_timer.Stop(); // останавливаем таймер движения вперед(вправо)
    }
    if (e.KeyCode == Keys.Left || e.KeyCode == Keys.A) // если отпущена клавиша влево или A
    {
    move_up_timer.Stop(); // останавливаем таймер движения влево(вверх)
    }
    if (e.KeyCode == Keys.Right || e.KeyCode == Keys.D) // если отпущена клавиша вправо или D
    {
    move_down_timer.Stop(); // останавливаем таймер движения вправо(вниз)
    }[/CODE]
    Вот и вся игра, реализовал так, как додумался, возможно это можно сделать более элегантно.
    Ссылка на исходники + ресурсы:
    P.S. Прошу не бить за говнокод и за говностатью, извините опыта не много
    P.S.S. Если это кому-либо пригодится, напишите, мне будет очень приятно
    P.S.S.S.
    [CODE]using System;
    using System.Windows.Forms;

    namespace Gonki
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }

    private void button3_Click(object sender, EventArgs e)
    {
    Application.Exit(); // Закрытие игры
    }

    private void Game_butt_Click(object sender, EventArgs e)
    {
    if (Info.Car_model != null) // проверка переменной в которой хранится путь до картинки с машиной
    {
    game Game = new game();
    Game.Show(); // Открытие формы с игрой
    this.Hide(); // Скрытие формы с меню, чтобы не мешала
    }
    else // если в ней нет значения
    {
    MessageBox.Show("Сначала выбери машину в гараже"); // выводим сообщение с ошибкой
    }
    }

    private void Garage_butt_Click(object sender, EventArgs e)
    {
    garage Garage = new garage();
    Garage.Show(); // Открытин формы с гаражом
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
    Application.Exit();
    }
    }
    }
    [/CODE]
    [CODE]using System;
    using System.Windows.Forms;

    namespace Gonki
    {
    public partial class garage : Form
    {
    string caption = "Гараж";
    public garage()
    {
    InitializeComponent();
    }

    private void Car1_Click(object sender, EventArgs e)
    {
    car1_lab.Text = "Выбрано"; // Отображение надписи под выбранной машиной
    car2_lab.Text = "";
    Info.Car_model = "res/car01.png"; // присвоение значения пути до первой модели машины
    DialogResult result = MessageBox.Show("Вы выбрали первую машину, покинуть гараж?", caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question); // вывод диалогового окна
    if (result == DialogResult.Yes) // если ответ да
    {
    this.Close(); // закрытие формы
    }

    }

    private void Car2_Click(object sender, EventArgs e)
    {
    car2_lab.Text = "Выбрано";
    car1_lab.Text = "";
    Info.Car_model = "res/car02.png"; // присвоение значения пути до второй модели машины
    DialogResult result = MessageBox.Show("Вы выбрали вторую машину, покинуть гараж?", caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
    if (result == DialogResult.Yes)
    {
    this.Close();
    }
    }
    }
    }
    [/CODE]
    [CODE]using System;
    using System.Windows.Forms;

    namespace Gonki
    {
    static class Program
    {
    /// <summary>
    /// Главная точка входа для приложения.
    /// </summary>
    [STAThread]
    static void Main()
    {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
    }
    }
    public static class Info
    {
    public static string Car_model { get; set; } // переменная для хранения пути до картинки с машиной
    }
    }[/CODE]
    [CODE]using System;
    using System.Drawing;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;

    namespace Gonki
    {
    public partial class game : Form
    {
    Image player_img; // переменная с картинкой машины игрока
    int playerspeed = 10; // переменная со скоростью игрока
    int enemyspeed = 5; // переменная со скоростью противника
    bool pause = true; // переменная паузы
    Image enemy_img; // переменная с картинкой машины противника
    Random rnd = new Random(); // рандом

    public game()
    {
    InitializeComponent();
    player_img = new Bitmap(Info.Car_model); // берем из переменной Car_model путь до картинки с машиной
    player.Image = player_img; // присваеваем объекту player(pictureBox) картинку с машиной
    enemy_img = new Bitmap($"res/car0{rnd.Next(1, 5)}.png"); // выбираем рандомную картинку для машины противника
    enemy.Image = enemy_img; // присваиваем рандомную картинку объекту enemy

    }

    private void game_FormClosed(object sender, FormClosedEventArgs e) // если форма закрылась
    {
    Form1 form = new Form1();
    form.Show(); // Отображение формы с меню


    }

    private void move_left_timer_Tick(object sender, EventArgs e) // таймер движения вперед (вправо)
    {
    if (player.Left < 1460) // проверка, чтобы игрок не заезжал за рамки трассы
    {
    player.Left += playerspeed; // Двигаем picuteBox с игроком
    }
    }


    private void move_up_timer_Tick(object sender, EventArgs e) // таймер движения влево (вверх)
    {
    if (player.Top > 210) // проверка, чтобы игрок не заезжал за рамки трассы
    {
    player.Top -= playerspeed; // Двигаем picuteBox с игроком
    }
    }

    private void move_down_timer_Tick(object sender, EventArgs e) // таймер движения вправо (вниз)
    {
    if (player.Top < 470) // проверка, чтобы игрок не заезжал за рамки трассы
    {
    player.Top += playerspeed; // Двигаем picuteBox с игроком
    }
    }

    private void game_KeyDown(object sender, KeyEventArgs e) // событие нажатия клавиши
    {
    if (e.KeyCode == Keys.Space) // если нажата клавиша Space
    {
    if (pause) //проверяем переменную pause, если истина то:
    {
    pause = false; // меняем на ложь
    pause_label.Hide(); //скрываем лэйбл паузы
    Thread.Sleep(1000); // задержка в одну секунду, чтобы игрок успел сориентироваться
    enemy_move_timer.Start(); // запускаем таймер с движением противника
    finish_timer.Start();
    }
    else // если ложь, то:
    {
    pause = true; // меняем на истину
    pause_label.Show(); // показываем лэйбл паузы
    enemy_move_timer.Stop();
    finish_timer.Stop();
    }
    }
    if (!pause) // проверяем стоит ли игры на паузе, если нет то:
    {
    if (e.KeyCode == Keys.Up || e.KeyCode == Keys.W) // проверяем если нажата клавиша вверх или W
    {
    move_right_timer.Start(); // запускаем таймер движения вперед(вправо)
    }
    if (e.KeyCode == Keys.Left || e.KeyCode == Keys.A) // если нажата клавиша влево или A
    {
    move_up_timer.Start(); // запускаем таймер движения влево(вверх)
    }
    if (e.KeyCode == Keys.Right || e.KeyCode == Keys.D) // если нажата клавиша вправо или D
    {
    move_down_timer.Start(); // запускаем таймер движения вправо(вниз)
    }
    }
    }

    private void game_KeyUp(object sender, KeyEventArgs e) // событие отпускания клавиши
    {
    if (e.KeyCode == Keys.Up || e.KeyCode == Keys.W) // если нажата клавиша вверх или W
    {
    move_right_timer.Stop(); // останавливаем таймер движения вперед(вправо)
    }
    if (e.KeyCode == Keys.Left || e.KeyCode == Keys.A) // если нажата клавиша влево или A
    {
    move_up_timer.Stop(); // останавливаем таймер движения влево(вверх)
    }
    if (e.KeyCode == Keys.Right || e.KeyCode == Keys.D) // если нажата клавиша вправо или D
    {
    move_down_timer.Stop(); // останавливаем таймер движения вправо(вниз)
    }
    }

    private void enemy_move_timer_Tick(object sender, EventArgs e)
    {
    enemy.Left += enemyspeed + rnd.Next(2, 8); // движение противника, с рандомом
    }

    private void finish_timer_Tick(object sender, EventArgs e) // таймер проверки пересечения финиша или столкновения игрока с врагом
    {
    if (player.Bounds.IntersectsWith(finish.Bounds)) // проверка пересечения игрока линии финиша
    {
    move_right_timer.Stop(); // останавливаем таймер движения вперед(вправо)
    enemy_move_timer.Stop(); // останавливаем таймер движения противника
    pause = true; // ставим паузу
    pause_label.Text = "Поздравляю! Вы выиграли";
    pause_label.Show(); // меняем надпись лэйбла и выводим его

    }
    if (enemy.Bounds.IntersectsWith(finish.Bounds)) // проверка пересечения врага линии финиша
    {
    enemy_move_timer.Stop();
    pause = true;
    pause_label.Text = "Увы, но вы проиграли";
    pause_label.Show();
    }
    if (player.Bounds.IntersectsWith(enemy.Bounds)) // проверка столкновения игрока с врагом
    {
    enemy_move_timer.Stop();
    pause = true;
    pause_label.Text = "Вы врезались, машина сломана";
    pause_label.Show();
    }
    }
    }
    }
    [/CODE]
     
  2. Frecadelka
    Frecadelka 8 ноя 2020 Заблокирован(а) 10 9 янв 2019
    Коротко о геймдеве в россии.. Но воще, сделал крута, ставлю клас :2011_like:
     
    1. AshotOneShot Автор темы
  3. itstranger
    itstranger 18 ноя 2020 12 19 апр 2020
    У меня вопрос, а зачем 4 таймера?) Можно же все делать в одном. Таймер и так работает асинхронно.)
    Плюс поскольку это старое доброе WinForm, используйте UserControls, для интерфейса.)
    А так вроде по логике и организации проекта все более менее нормально.) Кстати залейте эту игру на GitHub.) Как раз будет положено начало вашему портфолио.)
     
    18 ноя 2020 Изменено
    1. AshotOneShot Автор темы
      itstranger, насчет таймеров хз почему именно так, но тогда мне ничего лучше в голову не пришло, а насчет гитхаба, да, давно хотел создать, добавлять туды свой говнокод:thinking:
  4. mikuzeboka
    mikuzeboka 21 фев 2022 5 13 янв 2021

    Делай больше на ивентах.
     
  5. etoparanoia
    etoparanoia 2 май 2022 0 25 июл 2021
    Отлично! Подшаманю малёха, да возьму себе, для курсача :+rep:
     
    2 май 2022 Изменено
  6. JanitorHvhboom
    JanitorHvhboom 2 май 2022 хочу работать. 32 4 апр 2018
    Выглядит суглумиративненько. Как для новичков - пример кода норм. Хоть WinForms от части мертв, но пища для ума отличная, лайк.:finger_up::finger_up:
     
Top
Загрузка...