6 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 6 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 6 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 6 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
6 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 6 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
6 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 6 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 6 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()); }