Jump to content
  • Advertisement
Elit3d

[SFML & Tiled] Spawn items on each location

This topic is 422 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I am trying to get an item to spawn on specific locations. I am using a xml parser to get the objects name and location (solid walls, start point, end point and item spawn points). It will only spawn on the last location and totally avoids the first. Anyway here is my code that I have so far:

the problem:

d4d4240ce11b286553cb6f6618840709.png

 

The spawn locations i want to place on:
3ea4a993241e81a95356c661a0eba6b5.png

The code:

	for (int i = 0; i < obj.size(); i++)
	{
		if (obj[i].name == "item")
		{
			pickups->sprite.setPosition(obj[i].rect.left, obj[i].rect.top);
			pickupVector.push_back(pickups);
		}
	}

so I want to spawn it on the first one location, then push it onto the array, then spawn the next one and put on array and so on..

Edited by Elit3d

Share this post


Link to post
Share on other sites
Advertisement

"pickups" looks like a pointer to something. Inside the "if", you change a field in the pointed-to object, and push the pointer onto the "pickupVector". Since the "pickups" itself is not changed, you change the same field in the same object each time (erasing any previous value of "sprite.position"), and push the same pointer (all pointing to the same object) onto the vector each time.

 

Share this post


Link to post
Share on other sites
6 hours ago, Alberth said:

"pickups" looks like a pointer to something. Inside the "if", you change a field in the pointed-to object, and push the pointer onto the "pickupVector". Since the "pickups" itself is not changed, you change the same field in the same object each time (erasing any previous value of "sprite.position"), and push the same pointer (all pointing to the same object) onto the vector each time.

 

What is the best way to deal with this?

Share this post


Link to post
Share on other sites

I don't know, You didn't give any type / structure information, so I don't know what "pickups" is / contains, or what "sprite" contains. I guessed pickupVector purely based on its name, and the fact you use ".push_back", but also for that I have no type information.

Obviously, you need to display the same image at several places on the screen, which seems to suggest a "sprite" with a different position for each thing you need to display.

 

Share this post


Link to post
Share on other sites
1 hour ago, Elit3d said:

What is the best way to deal with this?

I'm not 100% sure on your system but I've programmed enough level editors in my time. Is the problem you're having that you want items to be placed in the array based on the same order of position clicks on the editor? Please let me know if I'm mistaken so I can provide a better answer.

If this is your only issue, all you need to do is program an event tracker for grid clicks before editing or changing a layer. When you click on any grid on your map record the position into a vector of sf::Vector2f so the order is kept. Then when you want to cycle through your loop you just use the position and remove it, then keep going.

The *32 is assuming your tiles are 32x32 it will give you the correct top left cord.

std::vector<sf::Vector2f> posTracker;
posTracker.push_back(sf::Vector2f(5 * 32, 2 * 32));
posTracker.push_back(sf::Vector2f(6 * 32, 4 * 32));
posTracker.push_back(sf::Vector2f(8 * 32, 6 * 32));

for (int i = 0; i < obj.size(); i++)
{
	if (obj[i].name == "item")
	{
		pickups->sprite.setPosition(posTracker[0].x, posTracker[0].y);
		posTracker.erase(posTracker.begin());
		pickupVector.push_back(pickups);
	}
}

You should also put something in your loop that when your positions are all used it exits the loop.

Share this post


Link to post
Share on other sites
4 minutes ago, Alberth said:

I don't know, You didn't give any type / structure information, so I don't know what "pickups" is / contains, or what "sprite" contains. I guessed pickupVector purely based on its name, and the fact you use ".push_back", but also for that I have no type information.

Obviously, you need to display the same image at several places on the screen, which seems to suggest a "sprite" with a different position for each thing you need to display.

 

Pickup::Pickup(std::string imgpath)
{
	texture.loadFromFile(imgpath);
	sprite.setTexture(texture);
}

its just a simple entity class really that lets me set the pickup sprite

entity class:

class Entity
{
public:
	sf::Sprite sprite;
	sf::Texture texture;
};

 

 

4 minutes ago, Rutin said:

I'm not 100% sure on your system but I've programmed enough level editors in my time. Is the problem you're having that you want items to be placed in the array based on the same order of position clicks on the editor? Please let me know if I'm mistaken so I can provide a better answer.

If this is your only issue, all you need to do is program an event tracker for grid clicks before editing or changing a layer. When you click on any grid on your map record the position into a vector of sf::Vector2f so the order is kept. Then when you want to cycle through your loop you just use the position and remove it, then keep going.

The *32 is assuming your tiles are 32x32 it will give you the correct top left cord.


std::vector<sf::Vector2f> posTracker;
posTracker.push_back(sf::Vector2f(5 * 32, 2 * 32));
posTracker.push_back(sf::Vector2f(6 * 32, 4 * 32));
posTracker.push_back(sf::Vector2f(8 * 32, 6 * 32));

for (int i = 0; i < obj.size(); i++)
{
	if (obj[i].name == "item")
	{
		pickups->sprite.setPosition(posTracker[0].x, posTracker[0].y);
		posTracker.erase(posTracker.begin());
		pickupVector.push_back(pickups);
	}
}

You should also put something in your loop that when your positions are all used it exits the loop.

basically, when the level loads, depending on how many "item" points there are on the parsed map, will spawn the correct amount of items (i know how to spawn the certain cap of items already) on each grid spot as shown, like Alberth said, its something to do with the sprite position updating to the last position passed to sprite.setPosition

Share this post


Link to post
Share on other sites

Sorry, I guess I read your question wrong.

The only thing I can think of is you're storing a pointer object into the container, so when you edit it the second time you're changing all the objects because you're not passing in copies. I might be wrong, but you really need to see what the debugger is showing you.

Why don't you just make new objects?

for (int i = 0; i < obj.size(); i++)
{
	if (obj[i].name == "item")
	{
		pickupVector.push_back(pickups(obj[i].rect.left, obj[i].rect.top));
	}
}

 

Edited by Rutin

Share this post


Link to post
Share on other sites
1 hour ago, Rutin said:

Sorry, I guess I read your question wrong.

The only thing I can think of is you're storing a pointer object into the container, so when you edit it the second time you're changing all the objects because you're not passing in copies. I might be wrong, but you really need to see what the debugger is showing you.

Why don't you just make new objects?


for (int i = 0; i < obj.size(); i++)
{
	if (obj[i].name == "item")
	{
		pickupVector.push_back(pickups(obj[i].rect.left, obj[i].rect.top));
	}
}

 

Ah great, many thanks! I can see my mistake now, I'm so stupid, I'm supposed to create a new instance of the object otherwise the position is going to be transferred to each pickup

this is now my code:

			pickups = new Pickup("images/icon-power.png", sf::Vector2f(obj[i].rect.left, obj[i].rect.top));

			if (bSpawnNoMore == false)
				pickupVector.push_back(pickups);

 

Share this post


Link to post
Share on other sites
Just now, Rutin said:

Great.

Glad you're up and running now!

I really appreciate the help, great community here :)

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!