编辑代码

//5.1初识图形世界
//5.1.2触摸事件

//
//ViewController.swift
//GraphDemo
//
//Created by Zhifeng Chen on 2020/8/4. 
//Copyright  2020 Zhifeng Chen. All rights reserved.
//

import UIKit

class CoreGraphUIView: UIView {

    override func touchesBegan (_touches: Set<UITouch>,with event: UIEvent?) {
        self.backgroundColor = UIColor.red
        print ("Began: \(touches) ")
    }

    override func touchesEnded (_touches: Set<UITouch>, with event: UIEvent?) {
        self. backgroundColor = UIColor.lightGray
        print ("Ended: \(touches) ")
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?){
        self. backgroundColor = UIColor.blue
        print ("Moved: \ (touches) ")
    }
}

class ViewController: UIViewController{

    override func viewDidLoad () {
        super.viewDidLoad ()
        //Do any additional setup after loading the view.
        let height = self.view.frame.size.height
        let width = self.view.frame.size.width
        let graphFrame = CGRect (x: 0, y: 0, width: width,height: height)
        let graphView = CoreGraphUIView (frame: graphFrame)
        graphView.backgroundColor = UIColor.white
        self.view.addSubview (graphView)
    }
}

//如果想获得触摸的对象及其坐标,程序如下:
let touch:UITouch = touches.first! as UITouch
print(touch.location(in: view).x)
print(touch.location(in: view).y)



//5.2拥有自己的绘图类
//5.2.1定义一个Shape类

class Shape {
    //名祢
    var name  : String?
    //边数
    var sides  : Int?
    //左上用的位首坐标
    Val origin : CGPoint?
    //线条颜色
    var lineColor : UIColor = UICOLOr.red
    //填充颜色
    var filColor : UICOLOr = UrCoLor.green
    //线条宽度
    var linewiath : CGELoat = 2
    //构造器涵数init
    init (name: String, sides : Int, origin: CGPoint) {
        self. name = name
        self.sides = sides
        self.origin = origin
    }
    //自定义方法sayHello
    func sayhello () {
        print ( "Shape is \(name!), sides \(sides!), and originCord is (\(origin!.x), \(origin!.y))")
    }
}

//5.2.2实例化Shape类

//
// Viewcontro_ler.swift 
// ShapeDemo 
//Created by Zhifeng Chen on 2020/8/4.
// Copyright  2020 Zhifeng Chen. All rights reserved.
//

Import UInit

class Shape {
    //名称
    var name  : String?
    //边数
    var sides : Int?
    //左上角的位置坐标
    var origin : CGPoint?
    //线条颜色
    var linecolor : UIColor = UICOlor.red
    //填充颜色
    var fillColor : UIColor = UIColor.green
    //线条笕度
    var lineWidth: CGFloat = 2
    //构造器函数 init
    init (name : String, sides : Int, origin : CGPoint) {
    self.name = name
    self.sides = sides
    self.origin = origin
    }
    //自定义方法 sayHie11o
    func sayhello) {
        print("Shape is \(name!), sides \(sides!), and originCord is (\(originCord!.x),\(origin!.y))")
    }
}
    
class ViewController: UIViewController {

    override func viewDidLoad () {

        super.viewDidLoad ()
        // Do any additional setup after loading the view.
        //此处调用Shape类,建立一个对象(实例)myShaple
        let myShape = Shape(name:"BaseShape", sides: 0, origin: CGPoint(x:0, y:0))
        myshape. sayHello ()
    }
}

//5.2.3重载UIView中的Draw函数

//
// VievController .swift
// DrawMusic
//
//Created by Zhifeng Chen on 2020/8/4.
//Copyright  2020 Zhifeng Chen. All rights reserved.

import UIKit

class Shape {

    //名称
    var name  : String?
    //边数
    var sides : Int?
    //左上角的位置坐标
    var origin : CGPoint?
    //线条颜色
    var lineColor : UIColor = UIColor.red
    //填充颜色
    var fillColor : UIColor = UIColor.green
    //线条宽度
    var lineWidth: CGFloat = 2
    //构造器函数 init
    init(name: String, sides : Int, origin : CGPoint) {
        self.name = name
        self.sides = sides
        self.origin = origin
    }
    //自定义方法 sayHe11o
    func sayHello () {
        print ("Shape: \(name!), sides \(sides!), origin (\(origin!.x), \(origin!.y)) ")
    }
}

class CzfView : UIView {
    //成员变量(属性)shape,共类型为Shape
    var shape : Shape?
    //重载UIView的draw方法
    override func draw(_ rect: CGRect) {
        //判断shape变量是否为空値nil
        guard let s = shape else {
            return
        }
        //不为空,则调用shape这个实例的方法
        s.sayHello ()
    }
}
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad ()
        // Do any additional setup after loading the view, typically from a nib.
        //此处调用Shape类,建立一个对象(实例)myShape
        let myShape = Shape(name:"BaseShape", sides: 0, origin: CGPOInt(x: 0, y:0))
        //此处建立了一个 Czfview 的买例myView
        let width = self.view.frame.size.width
        let height = self.view.frame.Size.height
        let myView = CzfView (frame: CGreet (x: 0, y: 0, width: width,height: height))
        //赋值给myView 中的成员(属性)shape
        myview.shape = myShape
        //显示myView
        self.view.addSubview(myview)
    }
}

//在Shape类中增加一个方法drawBezierPath(),其代码如下:

//自定义方法drawBezierPath用于四冬
func drawBezlerrath() {
    //调用贝基尔曲线函数UIBezierPath()
    let path = UIBezierPath()
    //圆孤的中心点center,其坐标为 (100,100)
    let center : CGPoint = CGPolnt (x: 100, y: 100)
    //圆的半径长度radius,其值为 80
    let radius : CGFloat = 80
    //生成一个园
    Path.addare(withCenter: center, radius: radius, startAngle: 0,endAngle: CGFLoat.p1*2, clockwise: true)
    //线条宽度为5
    path.lineWidth = 5
    //线条颜色为red红色
    UIColor.red.setStroke()
    //画出这个园
    path.stroke()
}

//在CztView这个类中,修改draw方法,增加一行:
S.drawBezierrath()

//最后在ViewController的ViewDidLoad()中,清除背景色,不然会出现黑色背景,具体增加的代码如下:
myview.backgroundColor = UIColor.clear  //清余背景色



//5.3绘制平面几何图形

//5.3.1常见图形绘制
//基类Shape

class Shape {
    //名称
    var name : String?
    //左上角的位置坐标
    var origin : CGPoint?
    //线条颜色
    var lineColor : UIColor? = UIColor.red
    //填充颜色
    var fil1color : UIColor? = UIColor .green
    //线条宽度
    var lineWidth : CGFloat? = 5
    //构造器函数init
    init(name : String, origin : CGPoint) {
        self.name = name
        self.origin = origin
    }
    //便利构造器函数init
    convenience init(origin : CGPoint) {
        self.init(name:"Shape Bassclass", origin: origin)
    }
    //自定义方法drawBezierPath用于画图
    func drawBezierPath(){
        //向控制台输出信息
        print("Draw \(name!)")
    }
}

//线段类Line

class Line : Shape {
    //线段的起点
    var start : CGPoint?
    //线段的终点
    var end: CGPoint?

    //构造器
    init (name: String, origin: CGPoint, start : CGPoint, end : CGPoint) {
        super.init (name: name, origin: origin)
        self.start = start
        self.end = end
    }
    convenience init (start : cGPoint, end: cGPoint) {
        selfinit (name : "Iine", origin: start, start: start, end: end)
    }
    //重载 drawBezierPath 方法
    override func drawBezierPath () {
        //向控制台输出信息
        print ("Draw \(name!)")
        //建立一个UIBezierPath实例对象
        let path = UIBezierPath()
        //调用实例path的move方法移动
        path.move (to: start!)
        //调用实例path的addLine方法画线
        path.addLine (to: end!)
        //设首实例path的线条笕度
        path.linewidth = linewidth!
        //设置实例path的线条终端样式.round或者.square
        path.lineCapStyle = .rouna
        //设置实例path的线条颜色
        linecolor?.setstroke()
        //画出线条
        path.stroke()
    }
}

//矩形类Rectangle

class Rectangle : Shape {
    //左上角采用基类Shape中的属性origin
    //宽度和高度,一般可以采用CGS1ze
    var size : CGSize?
    //构造器
    inst(name: String, origin: CGPoint , size : CGSize) {
        super.init (name: name, origin: origin)
        self.size = size
    }
    convenience init (origin: CGPoint , size : CGSize) {
        self.init(name:"Rectangle", origin: origin, size: size)
    }
    //重載drawBezierPath万法
    override func drawBezierPath () {
        //向控制台输出信息
        print("Draw \(name!)")
        //建立一个UIBezierPath实例对象
        let path = UrBezierPath(rect: CGRect (origin: origin!, size: size!))
        //设置买例path的线条宽度
        path.lineWidth = lineWidth!
        //设置买例path的线条顾色
        lineColor?.setstroke ()
        //画出线条
        path.stroke ()
    }
}

//在实际编程中,我们还需要画具有圆角的矩形,
//那就采用UIKit中的UIBezierPath(roundedRect:CGRect,cornerRadius:CGFloat)
//方法来实现矩形的绘制,这样就要修改这个矩形类
class Rectangle : Shape {
    //左上角采用基类 Shape 中的属性origin
    //宽度和高度,一般可以采用CGSize
    var size : CGsize?
    //圆角的大小
    var corner : CGFloat?
    //构造器
    init (name: String, origin: CGPoint, size: CGSize, corner : CGFloat) {
        super.init (name: name, origin: origin)
        self.size = size
        self.corner = corner
    }
    convenience init (origin: CGPoint , size : CGSize, corner : CGFloat = 0) {
        self.init(name: "Rectangle", origin: origin, size: size, corner: corner)
    }
    //重载drawBezierPath方法
    override func drawBezierPath(){
        //向控制台输出信息
        print ("Draw \(name!) ")
        //建立一个UIBezierPath实例对象
        let path = UIBezierPath(roundedRect : CGRect (origin : origin! size : size!), cornerRadius : corner!)

        //设置实例path的线条宽度
        path.lineWidth = linewidth!
        // 设置实例path的线条颜色
        lineColor?.setStroke ()
        //画出线条
        path.stroke ()
    }
}

//调用代码如下:
    let myRect = Rectangle(origin: start, size: CGSize (width: 150, height: 100),corner : 8.0//则会生成一个带圆角的矩形。如果调用方法如下:
    let myRect = Rectangle(origin: start, size: CGSize (width: 150, height: 100))
//则会生成一个不带圆角的普通矩形,因为在类的便利构造器中,corner默认数是0,也就是相当于圆角为0

//圆形类Circle

class Circle : Shape {
    //圆心坐标
    var center : CGPoint?
    //半径长度
    var raduis : CGFloat?
    //椭圆的宽度和高度,一般可以采用CGSize
    var size : cGsize?

    //构造器
    init(name: String, origin: CGPoint, center : CGPoint, raduis : CGFloat, size: CGSize) {
        super.init (name: name, origin: origin)
        self.center = center
        self.raduis = raduis
        self.size = size
    }
    convenience init(center : CGPoint,raduis : CGFloat) {
        let x = center.x - raduis
        let y = center.y - raduis
        self.init(name: "Circle", origin: CGPoint (×:x,y:y) , center: center, raduis: raduis, size: CGSize (width: raduis, height: raduis))
    }
    convenience init(center : CGPoint, size : CGSize) {
        let x = center.x - size.width/2
        let y = center.y - size.height/2
        self.init(name: "Oval/Ellipse", origin: CGPoint (x:x, y:y) , center:center, raduis: 0, size: size)
    }
    //重载dranBezierPath方法
    override func drawBezierPath (){
        //向控制台输出信息
        print ("Draw \(name!)")
        //建立一个UIBezierPath实例对象
        let path = UIBezierPath(ovalIn: CGRect(loriginorigin!, size:size!))
        //设置实例path的线条宽度
        path.linewidth = linewidth!
        //设置实例path的线条颜色
        linecolor?.setStroke ()
        //画出袋条
        path. stroke ()
    }
}

//多边形类Polygons

class Polygons : Shape {
    //多边形主要是通过多个顶点相互连接来绘图
    //顶点数组
    var points : Array<CGPoint>?

    init(name: String, origin: CGPoint, points: Array<CGPoint> ) {
        super.init(name: name, origin: origin)
        self.points = points
    }
    convenience init (points : Array<CGPoint> ) {
        if points.count == 3 {
            self.init(name: "Triangel", origin: points.first!, points:points)
        }
        else if points.count >= 3 {
            self.init (name: "Polygons", origin: points.first!, points: points)
        }
        else {
            let origin = CGPoint (x: 0, y: 0)
            self.init (name: "Error, origin: origin, points: points")
        }
    }   
    //重載drawBezierPath方法
    override func drawBezierPath() {
        //向控制台输出信息
        print ("Draw \(name!) ")
        //如果不能识别,直接返回
        if(name == "Error"){
            return
        }
        //建立一个UIBezierPath买例对象
        let path = UIBezierPath
        //调用实例path的move方法移动
        pach.move (to: origin!)
        for each in points! {
            //调用买例path的addLine方法画线
            path.addLine (to: each)
        }
        path.close ()
        //设置实例path的线条宽庋
        path.lineWidth = lineWidth!
        //设置实例path的线条颜色
        lineColor?.setstroke ()
        //画出线条
        path.stroke ()
        path.fill ()
    }
}

//5.3.2五角星的绘制

class FiveStar : shape {
    //五角星和正五边形较为类似
    //中心坐标
    var center : CGPoint?
    //半径
    var radius : CGFloat?
    //旋转的角度
    var angel : CGFloat?
    //构造器
    init(name: String, origin: CGPoint, center : CGPoint, radius : CGiloat, angel : CGFloat ) {
        super.init(name: name, origin: origin)
        self.center = center
        self.radius = radius
        self.angel = angel
    }
    convenience init(center : CGPoint, radius : CGFloat, angel : CGFloat = 0) {
        let x = center.x - radius
        let y = center.y - radius
        self.init(name: "FiveStar", origin: CGPOint (x:x, y:y) , center:center, radius: radius, angel: anges)
    }
    //自定义方法drawBezierPath用于画五角星
    override func drawBezierPath ( {
    //调用贝塞尔曲线函数UIBezierPath ()
    let path = UlBezierrath()
    //五角星旋转顶点
    let i = 360/angel!
    let xzAngle = cGFloat.pi*2/i
    let x2X = (center?.X)! - sin(xzAngle) * raaius!
    Let xZY = (center? .y)! - cos (xzAngle) * radius!
    Let p1 = CGPOint (x: zxX, y: zxY)
    path.move(to: p1)
    let angle = CGFloat.pi*4/5
    for i in 1...5 {
        let × - (center?.x)! - sin(CGFloat (i)*angle+×zAngle) *radius!
        let y = (center?.y)! - cos(CGFloat (i)*xangletxzAngle) *radius!
        path.addLine (to: CGPOint (x: x, y: y) )
    }
    path.close ()
    //线条宽度
    path.Linewiath = linewidth!
    //线条颜色为red红色
    lineColor?.setstroke
    //画出这个圆
    path.stroke()
    }
}



//5.4奏响乐队凯歌

//5.4.1声音播放功能
//FiveStar类的构造器需要修改如下

//构造器
init (name: String, origin: CGPoint, center: CGPoint, radius : CGtFloat, angel : CGFloat, soundFile : String = "SO.m4a") {      
    super.init (name: name, origin: origin, soundFile: soundFile)
    self.center = center
    self.radius = radius
    self.angel = angel
}

//5.4.4项目实现
//
// Viewcontroller.swift
// Geometrybana
//
// Created by Zhifeng Chen on 2020/8/4.
// Copyright  2020年 Zhifeng Chen• Al1 rights reserved.
//

import UIkit 
import Foundation 
import AVFoundation
class Shape {
    //名称
    var name: String?
    //声音播放器
    var soundPlayer : AVAudioPlayer?
    //声音文件名称
    var soundFile : String?
    //UIBezierPath
    Var path : UIBezierPath?
    //selected?
    var selectedFlag : Bool = false
    //左上角的位置坐标
    var origin : CGPoint?
    //线条颜色
    var lineColor : UIColor? = UIColor.red
    //填充颜色
    var fillColor : UIColor? = UIColor.green
    //线条宽度
    var lineWidth : CGFloat? = 5
    //构造器函数init
    init(name : String, origin : CGPoint, soundFile: String = "DO.m4a" ) {
        self.name = name
        self.origin = origin
        self.soundFile = soundFile
    }
    //便利构造器函数 init
    convenience init(origin : CGPoint) {
    self.init (name : "Shape Bassclass", origin : origin)
    }

    //自定义方法drawBezierPath用于画图
    func drawBezierPath () {
        //向控制台输出信息
        print ("Draw \(name !)")
    }
    func playAudio () {
        print ("Play sound: \(soundFile!) ")
        let path = Bundle.main. path (forResource: soundFile, ofType: nil)
        let url = URL(fileURLWithPath: path!)
        soundPlayer = try? AVAudioPlayer (contentsOf: ur1)
        soundPlayer?.play ()
    }
    func isSelected (point : CGPoint) -> Bool {
        if (path?.contains (point)) ! {
            selectedFlag = true
            return true
        }
        else {
            selectedFlag = false
            return false
        }
    }
}

class Line: Shape{
    //线段的起点
    var start : CGPoint?
    //线段的终点
    var end : CGPoint?

    //构造器
    init(name: String, origin: CGPoint, start : CGPoint, end : CGPoint,soundFile: String = "FA.m4a") {
        super.init (name: name, origin: origin, soundFile:soundFile)
        self.start = start
        self.end = end
    }
    convenience init(start : CGPoint , end : CGPoint) {
        self.init(name: "Line", origin: start, start: start, end: end)
    }
    //重载 drawBezierPath 方法
    override func drawBezierPath() {
    //向控制台输出信息
    print ("Draw \(name!)")
    //建立一个UIBezierPath实例对象
     path = UIBezierPath ()
    //调用实例path的move方法移动
    path?.move (to: start!)
    //调用实例path的addLine 方法画线
    path?.addLine (to: end!)
    //设置实例path的线条宽度
    path?.linenidth = linewidth!
    //设置实例path 的线条终端样式.round或者.square
    path? .linecapstyle = .round
    //设置实例path 的线条颜色
    llinecolor?.setstroke(
    //画出线条
    path?.stroke()
    }
}
class Rectangle : Shape {
    //左上角采用基类 Shape中的属性origin
    //宽度和高度,一般可以采用CGSize
    var size : CGsize?
    //圆角的大小
    var corner : CGFloat?
    //构造器
    init(name: String, origin: CGPoint, size: CGSize, corner: CGFloat, soundFile :String = "IA.m4a") {
        super.init(name: name, origin: origin, soundFile:soundFile)
        self.size = size
        self.corner = corner
    }
    convenience init(origin: CGPoint, size : CGSize, corner : CGFloat = 0) {
        self.init(name: "Reatangle", origin: origin, size: size, corner : corner)
    }
    //重载 drawBezierPath方法画短形或者正方形
    override func drawBezierPath() {
        //向控制台输出信息
        print ("Draw \(name)!")
        //建立一个UIBezierPath实例对象
        path = UIBezierPath(roundedRect: CGRect (origin: origin!, size:size!), cornerRadius: corner!)
        if selectedFlag {
            let dashes: [CGFloat] = [1, 3]
            path?.setLineDash(dashes, count: dashes. count, phase: 0)
        }
     //设置实例path的线条宽度
        path?.lineWidth = lineWidth!
        //设置实例path的线条颜色
        lineColor?.setStroke ()
        //画出线条
        path? .stroke()
    }
}

class Circle : Shape {
    //圆心坐标
    var center : CGPoint?
    //半径长度
    var raduis : CGFloat?
    //椭圆的宽度和高度,一般可以采用CGSize
    var size : CGSize?

    //构造器
    init(name: String, origin: CGPoint, center : CGPoint, raduis: CGFloat, size : CGSize, soundFile : String = "MI.m4a"'){
        super.init(name: name, origin: origin, soundFile: soundFile)
        self.center = center
        self.raduis = raduis
        self. size = size
    }
    convenience init(center : CGPoint, raduis: CGFloat) {
        let x = center.x - raduis
        let y = center.y - raduis
        self. init (name: "Circle", origin: cGpoint (x:x, y:y) , center: center,reduis: radtuis, Size: CGSize (wiath: raauis, heione: raduis))
    }
    convenience init(center : CGPoint, size : CGSize) {
        let x = center.x - size.width/2
        let y = center.y - size.height/2
        selt. init (name: "oval/E11ipsem" , origin: CGPoint (x:x,y:y), center: center, raduis: 0, size: size)
    }
    //重载 drawBezierPath方法画圆或者椭圆
    override func drawBezierPath() {
        //向控制台输出信息
        print ("Draw \(name!) ")
        //建立一个UIBezierPath实例对象
        path = UIBezierPath(ovalIn: CGRect (oriain: origin!, size: size!))
        if selectedFlag {
            let dashes: [CGFloat] = [1, 3]
            path?.setLineDash (dashes, count: dashes . count, phase: 0)
        }
        //设置实例 path 的线条宽度
        path?.linenidth = linevidth!
        //设置实例 path 的线条颜色
        linecolor?.setstroke ()
        //画出线条
        path? .stroke ()
    }
}

class Polygons : Shape {
    //多边形主要是通过多个顶点相互连接来绘图
    //顶点数组
    var points : Array<CGPoint>?
    //构造器
    init(name: String, origin: CGPoint, points : Array CGPoint>, soundFile: String= "RE.m4a" ) {
        super.init (name: name, origin: origin, soundFile: soundFile)
        self.points = points
    }
    convenience init(points : Array<CGPoint> ) {
        if points.count == 3 {
            self.init(name: "Triangel", origin: points.first!, points: points)
        }
        else if points.count >= 3 { 
            self.init(name: "Polygons", origin: points.first!, points: points)
        }
        else {
            let origin = CGPoint (x: 0, y: 0)
            self.init (name : "Error", origin: origin, Points: points)
        }
    }
    //重载drawBezierPath方法画多边形
    override func drawBezierPath () {
        //向控制台输出信息
        print("Draw \(name!)")
        //如果不能识别,直接返回
        if (name =="Error") {
            return
        }
        //建立一个UIBezierPath实例对象
        path = UIBezierPath ()
        //调用实例path的move方法移动
        path?.move (to: origin!)
        for each in points! {
            //调用实例 path的addiine方法画线
            path?.addLine (to: each)
        }
        path?.close()
        //设置实例path的线条宽度
        path?.linewidth = 1inewidth!
        //设置实例path的线条颜色
        linecolor?.setstroke ()
        //画出线条
        path?.stroke ()
        path?.fi11()
    }
}

class Fivestar : Shape {
    //五角星和正五边形较为类似
    //中心坐标
    var center : CGPoint?
    //半径
    var radius : CGFloat?
    //旋转的角度
    var angel : CGFloat?
    //构造器
    init(name: string, origin: CGPoint, center : CGPoint, radius : CGFloat,angel : CGFloat, soundFile : String = "SO.m4a") {
        super.init (name: name, origin: origin, soundFile: soundFile)
        self.center = center
        self.radius = radius
        self.angel = angel
    }
    convenience init(center : CGPoint, radius: CFloat, angel: CGFloat = 0) {
        let x = center.x - radius
        let y = center.y - radius
        self.init (name: "FiveStar", origin: CGPoint (x:x, y:y) , center: center,radius: radius, angel: angel)
    }
    //自定义方法 drawBezierPath 用于画五角星
    override func drawBezierPath () {
        //向控制台输出信息
        print ("Drav \(name!)")
        //调用贝塞尔曲线西数 UIBezierPath()
        path = UIBezierPath()
        //五角星旋转顶点
        let i = 360 /angel!
        let xzAngle = CGFloat.pi*2/i
        let xzX = (center?.x)!- sin(xzAngle) *radius!
        let xzY = (center?.y)! - cos(xzAngle) *radius!
        let pl = CGPoint (x:xzX,y:xzY)
        path?.move(to: p1)
        let angle = CGFloat.pi*4/5
        for i in 1...5 {
            let x = (center?.x)! - sin(CGFloat (i)*angle+xzAngle)*radius!
            let y = (center?.y)!= cos(CGFloat (i)*angle+xzAngle)*radius!
            path?.addLine (to: CGPoint (x: x, y: y) )
        }
        path?.close ()
        if selectedFlag {
            let dashes: [CGFloat] = [1, 3]
            path?.setLineDash (dashes, count: dashes. count, phase: 0)
        }
        //线条宽度
        path?.lineWidth = lineWidth!
        //线条颜色为red 红色
        linecolor?.setstroke()
        //画出这个圆
        path?. stroke ()
    }
}

marile: soundstle
class czfview : UIview {
    //成员变量(属性)shapes,其类型为Arrav<shape>
    private var shapes : Array<Shape> = []
    //重载UIView的draw方法
    override fune draw( rect : cGRect) {
        //调用shapes这个数组中的每个实例的方法
        for s in shapes {
            s. drawBezierPath()
        }
    }
    //增加实例到数组shapes中
    func add (shape : Shape) {
        shapes.append (shape)
    }
    //触摸事件
    override func touchesBegan (_ touches: Set<UITouch>, with event: UIEvent?)  {
        //获得UITouch 集合
        let touch : UITouch = touches.first! as UIrouch

        //获得触摸所在位置的坐标
        let point = touch . location (in: self)
        //调用shapes这个数组中的每个实例的方法
        for s in shapes {
            //如果被选中
            if s.isSelected (point: point) {
                //声音播放
                s.playAudio ()
                //更新屏幕显示
                self.setNeedsDisplay()
            }
        }
    }
}

class ViewController: UIViewController {

    override func viewDidLoad () {
        super.viewDidLoad ( )
        //Do any additional setup after loading the view, typically from a nib.
        //此处调用 Fivestar 类,建立一个对象(实例)star
        //五角星的中心坐标为 (180,180)
        let starcenter = CGPoint (x: 180,y: 180)
        //五角星的半径设定了90,旅转角度为15度
        let star = FiveStar(center: starCenter, radius: 50, angel: 45)
        star.linecolor = UIColor.blue
        //此处调用Circle类,建立一个对象oval
        let ovalCenter = CGPoint (x: 100, y: 300)
        let ovalsize = CGsize (width : 100, height: 60)
        let oval = Circle (center: ovalCenter, size: ovalSize)
        //此处调用Rectangle类,建立一个对象rect
        let rectorigin = CGPoint(x: 60,y:50)
        let rectsize = CGSize(width: 100, height: 50)
        let rect = Rectangle(origin: rectOrigin, size: rectSize, corner: 6)
        rect.lineColor = UIColor.gray
        //此处建立了一个CzfView的实例myView
        let myView = Czfview (frame: CGRect (x: 0, y: 0, width: self.view.frame.size.width, height: self.view .frame .size.height))
        //清除背景色
        myView.backgroundColor = UIColor.clear
        //赋值给myViem中的成员变量(属性)shape
        myView.add (shape: star)
        myView.add (shape: oval)
        myView.add (shape: rect)
        //显示myview
        self.view.addSubview (myView)
    }
}