记分牌动画

本文介绍了如何使用C#和GDI+来创建一个记分牌翻页动画效果。作者通过正交投影,实现页面在翻动时保持宽度不变,仅纵向拉伸压缩,并添加阴影效果。文章详细描述了C#中创建Bitmap、Graphics、Font、Brush等对象的过程,以及如何绘制文本和处理图像。最后,作者探讨了GDI+在Silverlight等新技术面前的未来地位。

又是帮忙,同事要做一个记分牌的功能,嵌入到程序主窗口,用来显示时间和一些选择列表

抽象的说,就是一个动画效果,每个页面的上半部或下半部可以翻动,显示上一页或下一页

每页上显示字符串

 

考虑用D3D太牛刀了,用GDI太繁琐了,用C#和GDI+尝试了一把,不过之前没用过C#,开始也没底

不打算做的太立体,所以用正交投影效果,页翻动时页宽不变,只是纵向拉伸压缩,辅以阴影效果

 

因为从来没用过C#,在此记录一下一些实现过程的问题和方法:

C#中类的成员函数的参数没有默认值吗?构造函数不能用默认值初始化成员变量吗?(未解,TODO)

 

从一个图片文件生成Bitmap对象,Bitmapbitmap("filename");

从Bitmap对象创建Graphics,Graphics g = Graphics.FromImage(bmp);

创建字体,Font font = new Font("font_type", size);

创建画刷,SolidBrush brush = new SolidBrush(color.Red);

创建输出矩形:Rectangle rect = new Rectangle(x, y, w, h);

创建文本格式,StringFormat strFormat = new StringFormat();

设置文本格式,strFormat.Alignment = strFormat.LineAlignment = StringAlignment.Center;

绘制文本:g.DrawString(str, font, brush, rect, strFormat);

释放:g.Dispose();

 

用上述方法创建旧页和新页Bitmap对象

创建上半部分和下半部分的矩形对象

下面代码并不完整,仅作说明

 

对角度i从90到-90度循环

  1. double s = Math.Sin(Math.PI * (double)i / 180.0);

使用缓冲,绘制旧图为背景图,

  1. BufferedGraphicsContext currentContext;
  2. BufferedGraphics myBuffer;
  3. currentContext = BufferedGraphicsManager.Current;
  4. myBuffer = currentContext.Allocate(dg, new Rectangle(0,0,m_w,m_h));
  5. myBuffer.Graphics.DrawImage(newBmp, rcUpSrc, rcUpDst, GraphicsUnit.Pixel);

用颜色属性使翻动页朝下的面和下半部将被遮挡的旧页变暗

  1. float[][] matrixItems = {
  2.         new float[] {s, 0.0f, 0.0f, 0.0f, 0.0f},
  3.         new float[] {0.0f, s, 0.0f, 0.0f, 0.0f},
  4.         new float[] {0.0f, 0.0f, s, 0.0f, 0.0f},
  5.         new float[] {0.0f, 0.0f, 0.0f, 1.0f, 0.0f},
  6.         new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f} };
  7. ColorMatrix colorMatrix = new ColorMatrix(matrixItems);
  8. ImageAttributes imageAttributes = new ImageAttributes();
  9. imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

每次计算出翻动页投影后的高度,用DrawImage绘制到对应位置

  1. int newH = (int)((double)m_h * s / 2.0);
  2. int newY = m_y + m_h/2 - newH;
  3. myBuffer.Graphics.DrawImage(m_curImage, rcPage, 
  4.                     rcUpSrc.X, rcUpSrc.Y, rcUpSrc.Width, rcUpSrc.Height,
  5.                     GraphicsUnit.Pixel, imageAttributes);
  6. myBuffer.Render();
  7. myBuffer.Render(dg);

上半部和下半部翻动页和静止页要分成两个循环来做,方法同上,只是绘制顺序,位置不同

 

神往GDI+已久,今日总算牛刀小试

最近在看Silverlight,不知道GDI+是否就被直接跳过,日后直接使用的机会也不大?

 

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值