Flash actionscript: moneycounter code not behaving correctly - actionscript-3

I am trying to set up a virtual bus fare vending machine in Adobe Flash (Animate) animation.
The premise is that you must enter exact fare into the slot because drivers don't carry change. Exact fare is $2. The machine accepts denominations of 5 cents, 10 cents, 25 cents, $1, $5, $10 and $20. If anything over $2 is entered, a message pops up saying the "Exact fare only please. Drivers cannot provide change." So in this case, only the 5 cent, 10 cent, 25 cent and $1 denominations will work, but they must be entered to add up to exactly $2.
The code below works correctly for the 25 cent and $1 denominations alone and in combination, but works erratically when 5 cent and 10 cent are used alone or included in combination with the 25 cent and $1. For example, if you try reach $2 by only using the dimes, the total reaches $1.90 but does not payout the fare when you enter the final 10 cents. Instead the pop up "Exact fare only please" message is triggered. If you then add a nickel, the total reaches $1.95 but again will not payout the fare when you enter the final nickel. Instead the pop up "Exact fare only please." message is triggered again.
Entering $1 and then another $1 works perfectly. Entering 8 quarters works as well as does entering $1 and 4 quarters. Can't figure out what the problem is. Would appreciate any help.
Thanks!
Code is below:
var Cash = 00.00
var payola = Money.text = "02.00";
Money.text = "$" + Cash.toFixed(2);
popup.visible = false;
nickel_btn.addEventListener(MouseEvent.CLICK, add5cents);
function add5cents(event:MouseEvent):void
{
nickelcoin_mc.gotoAndPlay ("nickel_pay");
Cash+=00.05;
Money.text = "$" + Cash.toFixed(2);
if(Cash == payola){
setTimeout(delay, 500);
function delay(){
gotoAndStop(46);
}
}
if(Cash > payola){
nickelcoin_mc.gotoAndPlay ("nickel_nopay");
Cash-=00.05;
Money.text = "$" + Cash.toFixed(2);
popup.visible = true;
}
else {
popup.visible = false;
}
}
dime_btn.addEventListener(MouseEvent.CLICK, add10cents);
function add10cents(event:MouseEvent):void
{
dimecoin_mc.gotoAndPlay ("dime_pay");
Cash+=00.10;
Money.text = "$" + Cash.toFixed(2);
if(Cash == payola){
setTimeout(delay, 500);
function delay(){
gotoAndStop(46);
}
}
if(Cash > payola){
dimecoin_mc.gotoAndPlay ("dime_nopay");
Cash-=00.10;
Money.text = "$" + Cash.toFixed(2);
popup.visible = true;
}
else {
popup.visible = false;
}
}
quarter_btn.addEventListener(MouseEvent.CLICK, add25cents);
function add25cents(event:MouseEvent):void
{
quartercoin_mc.gotoAndPlay ("quarter_pay");
Cash+=00.25;
Money.text = "$" + Cash.toFixed(2);
if(Cash == payola){
setTimeout(delay, 500);
function delay(){
gotoAndStop(46);
}
}
if(Cash > payola){
quartercoin_mc.gotoAndPlay ("quarter_nopay");
Cash-=00.25;
Money.text = "$" + Cash.toFixed(2);
popup.visible = true;
}
else {
popup.visible = false;
}
}
one_btn.addEventListener(MouseEvent.CLICK, add$1);
function add$1(event:MouseEvent):void
{
onebill_mc.gotoAndPlay ("one_pay");
Cash+=01.00;
Money.text = "$" + Cash.toFixed(2);
if(Cash == payola){
setTimeout(delay, 500);
function delay(){
gotoAndStop(46);
}
}
if(Cash > payola){
onebill_mc.gotoAndPlay ("one_nopay");
Cash-=01.00;
Money.text = "$" + Cash.toFixed(2);
popup.visible = true;
}
else {
popup.visible = false;
}
}
five_btn.addEventListener(MouseEvent.CLICK, add$5);
function add$5(event:MouseEvent):void
{
fivebill_mc.gotoAndPlay ("five_pay");
Cash+=05.00;
Money.text = "$" + Cash.toFixed(2);
if(Cash == payola){
setTimeout(delay, 500);
function delay(){
gotoAndStop(46);
}
}
if(Cash > payola){
fivebill_mc.gotoAndPlay ("five_nopay");
Cash-=05.00;
Money.text = "$" + Cash.toFixed(2);
popup.visible = true;
}
else {
popup.visible = false;
}
}
ten_btn.addEventListener(MouseEvent.CLICK, add$10);
function add$10(event:MouseEvent):void
{
tenbill_mc.gotoAndPlay ("ten_pay");
Cash+=10.00;
Money.text = "$" + Cash.toFixed(2);
if(Cash == payola){
setTimeout(delay, 500);
function delay(){
gotoAndStop(46);
}
}
if(Cash > payola){
tenbill_mc.gotoAndPlay ("ten_nopay");
Cash-=10.00;
Money.text = "$" + Cash.toFixed(2);
popup.visible = true;
}
else {
popup.visible = false;
}
}
twenty_btn.addEventListener(MouseEvent.CLICK, add$20);
function add$20(event:MouseEvent):void
{
twentybill_mc.gotoAndPlay ("twenty_pay");
Cash+=20.00;
Money.text = "$" + Cash.toFixed(2);
if(Cash == payola){
setTimeout(delay, 500);
function delay(){
gotoAndStop(46);
}
}
if(Cash > payola){
twentybill_mc.gotoAndPlay ("twenty_nopay");
Cash-=20.00;
Money.text = "$" + Cash.toFixed(2);
popup.visible = true;
}
else {
popup.visible = false;
}
}
stop();

This could be a problem caused by floating point numbers. Try putting this in your code and check the console output:
// Expect result to be 0.1
trace(0.3-0.2);
0.09999999999999998
// Adding lots of 5 cent coins. Expect result to be 0.5
trace(0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05);
0.49999999999999994
Your == comparison is failing sometimes because adding floating point numbers together can result in unexpected values. This answer explains the problem well: https://stackoverflow.com/a/3730040/11678918
For your case, try changing your Cash variable into an int, and store the cents instead of the dollars:
var Cash:int = 0;
var payola:int = 200; // 2 dollars
// Add 5 cents
Cash += 5;
// Adding 1 dollar
Cash += 100;
// Printing out the amount in dollars and cents
Money.text = "$" + (Cash / 100).toFixed(2);
// Our exact check is safe now that we avoid floats.
if(Cash == payola) { ... }

Related

Parse JSON string containing a colon

The class I am using to parse JSON does not allow you to have colons in any string. For example, this would cause an error in parsing:
{
"Test:": "Just a test"
}
Any ideas on how to make this class ignore colons that are in a string? Here is the class I am using:
class JSON {
static var inst;
var text;
function JSON() {
}
static function getInstance() {
if (inst == null) {
inst = new cinqetdemi.JSON();
}
return (inst);
}
static function stringify(arg) {
var _local3;
var _local2;
var _local6;
var _local1 = "";
var _local4;
switch (typeof (arg)) {
case "object" :
if (arg) {
if (arg instanceof Array) {
_local2 = 0;
while (_local2 < arg.length) {
_local4 = stringify(arg[_local2]);
if (_local1) {
_local1 = _local1 + ",";
}
_local1 = _local1 + _local4;
_local2++;
}
return (("[" + _local1) + "]");
} else if (typeof (arg.toString) != "undefined") {
for (_local2 in arg) {
_local4 = arg[_local2];
if ((typeof (_local4) != "undefined") && (typeof (_local4) != "function")) {
_local4 = stringify(_local4);
if (_local1) {
_local1 = _local1 + ",";
}
_local1 = _local1 + ((stringify(_local2) + ":") + _local4);
}
}
return (("{" + _local1) + "}");
}
}
return ("null");
case "number" :
return ((isFinite(arg) ? (String(arg)) : "null"));
case "string" :
_local6 = arg.length;
_local1 = "\"";
_local2 = 0;
while (_local2 < _local6) {
_local3 = arg.charAt(_local2);
if (_local3 >= " ") {
if ((_local3 == "\\") || (_local3 == "\"")) {
_local1 = _local1 + "\\";
}
_local1 = _local1 + _local3;
} else {
switch (_local3) {
case "\b" :
_local1 = _local1 + "\\b";
break;
case "\f" :
_local1 = _local1 + "\\f";
break;
case newline :
_local1 = _local1 + "\\n";
break;
case "\r" :
_local1 = _local1 + "\\r";
break;
case "\t" :
_local1 = _local1 + "\\t";
break;
default :
_local3 = _local3.charCodeAt();
_local1 = _local1 + (("\\u00" + Math.floor(_local3 / 16).toString(16)) + (_local3 % 16).toString(16));
}
}
_local2 = _local2 + 1;
}
return (_local1 + "\"");
case "boolean" :
return (String(arg));
}
return ("null");
}
static function parse(text) {
if (!text.length) {
throw new Error("JSONError: Text missing");
}
var _local1 = getInstance();
_local1.at = 0;
_local1.ch = " ";
_local1.text = text;
return (_local1.value());
}
function error(m) {
var _local2 = ((("JSONError: " + m) + " at ") + (at - 1)) + newline;
_local2 = _local2 + (text.substr(at - 10, 20) + newline);
_local2 = _local2 + " ^";
throw new Error(_local2);
}
function next() {
ch = text.charAt(at);
at = at + 1;
return (ch);
}
function white() {
while (ch) {
if (ch <= " ") {
next();
} else if (ch == "/") {
switch (next()) {
case "/" :
while ((next() && (ch != newline)) && (ch != "\r")) {
}
break;
case "*" :
next();
while (true) {
if (ch) {
if (ch == "*") {
if (next() == "/") {
next();
break;
}
} else {
next();
}
} else {
error("Unterminated comment");
}
}
break;
default :
error("Syntax error");
}
} else {
break;
}
}
}
function str() {
var _local5;
var _local2 = "";
var _local4;
var _local3;
var _local6 = false;
if ((ch == "\"") || (ch == "'")) {
var _local7 = ch;
while (next()) {
if (ch == _local7) {
next();
return (_local2);
} else if (ch == "\\") {
switch (next()) {
case "b" :
_local2 = _local2 + "\b";
break;
case "f" :
_local2 = _local2 + "\f";
break;
case "n" :
_local2 = _local2 + newline;
break;
case "r" :
_local2 = _local2 + "\r";
break;
case "t" :
_local2 = _local2 + "\t";
break;
case "u" :
_local3 = 0;
_local5 = 0;
while (_local5 < 4) {
_local4 = parseInt(next(), 16);
if (!isFinite(_local4)) {
_local6 = true;
break;
}
_local3 = (_local3 * 16) + _local4;
_local5 = _local5 + 1;
}
if (_local6) {
_local6 = false;
break;
}
_local2 = _local2 + String.fromCharCode(_local3);
break;
default :
_local2 = _local2 + ch;
}
} else {
_local2 = _local2 + ch;
}
}
}
error("Bad string");
}
function key() {
var _local2 = ch;
var _local6 = false;
var _local3 = text.indexOf(":", at);
var _local4 = text.indexOf("\"", at);
var _local5 = text.indexOf("'", at);
if (((_local4 <= _local3) && (_local4 > -1)) || ((_local5 <= _local3) && (_local5 > -1))) {
_local2 = str();
white();
if (ch == ":") {
return (_local2);
} else {
error("Bad key");
}
}
while (next()) {
if (ch == ":") {
return (_local2);
}
if (ch <= " ") {
} else {
_local2 = _local2 + ch;
}
}
error("Bad key");
}
function arr() {
var _local2 = [];
if (ch == "[") {
next();
white();
if (ch == "]") {
next();
return (_local2);
}
while (ch) {
if (ch == "]") {
next();
return (_local2);
}
_local2.push(value());
white();
if (ch == "]") {
next();
return (_local2);
} else if (ch != ",") {
break;
}
next();
white();
}
}
error("Bad array");
}
function obj() {
var _local3;
var _local2 = {};
if (ch == "{") {
next();
white();
if (ch == "}") {
next();
return (_local2);
}
while (ch) {
if (ch == "}") {
next();
return (_local2);
}
_local3 = this.key();
if (ch != ":") {
break;
}
next();
_local2[_local3] = value();
white();
if (ch == "}") {
next();
return (_local2);
} else if (ch != ",") {
break;
}
next();
white();
}
}
error("Bad object");
}
function num() {
var _local2 = "";
var _local3;
if (ch == "-") {
_local2 = "-";
next();
}
while (((((ch >= "0") && (ch <= "9")) || (ch == "x")) || ((ch >= "a") && (ch <= "f"))) || ((ch >= "A") && (ch <= "F"))) {
_local2 = _local2 + ch;
next();
}
if (ch == ".") {
_local2 = _local2 + ".";
next();
while ((ch >= "0") && (ch <= "9")) {
_local2 = _local2 + ch;
next();
}
}
if ((ch == "e") || (ch == "E")) {
_local2 = _local2 + ch;
next();
if ((ch == "-") || (ch == "+")) {
_local2 = _local2 + ch;
next();
}
while ((ch >= "0") && (ch <= "9")) {
_local2 = _local2 + ch;
next();
}
}
_local3 = Number(_local2);
if (!isFinite(_local3)) {
error("Bad number");
}
return (_local3);
}
function word() {
switch (ch) {
case "t" :
if (((next() == "r") && (next() == "u")) && (next() == "e")) {
next();
return (true);
}
break;
case "f" :
if ((((next() == "a") && (next() == "l")) && (next() == "s")) && (next() == "e")) {
next();
return (false);
}
break;
case "n" :
if (((next() == "u") && (next() == "l")) && (next() == "l")) {
next();
return (null);
}
break;
}
error("Syntax error");
}
function value() {
white();
switch (ch) {
case "{" :
return (obj());
case "[" :
return (arr());
case "\"" :
case "'" :
return (str());
case "-" :
return (num());
}
return ((((ch >= "0") && (ch <= "9")) ? (num()) : (word())));
}
var at = 0;
var ch = " ";
}
Take a look on my answer of this question and use the JSON class that I mentioned there, it's working fine with your test content :
import JSON;
var json = new JSON();
var data:String = '{"Test:": "Just a test"}';
trace(json.parse(data)['Test:']); // gives : Just a test
Hope that can help.

nodejs json.stringify a 1gb object running out of memory

I'm trying to json.stringify a 1 gb object so that I can write it to disk. I get FATAL ERROR: JS Allocation failed - process out of memory
What can I do to stringify successfully?
You can stringify bit by bit manually: if y is a key of x, then JSON.stringify(y) + ":" + JSON.stringify(x[y]) gives you one segment.
Using fs.appendFileSync, for example, you can use:
var output = "out.json";
fs.writeFileSync(output, "{");
var first = true;
for(var y in x) {
if(x.hasOwnProperty(y)) {
if(first) first = false;
else fs.appendFileSync(output, ",");
fs.appendFileSync(output, JSON.stringify(y) + ":" + JSON.stringify(x[y]))
}
}
fs.appendFileSync(output, "}");
You can also use a Write Stream
Extended with Object, Array checker
var first, y, i$, ref$, len$, toString$ = {}.toString;
switch (toString$.call(x).slice(8, -1)) {
case 'Object':
fs.writeFileSync(output, '{');
first = true;
for (y in x) {
if (x.hasOwnProperty(y)) {
if (first) {
first = false;
} else {
fs.appendFileSync(output, ',');
}
fs.appendFileSync(output, JSON.stringify(y) + ':' + JSON.stringify(x[y]));
}
}
fs.appendFileSync(output, '}');
break;
case 'Array':
fs.writeFileSync(output, '[');
first = true;
for (i$ = 0, len$ = (ref$ = x).length; i$ < len$; ++i$) {
y = ref$[i$];
if (first) {
first = false;
} else {
fs.appendFileSync(output, ',');
}
fs.appendFileSync(output, JSON.stringify(y));
}
fs.appendFileSync(output, ']');
break;
default:
fs.writeFileSync(output, JSON.stringify(x));
}

Error occurs, API SoundCloud Custom Player

Hi I'm trying to catch an Error when it occurs but I have a problem with Json
When the track is loading perfectly I received a success answer but in a crash I have nothing
$.getJSON(apiUrl, function(data, error) {
index += 1;
if(data.tracks){
playerObj.tracks = playerObj.tracks.concat(data.tracks);
}else if(data.duration){
data.permalink_url = link.url;
playerObj.tracks.push(data);
}else if(data.creator){
links.push({url:data.uri + '/tracks'});
}else if(data.username){
if(/favorites/.test(link.url)){
links.push({url:data.uri + '/favorites'});
}else{
links.push({url:data.uri + '/tracks'});
}
}else if($.isArray(data)){
playerObj.tracks = playerObj.tracks.concat(data);
}
if(links[index] && (index % 18) != 0){
var mod = index % 18;
loadUrl(links[index]);
}else{
playerObj.node.trigger({type:'onTrackDataLoaded', playerObj: playerObj, url: apiUrl});
if (links[index]) {
loadMoreTracksData($player, links, key, index);
}
}
}).success(function() { console.log("second success"); }).error(function() { console.log("error"); });
Does anyone know how to listen correctly Errors in this Api.
Assuming you're using a version of jQuery > 1.5 the below is a structure that would be better suited.
The fail method will only be called when an applicable HTTP code is returned from the server (e.g 500 / 404 / 400) not simply when an empty set of data is returned, but with a successful HTTP 200 response.
var index = 0;
var processResponse = function(data) {
index += 1;
if(data.tracks){
playerObj.tracks = playerObj.tracks.concat(data.tracks);
}else if(data.duration){
data.permalink_url = link.url;
playerObj.tracks.push(data);
}else if(data.creator){
links.push({url:data.uri + '/tracks'});
}else if(data.username){
if(/favorites/.test(link.url)){
links.push({url:data.uri + '/favorites'});
}else{
links.push({url:data.uri + '/tracks'});
}
}else if($.isArray(data)){
playerObj.tracks = playerObj.tracks.concat(data);
}
if(links[index] && (index % 18) != 0){
var mod = index % 18;
loadUrl(links[index]);
}else{
playerObj.node.trigger({type:'onTrackDataLoaded', playerObj: playerObj, url: apiUrl});
if (links[index]) {
loadMoreTracksData($player, links, key, index);
}
}
var processError = function(error){
console.log("Error:" + error);
}
$.getJSON(apiUrl)
.done(function(data){ processResponse(data); })
.fail(function(error){ processError(error); })
.complete(function(xhr, status) {console.log(status);};

jQuery click() each() unique?

I want to have multiple span.play without IDs which can be clicked and play some audio file.
Problem: Display the duration on only the current file $(this)
$('.play').each(function() {
$(this).append('<span class="playIcon"><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/7/76/Fairytale_player_play.png/14px-Fairytale_player_play.png"></span><span class="playDur"></span>');
$(this).click(function() {
var file = this.firstChild;
if (file.paused != false) {
//+ stop all others before playing new one
file.play();
} else {
file.pause();
}
file.addEventListener("timeupdate", function() {
var len = file.duration,
ct = file.currentTime,
s = parseInt(ct % 60),
m = parseInt((ct / 60) % 60);
if (s < 10) {
s = '0' + s;
}
$(".playDur").html(' (' + m + ':' + s + ')');
if (ct == len) {
$(".playDur").html('');
}
}, false);
});
});
Test:
http://jsfiddle.net/sQPPP/
http://jsfiddle.net/sQPPP/1/ - using $(this).children( ".foo" )
You need to save .play jQuery object in a variable, as this changes within the addEventListener callback.
http://jsfiddle.net/sQPPP/2/
$('.play').each(function(index) {
var $play = $(this);
$play.append('<span class="playIcon"><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/7/76/Fairytale_player_play.png/14px-Fairytale_player_play.png"></span><span class="playDur"></span>');
$play.click(function() {
var file = this.firstChild;
if (file.paused != false) {
//+ stop all others before playing new one
file.play();
} else {
file.pause();
}
file.addEventListener("timeupdate", function() {
var len = file.duration,
ct = file.currentTime,
s = parseInt(ct % 60),
m = parseInt((ct / 60) % 60);
if (s < 10) {
s = '0' + s;
}
$play.children( ".playDur" ).html(' (' + m + ':' + s + ')');
if (ct == len) {
$play.children( ".playDur" ).html('');
}
}, false);
});
});​

Why I receive different errors on real Android device and Chrome

I develop a mobile app in phonegap. When I test it on Chrome I receive no errors and the database if filled correctly. When I try it on a real device through eclipse i receive the below errors. Why I am getting these errors?
09-22 19:56:49.568: E/Web Console(6912): Uncaught SyntaxError: Unexpected token } at file:///android_asset/www/index.html#page2:1
09-22 19:56:49.558: E/Web Console(6912): Uncaught SyntaxError: Unexpected token ILLEGAL at file:///android_asset/www/index.html#page2:1
and where to find } because in index.html there is no such a char.
I receive these error in my try to read some JSON.
PS I use this code to read some json
function billpaymentstxt()
{
var billpaymentsjson = '{"posts" : [',
i,
line = 0,
billpayments = 0,
mybillpaymentsjson,
Amountint,
Amountdec;
jQuery.ajaxSetup({
'beforeSend' : function(xhr) {
xhr.overrideMimeType('text/plain; charset=iso-8859-7');
},
});
jQuery.get('BillPayments.txt',function(data){
// alert(data.length);
line=0;
for (i = 1; i <= ((data.length)/20); i += 1) {
billpaymentsjson += '{"Id" :' + '"' + data.substr((line+0), 10).trim() + '"' + ',';
Amountint = data.substr((line+10), 7).trim();
Amountdec = data.substr((line+17), 2).trim();
billpaymentsjson += '"PreviousPayments" : ' + '"' + Amountint + '.' + Amountdec + '"' + '}';
line = i * 20;
//alert(line);
if (line == data.length)
{
billpaymentsjson += ']';
}
else
{
billpaymentsjson += ',';
}
}
if (line == 0)
{
billpaymentjson += ']';
}
billpaymentsjson += "}";
//alert(billpaymentsjson);
mybillpaymentsjson = jQuery.parseJSON( billpaymentsjson );
if (((mybillpaymentsjson.posts.length)) == 0) {
$('#mycontent article').html('<strong>bill - <font color=blue>OK</font></strong>');
}
for (i = 0; i < (mybillpaymentsjson.posts.length); i += 1) {
notesdb.transaction((function(i) {
return function(t){
t.executeSql('INSERT into billpayments (barcode, amount, receiptno) VALUES (?,?,?);',
[mybillpaymentsjson.posts[i].Id, mybillpaymentsjson.posts[i].PreviousPayments, 0],
function(){
billpayments = billpayments + 1;
$('#mycontent article2').html(billpayments + '/' + mybillpaymentsjson.posts.length + ' <strong>billpayments</strong>');
if ((mybillpaymentsjson.posts.length) - billpayments == 0) {
$('#mycontent article2').html('<strong>billpayments - <font color=blue>OK</font></strong>');
}
}
);
};
})(i));
}
});
}
From what I know JSON cannot handle ISO-8859-7.
http://www.php.net/manual/en/function.json-encode.php
"This function only works with UTF-8 encoded data." Maybe you could try some conversion