Solved

I need ideas for a simple game

Posted on 2000-02-14
18
167 Views
Last Modified: 2013-11-20
Hi,

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

Thanks
0
Comment
Question by:gbzhhu
  • 8
  • 7
  • 2
  • +1
18 Comments
 
LVL 7

Expert Comment

by:Slimfinger
ID: 2521096
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_mdcAniOr,
                        m_mdcAniAnd,
                        m_mdcAniInvAnd,            
                                                 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,
                        m_bitmapAniOr,
                        m_bitmapAniAnd,
                        m_bitmapAniInvAnd;      
      // 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.LoadBitmap(Resource);                              
            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();            
                             LoadAnimation(IDB_ANI_WKINGTIP);

            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);
            ::Sleep(100);


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.
0
 

Expert Comment

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

http://www.codeguru.com/controls/gridctrl_in_view.shtml
0
 
LVL 7

Expert Comment

by:Slimfinger
ID: 2525582
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);
0
 
LVL 12

Author Comment

by:gbzhhu
ID: 2535746
Adjusted points to 500
0
 
LVL 12

Author Comment

by:gbzhhu
ID: 2535747
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.

0
 
LVL 7

Expert Comment

by:Slimfinger
ID: 2535868
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.
0
 
LVL 9

Expert Comment

by:cdesigner
ID: 2536572
you can use bitmaps directly, it's simply

Im using this method in my games:
http://www.wegabyte.com/games.shtml
0
 
LVL 12

Author Comment

by:gbzhhu
ID: 2536929
cdesigner,

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)

Thanks

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.
0
 
LVL 9

Expert Comment

by:cdesigner
ID: 2543305
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 12

Author Comment

by:gbzhhu
ID: 2578122
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.
0
 
LVL 7

Expert Comment

by:Slimfinger
ID: 2579188
gbzhhu-
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
ReleaseDC(pViewDC);

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.
0
 
LVL 12

Author Comment

by:gbzhhu
ID: 2583523
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
0
 
LVL 7

Expert Comment

by:Slimfinger
ID: 2583938
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.

0
 
LVL 12

Author Comment

by:gbzhhu
ID: 2614000
SlimFinger,

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!!)  

Hassan
0
 
LVL 7

Expert Comment

by:Slimfinger
ID: 2614591
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);

memDC.CreateCompatibleDC(pViewDC);
memDC.SelectObject(bitmapCrap);

// 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.

0
 
LVL 7

Expert Comment

by:Slimfinger
ID: 2614595
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...
0
 
LVL 7

Accepted Solution

by:
Slimfinger earned 500 total points
ID: 2627394
gbzhhu,
If you are still having trouble getting that specific algorithm to work right, try going the more standard route:

Use the memory DC as your "drawing pad", and when you have finished all your drawing, fire it over onto the view DC.  Set up the memory DC (I called it VideoBuffer in this example) along these lines (also load it with a bitmap, making both the DC and bitmap compatible with the view):

// Make mem DC compatible with view
m_mdcVideoBuffer.CreateCompatibleDC (pViewDC);
m_mdcVideoBuffer.SetMapMode(pViewDC->GetMapMode());

// Load it with a bitmap, also compatible with view
m_bitmapVideoBuffer.CreateCompatibleBitmap(pViewDC, SomeWidth, SomeHeight);
m_mdcVideoBuffer.SelectObject(&m_bitmapVideoBuffer);

Just do all your drawing in this DC instead, then BitBlt whatever section of it you'd like to the view.

Good luck.
0
 
LVL 12

Author Comment

by:gbzhhu
ID: 2717931
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.

Cheers

Hassan
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
mixString challenge 36 98
repeateFront java challenge 31 87
iSeries FTP Exit Program 8 114
canBalance challenge 34 65
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now