Sprites

First time I thought I would generate only procedural art but now I've realized that it would be much more simple if I would be able to just load some spritesheet and use it.

Sprites are just standard images like .png, .jpg.

SpriteSheets — is an image where a lot of sprites are combined in a single file.

Engine SHOULD at least provide an ability to load grid-based sheets and to define a sprite from custom region of an image.

Sprites loading

Introducing a sprite sheet abstraction! It can load grid based tilemaps automatically

// Tiles would be 16px x 16px const spriteSheet = px.spriteSheet('sprites.png', 16, 16); rect(0, 0, w, h, 0xFFFFFF); // We can use custom regions as a single sprite // in this case we should define it with left, top, width, height const fullImage = spriteSheet.define('full', 0, 0, 16*4, 16*2); spriteSheet.onload(function(){ print('Full Image', 3, 0); rect(0, 10, w, 32+4, 0x880055); sprite( fullImage, 4, 12) print('Sprites', 3, 50); // BACKGROUND rect( 0, 60, w, 16*2+3*2, 0xEECC00) // GRID // COLS for(var x = 0; x < 5; x++){ rect( x * (16 + 2), 60, 2, 16*2+3*2, 0xDDDDDD) } // ROWS for(var y = 0; y < 3; y++){ rect(0, 60 + y*(16 + 2), w, 2, 0xDDDDDD) } // DRAW ALL SPRITES for(var x = 0; x < 4; x++){ for(var y = 0; y < 2; y++){ sprite( spriteSheet.get(x, y), x*18+2, y*18+2 + 60 ); } } });

Sprite rotation and flipping

Let's make it possible to rotate the sprite around an origin point (by 90 degrees) and flip them

const spriteSheet = px.spriteSheet('sprites.png', 16, 16); const apple = spriteSheet.define('apple', 0, 8, 16, 24); apple.pivot.x = 0; // TOP-LEFT CORNER apple.pivot.y = 8; const textColor = 0x000077; const gridColor = 0x7777BB; const contrastColor = 0xFF00FF; const gridSize = 16; const gridOffset = 16; // MAKING THE GRID const backgroundLayer = px.createLayer(0); for(var x = gridOffset; x < 120; x += gridSize) { var markText = ( x - gridOffset ).toString(); backgroundLayer.print( markText, x - markText.length * 6 /2 + 1, 4, textColor ); backgroundLayer.line( x, gridOffset-2, x, h, gridColor ); } for(var y = gridOffset; y < 100; y += gridSize) { var markText = ( y - gridOffset ).toString(); backgroundLayer.print( markText, gridOffset-2 - markText.length * 6, y - 4, textColor ); backgroundLayer.line( gridOffset-2, y, w, y, gridColor ); } spriteSheet.onload(function(){ // DRAW PIVOT BASED ROTATED APPLES for(var i = 0; i < 4; i++){ var rotated = apple.rotate(i); backgroundLayer.sprite( rotated, gridOffset+32, gridOffset+32 ); } backgroundLayer.point( apple.pivot.x + gridOffset+32, apple.pivot.x + gridOffset+32, contrastColor); }); var position = new Point(0,0); var cone = spriteSheet.define('cone', 16, 16, 16, 16); cone.pivot.x = 8; // CENTER OF THE APPLE cone.pivot.y = 8; move = function(){ clear(); var dx = mouse.x - position.x-gridOffset |0, dy = mouse.y - position.y-gridOffset |0; position.x += dx > 0 ? 1 : dx < 0 ? -1 : 0; position.y += dy > 0 ? 1 : dy < 0 ? -1 : 0; // FLIPS DEMONSTRATION if( abs( dy ) < abs( dx ) ) { var flipped = cone.flipXY().flipX( dx > 0 ); } else { var flipped = cone.flipY( dy > 0 ); } sprite( flipped, gridOffset+position.x, gridOffset+position.y ); }

Add zoom feature

const spriteSheet = px.spriteSheet('sprites.png', 16, 16); const apple = spriteSheet.define('apple', 0, 8, 16, 24); apple.pivot.x = 0; // TOP-LEFT CORNER apple.pivot.y = 8; spriteSheet.onload(function(){ line(0, 16, w, 16, 0x00FFFF); for(var i = 0; i < 2.5; i+=0.01+i/4) sprite( apple, 64 * i, 16, i ); for(var i = 2; i < 4; i+=0.5+i/12) sprite( apple.brightness(0.2), 64 * (i-2) - 4, 96 - (6-i)*10 - 2, (6-i)+0.4 ); for(var i = 2; i < 4; i+=0.5+i/12) sprite( apple, 64 * (i-2), 96 - (6-i)*10, (6-i) ); });

Lets add some interactive and draw an apple under the mouse cursor with a fake 3D effect!

Try to move your cursor over the canvas.

px.frameRate = 60 const spriteSheet = px.spriteSheet('sprites.png', 16, 16); const apple = spriteSheet.define('apple', 0, 8, 16, 24); apple.pivot.x = 8; apple.pivot.y = 16; const backgroundLayer = px.createLayer(-1); backgroundLayer.rect(0, 0, w, h, 0x5500FF); var dotList = []; update = function(){ clear(); dotList.forEach(function(p, n){ sprite(apple, p.x, p.y, n/50+0.1); }); } move = function(){ dotList.push(mouse.clamp(0)); dotList = dotList.slice(-100); // TO PREVENT UPDATE AFTER MOVE RETURN false return false; }

Draw on sprite

Do not know why, but let it be sprite modification feature.

const spriteSheet = px.spriteSheet( 'sprites.png', 16, 16 ); const gridSize = 16; var tiles; spriteSheet.onload( function() { tiles = [ [ 2, 0 ], [ 3, 0 ] ] .map( pos => spriteSheet.get( pos ).clone() ); move(); // update the image } ); move = function() { if( !tiles ) return; var mouseInTile = ( ( mouse.x / gridSize | 0 ) + ( mouse.y / gridSize | 0 ) ) % 2; tiles[ 1 - mouseInTile ].point( mouse.x % 16, 16 - mouse.y % 16, color( 0xFF + cos( px._time ) * 0x70, 0x60 + cos( px._time / 1.7 ) * 0x30, 0x70 ) ); for( var x = 0; x < 16; x++ ) { for( var y = 0; y < 16; y++ ) { sprite( tiles[ ( x + y ) % 2 ].flipY(), x * gridSize, y * gridSize ); } } }