ITCS - Программирование в Action Script2 на конкретных примерах. Урок 2 - ПРОГРАММИРОВАНИЕ
Сегодня: Понедельник, 05.12.2016, 23:39 (МСК)| Здравствуйте, Гость| Мой профиль | Регистрация | Вход | RSS

Работаем с VirtualDub

Спецэффекты в Cinema4D

Эргономика компьютерных клавиатур

ТВ-тюнеры. Как выбирать?

Adobe Audition 3. Лучшая в 2010-м
Главная » ПРОГРАММИРОВАНИЕ

Программирование в Action Script2 на конкретных примерах. Урок 2

23.06.2011


В этой части материала я расскажу о коде калькулятора, написанного на ActionScript 2.0. Напомню, что все исходники даются, их можно скачать по ссылке http://itcs.3dn.ru/Programming/AS2-calc/AS2-calc.rar. В прошлой статье этой небольшой серии было рассказано, как можно быстро и эффективно создавать графический интерфейс и собственные интерактивные компоненты (кнопки). В этой части мы все привяжем к коду, а программировать будем только в первом фрейме.

Работающий пример перед вами:




Начинаем программирование


Итак, добавляем новый слой, кликаем на первом фрейме для него указателем мыши и нажимаем клавишу F9. Теперь Flash готов к программированию, как только вы введете в окне Actions хоть одну строчку кода, на обозначении первого фрейма во временной сетке появится значок «альфа». Это значит, что в нем содержится код. 


Уточнение ТЗ для программирования. План действий


Сразу скажу, что код не оптимизирован, дело в том, что данный калькулятор я когда-то писал в очень сжатые сроки, и тогда во главе угла была скорость реализации, а не ее емкость. Да, и язык был тогда мне не сильно знаком. При желании вы можете все оптимизировать самостоятельно. 
В рамках реализации первую итерацию проекта я разделил на несколько промежуточных этапов, а именно:
  1. Реализация ввода с цифровых кнопок на табло.
  2. Реализация добавления «.» и «+/-».
  3. Реализация математических операций: сумма, разность, деление, произведение, кнопок «=» и очистки «Clear». 
  4. Реализация математических функций, вывод на экран чисел e и Пи.
  5. Обработчик ошибок.
Теперь переходим непосредственно к решению поставленных задач. 


Первый и второй этапы…


Итак, давайте разберем немного саму структуру калькулятора, а именно, что мы должны использовать в качестве ключевых переменных. 
  • Переменная, хранящая в себе текущее значение, отображаемое на табло — она так и называется tablo.
  • Текущая динамическая переменная, в которой также будет храниться второй аргумент для стандартных математических операций (сложение, разность, умножение, деление). Эта переменная в рамках кода называется D2
  • Переменная, в которую сохраняется результат вычислений или же первый аргумент для стандартных математических операций (сложение, разность, умножение, деление) — в рамках кода называется X.
Теперь стоит расставить некоторые флаги, а именно, мы должны обеспечить правильный ввод в табло. При нажатии кнопки с цифрой, та добавляется к вводимому числу. Но у нас есть еще два таких тонких случая как нажатие точки, разделяющей дробную и целую части, а также кнопки «+/-», переключающей знаки перед числом. 

В рамках кода эти флаги указаны в переменных PointQuery и Munusplus. Также нам понадобится счетчик символов в вводимом числе, он хранится в переменной count

Таким образом, в первых строках нашего кода указываем первоначальные настройки для всех:

PointQuery = true;
//calc-point status query
Munusplus = false;
//calc-minus status query
tablo = "0";
//calc-on start: tablo text "0"
X = "0";
//calc-RESULT argument
D2 = "0";
//calc-dynamic variable
count = 1;
//calc-length of the argument

Именно с помощью этого арсенала переменных мы напишем первую небольшую итерацию, которая будет посвящена только организации правильного ввода. Например, нам нужно, чтобы точка могла нажиматься только один раз, «+/-» работал грамотно и так далее. 

Теперь напишем функцию добавления символа, к которой будут обращаться кнопки, в простейшем виде она будет выглядеть так:

function AddSym(var1) {

if (tablo == "0") {
dig = var1;
return dig;

} else {
dig = tablo+var1;
count++;
return dig;
}
}

Теперь расскажем, что же она делает. На входе она получает строку или символ, который нужно добавить к строке, изображенной на табло. Если на нем отображен «0», то текущей переменной (которую можно в равной степени считать внутренней переменной функции, потому как она используется только здесь) присваивается введенный символ, в ином случае текущая переменная является результатом сложения строки tablo и символом. После чего функция возвращает строку dig. Обратите внимание на то, что в рамках переменных мы работаем не с числовыми значениями, а со строками. 

Конечно, для тех, кто любит оптимизацию тут понятно, что саму переменную dig можно было и не применять, пользуясь лишь tablo. Но стоит сказать, что эту функцию я писал первой, и не очень хотел плотной увязки на одной переменной. 

Далее, если вы посмотрите на функции самих кнопок с цифрами, то при их нажатии происходит идентичный вызов, например, для 4-ки:

but_4.onPress = function() {
tablo = AddSym("4");
D2 = tablo;
};

С кнопками добавления точки и «+/-» несколько иная:
 
// enter point
but_point.onPress = function() {
//enter in work
if (PointQuery == true && tablo != "0") {
tablo = AddSym(".");
count++;
D2 = tablo;
PointQuery = false;
//enter after start or clear
} else if (PointQuery == true && tablo == "0") {
tablo = AddSym("0.");
count += 2;
D2 = tablo;
PointQuery = false;
}
};

В данном случае обрабатываются два условия, а именно, на табло уже введено какое-то число или на нем записан «0». В первом случае мы вызываем функцию добавления просто символа точки, во втором — строки «0.». Как можно увидеть, в данном случае мы еще нарастили значения в счетчиках символов, и также установили флаг PointQuery в значение false, то есть точка уже нажата. 

//+/- switcher
but_pm.onPress = function() {
if (Number(tablo)<0) {Munusplus = true;}
if (tablo != "0") {
if (Munusplus == true) {
tablo = tablo.substring(1, count+1);
} else { 
tablo = "-"+tablo;
}
Munusplus = false;
D2 = tablo;
}
};

В переключателе «+/-» нужно в первую очередь определить является число на табло отрицательным или нет? Если да, то флаг Minusplus устанавливается как true. Затем идут условные операции по добавлению или удалению «-» впереди строки. 


Этап третий, самый "веселый"


Самая большая трудность этого этапа состоит в том, что нужно сделать сложный переключатель между кнопками «+», «-», «/», «*». Например, после ввода числа вы хотите его умножить на следующее, но нажали случайно «+», затем вы кликаете на правильной кнопке «*», и у вас должно осуществляться произведение. Этот вариант условно назван «anti dblclick». Мало того, после того как сделана определенная математическая операция нажатие на одну из этих четырех кнопок должно срабатывать как «=», то есть показывается результат, и он уже должен быть готов к участию в следующих вычислениях. 

Для этого я предусмотрел специальную систему переменных-флагов операций Pl, Mi, Um и Del (в исходном состоянии все равны единице, если отличаются, то проводится соответствующая операция). И нам понадобится еще одна переменная-флаг KeyListen (в исходном состоянии false), указывающий на то, что одна из четырех кнопок математических операций нажата, но после этого уже введено какое-то число. Другими словами, что есть второй аргумент для вычислений. Для примера возьмем реализацию функции нажатия на кнопку «+».

// button "+"
but_plus.onPress = function() {
if (Pl>1 && KeyListen == false) {
X = Number(X)+Number(D2);
tablo = X;
}
if (Pl == 1) {
if (Mi>1 && KeyListen == false) {
X = Number(X)-Number(D2);
} else if (Mi == 1 && Um == 1 && Del == 1) {
X = D2;
}
if (Um>1 && KeyListen == false) {
X = Number(X)*Number(D2);
} else if (Mi == 1 && Um == 1 && Del == 1) {
X = D2;
}
if (Del>1 && KeyListen == false) {
X = Number(X)/Number(D2);
} else if (Mi == 1 && Um == 1 && Del == 1) {
X = D2;
}
Pl++;
tablo = X;
}
KeyListen = true;
Switcher = true;
Mi = 1;
Um = 1;
Del = 1;
};

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

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

Если предыдущая операция была разностью, умножением или делением, то и при этом был введен новый аргумент, то они выполняются, в ином случае число, отображенное на табло приравнивается к первому аргументу, а указатель Pl становится не равным единице. То есть при последующих нажатиях кнопок «+», «-», «/», «*» и «=» будет выполняться сумма. 

В рамках кода вы можете увидеть еще один флаг под названием Switcher, он используется для указания того, что в табло будет вводиться новое число. Соответственно, к его обработке нужно добавить специальную функцию переключения:

//Switch function -- zeroing tablo
function SwFunc() {
if (Switcher == true) {
tablo = "0";
PointQuery = true;
Switcher = false;
}
}

А сам вызов SwFunc(); нужно прописать первой строкой в функцию добавления символов в табло AddSym(var1). Также для нее нам понадобиться еще одна дополнительная функция, переключающая флаги в момент введения какого-либо числа в табло. В рамках кода я ее назвал ConstEnter(), и выглядит она следующим образом:

//Function "What to Do" after constants enter
function ConstEnter() {
KeyListen = false;
}

Думаю, смысл теперь уже становится более-менее понятным. В итоге функция добавления символов в табло выглядит так:

function AddSym(var1) {
SwFunc();
// стартовый ввод, когда на табло 0 или после нажатия сброса 
ConstEnter();
if (tablo == "0") {
dig = var1;
return dig;
ResultStatus = false;
} else {
dig = tablo+var1;
count++;
return dig;
}
}

По аналогии с функцией нажатия на кнопку «+» реализуются четыре другие кнопки «-», «/», «*» и «=».

Кнопка «Clear» подразумевает возвращение всех параметров в исходное состояние. Это можно вынести в отдельную функцию, что удобно.


Четвертый этап


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

При этом стоит сказать, что тригонометрические функции в математическом аппарате Flash принимают в качестве аргументов значения в радианах, а на калькуляторе пользователям удобнее вводить градусы. Поэтому нужно дополнительное преобразование.
Как это делается? Вот пример, взятый из функции FunCalc(A):

if (A == "sin") {
D2 = Math.sin(Number(D2)/180*Math.PI);
}


Пятый этап


Обработчик ошибок в данном калькуляторе сделан на самом примитивном уровне, поэтому, те, кто хотят довести все до совершенства, могут усилить этот модуль. Функция ErrorMess() переводит с «непонятного» на русский значения NaN (неопределен) и +/- INFINITY (плюс/минус бесконечность). В чем недоделан данный модуль? Не реализовано блокировки участия этих значений в дальнейших вычислениях. То есть нужно поставить флаг и т.п. 

function ErrorMess() {
if (isNaN(D2)) {
tablo = "Не определен";
Switcher = true;
}
if (isNaN(X)) {
tablo = "Не определен";
Switcher = true;
}
if (D2 == Number.NEGATIVE_INFINITY) {
tablo = "Минус бесконечность";
Switcher = true;
}
if (D2 == Number.POSITIVE_INFINITY) {
tablo = "Плюс бесконечность";
Switcher = true;
}
if (isNaN(X)) {
tablo = "Не определен";
Switcher = true;
}
if (X == Number.NEGATIVE_INFINITY) {
tablo = "Минус бесконечность";
Switcher = true;
}
if (X == Number.POSITIVE_INFINITY) {
tablo = "Плюс бесконечность";
Switcher = true;
}
}


Первая итерация завершена


Итак, ключевой блок программы сделан. Как говорилось выше, представленный код можно оптимизировать по вашему усмотрению. 


Кристофер

Перепечатка материалов или их фрагментов возможна только с согласия автора.





Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Ассоциация боевых роботов
Рекомендуем...
Новости

Разделы

Опросы

Какой язык программирования вы считаете наиболее актуальным сегодня?
Всего ответов: 308

Друзья

3D-кино






Найти на сайте:








Об авторе       Контакты      Вопрос-ответ        Хостинг от uCoz