Setting up FlameGame for pixel art #2480
-
Hi there, What's the recommended way to set up the FlameGame for pixel art for each of these two approaches below? (code Scale root canvasScale everything from the root x10 with no smoothing, so that each pixel is 10x10 pixels. Scale each spriteScale each sprite x10 with no smoothing, so that each pixel is 10x10 pixels. Any help appreciated! |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 8 replies
-
In my experience, scaling the whole viewport is simpler and more effective since it is done once per render, not to mention that doing the viewport, you need to write code to scale each individual sprite |
Beta Was this translation helpful? Give feedback.
-
Thanks @erickzanardo For scaling SpriteComponents it was as easy as settings up a fixed resolution viewport: camera.viewport = FixedResolutionViewport(Vector2(320,240), clip: false); This shows very nice crisp scaled sprites with no antialiasing. |
Beta Was this translation helpful? Give feedback.
-
Wow, this is super cool, you just got yourself a star and I've bookmarked that, will try to use in on of my projects!
Yeah, sure, flutter have you covered in that, Wrote the following example very quickly, so I haven't tested it, but hopefully my memory serves me well and this will work or give you some a path to follow: final recorder = PictureRecorder()
final canvas = Canvas(recorder);
canvas.draw...
recorder.endRecorder();
final picture = recorder.toPicture();
final image = picture.toImage(200, 200); // width and height
final flameSprite = Sprite(image); |
Beta Was this translation helpful? Give feedback.
-
Just to round off this discussion - I ended up going for the approach where all Sprites and assets are scaled individually, rather than scaling the viewport. This has a couple of benefits:
Having said all that, I implemented a new BitmapSpriteComponent that always snaps to a pixel boundary. Just extend/use this instead of Sprite. The scale of the sprite itself is used as the pixel size (x and y can be scaled differently). This could be simplified if Canvas allowed to set or reset the transform directly, but it only allows multiplication, so the math is little more complicated (but not much) because of that. Has not been tested when sprite is rotated. /// bitmap_sprite.dart
import 'dart:ui';
import 'package:flame/components.dart';
class BitmapSpriteComponent extends SpriteComponent {
final Float64List _pixelSnapTransform = Float64List.fromList([
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0]);
@override void render(Canvas canvas) {
_pixelSnapTransform[12] = -(position.x / scale.x - (position.x / scale.x).floor());
_pixelSnapTransform[13] = -(position.y / scale.y - (position.y / scale.y).floor());
canvas.save();
canvas.transform(_pixelSnapTransform);
super.render(canvas);
canvas.restore();
}
} This is just a general dart question rather than flame, but would this be more performant if the Float64List was a private class property and persisted rather than created each time p.s. Thanks for the star :) |
Beta Was this translation helpful? Give feedback.
I can't write any snippets right now, but this might help you
If you use Flame's camera Api, and use the fixed viewport, you will be able to achieve that super easily, you can just define the resolution that you want and then design your sprites all without any scaling, flame will take care of scaling the viewport for you
Flame have two camera APIs, the current one and the experimental one
Current: https://docs.flame-engine.org/1.7.0/flame/camera_and_viewport.html#
Experimental: https://docs.flame-engine.org/1.7.0/flame/camera_component.html#viewport
Both will be able to do what you need, but the current one will eventually be deprecated in favor of the experimental one.