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 );
}
}
}