I'm trying to make a Pixel RPG game, and am a bit confused.
What I'm trying to do:
var character = {
gender: male,
age: 18,
action: walking,
direction: left,
skin: 0,
eyes: aqua,
hairStyle: 0,
hairColor: blue,
hat: 'cap'
};
ctx.drawImage(characterIMG.body[character.gender][character.skinColor], 0, 0);
ctx.drawImage(characterIMG.eyes[character.gender][character, 0, 0);
ctx.drawImage(characterIMG.hair[style0], 0, 0);
if(character.hat != "none"){
ctx.drawImage(characterIMG.hat['cap'], 0, 0);
}
How would I go about defining the images?
So far got here, but am mixed up..
var characterIMG = [male, female]; //I want some separate variables to just write in, in case I need to add more images of the same type, then I can just write the "type" in the variable instead of changing a bunch of stuff :)
for(var i in characterIMG){
characterIMG[i] = {
skin: [],
eyes: [],
hair: [],
accessories: []
}
}
Unless there is a more efficient way to do this?
Thanks!
--In short, I want to do this:
ctx.drawImage(characterIMG.body[character.gender][character.skinColor], 0, 0);
ctx.drawImage(characterIMG.eyes[character.gender][character], 0, 0);
ctx.drawImage(characterIMG.hair[style0], 0, 0);
..with characterIMG containing a huge database of all the relevant images (this)
Use an object and then just new up the object whenever you want to create a new instance of a character. With this, each character can inherit their properties from the main Object (via prototype) and become a separate entity within your game.
var Person = function(payload) {
this.name = payload.name;
this.age = payload.age;
this.gender = payload.gender;
};
Person.prototype.talk = function() {
return console.log('hello, I am ' + this.name);
}
var Person1 = new Person({
name : 'Amanda',
age : 18,
gender : 'Female',
});
var Person2 = new Person({
name : 'Sam',
age : 21,
gender : 'Make',
});
Person1.talk();
Person2.talk();
You can load a set of images as follows
// a list of image name comma delimited
const imageURLs = "image1.jpg,image2.jpg,image3.jpg";
// create an array of images
const myImageList = imageURLs.split(",").map(url => {
const image = new Image;
image.src = url;
return image;
});
If you have many images with different categories and subcategories then it will depend on how you organise the images on your file system. If you have one directory and all the images in that then each image's name should have some description of the image
body_dark_female.jpg
body_light_female.jpg
body_dark_male.jpg
body_light_male.jpg
head_dark_female.jpg
head_light_female.jpg
head_dark_male.jpg
head_light_male.jpg
And so on, or a better option is to set the various categories in directories
body/dark/female/jill.jpg
body/dark/male/tom.jpg
body/light/female/jill.jpg
body/light/male/tom.jpg
head/light/female/jill.jpg
head/light/male/tom.jpg
head/dark/female/jill.jpg
head/dark/male/tom.jpg
You can then use the name or directories to create the data structure
// using the directory structure
function loadImage(imageURL,images){
const cats = imageURL.split("/"); // split the cats into an array
// remove the last item as that is the image name
var name = cats.pop();
// remove the extension and add just the image name to the cats
cats.push(name.split(".")[0]);
// reference the base category
var currentCat = images;
cats.forEach(cat => { // for each category create the objects
if(currentCat[cat] === undefined){ // does this cat exist?
currentCat[cat] = {}; // no them create an object for it
}
currentCat = currentCat[cat]; // reference the category
});
// now create the image and add it to the object
currentCat = new Image;
currentCat.src = imageURL;
}
Then use the directory listing to create the list of images to load
const imageURLs = `
body/dark/female/jill.jpg
body/dark/male/tom.jpg
body/light/female/jill.jpg
body/light/male/tom.jpg
head/light/female/jill.jpg
head/light/male/tom.jpg
head/dark/female/jill.jpg
head/dark/male/tom.jpg
`;
Because the directory listing may be a bit unclean (spaces, tabs, linefeeds, etc) you should ensure each image name is valid
// remove tabs, groups of spaces and returns, and use linefeed to seperate them
const imagesURLClean = imageURLs.replace(/\t|\r| +?/g,"").split("\n");
// create the base category
const characterIMG = {};
// add the images
imagesURLClean.forEach(imageURL => loadImage(imageURL,characterIMG));
When that has run you can access the image as follows
ctx.drawImage(characterIMG.body.light.female.jill,0,0);
Or via strings
var part = "body";
var skin = "light";
var gender = "female";
var name = "jill";
ctx.drawImage(characterIMG[part][skin][gender][name],0,0);
The directory listing will create the following data structure
characterIMG = {
body : {
dark : {
female : {
jill : // the image
},
male : {
tom : // the image
},
},
light : {
female : {
jill : // the image
},
male : {
tom : // the image
},
}
},
head : {
dark : {
female : {
jill : // the image
},
male : {
tom : // the image
},
},
light : {
female : {
jill : // the image
},
male : {
tom : // the image
},
}
}
If your list is very long it may have missing items, during development it would pay to add a default category that will return an image appropriate for that category.
Thus you directory listing would look like
body/default.jpg // default
body/light/default.jpg // default
body/light/female/default.jpg // default
body/light/male/default.jpg // default
body/dark/default.jpg // default
body/dark/female/default.jpg // default
body/dark/female/jill.jpg
body/dark/male/default.jpg // default
body/dark/male/tom.jpg
// and so on
Then create a function that gets a image via category and if it has problems it will use the default image as far as it can find to fit the categories
function getImage(images, ...categories){
const count = 0;
var image = images
while(count < categories.length){
if(image[categories[count]] !== undefined){
image = image[categories[count++]];
}else{
return image.default;
}
}
return image;
}
Then you can draw an image as follows
ctx.drawImage(getImage(characterIMG,"body","dark","female","jill"),0,0);
// when you get the wrong referance
ctx.drawImage(getImage(characterIMG,"leg","dark","female","jill"),0,0);
// it will return characterIMG.default
// or
ctx.drawImage(getImage(characterIMG,"body","dark","female","bill"),0,0);
// as there is no female bill, it will return characterIMG.body.dark.female.default
This is how you define an array inside an object.
var characterIMG = {
male: {
skins: [],
hair: ["black", "brown"]
},
female: {
skins: [],
hair: []
}
};
console.log(characterIMG);
console.log(characterIMG["male"]["hair"]);
console.log(characterIMG.male.hair); //does the same
Related
I didn't find out, how to create a json message in jquery with dynamic values for a key array element.
I'm trying to build a json message like this:
{
"line": {
"name": "Test",
"images": [
{
"order": "1",
"link": "https://google.com/1.jpg",
"name": "1.jpg"
},
{
"order": "2",
"link": "https://google.com/2.jpg",
"name": "2.jpg"
}
]
}
}
I fail to attach the pictures to the message.
jsonObbj = {};
line = {};
line ["name"] = $("#name").val();
counter = 1;
$("div.carousel_image > img").each(function() {
image = {};
image ["order"] = counter;
image ["name"] = $(this).attr('src');
line ["images"].push(image); // How can I edit this image to the images array
counter++;
});
// how can I add the line to the array
Thx for your help!
You need to initialize line.images to an empty array.
jsonObbj = {};
line = {};
line ["name"] = $("#name").val();
line["images"] = []; // add this line
counter = 1;
$("div.carousel_image > img").each(function() {
image = {};
image ["order"] = counter;
image ["name"] = $(this).attr('src');
line ["images"].push(image); // How can I edit this image to the images array
counter++;
});
Note, in general, when your object keys are normal strings, you want to use dot notation: line.images
JSFiddle: https://jsfiddle.net/to4xhewu/
You need to initialise line.images as an array before you can start pushing to it. You should also make sure you declare your variables properly with const, let or var or else they will be implicitly global.
Try this for a simple, object literal initialiser alternative
const jsonObbj = {
line: {
name: $("#name").val(),
images: $("div.carousel_image > img").map((i, img) => ({
order: i + 1,
name: img.getAttribute("src"),
link: img.src
})).get()
}
}
See https://api.jquery.com/map/
I have a dictionary as as shown below. I am trying to add dict values into them. This is what it stars with
var animals = {
flying : {},
underground : {},
aquatic : {},
desert : {}
};
For example: If I wanted to add d = {dove : [<some list>] } into animal[flying], how would i do it? I cannot enter the values manually as thus i am running a loop, I am able to write it manually, but not with program.
I have tried animals[flying] = d, this would work for the first time, but when i try to add another value it would be replaced and not appended.
In the end I am looking for something like this: This is what it ends with
var animals = {
flying : {
dove : [<list>],
sparrow : [<list>],
},
underground : {
rabbits : [<list>],
squirrel : [Squirrel],
},
aquatic : {
dolphin : [<list>],
whale : [Squirrel],
},
desert : {
camel : [<list>],
antelope : [<list>],
},
};
well because
myDict[subcat] = x
assigns it. You're working with lists. Think about it - when have you ever added an item to a list this way? Of course that overwrites your previous entry. What you want instead is to push the variable into the array (also, this isn't python. Lists are called Arrays and Dictionaries are called Objects. There is a distinction, but that's beyond the scope of an answer here. Google it).
So do this:
myDict = {
subCat: [],
}
And then when you loop:
myDict[subCat].push(x)
I think what you want to do is:
animals["flying"] = Object.assign(animals["flying"], d);
E.g.
animals = {
flying: {}
}
d = { dove: [1, 2, 3] }
Object.assign(animals["flying"], d);
d = { sparrow: [1, 2, 3] }
Object.assign(animals["flying"], d);
console.log(animals); //{"flying":{"dove":[1,2,3],"sparrow":[1,2,3]}}
var newAnimal = {name: 'bird'};
if(animals['flying']['dove'] && animals['flying']['dove'].length > 0) {
//List already exists so add the new animal
//TODO also check if the animal is already in the list?
animals['flying']['dove'].push(newAnimal);
}else {
//Create the new list
animals['flying']['dove'] = [newAnimal];
}
Have some issue with push the values in to the javascript array object. Please any one give me the perfect solution
Class code :
var myfuns = ( function(undefined) {
var myarr ={};
function _add(arrayparam){
if (myarr.current == undefined) {
myarr.current = [];
myarr.current.push(options.current_info);
}else{
}
}
function _getList() {
return $.extend(true, {}, myarr);
}
return {
add : _add,
getList : _getList
}
}());
Here am calling and manage the values and keys
function setmydetails(){
var my_param = {
current_info : {
pg : '#tset',
no : 12,
name : "john",
row : 0,
},
userprofile : [],
class : [],
marks : [],
games : []
};
myfuns.add(my_param);
}
Now i got the array
myfuns.getList() // GOT proper array what i passed in my_param
Question : How to modify the existing values from any one of the Inner array from the myarr Obj
Ex: Once First array created later have to modify some from "myarr.current" = > Change current_info.row to 2222
Similar i have to add some array in to " myarr.class " etc
I would like to say try this one not tested
function _add(arrayparam){
if (myarr.current == undefined) {
myarr.current = [];
myarr.current.push(options.current_info);
}else{
$.extend( myarr.current, arrayparam);
}
}
proper source : https://api.jquery.com/jquery.extend/
How to create, assign and access new values to object ?
Declaring new objects and adding new values to is is problem for me.
can any one help me?
var Countries = [
{
name : 'USA',
states : [
{
name : 'NH',
cities : [
{
name : 'Concord',
population : 12345
},
{
name : "Foo",
population : 456
}
/* etc .. */
]
}
]
},
{
name : 'UK',
states : [ /* etc... */ ]
}
]
Tried like this:
Countries = new Array();
Countries[0] = new Country("USA");
Countries[0].states[0] = new State("NH");
Countries[0].states[0].cities[0] = new city("Concord",12345);
Countries[0].states[0].cities[1] = new city("Foo", 456);
...
Countries[3].states[6].cities[35] = new city("blah", 345);
You're trying to create new objects over and over with things like new Country and new State but you don't have those defined as functions. Something much more simple should work:
Countries[0].states[0].name = "Not New Hampshire";
console.log(Countries[0].states[0].name);
[Edit] : I also highly agree with upsidedown. Please check a tutorial on working with data structures (arrays and objects) in JavaScript.
As #uʍop-ǝpısdn commented, you'll find lots of tutorials.
One of the common pattern for creating "newable" objects in JavaScript goes like this:
var Country = function(name, states){
this.name = name;
this.states = states || [];
}
var State = function(name, cities){
this.name = name;
this.cities = cities || [];
}
var Countries = [];
Countries.push( new Country("USA", [ new State("NH", ...), ... ]) );
I wish to grab content from various sources, using different API calls, and collate them all into an object or array with the same format. I am getting stuck with javascript arrays and objects, and none of the examples I find seem to do what I want to do. This is the format I want to store. This is pseudo coded for an example of what I want to achieve
var content = new Object();
getTweets();
getSoundCloud();
display();
function getTweets() {
//first result
content.type = "tweet
content.text = "the text of the tweet"
content.image = "the image from the tweet"
return content;
}
function getSoundCloud() {
//second result
content.type = "soundcloud
content.text = "the name of the song"
content.image = "the image of the song"
return content;
}
function display() {
//for each content
{
$("#container").append(content.text);
}
}
The first result is generated by one function call, and the Second result is generated by a different function call.
I want these functions to add all of the content together into the same format object. Once the object is populated, I wish to iterate it in a different function and display on the screen.
How do I make this object? I have tried it but the data is always the same, ie, overwritten with the same values. In php this would be an associative array perhaps or something like
I want to have an object for each piece of content I have, and can loop through it
content[0].type = "tweet"
content[1].type = "coundcloud"
Any suggestions with examples would be great.
Many Thanks
When you have many of something you should immediately think
I need to store these things in an array.
When your "things" are complex and have various properties/ state, you should immediately think:
I need to create an object to store them.
... so what would be best here is an array of objects. Each function will create objects and add them to content, which we'll switch to an array:
var content = []; // Array
getTweets();
getSoundCloud();
display();
function getTweets() {
var tweet = {}; // This is an object
tweet.type = "tweet";
tweet.text = "The text of the tweet";
tweet.image = "The image of the tweet";
content.push(tweet); // add the object to the array.
}
function getSoundCloud() {
var soundcloudThing = {};
soundcloudThing.type = "soundcloud"
soundcloudThing.text = "the name of the song"
soundcloudThing.image = "the image of the song"
content.push(soundcloudThing);
}
Now when it comes to showing this content, as have an array; the obvious thing to do here is iterate over it;
function display() {
for (var i=0;i<content.length;i++)
{
$("#container").append(content[i].text);
// You can also use content[i].image and content[i].type in here
}
}
Note that [] and {} is literal notation for creating arrays and objects. It's use is favoured over new Array() and new Object().
I have done an example here: http://jsfiddle.net/pdXsA/2/
var content = [];
content.push(getTweets());
content.push(getSoundCloud());
display();
function getTweets() {
return{
type : "tweet",
text : "the text of the tweet",
image : "the image from the tweet"
};
}
function getSoundCloud() {
return{
type : "soundcloud",
text : "the name of the song",
image : "the image of the song"
};
}
function display() {
content.forEach(function(item){
$("#container").append(item.text +"<br/>");
});
}
content should be an array of objects, each function adds its object into the content array :
var content = []; // empty array
getTweets();
getSoundCloud();
display();
function getTweets() {
content.push ({ //first result
type: "tweet",
text: "the text of the tweet",
image: "the image from the tweet"
});
}
function getSoundCloud() {
content.push ({ //second result
type: "soundcloud",
text: "the name of the song",
image: "the image of the song"
});
}
function display() {
content.forEach (v) {
// code to format the object v appropriately
var vtext = v.type + ' : ' + v.text;
$("#container").append(vtext);
}
}
Actually, just sussed it out like this
var content = {
text: this.text.linkify().linkuser().linktag(),
image: this.profile_image_url,
type: 'tweet'
};
arrayContent.push(content);
I can now loop through it, and each Content and display it!