Scrolling background in Flutter Flame - flutter

I have a list of sprite components in my game that represent three background sprite images which I would like to scroll infinitely. I initialize, update, and render the sprite components using the code below, however the sprites all move at different speeds and the game can slow down immensely at times, what is it that I am doing wrong?
Initializing:
List<SpriteComponent> bkgList = [];
bkgImage = await images.load('BGFull.png');
for (int i = 0; i < MAX_BKG_COUNT; i++) {
final spr = Sprite(bkgImage);
bkgList.add(SpriteComponent(
sprite: spr,
position: Vector2(640.0 * i, 0),
size: Vector2(640, 384)
));
}
Update:
for (int j = 0; j < bkgList.length; j++) {
bkgList[j].position.x -= 1.0;
if (bkgList[j].position.x < -640.0) {
bkgList.removeAt(0);
bkgList.add(SpriteComponent(
sprite: Sprite(bkgImage),
position: Vector2(bkgList.last.position.x + 640.0, 0),
size: Vector2(640, 384)
));
}
}
Render:
for (int z = 0; z < bkgList.length; z++) {
bkgList[z].render(canvas);
}

What you want to do for this is most likely to use the ParallaxComponent which you can find docs for here. For loading the spritesheet that you have in BGFull.png you can use the SpriteSheet class, and then pass in the images from there to the ParallaxComponent.
But from the code you have right now, the problem could be that you are not doing the initialization in the onLoad method, but I can't tell from your snippets.

Related

Why does the scale value of the object change?

I'm trying to learn the Unity game engine. I'm trying to develop a mechanic. Objects are created from the object pool in a fixed location. However, when I make them child object of a different object and finish the process and deactivate them, the scale values ​​of the reconstructed objects change. Why is this happening?
private IEnumerator Create_Green_Pizzas(List<Transform> pizzas)
{
int pizzaCount = 0;
while (pizzaCount < pizzas.Count)
{
currentColumn++;
if (currentColumn >= columnCount)
{
currentRow++;
currentColumn = 0;
}
if (currentRow >= rowCount)
{
pizzaLevel++;
currentRow = 0;
currentColumn = 0;
}
for (int i = 0; i < pizzas.Count; i++)
{
if (!pizzas[i].gameObject.activeInHierarchy)
{
pizzas[i].gameObject.SetActive(true);
pizzas[i].parent = pizzasParent;
pizzas[i].rotation = transform.rotation;
pizzas[i].position = initialSlotPosition + new Vector3(((pizzas[i].lossyScale.x) * currentColumn), (pizzaLevel * pizzas[i].lossyScale.y), ((-pizzas[i].lossyScale.z) * currentRow));
pizzas[i].GetComponent<MeshRenderer>().material.color = Color.green;
_player.collectableGreenPizzas.Add(pizzas[i]);
pizzaCount++;
yield return new WaitForSeconds(0.5f);
break;
}
}
}
}
Setting gameobject's the parent might be the cause, so instead of:
pizzas[i].parent = pizzasParent;
try instead:
pizzas[i].SetParent(pizzasParent, true);
You can find more info about this method Here
If a GameObject has a parent, they become part of the parent's referential, their transform is now a local transform that depends on the parent's transform.
This means that if a child transform has a scale of (1, 1, 1), has the same scale as its parent.
Here's a small clip that illustrates this, two sphere that are the same size while they both have a different scale.
However you can force the GameObject to preserve its coordinates and scale using this line :
child.SetParent(parent, true);

How to align tile game objects in a grid

How do I align tile game objects to my tilemap grid? I've the following settings:
tileSprite:
pixels per unit: 32
Grid (created tilemap gameobject):
Grid component:
cell size: 32, 32, 0
GridController script component:
tileSprite
In the GridController script:
public class GridController : MonoBehaviour {
public Sprite tileSprite;
// Use this for initialization
void Start () {
for (int x=0; x<5; x++) {
for (int y=0; y<5; y++) {
GameObject tile = new GameObject();
tile.transform.localPosition = new Vector3(x, y, 0);
tile.transform.localScale += new Vector3(32, 32, 1);
SpriteRenderer tile_sr = tile.AddComponent<SpriteRenderer>();
tile_sr.sprite = tileSprite;
}
}
}
}
I would like it to be placed side by side but it seems like they are only 1 pixel apart. Ie. I would like 1 unit to be equals to 32 pixels.
How do I do this? Thank you so much for your help!
I'm using Unity 2017.3.1f1.
Just by looking at your code:
tile.transform.localPosition = new Vector3(x, y, 0);
You used the loop's variables directly,
but you need to calculate the place where the tile is placed.
e.g.(might not be fully correct):
tile.transform.localPosition = new Vector3(x*32, y*32, 0);

Sprite Grid Positioning issue cocosd-js 3.16

I am making a 2d(25x20) grid of sprites. But somehow sprites are getting re positioned by itself.enter image description here
makeLandBlocksMatrix : function () {
this.LAND_BLOCK_TAG = 1;
var blockCounter = 0;
var prices = MMMapData.getPrices();
this._blocks = MMUtility.createArray(MMConstants.totalNoRowsPerMap,MMConstants.totalNoColsPerMap);
for (var i = 0; i< MMConstants.totalNoRowsPerMap; i++){
for (var j = 0; j< MMConstants.totalNoColsPerMap; j++){
var block = new MMLandBlockSprite();
block.initWithData(res.BlockBlack,prices[blockCounter],this.LAND_BLOCK_TAG);
block.setPosition(cc.p(block.getContentSize().width*0.5 + i * block.getContentSize().width * 1.0, (this._size.height - block.getContentSize().height*0.5) - j * block.getContentSize().height * 1.0));
this.addChild(block);
block.setBg();
block._bg.setOpacity(0.0);
block.setPriceLabel();
block._priceLabel.setOpacity(0.0);
this._blocks[i][j] = block;
this.LAND_BLOCK_TAG++;
blockCounter++;
}
}
}
And same code is working fine with cocos2d-x(c++).
Thanks.
After lots of tweaks and googling, i just used lower version of cocos2d-html(version 3.7). And same code work as expected.There might be problem in rendering pipeline in latest cocos2d-html. And same issue persist in case we try to make Grid of UI component or Basic components(Sprite,Label) as components number increases positioning difference increases(i.e as show in reference image).

Why comparing float values is such difficult?

I am newbie in Unity platform. I have 2D game that contains 10 boxes vertically following each other in chain. When a box goes off screen, I change its position to above of the box at the top. So the chain turns infinitely, like repeating Parallax Scrolling Background.
But I check if a box goes off screen by comparing its position with a specified float value. I am sharing my code below.
void Update () {
offSet = currentSquareLine.transform.position;
currentSquareLine.transform.position = new Vector2 (0f, -2f) + offSet;
Vector2 vectorOne = currentSquareLine.transform.position;
Vector2 vectorTwo = new Vector2 (0f, -54f);
if(vectorOne.y < vectorTwo.y) {
string name = currentSquareLine.name;
int squareLineNumber = int.Parse(name.Substring (11)) ;
if(squareLineNumber < 10) {
squareLineNumber++;
} else {
squareLineNumber = 1;
}
GameObject squareLineAbove = GameObject.Find ("Square_Line" + squareLineNumber);
offSet = (Vector2) squareLineAbove.transform.position + new Vector2(0f, 1.1f);
currentSquareLine.transform.position = offSet;
}
}
As you can see, when I compare vectorOne.y and vectorTwo.y, things get ugly. Some boxes lengthen and some boxes shorten the distance between each other even I give the exact vector values in the code above.
I've searched for a solution for a week, and tried lots of codes like Mathf.Approximate, Mathf.Round, but none of them managed to compare float values properly. If unity never compares float values in the way I expect, I think I need to change my way.
I am waiting for your godlike advices, thanks!
EDIT
Here is my screen. I have 10 box lines vertically goes downwards.
When Square_Line10 goes off screen. I update its position to above of Square_Line1, but the distance between them increases unexpectedly.
Okay, I found a solution that works like a charm.
I need to use an array and check them in two for loops. First one moves the boxes and second one check if a box went off screen like below
public GameObject[] box;
float boundary = -5.5f;
float boxDistance = 1.1f;
float speed = -0.1f;
// Update is called once per frame
void Update () {
for (int i = 0; i < box.Length; i++) {
box[i].transform.position = box[i].transform.position + new Vector3(0, speed, 0);
}
for (int i = 0; i < box.Length; i++)
{
if(box[i].transform.position.y < boundary)
{
int topIndex = (i+1) % box.Length;
box[i].transform.position = new Vector3(box[i].transform.position.x, box[topIndex].transform.position.y + boxDistance, box[i].transform.position.z);
break;
}
}
}
I attached it to MainCamera.
Try this solution:
bool IsApproximately(float a, float b, float tolerance = 0.01f) {
return Mathf.Abs(a - b) < tolerance;
}
The reason being that the tolerances in the internal compare aren't good to use. Change the tolerance value in a function call to be lower if you need more precision.

Chipmunk Physics: cpSpaceShapeQuery

How does the cpSpaceShapeQuery function work? I can not find any doc about it.
Andrea
Yeah... I never got around to documenting that... Sorry. Basically you create a body and shape (neither needs to be added to the space) and use that to query much like the other query functions.
This code snippet makes a copy of a body and shape on the stack and then simulates it out to it's first predicted collision point drawing the path as it goes.
cpBody body = *(originalBody);
cpPolyShape shape = *((cpPolyShape *)originalShape);
shape.shape.body = &body;
cpFloat dt = 1.0f/60.0f;
cpVect gravity = space->gravity;
int count = 0;
for(int i=0; i<300; i++){
cpBodyUpdatePosition(&body, dt);
cpBodyUpdateVelocity(&body, gravity, 1.0f, dt);
if(cpSpaceShapeQuery(space, (cpShape *)&shape, NULL, NULL)){
quads[count%maxQuads] = quad(body.p, body.rot, CGRectMake(0, 2*32, 64, 64), tsize);
count++;
break;
}
if(i%10==0){
quads[count%maxQuads] = quad(body.p, body.rot, rect, tsize);
count++;
}
}