Game Maker - создание игр | HellRoom Games
Апрель 30, 2025, 14:03:15 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости:
 
   Начало   Game Maker Помощь Правила форума Поиск Календарь Войти Регистрация  
Ссылки на события
  • Новый урок в школе GML: Октябрь 23, 2011 - Октябрь 26, 2011
Страниц: [1]   Вниз
  Печать  
Автор Тема: Урок 16. Операторы repeat, while, do until.  (Прочитано 20633 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Hummer
scio me nihil scire
GM Pro user
*

Репутация: 335
Offline Offline

Пол: Мужской
Награды:
2000 сообщений!За постоянность! [100 дней на форуме]За лояльность! [+300 репутации]Знаток Game Maker!За помощь новичкам!
API: Game Maker 8.0 Pro
Деятельность: GML, С++, OpenGL, Java. Бывший Директор бывшей школы GML
Сообщений: 2573


« : Октябрь 23, 2011, 08:40:14 »

Введём 4 термина.
Термин цикл. Последовательность действий, которая может (а может и нет) повторяться.
Термин тело цикла. Список действий, ограниченный фигурными скобками, стоящими после оператора цикла.
Термин итерация. В общем, это означает прохождение цикла. Например 5 итераций означает 5 выполнений цикла.
Термин передача управления. В общем случае это прерывание выполнения "здесь" и начало выполнения "там". Касательно циклов это досрочный выход из текущей итерации, а поведение далее зависит от самого оператора передачи управления.

Начнём с самого простого оператора - repeat.
Синтаксис
Код:
repeat(<число_итераций>)
{
<действия_цикла>
}
В результате <действия_цикла> выполнятся ровно <число_итераций> раз. <число_итераций> должно быть целым положительным числом. Если оно не целое, то округлится в ближайшую сторону. Если оно не положительное (в том числе и ноль), то цикл проигнорируется. Если оно не число, то выйдет ошибка (Repeat count must be a number).
Скобки не обязательны, но приветствуются. Также, если в теле цикла стоит одно действие, то фигурные скобки необязательны (но я советую всё равно их ставить. На игре это не скажется, но вы в любой момент можете добавить действия в тело цикла и совершенно запутаетесь в скобках).
Примеры
Код:
a=0;
repeat(get_string('Введите число', 0))
{
show_message(string(a))
a+=1;
}

Оператор while принято использовать, когда количество итераций заранее неизвестно.
Синтаксис:
Код:
while(<условие>)
{
<действия>
}
По-русски это можно перевести как "пока <условие> истинно, выполнять <действия>"
Как программа работает при этом цикле:
1. if(<условие>){выполнить пункт 2} else {выполнять пункт 4}
2. Выполнить <действия>
3. Перейти к пункту 1
4. Выйти из цикла (продолжать выполнение основной программы)

Понятно, что <условие> должно быть булевым. <действия>, как и у repeat, могут быть любыми.

Пример использования оператора while
Код:
a=0;
while(irandom(4)!=3)
{
a+=1
show_message('Итерация № '+string(a));
}
show_message('Потребовалось '+string(a)+' итераций')
Протестировав игру несколько раз, вы увидите, что число итераций всегда разное, а это значит, что while является подходящим инструментом в таких ситуаций.
Но у многих при первом знакомстве возникает несколько вопросов. Рассмотрим самые популярные из них:
1) Когда необходимо использовать while?
Как я уже говорил, когда заранее неизвестно, сколько раз нужно пройти цикл. И количество итераций зависит строго от данных обстоятельств, которые происходят или уже произошли.
Например. Пользователь вводит число. Если оно не равно нулю, то показываем сообщение с этим числом и просим заного ввести число и т д.
"и т. д." сразу говорит о том, что нужно использовать циклы. Но какой: repeat или while? while и вот по каким признакам я его выбрал
-наличие проверки условия ("Если оно не равно нулю")
-есть изменчивые условия (пользователь)
-неизвестно когда игрок введёт 0 (то есть неизвестно, сколько раз будет проходить цикл).
Код:
a=get_integer('Введите, пожалуйста, число', 0)
while(a!=0)
{
show_message('Вы ввели '+string(a))
a=get_integer('Введите, пожалуйста, число', 0)
}

2) Как правильно выбрать условие цикла?
Есть несколько способов.
а) while, как уже упоминалось, можно перевести как "пока свершается <условие>". Нужно продумать: какой ключевой момент обязывает к выполнению цикла и записать его в условии.
б) Явно обозначить условие фразой: "Если <условие>, то выполняем цикл. И запишите это условие рядом с while.

Скобки () и {} также можно опускать (см. repeat)

Оператор do until можно рассматривать как разновидность while, но является противоположностью.
Синтаксис:
Код:
do{
<действия>
}until(<условие>)
Здесь <действия> будут выполняться, пока не будет достигнута истинность условия.
Как видите, условие просто идёт после действий. Такой тип оператора называется с постусловием. А типа while - с предусловием.
Только всё же одна принципиальная разница есть. в do-until действия выполнятся как минимум 1 раз даже при ложном условии.
Кроме этого, есть одно полезное применение: инициализация переменных. Пример:
можно написать
Код:
a=get_integer('Число', 5)
b=random(4)
while(a>b)
{
a=get_integer('Число', 5);
b=random(4);
}
Очевидно, что если не сделать предварительную работу, то компилятор заругается на a>b, так как не знает ни а, ни b. Но если поставить проверку после тела, как делает do-until, то предварительную работу можно и не делать.
Код:
do{
a=get_integer('Число', 5)
b=random(4)
}until !(a>b)//нужно поменять истину на ложь (см. работу цикла)
Такой цикл прогонится как минимум 1 раз. И именно за этот раз переменные инициализируются.

Операторы передачи управления break, continue, return.
break, как вы помните, просто выходит и цикла в тот самый момент как его вызвали.
Пример
Код:
a=0;
while(a<15)
{
if(a==10)
{break;}
show_message(string(a))
a+=1;//заодно вспомните относительность
}
Будут показаны сообщения 1, 2, 3, 4, 5, 6, 7, 8, 9 а на 10 уже выйдет. Заметьте, важно определить куда поставить break: в начале тела или в конце. (Объясните почему)

continue прерывает текущую итерацию и переходит к следующей
Тот же пример
Код:
a=0;
while(a<15)
{
if(a==10)
{continue;}
show_message(string(a))
a+=1;
}
В данном случае будут сообщения 1, 2, 3, 4, 5, 6, 7, 8, 9 (на 10 цикле сработает continue и управление перейдёт к 11 циклу), 11, 12, 13, 14.

В этом случае замена while на do until (естественно с заменой условия на противоположное) не сыграет роли.
Нет смысла ставить continue в конец тела, ибо и так произойдёт естественный переход.

return (Только в скрипте) прерывает цикл и возвращает значение.

От цикла while сформировалось дочернее устойчивое выражение
Код:
while(true)
{
if(<условие выхода из цикла>)//очень очень важно
{
break;//ещё важней
}
}
По сути является альтернативой while(<условие>). Очень обязательно наличие break И! выполняемость условия выхода. Например условие
Код:
while(true)
{
if(random(4)<0)
{
break;
}
}
Никогда не выполнится и игра зависнет.
while(true) называют бесконечным циклом. Есть ещё бесконечные циклы, они имеют своё значение в программировании.

Следующий урок должен быть заключительным в теме операторы.
Записан

Есть вещи, которые нельзя объяснить. Для всего остального есть Справка
Рандом-рандом-рандомище (с)

C++ & OpenGL
DarkWing [GB]
Посетитель
**

Репутация: 0
Offline Offline

API: 8.1 Standard
Сообщений: 35


« Ответ #1 : Октябрь 23, 2011, 16:58:04 »

О! Отлично. Спасибо.
Записан
Михаил144
Участник
****

Репутация: 21
Offline Offline

Пол: Мужской
API: Game Maker 8.0 Pro
Сообщений: 181

Помни где ты живешь - Цив-я Брато и Отцеубийства


WWW
« Ответ #2 : Октябрь 23, 2011, 17:48:32 »

Спасибо!
Записан

Да пройдутся Святые Катары по земле своими огненными жезлами и возжгутся сердца миллионов огнем чистой Любви....
DarkWing [GB]
Посетитель
**

Репутация: 0
Offline Offline

API: 8.1 Standard
Сообщений: 35


« Ответ #3 : Октябрь 23, 2011, 22:20:50 »

Вот такой вопрос:

Есть упомянутая выше конструкция:
Код:
while(true)
{
if(<условие выхода из цикла>)//очень очень важно
{
break;//ещё важней
}
}

Выход из цикла хотелось-бы осуществлять через switch-case. т.е. так:
Код:
while(true)
{

  switch {переменная}
    case 1:  
      //действие
    break;
    case 2:  
      //действие
     break;
..........
    case 15:
      // вот тут нужно действие выхода. Вроде как оператор break. Но GM считает его за окончание Case, и выход из While не дает.
    break;
}


Как это лучше сделать?
Записан
Dmi7ry
Гл. Администратор
*

Репутация: 1379
Offline Offline

Пол: Мужской
Награды:
5000 сообщений!За постоянность! [200 дней на форуме]За лояльность! [+1000 репутации]За помощь в развитии форума!Знаток Game Maker!За помощь новичкам!
API: GameMaker Studio Master
Деятельность: Code, design
Сообщений: 6626



WWW
« Ответ #4 : Октябрь 24, 2011, 04:19:25 »

Просто добавить условие.
Код:
a=true
while(a)
{
  switch {переменная}
    case 1: 
      //действие
      break;
    case 2: 
      //действие
      break;
..........
    case 15:
      // вот тут нужно действие выхода. Вроде как оператор break. Но GM считает его за окончание Case, и выход из While не дает.
      a=false; break;
}
Записан

- А какой, собственно, командой процессора колобок ест черта?
- Командой EAT...
Справка и FAQ в правом верхнем углу...
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

HellRoom Games © 2006-2012 All Rights Reserved
Powered by SMF 1.1.21 | SMF © 2013, Simple Machines
Страница сгенерирована за 0.087 секунд. Запросов: 30.