ok I am almost done doing what I need to do and that is getting a portion of a bitmap to appear on the screen and have it move around using directional controls. My problem is that while I get the the bitmap move it leaves the original behind and a new one appears in the direction I pressed. Then when I take my finger off the button it returns to the middle.

So basically I want to make the bitmap that was in the previous position disappear and have the bitmap stay in the position I put it in so I can move it around like if I was playing zelda. The bitmap problem is the problem I really want to solve.

Here is my Game_Run function where all the magic happens
Let me know if you need the whole program..

void Game_Run(HWND hwnd)
{
 

HRESULT result;	
RECT rect2;
rect2.left = 164;
rect2.top = 0;
rect2.right = 320;
rect2.bottom = 160;
//load surface from file
result = D3DXLoadSurfaceFromFile(
surface, //destination surface
NULL, //destination palette
NULL, //destination rectangle
"spheres.bmp", //source filename
&rect2, //source rectangle
D3DX_DEFAULT, //controls how image is filtered
0, //for transparency (0 for none)
NULL); //source image info (usually NULL)
//return okay
if(d3ddev == NULL)
return;

//start rendering
if (d3ddev ->BeginScene())
{
 
 if (KEY_DOWN(VK_DOWN))
    {
      d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
      rect2.top = rect2.top + 10;
      rect2.bottom = rect2.bottom + 10;
       
   
      if (rect2.bottom > SCREEN_HEIGHT)
      {
      rect2.top = rect2.top - 10;
      rect2.bottom = rect2.bottom - 10;
      }
      }

      if(KEY_DOWN(VK_UP))
      {
      d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
      rect2.top = rect2.top - 10;
      rect2.bottom = rect2.bottom - 10;
   
      if (rect2.top == 0)
      {
      rect2.top = rect2.top + 10;
      rect2.bottom = rect2.bottom + 10;

      }
      }
  
      if(KEY_DOWN(VK_RIGHT))
     {
      d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
      rect2.left = rect2.left + 10;
      rect2.right = rect2.right + 10;
   
      if(rect2.right > SCREEN_WIDTH)
      {
      rect2.right = rect2.right - 10;
      rect2.left = rect2.left - 10;
      }
      }
 
      if(KEY_DOWN(VK_LEFT))
  
      {
  
      d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
      rect2.left = rect2.left - 10;
      rect2.right = rect2.right - 10;
       
 
      if(rect2.left == 0)
      {
      rect2.left = rect2.left + 10;
      rect2.right = rect2.right + 10;
      }
      }


//draw surface to the back buffer
	d3ddev ->StretchRect(surface, NULL, backbuffer, &rect2, D3DTEXF_NONE);
//create pointer to the back buffer
	d3ddev ->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);

 
 
//stop rendering
d3ddev ->EndScene();
}

//display the back buffer on the screen
d3ddev ->Present(NULL, NULL, NULL, NULL);

 


//check for escape key (to exit program)
if (KEY_DOWN(VK_ESCAPE))
PostMessage(hwnd, WM_DESTROY, 0, 0);
}

Dani AI

Generated

Short summary and concrete fixes (what actually caused the behaviour)

was right: your source/destination rectangle and position need to persist between frames, and clearing the back buffer must happen every frame. The ghosting/duplication you saw comes from two things that often get mixed up: (1) a RECT or x/y kept as a local that gets reset each call, and (2) only calling Clear when a key is pressed so old pixels remain on the back buffer. fixed it by making the position persistent (static) — that’s exactly the right idea — but you also want the correct draw order and to stop reloading the bitmap every frame.

Practical checklist

  • Load the image/surface once during init (don’t call D3DXLoadSurfaceFromFile inside your frame loop).
  • Clear the back buffer every frame (call Clear before BeginScene).
  • Keep a persistent src rect and a persistent x/y (static/global/member). Update x/y on input, compute a dest rect from those.
  • Call GetBackBuffer before you StretchRect (the destination surface must be obtained first). Release the back buffer after use.
  • For easier sprite handling and alpha, consider ID3DXSprite/IDirect3DTexture9 instead of repeatedly copying surfaces.

Minimal frame structure example (illustrative)

static RECT src = {164,0,320,160};
static int x=100, y=100; // persistent position

device->Clear(...);                     // every frame
device->BeginScene();
device->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&backbuf);

RECT dest = { x, y, x + (src.right-src.left), y + (src.bottom-src.top) };
device->StretchRect(mySurface, &src, backbuf, &dest, D3DTEXF_NONE);

backbuf->Release();
device->EndScene();
device->Present(NULL,NULL,NULL,NULL);

Quick troubleshooting notes
If the sprite still snaps or jitters, use time-based movement (delta time) and check bounds math. If you need transparency or rotation, switch to ID3DXSprite/Draw with a texture — it’s simpler and faster for 2D sprites.

Recommended Answers

All 2 Replies

You call this function multiple times right? Via a timer callback or in a while loop with a sleep?

If so, you're not keeping the rect2 variable around: every time this function gets called the variable is reset to it's initial value, and then any changes you make are lost when the function exits.

Not sure why the image appears duplicated. That sounds like you're not clearing the draw buffer properly... I don't have much recent experience with DirectX though, so can't help you much there.

The problem was I took out the first RECT function. So when I put it back in I didn't have that problem anymore. Anyway I got the program fixed. I needed to use static ints to make the sphere move around the smoothly instead of just appearing in another spot like in my original program.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.