引入了Core Graphices框架功能,演示如何画线条,文本,改变线条的额粗细,颜色,以及保存和恢复图形上下文。
要在一个视图中进行自定义绘制,我们必须首先获得当前图形上下文。图形上下文(CGContext)是一个绘图画布,它存放绘图信息,如颜色,线条宽度和字体。在调用drawRect:之前,由UIView配置当前图形上下文。UIGraphicsGetCurrentContext函数返回已经为当前UIView所配置的图形上下文。
//获取当前图形上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//保存这个上下文,因为我们需要上下翻转它
CGContextSaveGState(context);
//获取当前图形上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//保存这个上下文,因为我们需要上下翻转它
CGContextSaveGState(context);
/*通过调用CGContextRef中的CGContextTranslateCTM函数把坐标原点转换到左下角,该函数有两个参数,即水平和垂直方
/*通过调用CGContextRef中的CGContextTranslateCTM函数把坐标原点转换到左下角,该函数有两个参数,即水平和垂直方
向的变换数值。然后使用CGContextScaleCTM函数颠倒y轴,该函数有两个参数,即x轴和y轴的变换比例,第一个参数为1,保
向的变换数值。然后使用CGContextScaleCTM函数颠倒y轴,该函数有两个参数,即x轴和y轴的变换比例,第一个参数为1,保
持x轴不变,而第二个参数为-1,表示颠倒y轴*/
持x轴不变,而第二个参数为-1,表示颠倒y轴*/
//向下移动该上下文坐标原点
CGContextTranslateCTM(context, 0, self.view.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0); //向上翻转图像上下文
//以剩余时间来创建一个字符串
NSString *str = [NSString stringWithFormat:@"Time remaining:%i seconds", timeLeft];
//选择字体为16pt Helvetica
CGContextSelectFont(context, "Helvetica", 16, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(context, kCGTextFill); //设置绘制模式
//设置文本颜色为黑色
CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
//转换str为一个C 字符串并显示它
CGContextShowTextAtPoint(context, 10.0, 10.0, [str cStringUsingEncoding:[NSString defaultCStringEncoding]], str.length);
CGContextRestoreGState(context); //恢复上下文
//如果炮弹在屏幕上
if (cannonballOnScreen)
{
//创建矩形并在其中绘制炮弹
CGRect cannonballRect = CGRectMake(cannonball.x, cannonball.y, CANNON_BASE_RADIUS * 2, CANNON_BASE_RADIUS * 2);
UIImage *image = [UIImage imageNamed:@"cannonball80.png"];
//绘制图片到矩形中
CGContextDrawImage(context, cannonballRect, image.CGImage);
}
//绘制加农炮炮管
//移动加农炮底座到视图中间的位置
CGContextMoveToPoint(context, 0 , self.view.frame.size.height / 2);
//添加一根到加农炮炮管终端的线条
CGContextAddLineToPoint(context, barrelEnd.x , barrelEnd.y);
CGContextSetLineWidth(context, 20); //设置线条粗细
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0); //黑色
CGContextStrokePath(context); //绘制线条
//为加农炮底座创建矩形
CGRect cannonBase = CGRectMake(0, self.view.frame.size.height / 2 - CANNON_BASE_RADIUS, CANNON_BASE_RADIUS, CANNON_BASE_RADIUS * 2);
//加载加农炮底座图片
UIImage *baseImage = [UIImage imageNamed:@"cannon_base.png"];
//把加农炮底座图片绘制到矩形中
CGContextDrawImage(context, cannonBase, baseImage.CGImage);
//在拦截器两个端点之间添加一根线
CGContextMoveToPoint(context, blocker.start.x, blocker.start.y);
CGContextAddLineToPoint(context, blocker.end.x, blocker.end.y);
CGContextSetLineWidth(context, LINE_WIDTH);
CGContextStrokePath(context); //绘制线条
//计算目标每个分段的长度
float pieceLength = (TARGET_END - TARGET_BEGINING) / TARGET_PIECES;
//移到目标起点
CGContextMoveToPoint(context, target.start.x, target.start.y);
//绘制每个目标分段
for (int i = 1; i <= TARGET_PIECES; i++)
{
//相邻分段以黄、蓝色区分开
if(i % 2 == 0)
{
CGContextSetRGBStrokeColor(context, 1, 1, 0, 1);
}
else
{
CGContextSetRGBStrokeColor(context, 0, 0, 0.5, 1);
}
//移到下一个分段的端点
CGContextMoveToPoint(context, target.end.x, target.start.y + pieceLength * (i - 1));
//如果这个分段还没有被击中
if(!targetPieceHit[i - 1])
{
//为该分段添加一条线
CGContextAddLineToPoint(context, target.end.x, target.start.y + pieceLength * i);
CGContextStrokePath(context); //绘制分段
}
}
//向下移动该上下文坐标原点
CGContextTranslateCTM(context, 0, self.view.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0); //向上翻转图像上下文
//以剩余时间来创建一个字符串
NSString *str = [NSString stringWithFormat:@"Time remaining:%i seconds", timeLeft];
//选择字体为16pt Helvetica
CGContextSelectFont(context, "Helvetica", 16, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(context, kCGTextFill); //设置绘制模式
//设置文本颜色为黑色
CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
//转换str为一个C 字符串并显示它
CGContextShowTextAtPoint(context, 10.0, 10.0, [str cStringUsingEncoding:[NSString defaultCStringEncoding]], str.length);
CGContextRestoreGState(context); //恢复上下文
//如果炮弹在屏幕上
if (cannonballOnScreen)
{
//创建矩形并在其中绘制炮弹
CGRect cannonballRect = CGRectMake(cannonball.x, cannonball.y, CANNON_BASE_RADIUS * 2, CANNON_BASE_RADIUS * 2);
UIImage *image = [UIImage imageNamed:@"cannonball80.png"];
//绘制图片到矩形中
CGContextDrawImage(context, cannonballRect, image.CGImage);
}
//绘制加农炮炮管
//移动加农炮底座到视图中间的位置
CGContextMoveToPoint(context, 0 , self.view.frame.size.height / 2);
//添加一根到加农炮炮管终端的线条
CGContextAddLineToPoint(context, barrelEnd.x , barrelEnd.y);
CGContextSetLineWidth(context, 20); //设置线条粗细
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0); //黑色
CGContextStrokePath(context); //绘制线条
//为加农炮底座创建矩形
CGRect cannonBase = CGRectMake(0, self.view.frame.size.height / 2 - CANNON_BASE_RADIUS, CANNON_BASE_RADIUS, CANNON_BASE_RADIUS * 2);
//加载加农炮底座图片
UIImage *baseImage = [UIImage imageNamed:@"cannon_base.png"];
//把加农炮底座图片绘制到矩形中
CGContextDrawImage(context, cannonBase, baseImage.CGImage);
//在拦截器两个端点之间添加一根线
CGContextMoveToPoint(context, blocker.start.x, blocker.start.y);
CGContextAddLineToPoint(context, blocker.end.x, blocker.end.y);
CGContextSetLineWidth(context, LINE_WIDTH);
CGContextStrokePath(context); //绘制线条
//计算目标每个分段的长度
float pieceLength = (TARGET_END - TARGET_BEGINING) / TARGET_PIECES;
//移到目标起点
CGContextMoveToPoint(context, target.start.x, target.start.y);
//绘制每个目标分段
for (int i = 1; i <= TARGET_PIECES; i++)
{
//相邻分段以黄、蓝色区分开
if(i % 2 == 0)
{
CGContextSetRGBStrokeColor(context, 1, 1, 0, 1);
}
else
{
CGContextSetRGBStrokeColor(context, 0, 0, 0.5, 1);
}
//移到下一个分段的端点
CGContextMoveToPoint(context, target.end.x, target.start.y + pieceLength * (i - 1));
//如果这个分段还没有被击中
if(!targetPieceHit[i - 1])
{
//为该分段添加一条线
CGContextAddLineToPoint(context, target.end.x, target.start.y + pieceLength * i);
CGContextStrokePath(context); //绘制分段
}
}