play.p5 has both sprites and animations that can be added to sprites. The sprite is what can be scaled, not the animation. Was able to remove the confusing push/pop scaling and positioning by directly positioning the sprites. Using sprites also alleviates the need to slow the frameDelay.
Added tweenlite.js for juice
// var candle, incense;
var defaultItemHeight = 120 ;
var defaultItemWidth = 80 ;
// a room has
// a bool called isLit, a bool called isClean, a string called marker,
// a color called color,
// an array of items,
// this will eventually load items from the database but for now we add one item
// an array of characters
// an array of exits
let isLit ;
let roomColor ;
let items = [];
let characters = [];
let inscription ;
let selectedItem = 0 ;
//it's advisable (but not necessary) to load the images in the preload function
//of your sketch otherwise they may appear with a little delay
function preload () {
//create an animation from a sequence of numbered images
candleLit_sprite_sheet = loadSpriteSheet ( ' assets/animation/candleLit.png ' , 200 , 267 , 13 );
candleUnlit_sprite_frame = loadAnimation ( ' assets/animation/candleUnlit.png ' );
incenseLit_sprite_sheet = loadSpriteSheet ( ' assets/animation/incenseLit.png ' , 200 , 387 , 11 );
incenseUnlit_sprite_frame = loadAnimation ( ' assets/animation/incenseUnlit.png ' );
EBGaramond = loadFont ( ' assets/fonts/EBGaramond12-AllSC.otf ' );
}
function setup () {
textFont ( EBGaramond );
let canvas = createCanvas ( 1200 , 710 );
noSmooth ();
canvas . parent ( ' sketch ' );
// check to see if the player is logged in, if not authenticate them, autofill guest credentials
// read the json for the current logged in player
// read the player json or whatever and get the player character and items and put them in player
// read the json or whatever from the room page
// put the list of items in the room's item array
roomColor = color ( ' #ddaabb ' );
for ( i = 0 ; i < 40 ; i ++ ){
let candle = createSprite ( - 100 , - 100 );
let candleLitAnim = loadAnimation ( candleLit_sprite_sheet );
candle . addAnimation ( ' normal ' , candleLitAnim );
let candleItem = new Item ( ' Candle ' , candle );
items . push ( candleItem );
let incense = createSprite ( - 100 , - 100 );
let incenseLitAnim = loadAnimation ( incenseLit_sprite_sheet );
incense . addAnimation ( ' normal ' , incenseLitAnim );
let incenseItem = new Item ( ' Incense ' , incense );
items . push ( incenseItem );
}
inscription = " Robert Taylor Biggs, 1921 - 1986 " ;
console . log ( ` ${ roomColor } , ${ inscription } , ${ items [ 0 ]. itemName } ` )
}
class Item {
constructor ( name , sprite , active ) {
//an item has an itemType, and each itemType has a corresponding action
//an item has a string called itemName
// itemType would have an inherent action function, and may have multiple animations
this . name = " Candle " ;
this . sprite = sprite ;
this . active = active ;
}
}
function draw () {
//textOutput();
textAlign ( CENTER );
background ( roomColor );
textSize ( width / 25 );
fill ( 0 );
text ( inscription , width / 2 , 50 );
//draw room frame, is this needed? maybe this is multiple projection mapped screens in a 'real' room
/* strokeWeight(5);
line(0, height, width, 0);
line(0, 0, width, height);
rectMode(CENTER);
fill(roomColor);
rect(width /2, height/2, width /1.5, height/1.5); */
drawSprites ();
// from json or whatever fill the attributes of room and then
// check to see if the room is lit, if not set background to black, hiding everything
// if the player moves a candle to room items set room to lit
// if room is lit, set background to room color
// iterating over columns and rows using the screen width, place each itemAnim
// from each item in the room's item array
// get character from player
// get inventory from character
// for each item in chracter.inventory place the first frame of each itemAnim in a row in
// whatever part of the screen represents the player inventory
//let itemCounter = 0;
let itemRowCounter = 1 ;
let itemColumnCounter = 1 ;
let duration = 1 ;
for ( i = 0 ; i < items . length ; i ++ ) {
let thisItem = items [ i ];
let thisSprite = thisItem . sprite ;
thisSprite . scale = . 5 ;
if ( itemColumnCounter * defaultItemWidth > width - defaultItemWidth ){
itemRowCounter += 1 ;
itemColumnCounter = 1 ;
} else {
if ( selectedItem === i ) {
TweenLite . to ( thisSprite , duration , { scale : . 8 });
} else {
TweenLite . to ( thisSprite , duration , { scale : . 5 });
}
thisSprite . position . x = itemColumnCounter * defaultItemWidth ;
thisSprite . position . y = itemRowCounter * defaultItemHeight ;
itemColumnCounter += 1 ;
}
}
}
function keyPressed () {
if ( keyCode === LEFT_ARROW ) {
if ( selectedItem - 1 >= 0 ){
selectedItem -= 1 ;
console . log ( ' selected item ' + selectedItem );
} else {
selectedItem = 0 ;
}
} else if ( keyCode === RIGHT_ARROW ) {
if ( selectedItem + 1 <= items . length ){
selectedItem += 1 ;
console . log ( ' selected item ' + selectedItem );
} else {
selectedItem = items . length ;
}
} else if ( keyCode === DOWN_ARROW ) {
if ( selectedItem + 15 <= items . length ){
selectedItem += 15 ;
console . log ( ' selected item ' + selectedItem );
}
} else if ( keyCode === UP_ARROW ) {
if ( selectedItem - 15 > 0 ){
selectedItem -= 15 ;
console . log ( ' selected item ' + selectedItem );
}
} else if ( keyCode === RETURN ) {
// how should I make an item active? (much larger, held up and movable)
}
}