mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-02 20:13:50 +08:00
extract parallax renderer
This commit is contained in:
@ -54,52 +54,10 @@ abstract class Box2DComponent extends Component {
|
||||
|
||||
void initializeWorld();
|
||||
|
||||
/**
|
||||
* Follows the spececified body component using a sliding focus window
|
||||
* defined as a percentage of the total viewport.
|
||||
*
|
||||
* @param component to follow.
|
||||
* @param horizontal percentage of the horizontal viewport. Null means no horizontal following.
|
||||
* @param vertical percentage of the vertical viewport. Null means no vertical following.
|
||||
*/
|
||||
void cameraFollow(BodyComponent component,
|
||||
{double horizontal, double vertical}) {
|
||||
Vector2 position = component.center;
|
||||
|
||||
double x = viewport.center.x;
|
||||
double y = viewport.center.y;
|
||||
|
||||
if (horizontal != null) {
|
||||
Vector2 temp = new Vector2.zero();
|
||||
viewport.getWorldToScreen(position, temp);
|
||||
|
||||
var margin = horizontal / 2 * dimensions.width / 2;
|
||||
var focus = dimensions.width / 2 - temp.x;
|
||||
|
||||
if (focus.abs() > margin) {
|
||||
x = dimensions.width / 2 +
|
||||
(position.x * viewport.scale) +
|
||||
(focus > 0 ? margin : -margin);
|
||||
}
|
||||
}
|
||||
|
||||
if (vertical != null) {
|
||||
Vector2 temp = new Vector2.zero();
|
||||
viewport.getWorldToScreen(position, temp);
|
||||
|
||||
var margin = vertical / 2 * dimensions.height / 2;
|
||||
var focus = dimensions.height / 2 - temp.y;
|
||||
|
||||
if (focus.abs() > margin) {
|
||||
y = dimensions.height / 2 +
|
||||
(position.y * viewport.scale) +
|
||||
(focus < 0 ? margin : -margin);
|
||||
}
|
||||
}
|
||||
|
||||
if (x != viewport.center.x || y != viewport.center.y) {
|
||||
viewport.setCamera(x, y, viewport.scale);
|
||||
}
|
||||
viewport.cameraFollow(component,
|
||||
horizontal: horizontal, vertical: vertical);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:box2d/box2d.dart';
|
||||
import 'package:flame/box2d/box2d_component.dart';
|
||||
|
||||
class Viewport extends ViewportTransform {
|
||||
Size dimensions;
|
||||
@ -40,4 +41,53 @@ class Viewport extends ViewportTransform {
|
||||
double scroll = rest / width;
|
||||
return x > 0 ? scroll : 1 - scroll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Follows the spececified body component using a sliding focus window
|
||||
* defined as a percentage of the total viewport.
|
||||
*
|
||||
* @param component to follow.
|
||||
* @param horizontal percentage of the horizontal viewport. Null means no horizontal following.
|
||||
* @param vertical percentage of the vertical viewport. Null means no vertical following.
|
||||
*/
|
||||
void cameraFollow(BodyComponent component,
|
||||
{double horizontal, double vertical}) {
|
||||
Vector2 position = component.center;
|
||||
|
||||
double x = center.x;
|
||||
double y = center.y;
|
||||
|
||||
if (horizontal != null) {
|
||||
Vector2 temp = new Vector2.zero();
|
||||
getWorldToScreen(position, temp);
|
||||
|
||||
var margin = horizontal / 2 * dimensions.width / 2;
|
||||
var focus = dimensions.width / 2 - temp.x;
|
||||
|
||||
if (focus.abs() > margin) {
|
||||
x = dimensions.width / 2 +
|
||||
(position.x * scale) +
|
||||
(focus > 0 ? margin : -margin);
|
||||
}
|
||||
}
|
||||
|
||||
if (vertical != null) {
|
||||
Vector2 temp = new Vector2.zero();
|
||||
getWorldToScreen(position, temp);
|
||||
|
||||
var margin = vertical / 2 * dimensions.height / 2;
|
||||
var focus = dimensions.height / 2 - temp.y;
|
||||
|
||||
if (focus.abs() > margin) {
|
||||
y = dimensions.height / 2 +
|
||||
(position.y * scale) +
|
||||
(focus < 0 ? margin : -margin);
|
||||
}
|
||||
}
|
||||
|
||||
if (x != center.x || y != center.y) {
|
||||
setCamera(x, y, scale);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -84,29 +84,26 @@ class ParallaxRenderer {
|
||||
});
|
||||
}
|
||||
|
||||
void render(canvas, Rect rect) {
|
||||
bool get loaded => image != null;
|
||||
|
||||
void render(Canvas canvas, Rect rect) {
|
||||
if (image == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Rect leftRect = new Rect.fromLTWH(
|
||||
rect.left, rect.top, (1 - scroll) * rect.width, rect.height);
|
||||
Rect rightRect = new Rect.fromLTWH(
|
||||
(1 - scroll) * rect.width, rect.top, rect.width, rect.height);
|
||||
var imageHeight = image.height / window.devicePixelRatio;
|
||||
var imageWidth =
|
||||
(rect.height / imageHeight) * (image.width / window.devicePixelRatio);
|
||||
var count = rect.width / imageWidth;
|
||||
|
||||
Rect fullRect = new Rect.fromLTWH(
|
||||
-scroll * imageWidth, rect.top, (count + 1) * imageWidth, rect.height);
|
||||
|
||||
paintImage(
|
||||
canvas: canvas,
|
||||
image: image,
|
||||
rect: leftRect,
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.centerRight);
|
||||
|
||||
paintImage(
|
||||
canvas: canvas,
|
||||
image: image,
|
||||
rect: rightRect,
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.centerLeft);
|
||||
rect: fullRect,
|
||||
repeat: ImageRepeat.repeatX);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user