Open eonarheim opened 1 year ago
It's not 100% clear yet what the API would look like
This issue hasn't had any recent activity lately and is being marked as stale automatically.
For reference on possible API, PixiJS has a TilingSprite component
@mattjennings Thanks, this is a great reference. I might be able to sneak tiling into the existing API into the option bag constructor? Potentially if the repeat flag is set on a dimension, it will tile if the destSize is greater than the sourceView's corresponding dimension?
export interface SpriteOptions {
/**
* Image to create a sprite from
*/
image: ImageSource;
/**
* By default the source is the entire dimension of the [[ImageSource]]
*/
sourceView?: { x: number; y: number; width: number; height: number };
/**
* By default the size of the final sprite is the size of the [[ImageSource]]
*/
destSize?: { width: number; height: number };
repeatX: boolean;
repeatY: boolean;
}
Perhaps a new type would be best tho... tileScale
and tilePosition
seem pretty useful.
Hmm. To be honest I'm not entirely sure what tileScale
is as opposed to regular scale
, and what tilePosition
would do as opposed to changing the sprite origin. This is the rendering logic for those properties if that sheds any light.
My thinking is if you had repeatX
and repeatY
properties, I could manipulate the sprite scale & origin to achieve the same effect as tileScale
and tilePosition
... but it's probably not the most intuitive. Also not sure if origin
wraps in Excalibur? tilePosition
would have that behaviour if not, and could justify that property.
This issue hasn't had any recent activity lately and is being marked as stale automatically.
We accidentally implemented this feature (see discord conversation for full context https://discord.com/channels/1195771303215513671/1229051072027562074)
https://github.com/excaliburjs/Excalibur/assets/612071/8844704a-ac60-4c3f-b65b-2d63d5337834
The gist for sprites, is if the ImageWrapping.Repeat
is set AND you have a source view bigger than the natural width/height of the image source it will tile!
var game = new ex.Engine({
canvasElementId: 'game',
width: 600,
height: 400,
displayMode: ex.DisplayMode.FitScreenAndFill,
pixelArt: true
// antialiasing: false
});
var tex = new ex.ImageSource('https://cdn.rawgit.com/excaliburjs/Excalibur/7dd48128/assets/sword.png', {
wrapping: ex.ImageWrapping.Repeat
});
var loader = new ex.Loader([tex]);
var sprite = new ex.Sprite({
image: tex,
sourceView: {
x: 0,
y: 0,
width: 500,
height: 500
},
destSize: {
width: 1000,
height: 1000
}
});
var actor = new ex.Actor({
x: 0, y: 0,
anchor: ex.vec(0, 0),
coordPlane: ex.CoordPlane.Screen,
z: -10
});
actor.onInitialize = () => {
actor.graphics.add(sprite);
};
actor.onPostUpdate = (engine, delta) => {
sprite.sourceView.x += .05 * delta;
}
game.add(actor);
game.start(loader);
game.currentScene.camera.pos = actor.pos;
Current hack for animation tiling
this.backgroundAnim = Resources.Background.getAnimation('default')!;
// Terrible terrible to enable animation tiling
for (let frame of this.backgroundAnim.frames) {
const sprite = (frame.graphic as Sprite);
sprite.image.wrapping = { x: ImageWrapping.Repeat, y: ImageWrapping.Repeat };
sprite.image.image.setAttribute('wrapping-x', ImageWrapping.Repeat);
sprite.image.image.setAttribute('wrapping-y', ImageWrapping.Repeat);
sprite.image.image.setAttribute('forceUpload', 'true');
sprite.sourceView.width *= 5;
sprite.sourceView.height *= 5;
sprite.destSize.width *= 5;
sprite.destSize.height *= 5;
}
This issue hasn't had any recent activity lately and is being marked as stale automatically.
See comment
https://github.com/excaliburjs/Excalibur/discussions/2621#discussioncomment-5634534
Discussed in https://github.com/excaliburjs/Excalibur/discussions/2621