|
25.04.2014, 20:43
|
#1
|
Оператор ЭВМ
Регистрация: 05.09.2013
Адрес: Харьков, Украина
Сообщений: 25
Написано 13 полезных сообщений (для 49 пользователей)
|
Android game: Feel RoundAbout + механика игры
Всем привет!
В этой теме я хочу рассказать Вам о своей игре и процессе ее разработки.
О игре:
В этой игре Вы управляете маленькой птицей, которая летает по кругу. У нее на пути появляются препятствия и Вы должны помочь ей преодолеть их.
Просто коснитесь экрана и птица сделает небольшой взмах крыльями.
Контролируя полет птицы, попытайтесь пролететь как можно больше кругов.
Ссылка на игру - скачать из Google Play.
Скрины:
О разработке:
Концепт игры не мой, на ее создание меня вдохновила игра Mr Flap – ссылка на Google Play.
C самого начала, главной задачей было попытаться сделать нечто подобное, только для саморазвития. И я могу сказать, что в процессе разработки, я сделал несколько важных открытий для себя.
Продолжение под спойлером:
Изначально я решил делать игру без физики и начал я с движения куба по кругу.
Сначала я создал куб и пустой объект, а затем вложил куб в пустышку. На пустой объект я накинул C# скрипт, который будет вращать пустой объект и куб соответственно.
// update
void Update ()
{
// rotate
gameObject.transform.Rotate(0,0, 0.3f);
} // update end
Потом я создал сферу и установил цвет фона для камеры, добавил спрайты глаз, клюва и крыльев. Результат:
На этом этапе у меня была птица, которая двигалась по кругу и следующее, что я сделал - заставил птицу взлетать и падать на сферу.
Т.к. в этой игре, я решил не использовать физику, гравитацию решил сделать так:
// object's
public Transform targetSphere;
public float gravityPower;
// update
void Update ()
{
// gravity emulate
gameObject.transform.position = Vector3.MoveTowards(transform.position, targetSphere.position, gravityPower * Time.deltaTime);
} // update end
Флаппы птицы сделал так(версия пк):
// int's
private bool flapTimeStart = false; // flapp action
private float flapTime; // flapp time
public float upSpeed;
public float rightSpeed;
// update
void Update ()
{
// flapp action
if (Input.GetMouseButtonUp(0)) { flapTimeStart = true; }
// flapp engine
if (flapTimeStart)
{
if (flapTime > 0) { flapTime -= 1.0f * Time.deltaTime; transform.Translate(Vector3.up * upSpeed * Time.deltaTime); transform.Translate(Vector3.right * rightSpeed * Time.deltaTime); }
}
if (flapTime <= 0) { flapTime = 0.1f; flapTimeStart = false; }
} // update end
Теперь птица может летать. Она летает вокруг сферы и взлетает когда я нажимаю кнопку мыши. Но есть две проблемы:
1) Птица проваливается в сферу;
2) Птица может улететь за края экрана;
Чтобы ограничить движения птицы, я использовал систему триггеров:
// trigger enter
void OnTriggerEnter(Collider MyTrigger)
{
// stops triggers
if (MyTrigger.gameObject.name == "Sphere") { stopMove = true; }
if (MyTrigger.gameObject.name == "archway") { flapTimeStart = false; flapTime = 0.1f; transform.Translate(Vector3.down * 15.5f * Time.deltaTime); }
} // trigger enter end
Так вот, при входе в сферу, отключается притяжение.
А когда летящая птица выходит за края белого круга отключается возможность флаппа и птица отбрасывается назад к сфере.
Так что теперь моя птица может летать только в заданной области.
Следующее, что я сделал - создал систему стен
С вращения используется тот же метод, что и с полетом птицы. А для движения стен, я использовал этот код:
// int's
private bool iniLock = false; // ini lock
private int randomOrientation; // randomize orientation
private bool OrientationSide; // randomize orientation ~~~ true = move to right(+); ~~~ false = move to left(-); //
private float randomSpeed;
// start
void Start ()
{
if (!iniLock)
{
//randomOrientation = Random.Range(-0.6f, 0.68f);
// randomize orientation
randomOrientation = Random.Range(1, 10);
if (randomOrientation > 1 && randomOrientation < 5) { OrientationSide = true; }
else if (randomOrientation >= 5 && randomOrientation < 10) { OrientationSide = false; }
// randomize speed
randomSpeed = Random.Range(0.1f, 0.35f);
// ini lock
iniLock = true;
} // ini lock
} // start end
// update
void Update()
{
// orientation move
if (OrientationSide && !dd.finishGame)
{
if (gameObject.transform.localPosition.x < 0.68f) { gameObject.transform.localPosition += new Vector3(randomSpeed * Time.deltaTime, 0, 0); }
if (gameObject.transform.localPosition.x >= 0.68f) { OrientationSide = false; }
}
else if (!OrientationSide && !dd.finishGame)
{
if (gameObject.transform.localPosition.x > -0.6f) { gameObject.transform.localPosition -= new Vector3(randomSpeed * Time.deltaTime, 0, 0); }
if (gameObject.transform.localPosition.x <= -0.6f) { OrientationSide = true; }
}
} // update end
Самая сложная часть позади... (хотя, что тут сложного?)
Я не буду описывать систему подсчета кругов, она основана на триггере и очень проста. Вместо этого, я опишу систему случайного выбора цвета для спрайтов - тут тоже все просто, но все же.
Когда птица пересекает пунктирную линию, выполняется этот код:
dd.newColorNum = Random.Range(1,8);
А в другом скрипте, который подключен ко всем необходимым спрайтам, такой код:
// update
void Update ()
{
if (dd.newColorNum == 1) { GetComponent<SpriteRenderer>().color = new Color( 0, 0.7f, 1, 1); }
if (dd.newColorNum == 2) { GetComponent<SpriteRenderer>().color = new Color(0.7f, 0, 1, 1); }
if (dd.newColorNum == 3) { GetComponent<SpriteRenderer>().color = new Color(1, 0.6f, 0, 1); }
if (dd.newColorNum == 4) { GetComponent<SpriteRenderer>().color = new Color(0.411f, 0.862f, 0, 1); }
if (dd.newColorNum == 5) { GetComponent<SpriteRenderer>().color = new Color(0.113f, 0.333f, 0.568f, 1); }
if (dd.newColorNum == 6) { GetComponent<SpriteRenderer>().color = new Color(0.368f, 0.25f, 0.156f, 1); }
if (dd.newColorNum == 7) { GetComponent<SpriteRenderer>().color = new Color(0.243f, 0.266f, 0.464f, 1); }
if (dd.newColorNum == 8) { GetComponent<SpriteRenderer>().color = new Color(0.913f, 0.505f, 0.25f, 1); }
} // update end
Теперь, каждый раз, когда птица пересекает пунктирную линию, цвет изменяется случайным образом.
Чтобы изменить фоновый цвет камеры, я использовал стандартное обращение:
if (dd.newColorNum == 1) { camera.backgroundColor = new Color(0, 0.7f, 1, 1); }
Скрипт соответственно прикреплен к камере.
Конец
В общем-то это и есть самое интересное... хотя нет, не все!
Еще я хотел бы поделится с Вами небольшим опытом касательно Google Play Services:
В моей предыдущей игре Earth Defense 2 ( ссылка) я впервые использовал Google Play Services и по неопытности установил принудительную авторизацию при старте игры.
Это привело к тому, что на многих устройствах игра крашилась на старте.
Соответственно практически сразу посыпались плохие отзывы, которые, впрочем, были исправлены после обновления.
Так вот, ВСЕГДА давайте пользователю выбор! Это касаться не только google сервисов, а и любых функций...
В этой игре я использовал такое диалоговое окно:
Вот теперь все, вроде
Буду очень рад, если эта мини-статья будет кому-то полезна. Большое спасибо за внимание.
PS: Весь код написан на C# для Unity3d за выходные.
Последний раз редактировалось slee, 25.04.2014 в 23:12.
Причина: ссылки пофиксил
|
(Offline)
|
|
Эти 4 пользователя(ей) сказали Спасибо slee за это полезное сообщение:
|
|
25.04.2014, 20:49
|
#2
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: Android game: Feel RoundAbout + механика игры
это жесть, чтобы проверить выхождение за круг, достаточно дистанцию чекнуть, причём без sqrt, причём в 2д.
|
(Offline)
|
|
Эти 8 пользователя(ей) сказали Спасибо Mr_F_ за это полезное сообщение:
|
|
25.04.2014, 20:58
|
#3
|
Быдлокодер
Регистрация: 05.07.2009
Адрес: Проспит
Сообщений: 5,021
Написано 2,312 полезных сообщений (для 5,349 пользователей)
|
Ответ: Android game: Feel RoundAbout + механика игры
Можно пожалуйста всю эту простыню под сполеры убрать.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
25.04.2014, 21:04
|
#4
|
Оператор ЭВМ
Регистрация: 05.09.2013
Адрес: Харьков, Украина
Сообщений: 25
Написано 13 полезных сообщений (для 49 пользователей)
|
Ответ: Android game: Feel RoundAbout + механика игры
Сообщение от Mr_F_
это жесть, чтобы проверить выхождение за круг, достаточно дистанцию чекнуть, причём без sqrt, причём в 2д.
|
Буду рад узнать как это делается. Можно пример?
И еще вопрос: разве простой триггер грузит больше постоянного вычисления дистанции?
Спасибо!
|
(Offline)
|
|
25.04.2014, 21:14
|
#5
|
Оператор ЭВМ
Регистрация: 05.09.2013
Адрес: Харьков, Украина
Сообщений: 25
Написано 13 полезных сообщений (для 49 пользователей)
|
Ответ: Android game: Feel RoundAbout + механика игры
Сообщение от Arton
Можно пожалуйста всю эту простыню под сполеры убрать.
|
Я бы с радостью, но черт знает как тут спойлер юзать... вроде стандартный [spoiler] не работает, попробовал несколько вариантов, не вышло.
Справку по здешним bb на стр редактирования не нашел... Буду рад, если вы мне подскажите. Спасибо!
|
(Offline)
|
|
25.04.2014, 21:23
|
#6
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: Android game: Feel RoundAbout + механика игры
Буду рад узнать как это делается. Можно пример?
|
в 3д в юнити:
// Init
const float outOfLevelDist = 10;
const float tooCloseDist = 2;
float outOfLevelSqrDist = outOfLevelDist * outOfLevelDist;
float tooCloseSqrDist = tooCloseDist * tooCloseDist;
-----
// Update
float sqrDist = (birdPos - circlePos).sqrMagnitude;
if (sqrDist > outOfLevelSqrDist) улетели за пределы
if (sqrDist < tooCloseSqrDist) заехали в круг
Если круг находится в нуле, и считаем в 2д, то можно упростить до:
float sqrDist = birdPos.x*birdPos.x + birdPos.y*birdPos.y;
-----
разве простой триггер грузит больше постоянного вычисления дистанции?
|
по-твоему триггер будет работать быстрее 2х умножений и одного сложения в кадр?
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
25.04.2014, 21:31
|
#7
|
Оператор ЭВМ
Регистрация: 05.09.2013
Адрес: Харьков, Украина
Сообщений: 25
Написано 13 полезных сообщений (для 49 пользователей)
|
Ответ: Android game: Feel RoundAbout + механика игры
Сообщение от Mr_F_
в 3д в юнити:
// Init
const float outOfLevelDist = 10;
const float tooCloseDist = 2;
float outOfLevelSqrDist = outOfLevelDist * outOfLevelDist;
float tooCloseSqrDist = tooCloseDist * tooCloseDist;
-----
// Update
float sqrDist = (birdPos - circlePos).sqrMagnitude;
if (sqrDist > outOfLevelSqrDist) улетели за пределы
if (sqrDist < tooCloseSqrDist) заехали в круг
Если круг находится в нуле, и считаем в 2д, то можно упростить до:
float sqrDist = birdPos.x*birdPos.x + birdPos.y*birdPos.y;
-----
по-твоему триггер будет работать быстрее 2х умножений и одного сложения в кадр?
|
Большое спасибо за толковый пример! Реально здорово узнать что-то новое... хотя и так все подносом - я просто не подумал о таком варианте решения задачи.
---
Я не утверждаю, что триггер будет работать быстрее - я просто спрашиваю)
На мой взгляд триггер более оптимален, тк он, в отличии от вычислений, не используется постоянно. Или я чего-то не понимаю? Поправьте пожалуйста...
Спасибо!
|
(Offline)
|
|
25.04.2014, 21:36
|
#8
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: Android game: Feel RoundAbout + механика игры
На мой взгляд триггер более оптимален, тк он, в отличии от вычислений, не используется постоянно. Или я чего-то не понимаю? Поправьте пожалуйста...
|
физическому движку каждый кадр необходимо проверить, попадает ли птица внутрь или нет.
конечно при большом числе триггеров, он не будет прям попадание в каждый проверять, там свои оптимизации типа деревьев и проверки попадания сначала в AABB триггера - но в любом случае, тут как ни крути, дофига работы по сравнению с проверкой дистанции)
ты сам то думал, как триггеры могут быть реализованы, если бы ты их сам писал? они же не по волшебству пашут.
в случае с мешем-триггером, особенно из такого числа трианглов, конечная проверка будет весьма небыстрая. не знаю даже точно, как считают попадание в невыпуклый примитив, но это всегда куда сложнее, чем в выпуклый (convex), а для проверки попадания в выпуклый, движку нужно проверить с какой стороны находится объект (все его формообразующие точки) за каждой плоскостью триггера. жопа, короче.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
25.04.2014, 21:45
|
#9
|
Оператор ЭВМ
Регистрация: 05.09.2013
Адрес: Харьков, Украина
Сообщений: 25
Написано 13 полезных сообщений (для 49 пользователей)
|
Ответ: Android game: Feel RoundAbout + механика игры
Сообщение от Mr_F_
физическому движку каждый кадр необходимо проверить, попадает ли птица внутрь или нет.
конечно при большом числе триггеров, он не будет прям попадание в каждый проверять, там свои оптимизации типа деревьев и проверки попадания сначала в AABB триггера - но в любом случае, тут как ни крути, дофига работы по сравнению с проверкой дистанции)
ты сам то думал, как триггеры могут быть реализованы, если бы ты их сам писал? они же не по волшебству пашут.
в случае с мешем-триггером, особенно из такого числа трианглов, конечная проверка будет весьма небыстрая. не знаю даже точно, как считают попадание в невыпуклый примитив, но это всегда куда сложнее, чем в выпуклый (convex), а для проверки попадания в выпуклый, нужно проверить с какой стороны находится объект (все его формообразующие точки) за каждой плоскостью триггера. жопа, короче.
|
ОГРОМНОЕ СПАСИБО!
Скажу честно, о триггерах задумался только сегодня, благодаря Вам... со времен видео уроков, в голове устоялась мысль - триггеры - это хорошо, просто и понятно...
что может быть проще для понимания?!
- Есть граница, при пересечении которой выполняется действие.. и усе))
Теперь то я задумался, а как оно работает, сейчас(пока ждал ответ) уже нагуглил массу инфы - буду просвещаться.
Спасибо!
|
(Offline)
|
|
25.04.2014, 22:38
|
#10
|
Быдлокодер
Регистрация: 05.07.2009
Адрес: Проспит
Сообщений: 5,021
Написано 2,312 полезных сообщений (для 5,349 пользователей)
|
Ответ: Android game: Feel RoundAbout + механика игры
Сообщение от slee
Я бы с радостью, но черт знает как тут спойлер юзать... вроде стандартный [spoiler] не работает, попробовал несколько вариантов, не вышло.
Справку по здешним bb на стр редактирования не нашел... Буду рад, если вы мне подскажите. Спасибо!
|
Сполер никогда не работал здесь, насколько мне известно. В расширеном режиме кнопка сверху:
Либо:
[offtop]Бла-бла-бла[/offtop]
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
25.04.2014, 22:47
|
#11
|
Оператор ЭВМ
Регистрация: 05.09.2013
Адрес: Харьков, Украина
Сообщений: 25
Написано 13 полезных сообщений (для 49 пользователей)
|
Ответ: Android game: Feel RoundAbout + механика игры
Сообщение от Arton
Сполер никогда не работал здесь, насколько мне известно. В расширеном режиме кнопка сверху:
Либо:
[offtop]Бла-бла-бла[/offtop]
|
Угу, теперь буду знать, большое спасибо!))
|
(Offline)
|
|
28.04.2014, 12:01
|
#12
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: Android game: Feel RoundAbout + механика игры
Сообщение от Mr_F_
это жесть, чтобы проверить выхождение за круг, достаточно дистанцию чекнуть, причём без sqrt, причём в 2д.
|
Успокойся, это же юнити. *трололо*
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
28.04.2014, 21:10
|
#13
|
Дэвелопер
Регистрация: 13.02.2010
Сообщений: 1,645
Написано 620 полезных сообщений (для 2,419 пользователей)
|
Ответ: Android game: Feel RoundAbout + механика игры
Кто тут любит постить учебник геометрии за 7 класс?
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо den за это полезное сообщение:
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 01:38.
|