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

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

Итак, добавляем новый слой, кликаем на первом фрейме для него указателем мыши и нажимаем клавишу 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() {
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;
StPlBtn = false;
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 (плюс/минус бесконечность). В чем не доделан данный модуль? Не реализована блокировка участия этих значений в дальнейших вычислениях. То есть нужно поставить флаг и т.п.

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

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

Кристофер http://itcs.3dn.ru


Компьютерная газета. Статья была опубликована в номере 26 за 2011 год в рубрике программирование

©1997-2024 Компьютерная газета