PDA

View Full Version : Need a better way to move or remove images in a Scene.



vitaR
15th April 2014, 19:02
Hi, I just want to improve some efficiency in my code, or a better way to move and remove images around a Scene. I tried two ways, the first one, just normal code, and the second one using an array.

I have to move some images around a maze, let me show you the maze I have:
http://imgur.com/VbXg853

Let me explain what I'm doing:
I receive the maze from a .txt file. So there are numbers in this .txt file that represents an object, or in this case an image.
0:Space
1: Wall
2: Cat (Not in the maze, I have an algorithm to determinate where I have to place it)
3: Mouse(same as the Cat)
5:Whiskey
6:Pizza
7:Rum
8:Bread
9:Vine

Now I have to move the cat and the mouse every second, and they eat or get drunk with the respective situation.
But there's a problem, almost the whole time my code change the selected image, but sometimes my code just avoid all my conditions and don't do the work, and this happens always in specifics positions, I'll show you where:
http://imgur.com/qsPVdJ8

Marked in Red Circles, are the exact positions where this happen, the Whiskey and the Pizza doesn't get remove by my code, and the Space, gets remove when don't need to be. I checked if the maze I read have the same values as the .txt file, and everything is fine.

Let me show you the way I do this before trying to use Arrays:
How I add the images to the scene.



for(int i=0;i<this->n;i++){
for(int j=0;j<this->m;j++){
/*list is a QList <QString> that have the path of all image
and mat[][] is an int 2D array, that have each value of the maze*/
QGraphicsPixmapItem *image = new QGraphicsPixmapItem(QPixmap(list.at(mat[i][j])));
scene->addItem(image);
image->setPos(j*40+200,i*40+100);
}
}


How I move (Cat and Mouse) and remove (Drinks and Food) items, I'm just showing you a part of it (The movement of the Cat) cause the function have some other stuffs and its so much code to place here:



/*1.recorGato is a pile and have two int values only, row and colum.
2. 40 is the size of each image.
3. 220=width and 120=height are the place I started to add the images in the scene.
*/
while(recorGato!=NULL){
if(mat[recorGato->col][recorGato->row]!=0 && mat[recorGato->col][recorGato->row]!=1){ //if is not a space or wall, remove the image
QTransform transform;
int x = recorGato->col*40+220;
int y = recorGato->row*40+120;
QGraphicsPixmapItem *image2 = qgraphicsitem_cast<QGraphicsPixmapItem*>(scene->itemAt(x,y,transform));
QPixmap *icon = new QPixmap(list.at(0));
image2->setPixmap(*icon);
}
gato->setPos(recorGato->col*icon->width()+200,recorGato->row*icon->height()+100);
recorGato = recorGato->pre;
processEventsAndWaitFor(1); //Function I use to get set a new position every second, and make it looks like a movement, you don't need to know about it.
}


----------------------------------------------------------------------------------------------------------------
Second Way:
NOW USING AN ARRAY(sorry for caps), I'm looking to make a class and set 2 int variables and a QGraphicsPixmapItem.
Here I'm just trying to add images.


QGraphicsPixmapItem pixmapArray[n*m];
for(int i=0;i<this->n;i++){
for(int j=0;j<this->m;j++){
pixmapArray[i*10+j].setPixmap(QPixmap(list.at(mat[i][j])));
scene->addItem(&pixmapArray[i*10+j]);
pixmapArray[i*10+j].setPos(j*40+200,i*40+100);
}
}

The thing here is that, I can't even start to move the cat or the mouse, cause nothing appear in the scene, no images appear, neither one, I just have the scene with the default background. So I think I can't use an array. Why I tried to use an array? cause using array maybe I could avoid the error I said before.

If someone can help me about this, there's other way to avoid my errors? I mean, move or delete images?
I tried to save the images like I said in an array, to just change the image in a specific position (Example: arrayPixmap[10]), but didn't show the images in the Scene.

anda_skoa
15th April 2014, 20:43
Is the array a member of the class or local to the function?

Cheers,
_

d_stranz
15th April 2014, 20:46
This code is wrong:


QGraphicsPixmapItem pixmapArray[n*m];
for(int i=0;i<this->n;i++){
for(int j=0;j<this->m;j++){
pixmapArray[i*10+j].setPixmap(QPixmap(list.at(mat[i][j])));
scene->addItem(&pixmapArray[i*10+j]);
pixmapArray[i*10+j].setPos(j*40+200,i*40+100);
}
}


It creates your pixmapArray on the stack so as soon as this method exits, all of your pixmapArray instances will be automatically deleted. When that happens, they are also automatically removed from the scene.

Do this instead:



QGraphicsPixmapItem * * pixmapArray = new QGraphicsPixmapItem * [n*m];
for ( int i = 0; i < n*m; i++ )
pixmapArray[i] = new QGraphicsPixmapItem;


and then make the appropriate changes in the rest of your code to access pixmapArray[i] instances using pointer notation (->).

Also note that it is totally unnecessary to use "this->" syntax to access a member variable from within an object method. If you doing this because you are using local variables called "n" and "m" and member variables also called "n" and "m", then that's just bad programming. It's a guarantee that you eventually will have a bug that you can't track down because you can't determine which "n" or "m" should be used. Never, ever use the same names for both member and local variables in a member function.

@anda_skoa:


Is the array a member of the class or local to the function?

The way the poster is passing it to the scene (&pixmapArray[i]) implies it is a local variable on the stack, or so I interpret the code.

vitaR
16th April 2014, 00:50
@d_stranz:

Thanks, now I see the images in the Scene and yeah I know I don't have to use the same names for either, member function and local statements.
The thing is that sometime I use "this", and sometimes not. I have to change this for sure :)

@anda_skoa:

d_stranz answered that but I'll repeat what he said anyways, is a local variable on the stack :)

Thanks for the help!

anda_skoa
16th April 2014, 10:11
@anda_skoa:



The way the poster is passing it to the scene (&pixmapArray[i]) implies it is a local variable on the stack, or so I interpret the code.

I know.
Both syntax and description of what happens were in line with that assumption.

I just don't believe in handing out solutions to obvious problems, but in making the problem more obvious.

Cheers,
_

d_stranz
16th April 2014, 16:45
I just don't believe in handing out solutions to obvious problems, but in making the problem more obvious.

I generally agree; in this case it was only a partial solution - vitaR still had to integrate that code fragment to make it work. It's a toss-up - we have had several threads that have gone on for page after page because the OP just didn't get it. This one turned out not to be that kind of post, so hats off to vitaR for getting it right away.