Как сделать игру (шаг третий)

Шаг за шагом мы подобрались к моменту, когда игра перестает быть идеей и начинает обретать видимые черты. Но надо понимать, что это еще не сама игра, а только ее прототип. Поэтому что-то обозначится лишь условно, а что-то вообще будет пропущено.

Какие же части игры необходимо реализовать в прототипе? Это довольно сложный вопрос даже для опытного разработчика. Бывает так, что на первый взгляд не существенная деталь в последствии становится существенной проблемой. А в прототипе ее попросту не делали. Но т.к. заранее все такие вещи предсказать не возможно — придется полагаться на здравый смысл и собственное чутье.

Можно выделить несколько факторов, с помощью которых можно отсечь важные части игры от второстепенных. Во-первых, если игра разбита на несколько уровней или имеет несколько сложностей прохождения, то достаточно сделать один уровень/сложность. Не обязательно даже создавать уровень, в точности повторяющий какой-то из запланированных. Наоборот, гораздо лучше, если этот уровень будет сборной солянкой из всего. Тогда на этом уровне можно будет проверить все необходимые механики. Во-вторых, все что в игре можно менять — делается наиболее дешевыми средствами, то что будет неизменно — нужно делать максимально приближено к финальному качеству. Например звуки и музыка, это явно необязательная часть, но можно подключить два три звука, чтобы проверить саму работу звукового сопровождения.

Для нашего проекта мы в первую очередь создадим механику генерации игрового поля, удаление одноцветных фигур и переключение гравитации. Для этого нам понадобится пустой GameObject Game, префаб из обычной сферы Sphere и 2 скрипта с такими же названиями. Скрипт Sphere привяжем к префабу и добавим следующий функционал:

private int id;
	
public int ID{
	get{return id;}
	set{id = value;}
}

void OnMouseDown (){
	GameObject.Find("Game").GetComponent<Game>().Click(id);
}

Теперь наш префаб имеет переменную для ИД, публичную переменную для записи и чтения этого ИД, а также при клике на сферу в несуществующую ещё функцию будет отправляться ИД нажатого объекта.

Скрипт Game тоже привяжем к одноименному объекту. Заведём публичную переменную Object SpherePrefab, в которой укажем наш префаб. И добавим массив для хранения объектов GameObject[] Spheres. Для создания сфер на игровом поле будем использовать функцию:

void SetSphere (Vector3 pos, int id) {
	Object temp = Instantiate(SpherePrefab, pos, Quaternion.identity);
	Spheres[id] = (GameObject)temp;
	Spheres[id].GetComponent<Sphere>().ID = id;
}

Теперь можно завести переменные для количества позиций на экране и начальных координат:

private int countX = 10;
private int countY = 9;
private float constL = -2.6f;
private float constD = -4f;

void Start () {
	Spheres = new GameObject[countX*countY];
	int _id = 0;
	
	for (int i=0; i<countX; i++)
	for (int j=0; j<countY; j++)
	{
		SetSphere(new Vector3(constL + i, constD + j,0),_id);
		_id ++;
	}
}

С этого момента прототип обретает первую функциональность. При его запуске теперь будет не просто собранное из простых фигур игровое поле, а поле с игровыми объектами.

Для хранения цвета создадим массив int[,] sColor, который будет хранить цветовой код. И переменную Color SphereColor (int i), которая будет возвращать необходимый цвет. В функции Start добавим стоку sColor = new int[countX,countY]; и вызов функции генерации цвета:

void Generator (){
	for (int i=0; i<countX; i++)
	for (int j=0; j<countY; j++)
	{
		sColor[i,j] = Random.Range(1, 5);
	}
}

Чтобы сферы на игровом поле стали цветными допишем функцию Update. В результате, любое изменение в массиве sColor будет сразуже отображаться на экране:

void Update () {
	for (int i=0; i<countX; i++)
	for (int j=0; j<countY; j++)
	{
		Spheres[i*countY+j].renderer.material.color = SphereColor(sColor[i,j]);
	}
}

Теперь пришел черёд дописать функцию Click и реакцию, на нажатие по сфере:

public void Click(int id){
	int x = id / countY;
	int y = id % countY;
	if (sColor[x,y] !=0) 
	if (NotOne(x, y, sColor[x,y])){
		DelSphere(x, y, sColor[x,y]);
	}
}
	
bool NotOne(int x, int y, int type){
	bool temp = false;
	if (x > 0) if (sColor[x-1,y] == type) {temp = true;}
	if (x < countX-1) if (sColor[x+1,y] == type) {temp = true;}
	if (y > 0) if (sColor[x,y-1] == type) {temp = true;}
	if (y < countY-1) if (sColor[x,y+1] == type) {temp = true;}
	return temp;
}
	
void DelSphere(int x, int y, int type){
	if (sColor[x,y] == type){
		sColor[x,y]  = 0;
		if (x > 0) {DelSphere (x-1,y,type);}
		if (x < countX-1) {DelSphere (x+1,y,type);}
		if (y > 0) {DelSphere (x,y-1,type);}
		if (y < countY-1) {DelSphere (x,y+1,type);}
	}
}

Осталось только сделать падение шариков вниз и смещение к центру. Т.к. падение более приоритетно, то сделаем для него счетчик. А смещение будем делать только после остановки всех фигур.

int Grav(){
	int temp = 0;
	for (int x = 0; xy<countX; x++)
	for (int y = 0; yy<countY; y++)
	{
		if (y < countY-1){
			if ((sColor[x,y] == 0)&&(sColor[x,y+1] !=0)){
				sColor[x,y] = sColor[x,y+1];
				sColor[x,y+1] = 0;
				temp++;
			}
		}
	}
	return temp;
}
	
void Centr(){
	for (int x = 1; x<5; x++)
		if (sColor[x,0] == 0) {
			for (int y= 0; y<countY; y++){
				sColor[x,y] = sColor[x-1,y];
				sColor[x-1,y] = 0;
			}
		}	
	for (int x = 5; x<9; x++)
		if (sColor[x,0] == 0) {
			for (int y= 0; y<countY; y++){
				sColor[x,y] = sColor[x+1,y];
				sColor[x+1,y] = 0;
			}
		}
}

И добавим в Update строку if (Grav() == 0) {Centr();};

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

Прототип ColorJunction (351)

Как сделать игру (шаг третий): 2 комментария

  1. Уведомление: 356

Добавить комментарий

Ваш e-mail не будет опубликован.

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>