В этой части материала я расскажу о коде калькулятора, написанного на ActionScript 2.0. Напомню, что все исходники даются, их можно скачать по ссылке http://itcs.3dn.ru/Programming/AS2-calc/AS2-calc.rar. В прошлой статье этой небольшой серии было рассказано, как можно быстро и эффективно создавать графический интерфейс и собственные интерактивные компоненты (кнопки). В этой части мы все привяжем к коду, а программировать будем только в первом фрейме.
Работающий пример перед вами:
Начинаем программирование
Итак, добавляем новый слой, кликаем на первом фрейме для него указателем мыши и нажимаем клавишу F9. Теперь Flash готов к программированию, как только вы введете в окне Actions хоть одну строчку кода, на обозначении первого фрейма во временной сетке появится значок «альфа». Это значит, что в нем содержится код.
Уточнение ТЗ для программирования. План действий
Сразу скажу, что код не оптимизирован, дело в том, что данный калькулятор я когда-то писал в очень сжатые сроки, и тогда во главе угла была скорость реализации, а не ее емкость. Да, и язык был тогда мне не сильно знаком. При желании вы можете все оптимизировать самостоятельно. В рамках реализации первую итерацию проекта я разделил на несколько промежуточных этапов, а именно: - Реализация ввода с цифровых кнопок на табло.
- Реализация добавления «.» и «+/-».
- Реализация математических операций: сумма, разность, деление, произведение, кнопок «=» и очистки «Clear».
- Реализация математических функций, вывод на экран чисел e и Пи.
- Обработчик ошибок.
Теперь переходим непосредственно к решению поставленных задач.
Первый и второй этапы…
Итак, давайте разберем немного саму структуру калькулятора, а именно, что мы должны использовать в качестве ключевых переменных. - Переменная, хранящая в себе текущее значение, отображаемое на табло — она так и называется 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; } }
Первая итерация завершена
Итак, ключевой блок программы сделан. Как говорилось выше, представленный код можно оптимизировать по вашему усмотрению.
Кристофер Перепечатка материалов или их фрагментов возможна только с согласия автора.
|