We help IT Professionals succeed at work.

I need ideas for a simple game

gbzhhu asked
Last Modified: 2013-11-20

I am using VC++ 6 on Win 95/98.  I am trying to develop a simple game but I have never developed a game before, Though I have done fair bit of programming (mainly on VB and).

This game is called bugs.  There should be a two dimentional grid (How do you create one in MFC?) and in the grids there are either bugs or bactreia (How would you go about drawing them on the grid).  The bugs gain weight when they eat a bacteria (How would you make the bug look bigger) The bugs move to eight directions in the grid (Is there an easy way to imlement the movement of bugs?)

I have already got the algorithm for most of the things except drawing things - that is what I am stuck with.  Also I can do some of the things I asked above, but would like opinions as to what the best approach is.

Any pointer to good site/s about MFC game programming would be appreciated

I am giving 400 points and expect some sample code
I will increase points to 600 for near complete working sample code

Watch Question

Bill NolanOwner, Lead Technology Programmer

First of all, this topic is very complicated and there are many different answers.  The best thing you could ever do is get a good book on it.  I just saw one by Andre Lamothe in the bookstore- about $65 but WELL worth it.
Anyway, here is some code detailing one method.

Much of the complexity here involves moving shapes around that aren't just square bitmaps.  You want them to appear real.  So in a graphics editory you need to create your shapes and fill in the areas that you don't want to output to the screen with a certain color.  In your app, set a constant variable to this color [RGB(x,y,z)] and call it TRANSPARENT_COLOR.  Then add the bitmaps to your resources.

In .h file:
      // Device contexts used for animation
      CDC                  m_mdcAnimation,
                                                 m_mdcVideoBuffer;// Memory video buffer where all the crazy BitBlt's are done (prevents flashing on screen)
// The bitmaps for the current animation
      CBitmap                          m_bitmapAnimation,
      // Holds the specs of the Animation bitmap
              BITMAP                          m_AniBmpSpecs;

In .cpp file:

// This will load the bitmaps and create the masks needed for transparency
void CSomeAppView::LoadAnimation(int Resource) {
// Initialize the video buffer bitmap and DC to be compatible with the view DC (I'm using doc/view style, but pViewDC represents whatever DC draws to your screen)
    m_mdcVideoBuffer.CreateCompatibleDC (pViewDC);
    m_mdcVideoBuffer.SetMapMode (pViewDC->GetMapMode ());

// Load the 'bitmapAnimation' bitmap, and recreate the necessary masks
            CBitmap* bitmapDummy;
            CBitmap* bitmapTEMP = new CBitmap();
            bitmapTEMP->CreateCompatibleBitmap(&m_mdcAnimation, 2, 2);

            // Reload Animation bitmap
            // First, destroy old bitmap if there was one
            bitmapDummy = m_mdcAnimation.SelectObject(bitmapTEMP);  // select out of DC first
            BOOL success = m_bitmapAnimation.DeleteObject();  // delete it
            m_bitmapAnimation.GetBitmap(&m_AniBmpSpecs); // get specs
            m_mdcAnimation.SelectObject (&m_bitmapAnimation);
            // Create the "OR" bitmap mask
            // First, destroy old bitmap if there was one
            bitmapDummy = m_mdcAniOr.SelectObject(bitmapTEMP);  // select out of DC first
          success = m_bitmapAniOr.DeleteObject();  // delete it
            m_bitmapAniOr.CreateCompatibleBitmap (&m_mdcAnimation, m_AniBmpSpecs.bmWidth, m_AniBmpSpecs.bmHeight);            
            bitmapDummy = m_mdcAniOr.SelectObject(&m_bitmapAniOr);
          m_mdcAniOr.BitBlt (0, 0, m_AniBmpSpecs.bmWidth, m_AniBmpSpecs.bmHeight, &m_mdcAnimation, 0, 0, SRCCOPY);

            // Create monochrome "AND" bitmap mask
            // First, destroy old bitmap if there was one
            bitmapDummy = m_mdcAniAnd.SelectObject(bitmapTEMP);  // select out of DC first
            success = m_bitmapAniAnd.DeleteObject();  // delete it
            m_bitmapAniAnd.CreateBitmap (m_AniBmpSpecs.bmWidth, m_AniBmpSpecs.bmHeight, 1, 1, NULL);            
            bitmapDummy = m_mdcAniAnd.SelectObject(&m_bitmapAniAnd);
          COLORREF crOldColor = m_mdcAnimation.SetBkColor (TRANSPARENT_COLOR);
          m_mdcAniAnd.BitBlt (0, 0, m_AniBmpSpecs.bmWidth, m_AniBmpSpecs.bmHeight, &m_mdcAnimation, 0, 0, SRCCOPY);
          m_mdcAnimation.SetBkColor (crOldColor);            
            // Create monochrome "INVERSE AND" bitmap mask from the "AND" mask
            // First, destroy old bitmap if there was one
            bitmapDummy = m_mdcAniInvAnd.SelectObject(bitmapTEMP);  // select out of DC first
            success = m_bitmapAniInvAnd.DeleteObject();  // delete it
            m_bitmapAniInvAnd.CreateBitmap (m_AniBmpSpecs.bmWidth, m_AniBmpSpecs.bmHeight, 1, 1, NULL);
          bitmapDummy = m_mdcAniInvAnd.SelectObject (&m_bitmapAniInvAnd);
            m_mdcAniInvAnd.BitBlt (0, 0, m_AniBmpSpecs.bmWidth, m_AniBmpSpecs.bmHeight, &m_mdcAniAnd, 0, 0, NOTSRCCOPY);

            // Modify the "OR" mask; apply "INV AND" to it
            m_mdcAniOr.BitBlt (0, 0, m_AniBmpSpecs.bmWidth, m_AniBmpSpecs.bmHeight, &m_mdcAniInvAnd, 0, 0, SRCAND);

            success = bitmapTEMP->DeleteObject();  // delete it
            delete bitmapTEMP;


// Now you've got everything ready and only need your animation logic.
// For example:

                    CDC* pViewDC = GetDC();            

            FrameSize = CPoint(m_AniBmpSpecs.bmWidth, m_AniBmpSpecs.bmHeight);
            CPoint point = CPoint(50,100);
                                for (int i = 0; i <= 100; i++) {
            pViewDC->BitBlt (point.x + i, point.y, FrameSize.x, FrameSize.y, &m_mdcVideoBuffer, 0, 0, SRCCOPY);

// Apply the AND mask to the destination DC
            pViewDC->BitBlt (point.x + i, point.y, FrameSize.x, FrameSize.y, &m_mdcAniAnd, 0 ,0, SRCAND);

// Apply the OR mask to the destination DC
                    pViewDC->BitBlt (point.x +ij, point.y, FrameSize.x, FrameSize.y, &m_mdcAniOr, 0, 0,, SRCINVERT);

I hope I haven't omitted anything.  This should move your bitmap, with transparency, across the screen.  To change its size, you need to either draw more bitmaps, or experiment with StretchBlt, but I think that will mess up your transparency.

Here's good grid control code that works and can easily be adapted. Just put what ever you want to draw in DrawCell().

Bill NolanOwner, Lead Technology Programmer

Oh, sorry, the last section of code draws directly to the screen and doesn't use the m_mdcVideoBuffer as an intermediary.  It does use it to erase the frames, though.  But first m_mdcVideoBuffer needs to hold the background WITHOUT the shapes on it.
To do this, first do a BitBlt of your entire "playing area" onto the VideoBuffer DC.  You can compose this however you want, but for now I will just assume it is coming from your display and the display already has this image in it, such as:

m_mdcVideoBuffer.BitBlt (0, 0, PlayAreaSize.x, PlayAreaSize.y, pViewDC, 0, 0, SRCCOPY);


Adjusted points to 500


I have rejected your answer because it contains many errors and won't run at all.  It fails so many assertions.

If you could fix it then maybe.  I was expecting more than this thought.  How do I draw a good grid on the view, without having to include many classes (just a single grid class to draw gird)

I have increased the points to 500 in the hope of getting better feedback

Thanks for the input

Please, test code before posting so that you are sure it works.

Bill NolanOwner, Lead Technology Programmer

The code works beautifully and has been thoroughly tested.  It was removed directly from a completed application.  As I stated to you, what is going on here is not completely simple, and you will have to understand it to some degree and 'coordinate' it with your application.  You are not going to find the code you want in a form that you can simply cut and paste into your app and you're done.  If you are getting a lot of exceptions, I'm not sure where they are coming from, but you will have to follow through your app and find them.  You probably aren't too far from having it working.
you can use bitmaps directly, it's simply

Im using this method in my games:



I have just visited the site you pointed to me and I would like to code (or at least the bit that does the grid and the bitmaps).  I am willing to give you 600 points and a thanks for that plus your name in the about box as a major contributor)


as for Slimfinger,

The assertion happens at the following line

bitmapDummy = m_mdcAnimation.SelectObject(bitmapTEMP);  // select out of DC first

and most of the lines after that. The SelectObject method is not happy, perhaps bitmapTEMP is not niitialised properly - I don't  know.  You could send me a nice junk of working code and I will extract what I need.

If you wish to do so then my mail is hshussein@cwcom.net

Thanks to both of you.


Hi Chap,

Your code is amazing! it is not written to be read by others and after all it is commented in Russian and Italian mixed.

Whatever the case, It works but it is of no use to me as I cannot modify it. I spent a long time trying to figure out but without success.

I hope you are not upset that I reject it, but I must get some help for the points I am giving.

Slimfinger's code is a lot neater and readable.  I will give his another try and see if I can get it working.

I wished somebody could just send me a small MDI doc/view app which loads two bitmap from resource. One is a background bitmap the other moves around in the view (on top of the background bitmap) while keeping the background OK (I mean transparent)

This will teach me what I want and will get 600 points.

Thanks to all who contributed.
Bill NolanOwner, Lead Technology Programmer

A couple things that are off on what I sent to you: (the code does work, but it was pulled from a large app, and there are just a couple spots that I had to be careful when transporting to you).  Anyway, here are a couple notes:

First of all, I had you create a memory DC, m_mdcVideoBuffer.  This is a memory DC that you will find once you've gained some experience is a very valuable concept.  You do most of your drawin on that, since it is much faster than the screen, then you blast everything to the screen when you are done.  This also reduces flicker that is caused by the many drawing operations that often take place.  The way this buffer is used in this example is not quite the way it's normally used, but it works for this example and hopefully is simple enough that you can take it from there.  As I said, a good book on this stuff is invaluable.
Anyway, I made three mistakes above:

1) In the first couple lines of the .cpp material, I had you make this video buffer a DC compatible DC with the view DC, but didn't declare the view DC first.  You can do this by placing the line
CDC* pViewDC = GetDC();
at the beginning of this code.  (assuming you are within the view object)
Also, when you are finished with this pViewDC, you should release it with

2) I neglected to tell you to first write something (your view background) into the video buffer, before you start using it in the loop at program's end.  The following line should copy whatever is in your view into the video buffer mem DC.  (I assumed a size of 200x200)  
  m_mdcVideoBuffer->BitBlt (0, 0, 200, 200, &pViewDC, 0,0,SRCCOPY);

3) Last, in the loop at the end where the drawing/animation is done, the BitBlt's for the AND and OR mask will draw the object with transparency.
The BitBlt for the video buffer should cover the object with the background that you copied into it.  The above example erased before it drew anything, which wouldn't really matter, except for where the delay is, and that the frames would not be synchronized quite right.  Anyway, below should work better:

for (int i = 0; i <= 100; i++) {

  // Apply the AND mask to the destination DC
  pViewDC->BitBlt (point.x + i, point.y, FrameSize.x,   FrameSize.y,&m_mdcAniAnd, 0, 0, SRCAND);
  // Apply the OR mask to the destination DC
  pViewDC->BitBlt (point.x + i, point.y, FrameSize.x, FrameSize.y,&m_mdcAniOr, 0, 0, SRCINVERT);

  ::Sleep(100);  // Delay 100 msec's
  // Copy video buffer onto the destination DC
pViewDC->BitBlt (point.x + i, point.y, FrameSize.x,     FrameSize.y,&m_mdcVideoBuffer, point.x + i, point.y,SRCCOPY);

** It's pretty tough reducing code out of a complex program and making sure it's right.  I think you'll have better luck with these changes, and hopefully you'll better understand what's happening here.  Then you can much more easily get it working to your needs.

Good luck.


Hi Slimfinger,

Thanks for the help.

I have it just about working and the points are going your way.  one last fix though.

I can't get it working the bit where the view content is blit into the m_mdcVideoBuffer as follows as you suggested on fix no. 2 above.

                     m_mdcVideoBuffer->BitBlt (0, 0, 200, 200, &pViewDC, 0,0,SRCCOPY);

It just will not capture the view contents.#

I got it working by calling a function to draw the background bitmap again, but that is not acceptable.  when I debug it, it seems that m_mdcVideoBuffer contains one single white pixel and my background bitmap is sort of green.

If it will help I can send you the code.  It is pretty small (Just the view class)

I also had to make all the other DC's declared in the .h file compatible with the view DC otherwise it would not work for me.  I don't know why!

Also at the start of the LoadAnimation function when we make the m_mdcVideoBuffer compatible with the view DC it works OK but if I call this function again it brings up ASSERT dialog failing at Attach function of the CDC class as it sems that m_mdcVideoBuffer is already attached.  I can't seem to work it out.

Please, help with this last two fixes and I will acceopt your answer.

Thanks for the contribution
Bill NolanOwner, Lead Technology Programmer

It sounds like you are at least figuring out basic ideas here.  Yes, you have to make those other DC's compatible, I am sorry I left that out.  Good job figuring that out.

The second part is easy.  You only need to load the animation one time and you are set.  If you need to call this function repeatedly (maybe with different resources) don't include the code that makes the DC's compatible. Do these in another function and only call it once.

On the first part- let me explain another idea to you first.  As I mentioned, the usual method of using a memory DC is a bit different than I showed you  above, and would be very good to know, since it is often useful.   Normally, you have you have a surface you would like to draw to (your view).  However, as you start drawing (and especially when doing transparent blitting) often you find yourself drawing, erasing, moving, etc. etc. over and over to the same surface so many times per "frame" that your final program produces a real jumpy, "flickering" animation that basically just sucks.  The reason for this is two-fold: your eye picks up the 100's of draw operations taking place, and also the actual drawing to the screen is MUCH slower than it is to memory.  Therefore, normal practice in these situations is to first draw EVERYTHING to memory, then fire the entire section over to the view in one straight shot.  You may think this is even slower, but considering you are normally doing many different drawing operations, often to the same location (transparency techniques, etc.) it is usually quite a bit faster and more fluent to do it this way.

So my point is, you may want to experiment with this method since it is a better technique anyhow.  Use the m_mdcVideoBuffer as your "sketchpad".  Once you are done doing all the drawing to it, BitBlt whatever section you'd like over to the view.  I think you will figure this out pretty quickly.

Anyway, as far as blitting the view into the membuffer... I'm not too sure why that isn't working.  It seems like it should, but of course I could be overlooking something, hehe.  Maybe you don't have anything in the view at the time you try this, or possibly it isn't big enough (we put 200x200 in the example).  Try first drawing something into the view.  Either BitBlt something directly, or use on of the Pen or Text functions in the CDC class.
Whatever is going on there I'm sure is not too tough and I think you will find it.  If for some reason you still can't, write back and/or send me the code and I'll help.  Also, look over the help on CDC member functions and esp. the BitBlt function.  The point you are at now with this stuff, you will quickly understand the documentation and it will probably help a lot.

I told this stuff is tricky...hehe.



I am still trying to figure out how to make the DC compatible memDC take a copy of the view DC pDC.  I will keep trying but this is to let you know that I am still around and will get back to you as soon as I have some results (or give up trying!!)  

Bill NolanOwner, Lead Technology Programmer

Hey, gbzhhu...

Try first creating and loading a separate bitmap for your memory DC.  Make this bitmap also compatible with the view dc.  Do it along these lines (obviously, subsititute appropriate var names):

CBitmap bitmapCrap;
bitmapCrap.CreateCompatibleBitmap(pViewDC, Size.x, Size.y);


// Now try your drawing functions

The 'Size' used above can be whatever section you want to deal with within your view.  If you want to copy the whole view, you just need to find the size of this.  (There is probably a function to retrieve this, though I'm not sure what it is offhand.  Just as likely you will know its size, anyway).

Good luck.

Bill NolanOwner, Lead Technology Programmer

P.S. Remember, in the animation code you are using, to also copy view image into the memDC after you load it with the new bitmap...
Owner, Lead Technology Programmer
This one is on us!
(Get your first solution completely free - no credit card required)


Sorry about the wait, I tried many different methods to compare with yours.  And so far yours is the best.  I still have not fixed the flicker, because I cannot seem to make the memory CDC to work.  It simply does not do anything for me.  

Thanks for the help SlimFinger.



Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.