Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to Tile a background? #29

Closed
Panthro opened this issue Dec 31, 2018 · 5 comments
Closed

How to Tile a background? #29

Panthro opened this issue Dec 31, 2018 · 5 comments

Comments

@Panthro
Copy link
Contributor

Panthro commented Dec 31, 2018

Disclaimer: Flame is one of my first attempts at game development overall, just because I love flutter.

I know this isn't a issue and more a stackoverflow question, but being the case that the docs and the examples does not show how to do that you might want take the issue to add a documentation action.

I'm currently trying to implement a flappy bird with Flame, but it's being really hard to do basic stuff, mostly because of lack of documentation.

I already have the player jumping around, the HUD is working, but the way I currently have the background to move continuously feels hacky, and that is probably something a lot of people would like to have in 2D games, a tile background.

Currently I had to overlap 2 components of my background and when they hit the beginning of the screen x=0 I'm repositioning them to the end of the screen x=width.

Having to have 2 backgrounds seems odd, and doesn't feel natural on game development, same thing is happening to the ground where the bird can 'hit'.

Can we pleeeease have an example or documentation on how to tile an endless background?

Thanks.

@erickzanardo
Copy link
Member

I am not sure if I understand what is your problem, Flappy Bird's background is static if I recall correctly, but If you want to keep the background moving, the way you explained does not seems odd to me, I would actually do something similar.

I'm currently trying to implement a flappy bird with Flame, but it's being really hard to do basic stuff, mostly because of lack of documentation.

Could you list the parts of the documentation that you had problems with? We would sure try to improve it.

@luanpotter
Copy link
Member

It seems fine to me to use two sprites, you could use only one if you did the following: make it twice the width of the screen, repeated twice, render it as you are moving, when you get x = [half width of the sprite | full screen width] we are in the scenario where the bg is exactly repeated, at this point you can move x = -width to x = 0 again and nothing will change, then the bg will continue to loop. But using two sprites for the background seems really good to me, it makes sense. Doesn't mean you need to Flame Components though, you could make a single component that renders two sprites taking care of moving then appropriately .

If you want to see a more complex background, you can take a look at the Parallax Component, which actually renders several bgs and move them with parallax; might give you some ideas on how to implement other stuff to your background.

One example of the exact effect you are looking for, I believe, is in one of our example games, BGUG. See here the background component. I make sure it's at least twice the screen size, so (x, y) can range from (0,0) to (size.width, size.height) without a problem. Then I move x and y in a random direction after that I use the modulus operation to make sure it's rendered in the acceptable range. So it automatically loops if (x,y) gets too big or too small.

Thanks for using Flame and helping with PRs, if you have more questions or specific bits of documentation you'd like to see added or improved, please let us know! :)

@luanpotter
Copy link
Member

PS. note that in the end in BGUG example we ended up drawing 4 sprites instead of 2, because it can move in the y direction too. Just make sure your background is cyclic (can be connect in the desired directions start to end) and to be at least as big as the screen. It's a very good solution (even better than using larger images as I described in the first paragraph, actually, because you need smaller images).

@erickzanardo
Copy link
Member

Closing this in flavor of #31 , @Panthro if there is any more documentation or tutorials that you feel the need, please open another issue.

@gaddlord
Copy link

gaddlord commented Nov 5, 2023

Copilot reply: To draw a tile-based background in the Flame game engine, you can use the SpriteBatch class. Here's a step-by-step guide:

Load the tile image as a Sprite in the onLoad method.
Create a SpriteBatch and add the sprite to it in a loop to cover the entire screen.
Draw the SpriteBatch in the render method.
Here's how you can implement this:

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';

class SoloPlay extends FlameGame {
  late SpriteBatch _batch;

  @override
  Future<void> onLoad() async {
    final sprite = await loadSprite('tile.png');
    _batch = SpriteBatch(sprite.image);
    final Vector2 tileSize = Vector2.all(50); // adjust based on your tile size
    for (int x = 0; x < size.x; x += tileSize.x.toInt()) {
      for (int y = 0; y < size.y; y += tileSize.y.toInt()) {
        _batch.add(
          source: Rect.fromLTWH(0, 0, tileSize.x, tileSize.y),
          offset: Vector2(x.toDouble(), y.toDouble()),
        );
      }
    }
  }

  @override
  Color backgroundColor() => const Color.fromRGBO(128, 0, 0, 1);

  @override
  void render(Canvas canvas) {
    super.render(canvas);
    _batch.render(canvas);
  }

  @override
  void update(final double dt) {
    super.update(dt);
  }
}

In this code, replace 'tile.png' with the path to your tile image. The tileSize should be adjusted based on the size of your tile image. The SpriteBatch is created in the onLoad method and rendered in the render method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants