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.
Related
I am trying to call a R-script from a js-file but I always get null as a return value
My folder-structure is as following
-R_test
--example.js
--helloWorld.R
example.js looks as follows:
var R = require("r-script");
var out = R('helloWorld.R')
.callSync();
console.log(out);
and helloWorld.R looks as like this:
print("Hello World")
Looking at the only other question I could find similar to mine here my syntax is correct. Changing the js-file to
var R = require("r-script");
var out = R('helloWorld.R')
.data("Hello World)
.callSync();
console.log(out);
and helloWorld.R to
print(input)
should according to the readme of r-script print the data Hello World but it also just returns null
If there is any better way to run a R-script from a nodeJS-file please let me know
Thanks to dcruvolo I got it working. Here is how the js-file needs to look:
const { R } = require('#fridgerator/r-script')
let r = new R('./members.R')
r.call()
.then(response => console.log(response))
.catch(e => console.log('error : ', e))
And here is the .R-file:
members <- c(129, 1, 5, 3, 2, 1, 21, 1, 8, 7, 0, 1, 1, 1, 110, 0, 0, 5, 1, 0, 0, 0)
membersSorted <- sort(members, decreasing = TRUE)
# Graph cars using blue points overlayed by a line
plot(membersSorted, type="o", col="blue")
# Create a title with a red, bold/italic font
title(main="Members", col.main="red", font.main=4)
png(filename="members.png")
plot(membersSorted, type="o", col="blue")
dev.off()
I was making a graphing utility for fun, and then it turned into a real project...
I was trying to achieve a very simple graph... a line graph.
However, using a for-loop inside of my typescript project yields no results.
Look in the source code below, you can see I have console logs where I need to confirm an action is occuring. All of them run fine and in the perfect order in my typescript project.
Since SO doesnt support typescript, heres a codepen with the full source and typescript compiler: https://codepen.io/SkylerSpark/pen/zYvpWNZ
Snippet causing me the issues:
g.px & g.py are my coordinates. They are grabbed from this array (its an example array of pizza sales):
const pizzas = {
x: [0, 5, 10, 15, 20, 25, 30, 35, 40],
y: [0, 1, 2, 3, 4],
px: [0, 5.2, 7, 20.9, 34.3, 39.5],
py: [0, 1.1, 1.3, 2.7, 3.5, 3.9]
};
// Draw Numbers
if (g.px.length == g.py.length) {
console.log("confirm");
for (var i = 1; i < g.px.length + 1; i++) {
if (i == 1) {
console.log("start");
ctx.beginPath();
ctx.moveTo(g.px[i], g.py[i]);
} else if (i < g.px.length) {
console.log("continue");
ctx.lineTo(g.px[i], g.py[i]);
} else {
console.log("draw");
ctx.stroke();
}
console.log(i);
}
}
Now see the picture below, its running fine:
The problem is that your y-values need to be negative. In situations like these it's often useful to just draw any line instead of immediately using loops. I found this out by adding the following code
ctx.beginPath();
ctx.moveTo(-40, -40);
ctx.lineTo(40, -40);
ctx.lineTo(40, 40);
ctx.lineTo(-40, 40);
ctx.stroke();
just before you start drawing the line, which actually shows some results. If I change g.py[i] to -g.py[i] everywhere, then a small line is added to the bottom left of the graph. Hope this helps!
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/
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";
}
I have a need to implement labels on features in a FeatureLayer in version 3.5 if Esri's Javascript API. The labels are from a field returned by a REST feature service. I can't move to 3.7 for various reasons at this time. I have tried using a TextSymbol but my map features just turn to the color of the TextSymbol and no text appears. I may be approaching this in he wrong manner, though. Below is the code I'm attempting to use for labeling with the featureLayer object being my instance of the FeatureLayer I'm adding to the map. Is there a different or proper way to accomplish this task?
featureLayer.on("graphic-add", function (evt) {
var labelColor = new Color([255, 0, 0, 0.25]);
var myLabel = new TextSymbol(evt.graphic.attributes["My Field Name"]);
myLabel.setColor(labelColor);
myLabel.font.setSize("14pt");
evt.graphic.setSymbol(myLabel);
//console.log(evt);
});
Thanks for any help that can be provided!
I was able to solve this with the code below. This seems to work great.
var labelList = new Array();
featureLayer.on("update-end", function (evt) {
for (var i = 0; i < evt.target.graphics.length; i++) {
var gfx = evt.target.graphics[i];
//if label hasn't been added go ahead and generate it and add to array
if (labelList.indexOf(gfx.attributes[idField]) == -1) {
labelList.push(gfx.attributes[idField]);
addLabelToGeometry(gfx.attributes[labelField], gfx.geometry);
}
}
});
function addLabelToGeometry(text, geometry) {
var point = geometry.getExtent().getCenter();
//top level label of text
var TextSymbolJson = {
"type": "esriTS",
"color": [0, 0, 0, 255],
"verticalAlignment": "middle",
"horizontalAlignment": "center",
"font": {
"family": "Helvetica",
"size": 12,
"style": "normal",
"weight": "bold",
"decoration": "none"
}
};
var labelTextSymbol = new esri.symbol.TextSymbol(TextSymbolJson);
labelTextSymbol.setText(text);
var labelGraphic = new esri.Graphic(point, labelTextSymbol);
map.graphics.add(labelGraphic);
}