flame-engine / flame

A Flutter based game engine.
https://flame-engine.org
MIT License
9.29k stars 913 forks source link

rotate effect not working in a simple game #431

Closed LiquidatorCoder closed 4 years ago

LiquidatorCoder commented 4 years ago

I am new to Flame and I was following the official documentation to make an endless game in it.

I hope the game is clear from this image.

Now I have two dart files. First is box.dart which is the main player component.

import 'dart:ui';
import 'package:flame/components/component.dart';
import 'package:flame/components/mixins/resizable.dart';
import 'package:flame/effects/effects.dart';
import 'package:flutter/animation.dart';

class Box extends PositionComponent with Resizable {
  double speedY = 0.0;
  Rect boxRect;
  Paint boxPaint = Paint()..color = Color(0xffdf5e88);

  void reset() {
    this.x = size.width / 2 - size.width / 9 / 2;
    this.y = size.height - size.height / 9 / 2 - 200;
    this.speedY = 0.0;
  }

  void render(Canvas c) {
    boxRect = Rect.fromLTWH(this.x, this.y, size.width / 9, size.width / 9);
    c.drawRect(boxRect, boxPaint);
  }

  void resize(Size size) {
    super.resize(size);
    reset();
  }

  void spin() {
    print("spinning");
    this.addEffect(
      RotateEffect(
        radians: double.maxFinite,
        speed: 250,
        isInfinite: true,
        curve: Curves.easeIn,
      ),
    );
  }

  void update(double t) {
    super.update(t);
  }
}

As you can see I have added a spin method which I want to use when I will drag the player.

Now in game.dart file -

import 'dart:math';
import 'dart:ui';
import 'package:boxdash/components/bg.dart';
import 'package:boxdash/components/box.dart';
import 'package:boxdash/components/level.dart';
import 'package:boxdash/components/lives.dart';
import 'package:boxdash/components/obstacle.dart';
import 'package:boxdash/components/score.dart';
import 'package:boxdash/main.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/gestures.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class BoxGame extends BaseGame with HorizontalDragDetector {
  int lives;
  Score score;
  Level level;
  Lives livesDisplay;
  BuildContext context;
  int counter = 0;
  var speed = 200.0;
  double multiplier = 1.0;
  double obsMultiplier = 1;
  double speedMultiplier = 1;
  Box box;
  List<Obstacle> obs;
  BoxGame(Size size, context) {
    this.context = context;
    lives = 3;
    add(Bg());
    add(box = Box());
    obs = List<Obstacle>();
    score = Score(this);
    level = Level(this);
    livesDisplay = Lives(this);
  }

  @override
  void update(double t) {
    // spawning obstacles
    if (box != null) box.update(t);
    if (size != null && counter % ((40 / obsMultiplier) + 10).round() == 0) {
      var r = Random.secure();
      var position = r.nextInt(3);
      var delta = r.nextDouble() * 50;
      switch (position) {
        case 0:
          // first obstacle
          obs.add(Obstacle(0 + delta, speed + speedMultiplier));
          add(obs.last);
          break;
        case 1:
          // second obstacle
          obs.add(Obstacle(size.width / 3 + delta, speed + speedMultiplier));
          add(obs.last);
          break;
        case 2:
          // third obstacle
          obs.add(
              Obstacle(size.width * 2 / 3 + delta, speed + speedMultiplier));
          add(obs.last);
          break;
      }
    }
    // update obstacle
    if (obs.length != 0) {
      obs.forEach((element) {
        element.update(t);
      });
    }
    obs.forEach((element) {
      if (lives != null) if (lives == 0) {
        // game over
        Flame.bgm.stop();
        this.pauseEngine();
        Navigator.pop(context);
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) {
              return Scaffold(
                body: Container(
                  child: Home(score: (counter * obsMultiplier / 10).round()),
                ),
              );
            },
          ),
        );
      }
      // detecting collisions
      if (box.x >= element.x - size.width / 9 &&
          box.x <= element.x + size.width * 1 / 3) {
        if (box.y <= element.y + size.width / 18 &&
            box.y + size.width / 9 >= element.y) {
          element.crash();
          HapticFeedback.vibrate();
          Flame.audio.play('crash.wav', volume: 0.5);
          if (lives != null) lives--;
        }
      }
    });
// score counter
    counter++;
    if (counter % 1000 == 0) {
      obsMultiplier++;
      // level up
      Flame.audio.play('levelup.wav', volume: 0.5);
    }
    if (counter % 10 == 0) {
      // increasing game speed
      speedMultiplier = speedMultiplier + 2;
    }
    if (score != null) score.update(t);
    if (level != null) level.update(t);
    if (livesDisplay != null) livesDisplay.update(t);
  }

  @override
  void render(Canvas c) {
    super.render(c);
    score.render(c);
    level.render(c);
    livesDisplay.render(c);
  }

  @override
  void onHorizontalDragCancel() {
    box.clearEffects();
  }

  @override
  void onHorizontalDragStart(DragStartDetails d) {
    box.spin();
  }

  @override
  void onHorizontalDragUpdate(DragUpdateDetails d) {
    // controlling player
    box.x += d.delta.dx * multiplier;
    if (box.x > size.width - size.width / 9) {
      box.x = size.width - size.width / 9;
    } else if (box.x < 0) {
      box.x = 0;
    }
    if (box.x > size.width * 2 / 3) {
      multiplier = 3.0;
    } else if (box.x < size.width / 3) {
      multiplier = 3.0;
    } else {
      multiplier = 1.0;
    }
  }
}

I have added a calling statement to box.spin in onHorizontalDragStart method. But whenever I run the game the rotate effect is not working. Am I missing something?

erickzanardo commented 4 years ago

It seems that you are using BaseGame and overriding the update method. When using BaseGame, that is not advisable, as the BaseGame is responsible to handle your components lifecycle, which includes calling the update from the components, and a bunch of additional stuff.

So, long story short, you need to make sure that your update method calls the super.update.

luanpotter commented 4 years ago

Underlying misconception was addressed by #437