Показать сообщение отдельно
Старый 25.04.2014, 20:43   #1
slee
Оператор ЭВМ
 
Аватар для slee
 
Регистрация: 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 за выходные.
__________________
мой мини-блог - serge-lypii.com

Последний раз редактировалось slee, 25.04.2014 в 23:12. Причина: ссылки пофиксил
(Offline)
 
Ответить с цитированием
Эти 4 пользователя(ей) сказали Спасибо slee за это полезное сообщение:
LLI.T.A.L.K.E.R. (29.04.2014), Nex (25.04.2014), SBJoker (25.04.2014), Жека (26.04.2014)