Статьи

Ретро революция: создание клона понг в Unity

Перед началом вы можете посмотреть игру на itch.io

Анализ Понг

Понг был одной из первых когда-либо созданных видеоигр и первой успешной коммерческой игрой. Когда Pong был впервые создан, разработчики, скорее всего, боролись с логикой кода, однако в настоящее время вы можете создать простой Pong для двух игроков с одним вызовом метода, коллайдерами и спрайтами. Понг становится сложнее создавать, когда принято решение сделать Понга для одного игрока. В этом уроке мы создадим базовый игровой процесс для понга и разберем очень простую альтернативу искусственного интеллекта, которая все еще увеличивает ценность игрового процесса.

Мы должны спросить, каковы основные элементы игрового процесса понг? Вот список с ответом на этот вопрос:

  1. Ввод игрока — мы хотим, чтобы игрок мог перемещать весло вверх и вниз, чтобы он мог ударить по мячу.
  2. Столкновение мяча — когда мяч попадает на весло или границы, нельзя терять скорость.
  3. Столкновение границ — мяч должен отскакивать от верхней и нижней части экрана, чтобы он не покинул игровую зону.
  4. Enemy AI — Значение игрового процесса в игре было бы близко к нулю, если бы противник сидел на противоположном конце экрана и не двигался.
  5. Spawning the Ball — когда мяч попадает на одну из границ позади весла, нам нужно его возродить, чтобы мы могли продолжить игру.
  6. Обнаружение зоны попадания мяча в лопатку — это позволяет мячу отскочить от лопатки под уникальными углами, чтобы мы могли лучше целиться в мяч, когда он ударен лопаткой.

С помощью этого списка мы можем начать программирование игры.

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

Настройка игры

Теперь, когда мы проанализировали основы понга, мы можем приступить к настройке игры. Идите вперед, откройте Unity и создайте новый 2D-проект. После открытия редактора установите соотношение сторон экрана игры на 4: 3. Мы используем 4: 3, поскольку это одно из самых распространенных соотношений экрана и одно из самых близких к стандартным. Внутри панели « AssetsScriptsSpritesPrefabsMaterials Эти папки будут использоваться для хранения всех наших игровых активов.

Добавление папок

Загрузите соответствующие изображения для игры и добавьте их в папку Sprites (это можно сделать с помощью перетаскивания). Добавленные нами изображения будут спрайтами, интерактивными игровыми объектами, используемыми в игре.

Серый круг спрайтСиний квадратный спрайтКрасный квадратный спрайт

Нам нужно изменить пиксели на единицу для спрайтов, чтобы они соответствовали стандарту. Я обычно использую 64 пикселя на единицу, поскольку это дает большинству спрайтов четкий чистый вид и сохраняет их относительный размер. Вы можете думать о пикселях на единицу как о плотности пикселей, размещенных в пространстве 1 × 1 в редакторе Unity.

Давайте установим пиксели квадратов на единицу равными 64, а пиксели круга на единицу — 128. Мы можем продолжить и добавить три изображения на панель иерархии.

Панель иерархии

Теперь нам нужно дать каждому активу имя и установить его начальные свойства и теги. Вы можете назвать синий блок «Player» и установить x-позицию игрока на 6.2

Нам понадобится создать тег, чтобы отделить игровые объекты от других. В широком смысле вы можете думать о Tags Нажмите «Untagged» (находится под именем игрока) и выберите «Добавить тег». Создайте новый тег с именем «Paddle», повторно выберите игровой объект игрока и установите для него «Paddle».

Назовите красный блок «Враг». Установите х-позицию противника в -6.2 Сделайте тег вражеского игрового объекта Paddle.

Назовите серый кружок «Ball» и создайте новый тег «Ball». Убедитесь, что для тега объекта игры с мячом установлено значение Ball.

Добавление ввода игрока

На панели «Ресурсы» откройте папку «Сценарии» и создайте новый сценарий C # с именем «PlayerController». Откройте скрипт PlayerController в вашей IDE и введите:

 	//speed of player
	public float speed = 10;

	//bounds of player
	public float topBound = 4.5F;
	public float bottomBound = -4.5F;

	// Use this for initialization
	void Start () {
		Time.timeScale = 0;
	}

	void Update(){

		//pauses or plays game when player hits p
		if(Input.GetKeyDown(KeyCode.P) && Time.timeScale == 0){
			Time.timeScale = 1;
		} else if(Input.GetKeyDown(KeyCode.P) && Time.timeScale == 1){
			Time.timeScale = 0;
		}
	}

	// Update is called once per frame
	void FixedUpdate () {

		//get player input and set speed
		float movementSpeedY = speed * Input.GetAxis("Vertical") * Time.deltaTime;
		transform.Translate(0, movementSpeedY, 0);

		//set bounds of player
		if(transform.position.y > topBound){
			transform.position = new Vector3(transform.position.x, topBound, 0);
		} else if(transform.position.y < bottomBound){
			transform.position = new Vector3(transform.position.x, bottomBound, 0);
		}
	}

Добавьте сценарий PlayerController к игровому объекту Player на панели иерархии, перетащив сценарий на игровой объект. Выберите игровой объект Player и добавьте Box Collider 2D к игровому объекту, щелкнув «Добавить компонент» в нижней части панели инспектора.

Столкновение мячей

Откройте папку «Материалы» внутри панели «Ресурсы». Вы можете создать новый Материал Physics2D, щелкнув правой кнопкой мыши и выбрав Создать -> Материал Physics2D (как на рисунке ниже).

Создание нового материала Physics2D

Идите вперед и назовите новый материал «Bounce», и установите его отскок на 1 и его трение на 0.

Настройки трения и упругости

Выберите объект игры с мячом на панели иерархии. Добавьте Circle Collider 2D к игровому объекту Ball. Перетащите материал отказов в свойство Материал коллайдера, чтобы настроить материал на отскок. Предоставляя объекту игры с мячом материал для отскока, мы делаем его таким образом, чтобы, когда объект игры с мячом достигал границ, он не терял никакой скорости и отскакивал под правильным углом. Нам также нужно добавить Rigidbody 2D к игровому объекту Ball и установить гравитационный масштаб на 0, затем проверить фиксированный угол.

Настройки мяча

Откройте папку «Сценарии» внутри панели «Ресурсы» и создайте сценарий с именем «BallController». Откройте скрипт BallController внутри вашей IDE и введите:

 //speed of the ball
	public float speed = 3.5F;

	//the initial direction of the ball
	private Vector2 spawnDir;

	//ball's components
	Rigidbody2D rig2D;
	// Use this for initialization
	void Start () {
		//setting balls Rigidbody 2D
		rig2D = this.gameObject.GetComponent<Rigidbody2D>();

		//generating random number based on possible initial directions
		int rand = Random.Range(1,4);

		//setting initial direction
		if(rand == 1){
			spawnDir = new Vector2(1,1);
		} else if(rand == 2){
			spawnDir = new Vector2(1,-1);
		} else if(rand == 3){
			spawnDir = new Vector2(-1,-1);
		} else if(rand == 4){
			spawnDir = new Vector2(-1,1);
		}

		//moving ball in initial direction and adding speed
		rig2D.velocity = (spawnDir*speed);

	}

Столкновение границы

Внутри панели иерархии создайте два пустых игровых объекта (щелкните правой кнопкой мыши -> создать пустой) и назовите новые игровые объекты «RightBound» и «TopBound». Установите x-положение RightBound равным 7 и добавьте Box Collider 2D к игровому объекту RightBound. На панели «Инспектор» установите флажок «Триггер» и установите для y-размера коллайдера значение 20. Дублируйте игровой объект RightBound (выберите его и нажмите Ctrl + D). Назовите дубликат «LeftBound» и установите его y-позицию в -7.

Затем выберите игровой объект TopBound и установите его y-позицию равным 5,5, и добавьте Box Collider 2D к игровому объекту TopBound. Установите размер x коллайдера на 20. Дублируйте игровой объект TopBound и назовите дубликат «BottomBound». Установите у-позицию игрового объекта BottomBound на -5,5.

Каркас понга

Мы хотим, чтобы левая и правая границы уничтожали мяч, когда мяч проходит мимо одного из лопаток. Внутри панели Assets откройте папку Scripts и создайте новый скрипт C # с именем «BoundController». Откройте BoundController внутри вашей любимой IDE и введите:

 void OnTriggerEnter2D(Collider2D other){

		//Destroys gameobject if its tag is Ball
		if(other.gameObject.tag == "Ball"){
			Destroy(other.gameObject);
		}
}

Добавьте скрипт BoundController к игровому объекту LeftBound и игровому объекту RightBound.

Враг А.И.

Выберите игровой объект Враг и добавьте Box Collider 2D. Внутри панели Assets откройте папку Scripts. Создайте новый сценарий C # с именем «EnemyController» и введите:

 //Speed of the enemy
	public float speed = 1.75F;

	//the ball
	Transform ball;

	//the ball's rigidbody 2D
	Rigidbody2D ballRig2D;

	//bounds of enemy
	public float topBound = 4.5F;
	public float bottomBound = -4.5F;

	// Use this for initialization
	void Start () {

	}

	// Update is called once per frame
	void FixedUpdate () {

		//finding the ball
		ball = GameObject.FindGameObjectWithTag("Ball").transform;

		//setting the ball's rigidbody to a variable
		ballRig2D = ball.GetComponent<Rigidbody2D>();

		//checking x direction of the ball
		if(ballRig2D.velocity.x < 0){

			//checking y direction of ball
			if(ball.position.y < this.transform.position.y){
				//move ball down if lower than paddle
				transform.Translate(Vector3.down*speed*Time.deltaTime);
			} else if(ball.position.y > this.transform.position.y){
				//move ball up if higher than paddle
				transform.Translate(Vector3.up*speed*Time.deltaTime);
			}

		}

		//set bounds of enemy
		if(transform.position.y > topBound){
			transform.position = new Vector3(transform.position.x, topBound, 0);
		} else if(transform.position.y < bottomBound){
			transform.position = new Vector3(transform.position.x, bottomBound, 0);
		}
	}

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

Еще одно примечание: мы использовали фиксированное обновление, потому что этот метод лучше для движения, поскольку он обновляет игровой объект с фиксированной скоростью.

Порождение мяча

Создайте пустой игровой объект внутри панели иерархии и назовите его «BallSpawner». Затем добавьте объект игры Ball в папку Prefabs на панели Assets. Мы можем удалить игровой объект Ball внутри панели иерархии.

Откройте папку «Сценарии» внутри панели «Ресурсы» и создайте новый сценарий C # с именем «BallSpawnerController». Откройте BallSpawnerController внутри вашей IDE и введите:

 public GameObject ball;

	// Use this for initialization
	void Start () {
		GameObject ballClone;
		ballClone = Instantiate(ball, this.transform.position, this.transform.rotation) as GameObject;
		ballClone.transform.SetParent(this.transform);
	}

	// Update is called once per frame
	void Update () {
		if(transform.childCount == 0){
			GameObject ballClone;
			ballClone = Instantiate(ball, this.transform.position, this.transform.rotation) as GameObject;
			ballClone.transform.SetParent(this.transform);
		}
	}

Добавьте скрипт BallSpawnerController к игровому объекту BallSpawner. Теперь мы можем перетащить объект игры Ball из папки Prefabs в значение Ball в BallSpawnerController.

введите описание изображения здесь

Добавление основного текста

Нам нужно добавить текст на экран, чтобы игроки нажимали P, чтобы начать игру и поставить игру на паузу, чтобы игроки знали, как начать игру и поставить игру на паузу.

Мы можем создать текстовый игровой объект (в панели иерархии щелкните правой кнопкой мыши -> UI -> Text) и назовите текстовый игровой объект PlayText. Далее давайте установим его текстовое значение «Hit P to play или pause» и выровняем текст по центру. Теперь мы можем выровнять игровой объект по верху экрана и затем привязать его. Давайте установим его ширину на 200, чтобы весь текст был виден. Наконец, установите цвет текста на белый.

Сохраните сцену и добавьте ее в настройки сборки (путем перетаскивания или проверки добавления текущей сцены), и все готово!

Вывод

Теперь вы официально создали базовый клон Pong для одного игрока в Unity2D. Для большей практики попробуйте придумать способы обновить игру и сделать ее лучше — добавьте ускорение мячу (чем больше ударов, тем быстрее мяч), добавьте инерцию к веслам, добавьте уровни сложности, увеличив скорость противника и т. Д.

Вы можете скачать проект на GitHub