7 years ago
Bonjour,
J'ai un soucis avec mon code et en particulier avec les images.
Quand j'écris le code suivant pas de soucis :
const uint16_t wallData[] = {
8,8,1, 0, 0, 0,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0xacd0,0xacd0,0xacd0,0x5268,0x5268,0xacd0,0xacd0,0xacd0,
0xacd0,0xacd0,0xacd0,0x5268,0x5268,0xacd0,0xacd0,0xacd0,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0x5268,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0x5268,
0x5268,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0x5268,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268
};
Image wallI = Image(wallData);
for(uint16_t i=0 ; i<10 ; i++) {
gb.display.drawImage(i*8, 0, wallI);
}
En revanche quand j'essaye de découper mon code en plusieurs fichiers comme dans l'exemple suivant j'ai une erreur qui est :
no matching function for call to 'Gamebuino_Meta::Image::drawImage(int, int, Gamebuino_Meta::Image)'
SpritesManager.h
#ifndef SPRITESMANAGER
#define SPRITESMANAGER
#include <Gamebuino-Meta.h>
class SpritesManager {
private:
static Image wall;
static bool wallInitialized;
public:
static Image getWall();
};
#endif
SpritesManager.cpp
#include "SpritesManager.h"
bool SpritesManager::wallInitialized = false;
// Récupérer l'image du mur
Image SpritesManager::getWall() {
if(! SpritesManager::wallInitialized) {
const uint16_t wallData[] = {
8,8,1, 0, 0, 0,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0xacd0,0xacd0,0xacd0,0x5268,0x5268,0xacd0,0xacd0,0xacd0,
0xacd0,0xacd0,0xacd0,0x5268,0x5268,0xacd0,0xacd0,0xacd0,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0x5268,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0x5268,
0x5268,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0x5268,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268
};
SpritesManager::wall = Image(wallData);
SpritesManager::wallInitialized = true;
}
return SpritesManager::wall;
}
Lorsque j'écris le code suivant j'obtiens l'erreur décrite plus haut (évidement j'ai bien inclus SpritesManager.h).
for(uint16_t i=0 ; i<10 ; i++) {
gb.display.drawImage(i*8, 0, SpritesManager::getWall());
}
Ce que je cherche à effectuer c'est d'instancier qu'une seule fois l'image car elle ne change pas, es-ce possible ?
NEW 7 years ago
J'ai essayé avec une allocation dynamique soit le code suivant :
SpritesManager.h
#ifndef SPRITESMANAGER
#define SPRITESMANAGER
#include <Gamebuino-Meta.h>
class SpritesManager {
private:
static Image* wall;
static bool wallInitialized;
public:
static Image getWall();
};
#endif
SpritesManager.cpp
#include "SpritesManager.h"
bool SpritesManager::wallInitialized = false;
// Récupérer l'image du mur
Image SpritesManager::getWall() {
if(! SpritesManager::wallInitialized) {
const uint16_t wallData[] = {
8,8,1, 0, 0, 0,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0xacd0,0xacd0,0xacd0,0x5268,0x5268,0xacd0,0xacd0,0xacd0,
0xacd0,0xacd0,0xacd0,0x5268,0x5268,0xacd0,0xacd0,0xacd0,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0x5268,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0x5268,
0x5268,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0x5268,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268
};
SpritesManager::wall = new Image(wallData);
SpritesManager::wallInitialized = true;
}
return *SpritesManager::wall;
}
Le reste du code ne change pas.
Mais l'erreur reste la même :
no matching function for call to 'Gamebuino_Meta::Image::drawImage(int, int, Gamebuino_Meta::Image)'
NEW 7 years ago
The problem is that drawImage takes a reference to an Image object, but when you call it like drawImage(SpritesManager::getWall()) you end up passing the Image by value instead. You need to assign what getWall returns to a variable first, so that there's something to reference when you call drawImage:
Image wall =SpritesManager::getWall();drawImage(i*8, 0, wall);
For a nicer fix, you could change SpritesManager::getWall (from your first post) to return a reference to the Image instead, then you'll be able to call drawImage(SpritesManager::getWall()) directly without the intermediary variable:
SpritesManager.h
public:
static Image& getWall();
SpritesManager.cpp
#include "SpritesManager.h"
Image SpritesManager::wall;
bool SpritesManager::wallInitialized = false;
// Récupérer l'image du mur
Image& SpritesManager::getWall() {
...
Note that for both fix options you also have to define SpritesManager::wall in the CPP file in order to be able to reference it.
NEW 7 years ago
Hello alxm,
I use your solution but my gamebuino draw an other image with differents pixels of my sprites.
Have you an idea ?
alxm
7 years ago
When you create an image like SpritesManager::wall = Image(wallData), the library expects the wallData buffer to exist in Flash memory instead of RAM. However, the way you declare wallData places it in RAM, which causes corruption and eventually a crash when the Image object is destroyed.
You need to add the static keyword to place the data buffer in Flash:
if(! SpritesManager::wallInitialized) {
static const uint16_t wallData[] = {
I can confirm that your test program works on a real Gamebuino after these two fixes, hope this helps.
NEW 7 years ago
When you create an image like SpritesManager::wall = Image(wallData), the library expects the wallData buffer to exist in Flash memory instead of RAM. However, the way you declare wallData places it in RAM, which causes corruption and eventually a crash when the Image object is destroyed.
You need to add the static keyword to place the data buffer in Flash:
if(! SpritesManager::wallInitialized) {
static const uint16_t wallData[] = {
I can confirm that your test program works on a real Gamebuino after these two fixes, hope this helps.
chris-scientist
7 years ago
Thanks for all alxm !
It's a problem of memory.
The complete solution is :
SpritesManager.h
#ifndef SPRITESMANAGER
#define SPRITESMANAGER
#include <Gamebuino-Meta.h>
class SpritesManager {
private:
static bool wallInitialized;
static Image wall;
public:
static Image& getWall();
};
#endif
SpritesManager.cpp
#include "SpritesManager.h"
bool SpritesManager::wallInitialized = false;
Image SpritesManager::wall;
// Récupérer l'image du mur
Image& SpritesManager::getWall() {
if(! SpritesManager::wallInitialized) {
static const uint16_t wallData[] = {
8, 8, 1, 0, 0, 0,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0xacd0,0xacd0,0xacd0,0x5268,0x5268,0xacd0,0xacd0,0xacd0,
0xacd0,0xacd0,0xacd0,0x5268,0x5268,0xacd0,0xacd0,0xacd0,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0x5268,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0x5268,
0x5268,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0x5268,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268
};
SpritesManager::wall = Image(wallData);
SpritesManager::wallInitialized = true;
}
return SpritesManager::wall;
}
Code principale
for(uint16_t i=0 ; i<10 ; i++) {
gb.display.drawImage(i*8, 0, SpritesManager::getWall());
}
NEW 7 years ago
Whoua alxm, you have good level ;) I don't yet understand all but i see that you do. Thanks for your support
NEW 7 years ago
Thanks for all alxm !
It's a problem of memory.
The complete solution is :
SpritesManager.h
#ifndef SPRITESMANAGER
#define SPRITESMANAGER
#include <Gamebuino-Meta.h>
class SpritesManager {
private:
static bool wallInitialized;
static Image wall;
public:
static Image& getWall();
};
#endif
SpritesManager.cpp
#include "SpritesManager.h"
bool SpritesManager::wallInitialized = false;
Image SpritesManager::wall;
// Récupérer l'image du mur
Image& SpritesManager::getWall() {
if(! SpritesManager::wallInitialized) {
static const uint16_t wallData[] = {
8, 8, 1, 0, 0, 0,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0xacd0,0xacd0,0xacd0,0x5268,0x5268,0xacd0,0xacd0,0xacd0,
0xacd0,0xacd0,0xacd0,0x5268,0x5268,0xacd0,0xacd0,0xacd0,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,
0x5268,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0x5268,
0x5268,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0xacd0,0x5268,
0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268,0x5268
};
SpritesManager::wall = Image(wallData);
SpritesManager::wallInitialized = true;
}
return SpritesManager::wall;
}
Code principale
for(uint16_t i=0 ; i<10 ; i++) {
gb.display.drawImage(i*8, 0, SpritesManager::getWall());
}