CPU Memory? im not sure what the problem is :)

Hello guys, im building a game in sfml.
in the loadLevel class i create 20-40 objects and push them into vector.
use them in vector to group them and i create all those objects cause i need to know if the object got hit by the player and more functions.
now when i load the game (when loadLevel class constructor runs the game "stuck" for the amount of time it takes the computer to create all these objects and push them into the vector after all objects has been created the game runs fine, each time the player levels up the loadLevel class recreate it self with same amount of objects with "level2" settings and the same happens it stuck until the computer finish creating the objects.

how do i fix it or how do i minimize the time it takes to load the level.

loadLevel class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include "loadLevel.h"

loadLevel::loadLevel(int level) {


	int tempX = 120 , tempY = 120, type = 1, strenth = 0;

	if (level == 1) {
		for (int y = 0; y < 5; y++) { // line number (Y)
			for (int i = 0; i < 8; i++) { // place in the line (X)
				this->_bricks[y].push_back(new Brick(type, strenth)); // creating brick object and push it into the vector _bricks
				this->_bricks[y][i]->setPosition(tempX, tempY); // setting bricks positions.
				tempX += 170 * 0.5;
			}
			type++;
			tempX = 120;
			tempY += 60 * 0.5;
		}
	}
	else if (level == 2) {
		strenth = 1;
		type = 10;
		for (int y = 0; y < 5; y++) {
			for (int i = 0; i < 8; i++) {
				this->_bricks[y].push_back(new Brick(type, strenth));
				this->_bricks[y][i]->setPosition(tempX, tempY);
				tempX += 170 * 0.5;
			}
			if (y > 2) {
				strenth = 0;
			}
			type--;
			tempX = 120;
			tempY += 60 * 0.5;
		}
	}

}

bool loadLevel::ballHits(ball * _ball) {

	for (int y = 0; y < 5; y++) {
		for (int i = 0; i < _bricks[y].size(); i++) {
			if (this->_bricks[y][i]->getGlobal().intersects(_ball->getHitBox())) { // if ball hits
				if(this->_bricks[y][i]->gotHit(_ball->getStrength())){ // make dmg and check if brick destroyed.
					delete _bricks[y][i];
					this->_bricks[y].erase(std::remove(this->_bricks[y].begin(), this->_bricks[y].end(), this->_bricks[y][i]), this->_bricks[y].end());
				}
				_ball->isCollidedBrick(true); //  tell ball that he has collided a brick and change his direction
				return true;
			}
		}
	}
	
	return false;
}

bool loadLevel::levelEnd() {

	int count = 0;
	for (int y = 0; y < 5; y++) {
		if (this->_bricks[y].empty()) // check if vector is empty.
			count++;
	}
	if (count == 5) {
		return true;
	}

	return false;
}

void loadLevel::draw(RenderWindow& window) {
	
	for (int y = 0; y < 5; y++) {
		for (int x = 0; x < _bricks[y].size(); x++) {
			this->_bricks[y][x]->draw(window); // draw bricks objects from vector.
		}

	}
}
Obvious inefficiencies in here are the manual memory management (why are they vectors of pointers-to-brick? Why not just vector of brick?), and that when a brick in a vector reaches a "destroyed" state you do a whole lot of moving things in memory as you erase pieces from inside vectors, and also a whole lot of calls to delete.

What happens if you don't use manual memory management - just use vectors of bricks - and if you don't actually remove them from the vector (you could give them a state, active/inactive, for example).

This is just guessing, though, You should measure and know for sure what's taking all the time before you try to make things faster.
Last edited on
if i wont use pointer of brick i could not access his voids like setPosition, or check if something collided the brick and all of brick functions
if i wont use pointer of brick i could not access his voids like setPosition


That makes no sense. You don't need a pointer to a brick to use the brick's functions.

Here, you are using a pointer-to-brick:
bricks[y][i]->setPosition(tempX, tempY);

But if the object in the array wasn't a pointer, was just a brick, you would write this code:
bricks[y][i].setPosition(tempX, tempY);

You do not need a pointer-to-brick to use brick's functions.

Here's a simple example:

1
2
3
4
5
6
7
8
class animal
{
  public:
  void bark() {cout << "Bark!";}
};

animal bob;
bob.bark(); // HERE - call the function WITHOUT a pointer-to-animal 


Last edited on
Okay i am foolish for saying that idk why i did i know u can access class functions with no ptr reference really stupid me.
i did changed the brick* vector to normal Brick class reference and still got 0 changes in the time that program loads the objects
any suggestions?
What does the Brick constructor do? I don't see anything particularly costly in the code you've posted.
Brick constructor does check which brick you want to create and how much durability you give her and by the type of the brick you choose it set her textureRect from the big picture that all bricks are in.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Brick::Brick(int type, int durability) {

	this->_durability = durability;
	this->_type = type;

	this->brickTile.loadFromFile(BRICK_TILE_PATH);
	this->_brick.setTexture(this->brickTile);
	std::cout << _durability;
	
	switch (type)
	{
	case 1:
		this->_brick.setTextureRect(IntRect(tempX, tempY + distanceY * 0, 170, 58));
		break;
	case 2:
		this->_brick.setTextureRect(IntRect(tempX, tempY + distanceY * 1, 170, 58));
		break;
	case 3:
		this->_brick.setTextureRect(IntRect(tempX, tempY + distanceY * 2, 170, 58));
		break;
	case 4:
		this->_brick.setTextureRect(IntRect(tempX, tempY + distanceY * 3, 170, 58));
		break;
	case 5:
		this->_brick.setTextureRect(IntRect(tempX, tempY + distanceY * 4, 170, 58));
		break;
	case 6:
		this->_brick.setTextureRect(IntRect(tempX, tempY + distanceY * 5, 170, 58));
		break;
	case 7:
		this->_brick.setTextureRect(IntRect(tempX, tempY + distanceY * 6, 170, 58));
		break;
	case 8:
		this->_brick.setTextureRect(IntRect(tempX, tempY + distanceY * 7, 170, 58));
		break;
	case 9:
		this->_brick.setTextureRect(IntRect(tempX, tempY + distanceY * 8, 170, 58));
		break;
	case 10:
		this->_brick.setTextureRect(IntRect(tempX, tempY + distanceY * 9, 170, 58));
		break;
	}

	this->_brick.setScale(0.5f, 0.5f);
}
Is BRICK_TILE_PATH a constant string? If it is then you don't need to load the texture from the disk over and over again for every brick you want to create. Read the file once and create a single texture object, and set all your bricks to that texture.
this->brickTile.loadFromFile(BRICK_TILE_PATH);

Every brick is individually loading from a file?

As Helios says, that is going to be VERY expensive. So, so expensive. Reading from file is VERY expensive. Every brick object constructor individually reading from file will be outrageously expensive. Is that function opening the file, reading from it, and closing the file? So, so expensive.
Also, it looks like you can replace the switch statement with a bit of math:
this->_brick.setTextureRect(IntRect(tempX, tempY + distanceY * (type-1), 170, 58));
This assumes that type is between 1 and 10, inclusive.
Topic archived. No new replies allowed.