mirror of
				https://github.com/flame-engine/flame.git
				synced 2025-11-04 21:17:13 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			122 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
import 'dart:async';
 | 
						|
import 'dart:ui';
 | 
						|
 | 
						|
import 'package:flutter/src/painting/images.dart';
 | 
						|
 | 
						|
import '../flame.dart';
 | 
						|
import 'component.dart';
 | 
						|
 | 
						|
class ParallaxRenderer {
 | 
						|
  String filename;
 | 
						|
  Future future;
 | 
						|
 | 
						|
  Image image;
 | 
						|
  double scroll = 0.0;
 | 
						|
 | 
						|
  ParallaxRenderer(this.filename) {
 | 
						|
    this.future = _load();
 | 
						|
  }
 | 
						|
 | 
						|
  Future _load() {
 | 
						|
    return Flame.images.load(filename).then((image) {
 | 
						|
      this.image = image;
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  bool loaded() => image != null;
 | 
						|
 | 
						|
  void render(Canvas canvas, Rect rect) {
 | 
						|
    if (image == null) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    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: fullRect,
 | 
						|
        repeat: ImageRepeat.repeatX);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
class ParallaxComponent extends PositionComponent {
 | 
						|
  final BASE_SPEED = 30;
 | 
						|
  final LAYER_DELTA = 40;
 | 
						|
 | 
						|
  List<ParallaxRenderer> _layers = new List();
 | 
						|
  Size _size;
 | 
						|
  bool _loaded = false;
 | 
						|
 | 
						|
  ParallaxComponent(this._size);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Loads the images defined by this list of filenames. All images
 | 
						|
   * are positioned at its scroll center.
 | 
						|
   *
 | 
						|
   * @param filenames Image filenames
 | 
						|
   */
 | 
						|
  void load(List<String> filenames) {
 | 
						|
    var futures =
 | 
						|
        filenames.fold(new List<Future>(), (List<Future> result, filename) {
 | 
						|
      var layer = new ParallaxRenderer(filename);
 | 
						|
      _layers.add(layer);
 | 
						|
      result.add(layer.future);
 | 
						|
      return result;
 | 
						|
    });
 | 
						|
    Future.wait(futures).then((r) {
 | 
						|
      _loaded = true;
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  void updateScroll(int layerIndex, scroll) {
 | 
						|
    _layers[layerIndex].scroll = scroll;
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  bool loaded() {
 | 
						|
    return _loaded;
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  void render(Canvas canvas) {
 | 
						|
    if (!this.loaded()) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    canvas.save();
 | 
						|
    prepareCanvas(canvas);
 | 
						|
    _drawLayers(canvas);
 | 
						|
    canvas.restore();
 | 
						|
  }
 | 
						|
 | 
						|
  void _drawLayers(Canvas canvas) {
 | 
						|
    Rect rect = new Rect.fromPoints(
 | 
						|
        new Offset(0.0, 0.0), new Offset(_size.width, _size.height));
 | 
						|
    _layers.forEach((layer) {
 | 
						|
      layer.render(canvas, rect);
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  void update(double delta) {
 | 
						|
    if (!this.loaded()) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    for (var i = 0; i < _layers.length; i++) {
 | 
						|
      var scroll = _layers[i].scroll;
 | 
						|
      scroll += (BASE_SPEED + i * LAYER_DELTA) * delta / _size.width;
 | 
						|
      if (scroll > 1) {
 | 
						|
        scroll = scroll % 1;
 | 
						|
      }
 | 
						|
      _layers[i].scroll = scroll;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |