Is there a method to address a single sprite other than the name given in the spritemap?
ogrotten opened this issue · 4 comments
I've got a spritesheet with playing cards, row = suit, col = value.
Is there a built-in function/method to call up a single sprite from the sheet by coordinate? so that say map[3,1]
would be the 3 of Clubs at the sprite location 4th row, 2nd col?
The example at Sprite.sprite seems to be used to rename the sprite at that coordinate position, so I was looking for a related function to get/show a sprite.
Calling e.sprite(3, 1)
should work. The sprite
method is overloaded -- you can pass in either coordinates or a name.
The example is just showing two different ways of calling the method. (The first passing the exact position/dimensions in tile coordinates, the second passing a predefined sprite name.)
Thank you.
How should I refer to this when defining the element?
Crafty.e('2D, Canvas, Mouse, SpriteAnimation, Tween, Sprite, ' + (3,1))
Does not work, so I've used
Crafty.e('2D, Canvas, Mouse, SpriteAnimation, Tween, Sprite, FullDeck')
But FullDeck is only a name mapped to 0,0
coordinates map{FullDeck: [0, 0]}
, which seems to work-ish but doesn't seem quite right.
Not sure if this is the source, but there winds up being a downline problem:
function go() {
let front = true;
let cardsuit = Math.floor(Math.random()*4);
let cardcard = Math.floor(Math.random()*13);
let actual = (cardcard, cardsuit);
Crafty.e('2D, Canvas, Mouse, SpriteAnimation, Tween, Sprite, FullDeck')
.sprite(cardcard, cardsuit)
.reel("Flip2Back", 10, [actual ,'Back'])
.reel("Flip2Front", 10, ['Back', actual])
.bind('Click', function(e){
if (front) {
front = !front;
this.animate('Flip2Back');
} else {
front = !front;
this.animate('Flip2Front');
}
});
}
- If I go
.sprite(actual)
(line 7), then it fails silently, showing nothing. The display is blank, but the flip reel animates, showing the sprite defined atBack
when clicked for toggle. - With the code as shown, the card at the coordinate shows, and then a click shows the back. However, a 2nd click shows a blank front. It then does as the first item, showing the sprite at
Back
but no front when toggled.
Please advise?
let actual = (cardcard, cardsuit);
I think this is the root of your confusion here -- it looks like you're thinking of actual
as a tuple, but unfortunately that's not how javascript works. You're accidentally using javascript's comma operator -- (1, 2)
is an expression that returns 2
. (Try logging actual
, or checking its type).
If you're testing in a browser, you might want to invest some time in learning how the debugging tools work -- by stepping through the code you'll be able to see that actual
wasn't of the type you thought it was. And remember that javascript isn't a completely untyped language -- you can't declare the type of a variable up front, but values have types, and you need to understand what types you're passing around.
So although conceptually you can think of a sprite's location as being identified by either a name or a tuple of coordinates, since a tuple isn't a construct in javascript, you need to pass in either a string
or two separate coordinates when calling sprite:
// ok
e.sprite('name');
// ok
e.sprite(1, 4);
// doesn't do what you want -- you're passing one argument,
// and javascript doesn't support tuples like this
let actual = (1, 4)
e.sprite( actual );
// Need an object to refer to multiple values together
let actual = {r: 1, c:4);
e.sprite(actual.r, actual.c);
(There are some tricks you can do by invoking apply
, which can call a function with the items of an array as its arguments, but that's probably overkill in this particular case.)
But FullDeck is only a name mapped to 0,0 coordinates map{FullDeck: [0, 0]}, which seems to work-ish but doesn't seem quite right.
When you create a sprite map, under the covers Crafty generates a new component for each named sprite in the map. (You can see that each such component has the same initialization method, since they all use the same asset -- the only difference is the initial coordinate.)