Skip to main content
gamedev.net
🔒 Locked

Window Sprites

Started by King Mar 19, 2000 at 11:41 PM 12 replies 1.3k views
Original Post
King
King
I have a bitmap that(in a simple window) moves 5 pixels every press of the button, but i'd lie to know how to delete the last bitmap. Example: pretend X is the bitmap. #1 is the bitmap (X) at its starting coordination. #2 is the new coordination, and #3 is what the window shows. I want the window to show what #2 looks like, without the old position showing. #1. X #2.   X #3. X X It shows the old position of the bitmap. because its still blitted there. I want to know how to delete the old position after it shows it moved(just like a sprite). I'm programming in C++ Windows API, no directx. Please i'm really stumped and was hoping for some help. Thanks. - king171@hotmail.com
- http://www.cfxweb.net/mxf/ Edited by - King on 3/19/00 11:56:18 PM
Qoy
Qoy
If I know what you''re talking about, then all you have to do is clear the window every time before you redraw it. Either that, or just draw something that fills up the whole window (a background or something) and then draw over it. All that''s happening is that you''re not putting anything over the old one, so it stays there.

BTW, if this is what you need, then it''s NOT eating up your RAM, because whether the pixels are the background color or not, then still take the same amount of memory.

------------------------------
Jonathan Little
invader@hushmail.com
http://www.crosswinds.net/~uselessknowledge
BeamMeUp
BeamMeUp
If you have your window''s background set to WHITE_BRUSH (I''m assuming your window is white) then you can invalidate the entire window every frame, if you want to do that. Before animating (straight after you''ve moved your bitmap''s coordinates):

InvalidateRect (hwnd, NULL) ;
//I''m not sure if they are the correct parameters; I don''t have any access to help files right now...

However, you might want to use an off-screen buffer and then Blt that to the hdc every frame. You can create an hdcMem by using something like:

HDC hdcMem ;//you might want to make this global

//create a DC somewhere in your code
hdcMem = CreateCompatibleDC (hdc) ;

//delete the DC later
DeleteDC (hwnd, hdcMem) ;

... (again, not sure of syntax and parameters, sorry) then you can draw or Blt to your hdcMem and finally BltFast it to the window. If you want to reduce flicker without DirectDraw, this method may be slow, but it should eliminate flicker entirely. The InvalidateRect method above may flicker if you''re drawing too many sprites, or a large bitmap.

I hope that helps.


-----------

C++ is the language of the not-so-ancients.
Learn to speak it well.


BeamMeUp
-----------C++ is the language of the not-so-ancients.Learn to speak it well.BeamMeUp
King
King
Qoy

if you'd be so kind to explain how is erase window and redraw it, i'd really appreciate it.

"BTW" it is eating up my ram loading hundreds of bitmaps. OR... my compute just sux and randomly slows down when i daw all those bitmaps.

Edited by - King on 3/20/00 12:58:03 AM
DerekDay
DerekDay
Well, erasing the window can be done several ways, but the simplest if probably just calling FillRect( hDC, &rectangle, &brush ) with rectangle set to the size of the window... Then draw the bitmap the way you were previously doing it. However, I''m thinking the way you are doing it is not quite right, because it sounds like you are loading the bitmap into memory every time and then not deleting the bitmap object. So, you may want to look over your code a little and make sure you load the bitmap only once and delete it after all the animation has been done. The call to delete it is DeleteObject( bitmap ).
-Derek
Zipster
Zipster
just clear the screen between each frame. its like erasing the old bitmap, and them placing the new one. Use this function and macro:

#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }

the previous #define statement must be all on one line!!

int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds, USHORT color, RECT *client)
{
DDBLTFX ddbltfx; // this contains the DDBLTFX structure

// clear out the structure and set the size field
DDRAW_INIT_STRUCT(ddbltfx);

// set the dwfillcolor field to the desired color
ddbltfx.dwFillColor = color;

// ready to blt to surface
lpdds->Blt(client, // ptr to dest rectangle
NULL, // ptr to source surface, NA
NULL, // ptr to source rectangle, NA
DDBLT_COLORFILL / DDBLT_WAIT, // fill and wait
&ddbltfx); // ptr to DDBLTFX structure

// return success
return(1);
} // end DDraw_Fill_Surface
olp-fan
olp-fan
Alright, you don''t need to clear the screen, doing so will eat up your performance like crazy with WinAPI. There is something called Dirty Rectangles which works by basically having a surface the size of the sprite that you are blitting that is background. So before you blit the next image, you replace the background.

So You grab the background of which you are blitting to, you blit the sprite, and when you move, you replace the background, get a new background, and blit again.
Rock on,- Tom
Kylotan
Kylotan
You don''t need to load it in anew each time. Each time you blit it, you are simply copying the bitmap memory, not moving it. So wherever it is getting loaded to the first time should (unless you deallocate that memory) be fine to use as many times as you like. Just because you can see more than one copy of it on the screen, doesn''t mean it''s duplicated. It just means that whatever used to be on the screen has been overwritten with your bitmap. Memory usage is the same unless you are explicitly allocating more memory (for no good reason, as far as I can tell.)
null_pointer
null_pointer
King: I think what you need to do is to have a global HBITMAP, load it from disk during initialization, and delete it during shutdown. Like this:

// near beginning of source file
HBITMAP hMyBitmap;

// in the creation code (i.e., InitInstance())
hMyBitmap = LoadBitmap(...); // more params, but read the docs

// in the shutdown code (i.e., ExitInstance())
DeleteObject(hMyBitmap);


Now, you simply select it in and out of the HDC before you blit it.

// Select it into the device context, and
// make sure to save the old one.
HBITMAP hOldBitmap = SelectObject(hDC, hMyBitmap);

// Do all your blitting/drawing with the bitmap here.
BitBlt( /* whatever */ );

// Remove our bitmap from the device context
// by selecting in whatever was there previously.
SelectObject(hDC, hOldBitmap);


You can use the hMyBitmap as many times as you want this way. Also, different flags in BitBlt allow you to simply blit white or black rectangles, inverted bitmaps, etc.

BTW, I've been trying to do a "plain" windows app for a game map editor -- it's like pulling out the old NES! Sllooowwwww...

As far as I know, all you need to do is to BitBlt with WHITENESS or BLACKNESS as the flag. Have another global, this time a RECT, and simply save the position of each BitBlt when you do it. That way, you always know where the last blit took place. Simply blit WHITENESS or BLACKNESS over that spot before painting the next frame. If someone could elaborate on the Windows clipping rects, InvalidateRect, and how to use them to implement dirty rects, I'd be much obliged!

The biggest difference between Windows GDI and DirectX is that with DX you typically "hog" the computer, updating each frame; in Windows GDI you just draw when a paint event occurs. If you want to do animation, just trigger those events yourself with one of the InvalidateX() functions. If you need to just draw something quick, like in response to a mouse event, you can use HDC hDC = GetWindowDC(hWnd), and ReleaseDC(hDC) to get a valid HDC and destroy it anywhere in your code. (or was it DeleteDC() ?)

Good Luck!


- null_pointer


Edited by - null_pointer on 3/21/00 7:33:30 AM

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.