forloRn_
Legacy Member
Gegroet,
Ben een platformspel aan het maken.
De zichtbare voorwerpen in het spel (speler, vijand, blokje, projectiel, ...) behoren tot de superklasse Entity.
AvatarOne is de voorstelling van speler 1 in het spel (bevat concrete sprites en bewegingen). Zij is via Creature en Avatar een subklasse van Entity.
De hiërarchie gaat dus als volgt:
Entity <- Creature <- Avatar <- AvatarOne
De methode update() in Entity.h heb ik zo gedeclareerd:
Zij bevat een default implementatie in Entity.cpp:
De bedoeling is dat AvatarOne deze methode override. Declaratie in AvatarOne.h:
Implementatie in AvatarOne.cpp:
Ze roept dus Entity::update() aan, en voegt zelf nog wat code toe omtrent de animatie. Vreemd genoeg wordt nooit AvatarOne::update() aangeroepen, maar Entity::update(). Ik dacht dat virtual er voor zorgde dat er dynamic dispatching (of dynamic binding, zo u wil) toegepast werd?
De plaats waar update() aangeroepen wordt is in de klasse Level, die een lijst bijhoudt van al de Entities in dat Level:
Declaratie van entities in Level.h:
En zo voeg ik tenslotte Entities toe aan het level:
en elders:
Conclusie: ik krijg mijn ventje op het scherm, maar het is niet geanimeerd, omdat het Entity::update() aanroept in plaats van AvatarOne::update().
Waarom?
Ben een platformspel aan het maken.
De zichtbare voorwerpen in het spel (speler, vijand, blokje, projectiel, ...) behoren tot de superklasse Entity.
AvatarOne is de voorstelling van speler 1 in het spel (bevat concrete sprites en bewegingen). Zij is via Creature en Avatar een subklasse van Entity.
De hiërarchie gaat dus als volgt:
Entity <- Creature <- Avatar <- AvatarOne
De methode update() in Entity.h heb ik zo gedeclareerd:
Code:
virtual void update(int delta);
Zij bevat een default implementatie in Entity.cpp:
Code:
void Entity::update(int delta) {
position += velocity * delta / 1000;
}
De bedoeling is dat AvatarOne deze methode override. Declaratie in AvatarOne.h:
Code:
void update(int delta);
Implementatie in AvatarOne.cpp:
Code:
void AvatarOne::update(int delta) {
std::cout << "In update() van AvatarOne!" << std::endl;
Entity::update(delta);
time_elapsed += t.elapsed();
if(time_elapsed > 1000) {
advanceFrame();
time_elapsed = 0;
t.start();
}
}
Ze roept dus Entity::update() aan, en voegt zelf nog wat code toe omtrent de animatie. Vreemd genoeg wordt nooit AvatarOne::update() aangeroepen, maar Entity::update(). Ik dacht dat virtual er voor zorgde dat er dynamic dispatching (of dynamic binding, zo u wil) toegepast werd?
De plaats waar update() aangeroepen wordt is in de klasse Level, die een lijst bijhoudt van al de Entities in dat Level:
Code:
void Level::update(int delta, QPainter &painter) {
/* Het updaten en tekenen wordt naar de entities zelf gedelegatet */
for(unsigned int i = 0; i < entities.size(); i++) {
entities[i]->update(delta);
entities[i]->paint(painter, 0, 0);
}
}
Declaratie van entities in Level.h:
Code:
vector<Entity *> entities;
En zo voeg ik tenslotte Entities toe aan het level:
Code:
void Level::addEntity(Entity *e) {
entities.push_back(e);
}
en elders:
Code:
AvatarOne *av = new AvatarOne(player);
addEntity(av);
Conclusie: ik krijg mijn ventje op het scherm, maar het is niet geanimeerd, omdat het Entity::update() aanroept in plaats van AvatarOne::update().
Waarom?
.