Создание простой кликер-игры с нуля

В последние несколько лет набирают большую популярность игры такого жанра, как «кликеры». Мне самому очень интересно играть в них, но не менее интересно создавать игру — кликер самому. Благодаря такому движку как Unity, создать свой шедевр не составит труда даже простому новичку. Давайте перейдем к делу.

Что нужно сделать?


  1. Подумать, почему и на что мы должны кликать?
  2. Что должно произойти, когда мы кликнем?
  3. Что должно произойти, если не кликнем?

Как ответил я на эти вопросы:

  1. Мы должны кликать в любое место на экране.
  2. При клике должен смениться объект.
  3. При игнорировании — проигрыш.

О чем будет игра?


Игроку нужно вовремя выбрать либо меч, либо щит, в зависимости от того, что будет падать сверху. То есть, падает меч — выбираем меч, падает щит — выбираем щит. При неправильном выборе игрок просто проиграет. На словах всё довольно просто, а в реализации еще проще.

Откуда мне новичку брать красивый спрайт и фон? Ответ: нарисовать самому.

Тут нет ничего сложного, так как мы рисуем в Adobe Illustrator. Даже если у вас нет опыта в рисовании, то опять же не расстраиваемся, так как я покажу вам всё по деталям.

Что нам нужно:

  1. Меч
  2. Щит
  3. Задний фон
  4. Ветка с листьями

Этого хватит.

Техника проста и покажу на примере меча:

  1. Рисуем контур
  2. Заливаем цветами
  3. Рисуем тени



И всё, наш меч готов!

Также проделываем и с другими. Не пугайтесь, если в начале одно ваше творение покажется вам далек от идеала, ведь в совокупности они будут смотреться, как картина Ван Гога. Шутка. А может и нет.







Задний фон сделаем еще хитрее.

Нарисуем зеленый прямоугольник и используем градиент. Выглядит вот так:



Можно сказать, что уроки художества на этом закончены и мы наконец идем в Unity.

В первую очередь закинем наши спрайты, а меч и щит перетащим в окно иерархии, так как нам нужно будет создать из них префабы и не только.



  1. Добавляем Rigidbody 2D и установим значение “0” в поле Gravity Scale, чтобы щит стоял на одном месте.
  2. Добавим Circle Collider 2D и установим галочку в Is Trigger, чтобы отслеживать действия.

С префабом те же действия, только нужно установить значение “1” в поле Gravity Scale, чтобы щит падал вниз. И перетаскиваем его в папку Prefabs. С мечом те же действия. Готово!

Далее украсим игру спрайтами, нарисованными ранее. Первым делом кидаем фон.

  1. Размещаем ветки сверху
  2. Добавим снизу бревно
  3. Посередине разместим мост



Основной секрет дизайна такой: сверху и снизу разместим ветки, а у лесенки уменьшим значение прозрачности. Зачем это делать?

Дело в том, что таким образом мы создаем некую иллюзию пространства. Игроку будет казаться, что есть передний объект, задний и горизонт. И это классно!

Теперь создадим кнопку, которая будет занимать весь экран. Чтобы создать кнопку нужно в иерархии нажать на UI -> Button. Далее:

  1. Нажимаем на Color.
  2. Устанавливаем значение «0» в поле А, которая отвечает за прозрачность нашей кнопки.
  3. Убеждаемся, что кнопка стала такой, какой мы хотели.



Таким же путем создаем текст, чтобы показывать наш текущий счет и рекорд.

И наконец, мы дошли и до программирования.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class MainScript : MonoBehaviour
{
	public GameObject[] prefabs;    		//массив префабов
	public GameObject[] players;    		//массив объектов 
	public static int score,record,n,k = 0;	//счёт, рекорд, "n,k" - счетчики
	public Text scoreT;				//текст на экране

    void Start()
    {
		score = 0;
		Time.timeScale = 1;								
		StartCoroutine (PrefabsCreate ());
		scoreT = scoreT.GetComponent<Text> ();
		record = PlayerPrefs.GetInt ("Record");
    }

 
    void Update()
    {
		n = Random.Range (0, prefabs.Length); // генерация случайных чисел 
                                        //от 0 до кол-ва префабов
		scoreT.text = score + "/" + record;	  // вывод счета и рекорда 
		if (score >= record) {							
			record = score;
			PlayerPrefs.SetInt ("Record", record); // сохранение рекорда
		}
			
    }

	IEnumerator PrefabsCreate(){	// создание случайного префаба
		while (true) {
			Instantiate (prefabs [n], new Vector2 (0, 6.5f), Quaternion.identity);
			yield return new WaitForSeconds (0.5f);
		}
	}

	public void BtnClick(string btn){			// метод для кнопок
		if(btn == "Click"){
			Time.timeScale = 1;
			players [k].SetActive (false);      
                     // отключаем активный объект(меч, щит...)
			k++;										
			if (k >= prefabs.Length) {					
				k = 0;                 
                               // обнуляем счетчик, если k превышает кол-во префабов
			} 
			players [k].SetActive (true);
                        // активируем объект (меч, щит...)
		}
		
	}

}


Второй скрипт:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerScript : MonoBehaviour
{

	void OnTriggerEnter2D(Collider2D other){// столкновение объекта (меч, щит)
// проверка на соответствие тэга
		if (other.gameObject.tag != gameObject.tag) {	
			Time.timeScale = 0;
			MainScript.score = 0;
		} else {
			MainScript.score++;
			Destroy (other.gameObject);// уничтожение префаба
		}
	}
}

Что творится в этих методах?

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

Update (). Выполняется раз за кадр. Сюда удобно записать то, что постоянно должно обновляться. В нашем случае: показатель счета и рекорда, рандомное значение n от которого зависит что создастся – меч или щит.

BtnClick (). Вы спросите, почему перед этим методом стоит «public»? Нам необходимо, чтобы он отражался в самом Unity и мы могли прописать слово «Click», чтобы отследить, на какую именно кнопку мы нажимаем, хотя и кнопка всего одна, знать чуточку больше никому не помешает.



Сюда запишем то, что должно произойти после нажатия на кнопку. При нажатии должно меняться с меча на щит и наоборот, устанавливать значение времени «1», так как при проигрыше она обнуляется.

OnTriggerEnter2D (). Проверяет столкновение объекта. Если теги обеих объектов совпадает, то счет увеличивается на единицу, а префаб уничтожается. Если теги разные, то проигрыш – останавливается время и обнуляется счет.

Осталось добавить эти самые теги. И тут всё очень просто:

  1. В окне Inspector нажимаем на Tag.
  2. В выпавшем списке в самом низу нажимаем на Add Tag.
  3. Жмем на плюсик и называем тег как хотим.



После создания также нажимаем на Tag и выбираем нужный.

Осталось перенести скрипты нужным объектам и заполнить некоторые поля. Создадим пустой объект и добавим скрипт «Main Script», а «Player Script» добавим в наш меч и щит.



С полной уверенностью могу сказать, что игра готова. Запускаем и наслаждаемся своим первым творением.



Всем добра и удачи в геймдеве!
  • +10
  • 4,7k
  • 4
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 4

    0
    Просто и наглядно! А можно поподробнее раскрыть причину применения корутины в данном примере? Обычным таймером, было бы проще, или есть нюансы?
      0
      Просто чтобы новичок знал больше об этом. Да и на мой взгляд такой путь легче.
      0
      Ещё можно ссылку на проект выложить. Чтобы те кто пробует создавать в Unity могли руками поменять, да и скомпилить со своими изменениями. Иначе новость проигрывает официальному туториалу по Unity где есть видео c каждым измнением и объяснением, код, субтитры.

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое