I am writing a tile based topdown 2D game and would like the tiles to 'scroll' on the screen when the player moves. For performance reasons, I would like to 'shift' the image from the previous frame, and only draw the individual tiles for the new areas for this frame.
At the moment the game re-draws all of the tiles (lots of tiles, i.e. full screen of 10px*10px colour blocks) every frame, which does not yield satisfactory framerates. To avoid this, I planned to 'save' each frame (e.g. to a bitmap) after it had been drawn, then re-insert it into the next frame taking into account how the player has moved, however I have not found a way to do the 'saving' with SlimDX.
My current approach, which seems more hopeful, is to have 2 Direct2D.BitmapRenderTargets (created with CreateCompatibleRenderTarget() on the window render target) which switch roles each frame between being the 'current and 'previous' targets. The image from the 'previous' target's image would be drawn onto the 'current' target, and then the new tiles would be drawn onto the 'current' target, then the 'current' target would be drawn to the window. The issue I am having now is that the drawing of the 'previous' image onto the 'current' target causes a Direct2DException, I believe due to the fact it was created from the window target, and is therefore not compatible with the other BitmapRenderTarget.
This is the code for the method described above using the 2 BitmapRenderTargets:
public void draw(RenderTarget target) { //target is a WindowRenderTarget
BitmapRenderTarget currentBuffer;
BitmapRenderTarget previousBuffer;
int[] distance; //the distance the player has moved [0]=x, [1]=y
previousBuffer.BeginDraw();
if(backgroundBuffer.Bitmap != null) {
currentBuffer.DrawBitmap(previousBuffer.Bitmap, //draw the previous frame onto the current frame
new Rectangle( //target rectangle
new Point(
-1*distance[0]*getZoomLevel(),//xpos of previous frame image
-1*distance[1]*getZoomLevel()//ypos of previous frame image
),
currentBuffer.Size.ToSize() //the size of the image
),
1,//opacity
InterpolationMode.Linear,
new Rectangle( //source rectangle (covers whole image)
new Point(0,0),
previousBuffer.Size.ToSize()
)
);
}
drawChangeToTarget(currentBuffer); //draw the new tiles onto the current Buffer
currentBuffer.EndDraw(); //throws Direct2DException here
target.DrawBitmap(currentBuffer.Bitmap, //draw the result to the screen
new Rectangle ( //destination rectangle
new Point (0,0),
target.Size.ToSize()
),
1, //opacity
InterpolationMode.Linear,
new Rectangle( //target rectangle
new Point(0,0),
currentBuffer.Size.ToSize()
)
);
}