Pull to refresh

Игра про ракету в космосе

Лето — слишком длинное, чтобы не попробовать себя в игрострое. Захотелось сделать небольшую игру, где можно перемещаться между небольшими планетами, перепрыгивая с одной на другую.

Основной фишкой игры является переменчивое притяжения (при приближении к планете, сменяется и притяжение) и соответствующие переходы в управлении.

Игру можно сделать и от первого лица, но тогда будет сложнее ориентироваться.

Если вас заинтересовала реализация этой идеи, прошу под кат



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

Первые проблемы


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

Много вычислений, может быть, можно упростить?

И тут на выручку пришла хитрость — камера может перемещаться, но не вращаться. С одной стороны идея провальная, так как не будет видно, что твориться на другой стороне планеты, но с другой стороны это сильно облегчит задачу работы с камерой.
Чтобы смягчить это было сделано:
  • во первых — планеты стали вращаться каждая вокруг своих двух осей (скорость по каждой из них регулируется рандомом, потому они всегда разные).
    Как это выглядит


  • во вторых — перемещение по планете можно было осуществлять только по двум осям (x и y, а ось z отвечает за полет — об этом дальше).
    Реализация
    		float A = (gameObject.transform.position.x - main.transform.position.x);
    		float B = (gameObject.transform.position.y - main.transform.position.y);
    		float C = (gameObject.transform.position.z - main.transform.position.z);
    		R = Mathf.Sqrt (A * A + B * B + C * C);
    /*		float r = Mathf.Sqrt ((gameObject.transform.position.x - main.transform.position.x) * (gameObject.transform.position.x - main.transform.position.x) +
    		                      (gameObject.transform.position.y - main.transform.position.y) * (gameObject.transform.position.y - main.transform.position.y) +
    		                      (gameObject.transform.position.z - main.transform.position.z) * (gameObject.transform.position.z - main.transform.position.z));
    */		float zn;
    		if (Input.GetKey(KeyCode.W))
    		{
    //			zn=-Mathf.Sign (gameObject.transform.position.z - main.transform.position.z);
    			dy=-(C/Mathf.Sqrt (B*B+C*C));
    			dz=(B/Mathf.Sqrt (B*B+C*C));
    		}
    		if (Input.GetKey(KeyCode.S))
    		{
    			dy=(C/Mathf.Sqrt (B*B+C*C));
    			dz=-(B/Mathf.Sqrt (B*B+C*C));
    		}
    		if (Input.GetKey(KeyCode.D))
    		{
    			dx=-(C/Mathf.Sqrt (C*C+A*A));
    			dz=(A/Mathf.Sqrt (C*C+A*A));
    		}
    		if (Input.GetKey(KeyCode.A))
    		{
    			dx=(C/Mathf.Sqrt (C*C+A*A));
    			dz=-(A/Mathf.Sqrt (C*C+A*A));
    		}
    
    		Vector3 Move = new Vector3 (dx*speed_boost, dy*speed_boost, dz*speed_boost);
    		transform.position = transform.position + Move;
    


Перемещение было сделано по отклонению на небольшой угол по радиусу планеты.

Гравитация


С гравитацией пришлось слегка побороться, но в основу лёг закон всемирного тяготения, где координаты брались из центра планеты и центра ракеты-сферы.
Ещё кусочек кода
		float r = Mathf.Sqrt ((gameObject.transform.position.x - player.transform.position.x) * (gameObject.transform.position.x - player.transform.position.x) +
		                (gameObject.transform.position.y - player.transform.position.y) * (gameObject.transform.position.y - player.transform.position.y) +
		                (gameObject.transform.position.z - player.transform.position.z) * (gameObject.transform.position.z - player.transform.position.z));

		F = gameObject.GetComponent<Rigidbody>().mass * player.GetComponent<Rigidbody>().mass / (r * r);

		player.GetComponent<Rigidbody>().AddForce (F*((gameObject.transform.position.x-player.transform.position.x)/r),
		                               F*((gameObject.transform.position.y-player.transform.position.y)/r),
		                               F*((gameObject.transform.position.z-player.transform.position.z)/r));



Для того, чтобы «сменилось» гравитационное поле, его нужно пролететь. Сделать это можно, нажав на пробел. И тогда с почти что постоянной силой (немного шаманства, чтобы с разных планет можно было улететь) ракета летить в противоположную сторону от центра текущей планеты по линии, соединяющей их центры.

Как это выглядит


Небольшие фишки


  1. Крайне приятно смотреть на разукрашенные текстуры. Поэтому каждой планете следует сделать свою текстуру
  2. Чтобы было интереснее — нужно ограничить скорость перемещения между планетами. Один из вариантов, это создание ресурса топлива, который медленно восстанавливается и быстро тратиться при отрыве от планет
  3. В качестве стимула можно создать несколько «канистр», которые быстрее восстанавливают этот ресурс
  4. И самое главное. Нужно передать атмосферу того, что дело происходит в космосе. Чем красочнее будет задний фон, тем лучше!

Прокрастинация


Самой большой проблемой при разработке является именно прокрастинация. Очень сложно, пока ищешь решение своей проблемы, не переключиться на другие прелести интернета. Будь то лекции с ютьюба или же туториалы на официальном сайте

Типа заключение


Лето — время реализации всех интересностей, что скопилось за учебный год (если ты студент или школьник). Не потеряйте его впустую!
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.