Trying to find an object in a map, and set a member class pointer variable.
# Animations.h
#ifndef _ANIMATIONS_H
#define _ANIMATIONS_H
#include <map>
#include "Animation.h"
using namespace std;
class Animations {
public:
Animations();
void add(Animation* animation, string name);
void play(string name);
Animation* animation;
map<string, Animation*> animations;
};
#endif
# Animations.cpp
...
void Animations::play(string name) {
std::map<string, Animation*>::iterator itr = animations.find(name);
if (itr != animations.end()) {
animation = itr->second;
}
}
I've seen lots of examples with itr->second
in couts
and printing, which I've tested, works fine. However I need to convert it to an Animation *
somehow, but don't know how. When I use the variable from above, it compiles, but the data is all messed up (frame
should be 0
and instead is some huge int) so probably wrong memory address. I did verify the frame
of the original Animation
object is 0
, and a pointer to it is 0
too before adding it to the map.
The closest I've come is this &(*itr);
via https://stackoverflow.com/a/2160319/1183537 and what I'm doing is close to c Find map value and key although I want to assign the variable, not just print it out, which are the examples I usually find on map#find
like https://cplusplus.com/reference/map/map/find/ and https://www.guru99.com/cpp-map-stl.html
Can anyone lend some help?
I'm newish to C , and rusty on C, but programming for 10 years, so I should be able to handle this.
edit: here's how i'm adding animations:
# Animations.cpp
void Animations::add(Animation* animation, string name) {
animations[name] = animation;
cout << "> Animations::add " << name << " frame: " << animation->frame << endl;
}
and here's how I'm testing the set animation
pointer:
# Animations.cpp
void Animations::update() {
cout << "> Animations::update" << endl;
if (animation != NULL) {
cout << "> Animations::update animation frame: " << animation->frame << " " << animation->width << "x" << animation->height << endl;
animation->update();
}
cout << "> Animations::update done" << endl;
}
here's where I was creating the Animation
s and calling animations.add
:
# Player.cpp
...
void Player::initAnimations(ALLEGRO_BITMAP* sheet) {
Animation spark(FPS, true, true);
Animation explosion(FPS / 3, true, true);
spark.add(sheet, 34, 0, 10, 8);
spark.add(sheet, 45, 0, 7, 8);
spark.add(sheet, 54, 0, 9, 8);
animations.add(&spark, "spark");
animations.play("spark");
}
I've tried not using pointers, from the comment suggestions. But I'm getting error error: no matching constructor for initialization of 'Animation'
around the place where I do
animation = itr->second;
not sure if it needs to be itr.second
instead, I think I tried both.
CodePudding user response:
I switched to non pointers in the map
# Animations.h
map<string, Animation> animations;
Animation* animation;
while leaving the animation
a pointer. Then thanks to @EtiennedMartel's comment I used &itr->second
to set the Animation* animation
pointer. The other thing I needed to do was to add a default Animation()
constructor, which I originally didn't have, which was needed from the map/iterator.
# Animations.cpp
void Animations::play(string name) {
std::map<string, Animation>::iterator itr = animations.find(name);
if (itr != animations.end())
animation = &itr->second;
}