Adding a variable to a variable set in JavaScript - javascript

So I'm making my incremental game, Periodic Alchemy, and I'm trying to make something that ensures that a save keeps all the new variables in another version. In order to save, I take a variable, "player", which includes all my variables inside it, and make it into a Base64 string that you can copy.
In almost every new version, however, I add new variables. If a player uses their old save on a new version with new variables, then those new variables are lost and the new functions break. So when you load the game, the game checks to see if that old save_data contains certain variables, and if a variable is not included, the game adds that variable to the save data. I don't know, however, how to do that. Here is my "player" code:
var player = {
upQuarkClicks: 0,
electronClicks: 0,
downQuarkClicks: 0,
auto_up_quark_clicks: 0,
auto_electron_clicks: 0,
auto_down_quark_clicks: 0,
auto_proton_clicks: 0,
auto_neutron_clicks: 0,
up_quark_click_cost: 15,
electron_click_cost: 15,
down_quark_click_cost: 15,
proton_click_cost: 15,
neutron_click_cost: 15,
upgrade_up_quark_1_cost: 50,
upgrade_electron_1_cost: 50,
upgrade_down_quark_1_cost: 50,
auto_up_quark_clicks_amount: 1,
auto_electron_clicks_amount: 1,
auto_down_quark_clicks_amount: 1,
auto_proton_clicks_amount: 1,
auto_neutron_clicks_amount: 1,
upgrade_up_quark_click_1_bought: "False",
upgrade_electron_click_1_bought: "False",
upgrade_down_quark_click_1_bought: "False",
proton_up_quark_cost: 2,
proton_down_quark_cost: 1,
neutron_up_quark_cost: 1,
neutron_down_quark_cost: 2,
protonClicks: 0,
neutronClicks: 0,
hydrogen2DeuteriumClicks: 0,
hydrogen1ProtiumClicks: 0,
hydrogen3TritiumClicks: 0,
helium3Clicks: 0,
helium4Clicks: 0,
lithium6Clicks: 0,
lithium7Clicks: 0
};
So, let's say I added a new variable: lithium_7_bought: "false". This new variable is not in the old save data, and so is erased by the load. How do I add it in if it is not found?

Something like this should work:
if (!("lithium_7_bought" in player))
{
player.lithium_7_bought = "false";
}

Related

Set and Get array from cookies with js-cookie and JSON.parse

I'm using js-cookie to store data and get them back, I'm trying to sore an array variable but I have trouble mantaining its format. This is the process that create, retrive, change and save data of the cookie, it works but just the first time, as I'm not able to
// store array in cookie
Cookies.set('points', '0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0', { expires: 30 });
// get data from cookie into a variable (becomes a string)
points = Cookies.get('points');
// convert to object with (length 12)
points = JSON.parse("[" + points + "]");
// change value of the array in the varable position
points[playerId]++;
// save data in cookie
Cookies.set('points', points, {expires: 30});
This works only the first time, any subsequent time I get error and the array become length 1. I'm sure it's because I'm missing squarebrackets but if I try:
Cookies.set('points', '[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]', { expires: 30 });
the variable becomes an object with lenght 1 and it does not work.
The reason it fails the second time is that you pass to Cookies.set an array as second argument, making assumptions that this will end up as a comma separated string in the cookie. But js-cookie will in that case do the conversion to string by adding the square brackets.
So the very quick solution is to change this:
Cookies.set('points', points, {expires: 30});
to:
Cookies.set('points', points.toString(), {expires: 30});
However, it is better to encode and decode with JSON.stringify and JSON.parse without doing any string manipulation "yourself", like this:
var points = Array(12).fill(0);
Cookies.set('points', JSON.stringify(points), { expires: 30 });
var points = JSON.parse(Cookies.get('points'));
points[0]++;
Cookies.set('points', JSON.stringify(points), {expires: 30});
// ...etc

Error 1105: Target of Assignment must be a Reference Value

Flash says the code is on my second line, but I've done some reading and it says this error is mainly due to me trying to assign a value to a value, and I've looked back over my code, and I can't seem to find any instance of this.
Here is my code:
this.mc=new MovieClip();
addChild(mc)=("myButton1", this.DisplayOBjectContainer.numChildren());
myButton1.createEmptyMovieClip("buttonBkg", myButton1.getNextHighestDepth());
myButton1.buttonBkg.lineStyle(0, 0x820F26, 60, true, "none", "square", "round");
myButton1.buttonBkg.lineTo(120, 0);
myButton1.buttonBkg.lineTo(120, 30);
myButton1.buttonBkg.lineTo(0, 30);
myButton1.buttonBkg.lineTo(0, 0);
Thanks!
Check what you are trying to in these lines:
addChild(mc)=("myButton1", this.DisplayOBjectContainer.numChildren());
myButton1.createEmptyMovieClip("buttonBkg", myButton1.getNextHighestDepth());
To create an empty MovieClip, you can just create a new display object w/o linking it to a clip in the library like this:
addChild(mc);
var myButton1:MovieClip = new MovieClip(); // creates an empty MovieClip
addChildAt(myButton1, numChildren); // adds the MovieClip at a defined level (on this case, the numChildren added on stage
Your code is very confusing. You mix AS2 methods (createEmptyMovieClip, getNextHighestDepth) with AS3 methods (addChild). Here is what you are trying to do:
const MC:Sprite = new Sprite(); // Sprite container
this.addChild(MC);
const MYBUTTON1:Sprite = new Sprite(); // button in container
MC.addChild(MYBUTTON1);
const BUTTONBKG:Shape = new Shape(); // background in button
MYBUTTON1.addChild(BUTTONBKG);
const BTG:* = BUTTONBKG.graphics;
BTG.beginFill(0x86B1FB);
BTG.lineStyle(0, 0x820F26, 0.6, true, "none", "square", "round");
BTG.lineTo(120, 0);
BTG.lineTo(120, 30);
BTG.lineTo(0, 30);
BTG.lineTo(0, 0);
MYBUTTON1.addEventListener(MouseEvent.CLICK, pressButton);
function pressButton(e:MouseEvent):void {
trace('I click on you');
}
Notes : the alpha value in AS3 is between 0 and 1. If you want your button to be clickable, you should use beginfill method.

Cache SpriteSheets in EaselJS

How can I cache SpriteSheets in EaselJS? I have a Sprite object and when I use user.hero.cache(0, 0, 30, 40); it stops playing animation (probably because I'm just caching the current frame, not the entire SpriteSheet image). So how can I cache it?
Here's my relevant EaselJS code:
data = {
images: ["Graphics/hero.png"],
frames: {
width: 30,
height: 40
},
animations: {
stand: 0,
run: [1, 2, "runLoop", 0.15],
runLoop: [3, 7, true, 0.15],
jump: [8, 10, "happy", 0.5],
happy: 11,
fall: 12,
stopFalling: [13, 14, "stand", 0.2],
almostFalling: [16, 19, true, 0.1]
}
};
user.hero.spriteSheet = new createjs.SpriteSheet(data);
user.hero = new createjs.Sprite(user.hero.spriteSheet, "stand");
user.hero.name = "hero";
user.hero.x = user.hero.safeX = 40 * 3;
user.hero.y = user.hero.safeY = 0;
user.hero.offset = 4;
user.hero.regX = user.hero.offset + 2;
user.hero.regY = user.hero.offset;
user.hero.width = 30 - (user.hero.offset * 2) - 10;
user.hero.height = 40 - (user.hero.offset * 2);
user.hero.xvel = user.hero.yvel = 0;
user.hero.cache(0, 0, 30, 40); // <--- This is the problem.
movableObjContainer.addChild(user.hero);
movableObj.push(user.hero);
Without cache:
With cache:
I've tried caching the data.image or user.hero.spriteSheet too, without success.
Is there any way to cache the SpriteSheet without compromising its animations?
When you cache the sprite, you are saving off how it looks at that instant.
Can you explain why you want to cache it? The only reason I can think of to cache it would be to apply filters. Each time you cache it, the contents are drawn to an off-screen canvas, which is then drawn in place of it. This makes a lot of sense if you have complex content, like a container or graphics, which do not change, but with the spritesheet, it means you are creating a new bitmap to draw a bitmap. The spritesheet itself is a great way to be filesize, network, and GPU-optimzed, so re-caching it is basically negating all those benefits.
If you want to cache anyways, you will need to re-cache it, or call updateCache() every time it changes. Here is an example using the ticker.
createjs.Ticker.on("tick", function() {
user.hero.updateCache();
// or
user.hero.cache(0,0,30,40)
}, this);
Here is a quick demo I did a while back using a few approaches for filters. It provides an example of constant re-caching, as well as an example where the entire spritesheet is cached to apply the filter once, and then that cached version is used for the sprite.
http://jsfiddle.net/lannymcnie/NRH5X/

How to create a sprite with EaselJS?

So I've been looking for the best way for me to create a game in Javascript, and decided that EaselJS would probably work best (If there is a better library, please do tell).
I've just hardly started, but I can't seem to get loading a sprite to work... I'm not quite sure what the problem is, as it's connecting with the canvas, it's loading the library...
Here is the javascript console error:
Uncaught TypeError: Cannot read property 'length' of null easeljs-0.7.1.min.j
s:12
b._calculateFrames easeljs-0.7.1.min.js:12
b.initialize easeljs-0.7.1.min.js:12
a easeljs-0.7.1.min.js:12
init index.html:3
onload
So yeah... If you could help me out that'd be great... here is the src code:
function init() {
var stage = new createjs.Stage(document.getElementById("demoCanvas"));
var jazaSheet = new createjs.SpriteSheet ({
"frames": {
"width": 15,
"height": 16,
"numFrames": 8,
"regX": 0,
"regY": 0
},
"animations":{
"walkDown": [0, 1, "walkDown", 2],
"images": ["http://imgur.com/bLfR7TO.png"]
}
});
var jaza = new createjs.Sprite(jazaSheet);
jaza.x = 0;
jaza.y = 0;
jaza.goToAndPlay("walkDown");
stage.addChild(jaza);
Ticker.setFPS(60);
Ticker.addListener(stage);
stage.update();
}
EDIT:
Ok so I've changed it as said, but I still can't seem to get it to show up on the canvas...
function init() {
var stage = new createjs.Stage(document.getElementById("demoCanvas"));
var jazaSheet = new createjs.SpriteSheet ({
"frames": {
"width": 15,
"height": 16,
"numFrames": 8,
"regX": 0,
"regY": 0
},
"animations":{
"walkDown": [0, 1, "walkDown", 2]
},
"images": ["http://imgur.com/bLfR7TO.png"]
});
var jaza = new createjs.Sprite(jazaSheet);
jaza.x = 100;
jaza.y = 100;
jaza.gotoAndPlay("walkDown");
stage.addChild(jaza);
createjs.Ticker.setFPS(60);
stage.update();
}
I took a look at it, you can see the source of the class here.
Basically, you have a typo in your parameter object.
Take the images object out of the animations
var jazaSheet = new createjs.SpriteSheet ({
"frames": {
"width": 15,
"height": 16,
"numFrames": 8,
"regX": 0,
"regY": 0
},
"animations":{
"walkDown": [0, 1, "walkDown", 2]
},
"images": {
["http://imgur.com/bLfR7TO"]
}
});
Explanation:
_calculateFrames() function uses the private variable images. Row 464 creates a loop with the array.length as one parameter. Since the array is null (typo in parameter), TypeError exception is thrown.

Google Area Chart is not taking value as int

I'm using Google's Area Chart to dispaly a graph.
For some reason I'm not ble to use values past into the function:
I have the following code:
function SetAreaChartData(valueString) {
//This works
AreaChartData.setValue(0, 0, 'SomeName');
AreaChartData.setValue(0, 1, 500);
AreaChartData.setValue(0, 2, 500);
AreaChartData.setValue(0, 3, 500);
//This does not work
// First I must "cast" the input to string in order to use the .split function
var str = new String(valueString);
// Then I split the string in order to get an array of string
val = str.split(",");
AreaChartData.setValue(0, 0, 'SomeName');
AreaChartData.setValue(0, 1, val[0]*1); //Multiply by one to cast it to integer
AreaChartData.setValue(0, 2, val[1]*1);
AreaChartData.setValue(0, 3, val[2]*1);
}
I've also tried using parseInt(val[0]), but that is not helping either.
Why won't .setValue recognize val[0] as an integer?

Categories