这个游戏打算是用C#+GDI做~所以渲染效率上还是要进行一些考虑的
public interface IRenderHandler
{
void Clear(Color backgroundColor);
void DrawLine(int x1, int y1, int x2, int y2, Color color);
void DrawBox(int x, int y, int width, int height, Color color, bool fill);
void DrawImage(int destX, int destY, int destWidth, int destHeight, Bitmap source, int sourceX, int sourceY, int sourceWidth, int sourceHeight);
object GetSurface();
}
这是实现一个渲染器需要实现的接口,大体上就这么多
然后是用GDI实现的一个渲染器
/// <summary>
/// GDI渲染器
/// </summary>
public class GDIRender : IRenderHandler
{
private Bitmap mSurface;
private Graphics mG;
public GDIRender(int width, int height)
{
mSurface = new Bitmap(width, height);
mG = Graphics.FromImage(mSurface);
}
public void Clear(Color backgroundColor)
{
mG.Clear(backgroundColor);
}
public void DrawLine(int x1, int y1, int x2, int y2, Color color)
{
mG.DrawLine(new Pen(color), x1, y1, x2, y2);
}
public void DrawBox(int x, int y, int width, int height, Color color, bool fill)
{
if (fill == true)
{
mG.FillRectangle(new SolidBrush(color), new Rectangle(x - width / 2, y - height / 2, width, height));
}
else
{
mG.DrawRectangle(new Pen(color), new Rectangle(x - width / 2, y - height / 2, width, height));
}
}
public void DrawImage(int destX, int destY, int destWidth, int destHeight, Bitmap source, int sourceX, int sourceY, int sourceWidth, int sourceHeight)
{
mG.DrawImage(source,
new Rectangle(destX - destWidth / 2, destY - destHeight / 2, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
}
public object GetSurface()
{
return mSurface;
}
}
有了这个东西,我们就可以在屏幕上画东西了。。。
下面实现的是一个图形设备,封装了一下渲染器
/// <summary>
/// 图形设备
/// </summary>
public class GraphicDevice
{
public IRenderHandler RenderHandler;
private int mRenderStatus; // 渲染器的状态(0:Normal 1:Begin)
private int mWidth;
private int mHeight;
private Color mBackgroundColor;
public object Surface
{
get
{
return RenderHandler.GetSurface();
}
}
private List<RenderObject> mRenderObjects;
public event RenderOverHandler RenderOver;
public GraphicDevice(int width, int height, Color backColor)
{
this.RenderHandler = new GDIRender(width, height);
this.mWidth = width;
this.mHeight = height;
this.mBackgroundColor = backColor;
this.mRenderObjects = new List<RenderObject>();
this.RenderOver = null;
}
public void Begin()
{
if (mRenderStatus != 0)
{
throw new Exception("上一次调用Begin()后未调用End()");
}
mRenderStatus = 1;
mRenderObjects.Clear();
RenderHandler.Clear(mBackgroundColor);
}
public void End()
{
if (mRenderStatus != 1)
{
throw new Exception("调用End()之前必须调用Begin()");
}
mRenderStatus = 0;
mRenderObjects.Sort(DepthComparer);
int len = mRenderObjects.Count;
for (int i = 0; i < len; i++)
{
mRenderObjects[i].Render(RenderHandler);
}
if (RenderOver != null)
{
RenderOver(this);
}
}
public void RenderObject(RenderObject obj)
{
mRenderObjects.Add(obj);
}
private int DepthComparer(RenderObject obj1, RenderObject obj2)
{
if (obj1.Depth < obj2.Depth)
{
return -1;
}
else if (obj1.Depth > obj2.Depth)
{
return 1;
}
return 0;
}
}
在Begin的时候清空需要渲染的东西,在End的时候进行批处理绘制。
绘制的对象是一个叫做RenderObject的类,这个类是基础渲染图元,也就是Line,Image之类的基类了
/// <summary>
/// 渲染目标基类
/// </summary>
public class RenderObject
{
/// <summary>
/// 渲染深度(0-100越大越靠前)
/// </summary>
public int Depth;
public RenderObject()
{
Depth = 0;
}
public virtual void Render(IRenderHandler renderHandler)
{
}
}
然后接下来给出几种具体实现
public class RenderLine : RenderObject
{
public int X1;
public int Y1;
public int X2;
public int Y2;
public Color Color;
public RenderLine(int x1, int y1, int x2, int y2, Color color, int depth = 100)
: base()
{
this.Depth = depth;
this.X1 = x1;
this.Y1 = y1;
this.X2 = x2;
this.Y2 = y2;
this.Color = color;
}
public override void Render(IRenderHandler renderHandler)
{
renderHandler.DrawLine(X1, Y1, X2, Y2, Color);
}
}
public class RenderBox : RenderObject
{
public int X;
public int Y;
public int Width;
public int Height;
public Color Color;
public bool Fill;
public RenderBox(int x, int y, int width, int height, Color color, bool fill, int depth = 100)
{
this.Depth = depth;
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
this.Color = color;
this.Fill = fill;
}
public override void Render(IRenderHandler renderHandler)
{
renderHandler.DrawBox(X, Y, Width, Height, Color, Fill);
}
}
其余的类似~~
好了,有了这些东西,我们才真正的开始在屏幕上绘制东西了,大概流程是这样
GraphiceDevice.Begin()
...
GraphiceDevice.RenderObject(obj);
...
GraphiceDevice.End()