Could there be a future plugin to integrate Rive (already supported on Defold 2D Game Engine)
2 Likes
That’s the only thing missing for my company, that keeps us from using phaser
really or just kidding?
sadly no. When I joined they went with rive and konva. Throwing in a phaser layer here and there, but it’s really a pain. Now that I think about it… one could render the rive offscreen and somehow copy every texture/frame into phaser somehow. but I will also need to map the clicks…ahrg
ok, that did not take long!
quick protoype:
this.canvas = document.createElement('canvas');
this.riveInstance = new rive.Rive({
// Load a local riv `clean_the_car.riv` or upload your own!
src: hamster,
// Be sure to specify the correct state machine (or animation) name
stateMachines: 'State Machine 1', // Name of the State Machine to play
canvas: this.canvas,
layout: layout, // This is optional. Provides additional layout control.
autoplay: true,
onLoad: () => {
// Prevent a blurry canvas by using the device pixel ratio
this.riveInstance.resizeDrawingSurfaceToCanvas();
},
});
document.body.appendChild(this.canvas);
this.canvas.width = 200; // Set your desired width
this.canvas.height = 200; // Set your desired height
setTimeout(() => {
// Add the canvas to the Phaser game
this.texture = this.textures.addCanvas('canvasTexture', this.canvas);
// Now you can use 'canvasTexture' as any other Phaser texture
let image = this.add.image(0, 0, 'canvasTexture').setOrigin(0, 0);
const barrel = image.preFX.addBarrel(1);
this.add.tween({
duration: Phaser.Math.Between(400, 500),
repeatDelay: Phaser.Math.Between(100, 200),
targets: barrel,
ease: 'Sine.easeInOut',
amount: 0.786,
yoyo: true,
repeat: -1,
});
// Enable input on the image
image.setInteractive();
// Get the inputs via the name of the state machine
const inputs = this.riveInstance.stateMachineInputs('State Machine 1');
// Add a pointer down event
image.on('pointerdown', (pointer) => {
if (!this.riveInstance) return;
// Get the local y-coordinate of the pointer relative to the image
let localY = pointer.y - image.y;
// Calculate the height of each third of the image
let thirdHeight = image.height / 3;
let animationName;
// Check which third was clicked
if (localY < thirdHeight) {
console.log('First third clicked');
animationName = inputs.find((i) => i.name === hamsterEvents.TOUCH_1);
} else if (localY < 2 * thirdHeight) {
console.log('Second third clicked');
animationName = inputs.find((i) => i.name === hamsterEvents.TOUCH_2);
} else {
console.log('Third third clicked');
animationName = inputs.find((i) => i.name === hamsterEvents.TOUCH_3);
}
animationName.fire();
});
}, 1000);```
1 Like
And just draw the new frame over it
update() {
if (this.texture) {
const ctx = this.texture.context;
// Draw the external canvas onto the texture
ctx.drawImage(this.canvas, 0, 0, this.texture.width, this.texture.height);
this.texture.refresh();
}
}
Any performance hints welcome. Not sure how expensive this is
1 Like