2018-02-12 Beginning Tile Maps

因?yàn)楣ぷ魃系氖虑橐毓耄瑢K學(xué)習(xí)擱置了一周左右陡舅,心頭實(shí)在過(guò)意不去靶衍,所以晚上繼續(xù)抽空開(kāi)始學(xué)習(xí)新的篇章:Tile Maps


image.png

地圖編輯

地圖編輯大概原理就是將背景拆分成一個(gè)個(gè)的單元格颅眶,首先預(yù)置一些單元格的填充元素涛酗,比如花花草草啊商叹、河流啊,植物啊之類的卵洗,然后通過(guò)地圖編輯器將之前預(yù)置的填充元素編輯到bg中即可忌怎,效果如下:


image.png

單元格的形狀也可以是多樣榴啸,除了標(biāo)準(zhǔn)的正方形以外鸥印,還可以是以下形狀:


image.png

本教程運(yùn)用的是標(biāo)準(zhǔn)正方形的單元格库说,步驟如下:

1. 創(chuàng)建預(yù)置單元格模板TileSet

快捷鍵 cmd+N 選擇 SpriteKit Tile Set潜的,自己命名啰挪,一路enter到底就完成了TileSet的創(chuàng)建嘲叔。


image.png

2. 創(chuàng)建grass tile模板

方法很簡(jiǎn)單锰什,首先將父節(jié)點(diǎn)命名為Background丁逝,然后將默認(rèn)的子節(jié)點(diǎn)命名為grass tile(一開(kāi)始就種點(diǎn)花花草草嘛)霜幼,在media library中選擇花花草草的素材并拖動(dòng)到屏幕中間就完成了grass tile模板的創(chuàng)建辛掠。


image.png

有時(shí)候我們可能會(huì)在地圖中隨機(jī)生成不同樣式的花花草草回挽,實(shí)現(xiàn)也非常簡(jiǎn)單猩谊,我們只需要再拖點(diǎn)其他樣式的花花草草到中間的tile中牌捷,選擇create new variant即可


image.png

拖了以后該Tile下就會(huì)有多個(gè)素材了(因?yàn)槲覍rass2拖了兩遍喜滨,所以出現(xiàn)了兩個(gè)grass2)
image.png

3. 回到GameScene.sks虽风,拖一個(gè)Tile Map Node到場(chǎng)景中寄月,雙擊編輯地圖

image.png

雙擊地圖后如下圖所示漾肮,這樣就可以選擇不同的素材進(jìn)行地圖編輯了克懊。


image.png

編輯完成點(diǎn)擊“Done”退出編輯保檐。
還有一種比較使用的tile夜只,就是8-Way Adjacency Group,大概原理就是將素材拆分成九宮格進(jìn)行處理场躯,這樣我就可以編輯一條帶邊框踢关、不規(guī)則的河了粘茄。


image.png

以上就是純界面操作的地圖基本編輯功能。接下來(lái)我們就要在這個(gè)地圖上來(lái)添加player和bugs了

添加Player

1. 創(chuàng)建Player類吠架,初始化相關(guān)參數(shù)

//創(chuàng)建Player類
class Player: SKSpriteNode {
    
    //預(yù)置player的動(dòng)畫(huà)數(shù)組
    var animations: [SKAction] = []
    
    
    //大概的意思就是要求初始化吧傍药,否則報(bào)錯(cuò)魂仍,不能理解就暫時(shí)當(dāng)成模板記住吧擦酌?
    required init?(coder aDecoder: NSCoder) {
        fatalError("Please use init()")
    }
    
    /*初始化player的參數(shù)如下:
     1. 圖片紋理
     2. 名稱
     3. zPosition
     4. 物理碰撞相關(guān)參數(shù)
     5. 添加動(dòng)畫(huà)效果
    */
    init() {
        
        let texture = SKTexture(imageNamed: "player_bk1")
        
        super.init(texture:texture,
                   color:.white,
                   size:texture.size())
        
        name = "Player"
        
        zPosition = 50
        
        physicsBody = SKPhysicsBody(circleOfRadius: size.width/2)
        
        physicsBody?.restitution = 1.0
        
        physicsBody?.linearDamping = 0.5
        
        physicsBody?.friction = 0
        
        physicsBody?.allowsRotation = false
        
        createAnimations(character: "player")
        
    }

2. 設(shè)置player運(yùn)動(dòng)速率

enum PlayersSetting {
    static let playerSpeed: CGFloat = 5.0
}

3. 創(chuàng)建player運(yùn)動(dòng)方法

教程中是如下寫(xiě)的仑氛,直接讓兩個(gè)CGPoint值相減锯岖,我按照這個(gè)來(lái)寫(xiě),直接報(bào)錯(cuò)遇伞。

func move(target: CGPoint) {
  guard let physicsBody = physicsBody else { return }
  let newVelocity = (target - position).normalized()
                             * PlayerSettings.playerSpeed
  physicsBody.velocity = CGVector(point: newVelocity)
}

所以我還是老老實(shí)實(shí)x-x y-y咯

func move(target: CGPoint) {
        
        guard let physicsBody = physicsBody else {
            return
        }
        
        let newVelocity = CGVector(dx: (target.x - position.x) * PlayersSetting.playerSpeed, dy: (target.y - position.y)  * PlayersSetting.playerSpeed)
        
        physicsBody.velocity = newVelocity
        
        
        print("* \(animationDirection(for: physicsBody.velocity))")
        
        checkDirection()
        
        
    }

然后在GameScene.swift中的touchesBegan中添加player的move事件即可

 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch  = touches.first else {
            return
        }
        
        player.move(target: touch.location(in: self))
    }

到現(xiàn)在player就指哪打哪了鸠珠,但是player沒(méi)有動(dòng)畫(huà)渐排,也無(wú)法轉(zhuǎn)向

設(shè)置Camera

設(shè)置camera的需求是想讓相機(jī)(也就是視角)跟隨player驯耻。

我們先拖一個(gè)camera到場(chǎng)景中并命名為“camera”炒考。然后點(diǎn)擊Scene斋枢,將Camera設(shè)置為camera如下圖所示。


image.png

在學(xué)習(xí)這一節(jié)時(shí)描姚,又學(xué)到了一個(gè)新的東東SKConstraint轰胁。顧名思義就是跟約束相關(guān)的吧。這節(jié)用到這個(gè)類的作用就是要設(shè)置相機(jī)的constraint,使得相機(jī)跟隨player動(dòng)榛斯,而且不能漏出邊框搂捧。

首先讓相機(jī)跟隨player動(dòng)允跑,實(shí)現(xiàn)方法如下(Player類中):

func setupCamera() {
  // 保證有camera的存在
  guard let camera = camera else { return }
// 保證與player的距離為0
  let zeroDistance = SKRange(constantValue: 0)
  let playerConstraint = SKConstraint.distance(zeroDistance,
// 設(shè)置該約束于camera
  camera.constraints = [playerConstraint]
}

然后在GameScene中didMove中添加setCamera()

現(xiàn)在player到哪聋丝,camera就到哪了(2D第一人稱視角,哈哈哈)

但是問(wèn)題就來(lái)了百姓,當(dāng)player到場(chǎng)景邊框時(shí)垒拢,邊框以外的空白區(qū)域就顯現(xiàn)出來(lái)了火惊,很難看屹耐,而且player會(huì)跑到場(chǎng)景邊框以外,如下所示


image.png

我們想要的是如果player接近場(chǎng)景邊框了仓技,相機(jī)照到的區(qū)域就是對(duì)齊場(chǎng)景邊框的區(qū)域脖捻。而且player觸碰到場(chǎng)景邊框了就要被彈回來(lái)地沮。
首先我們需要將場(chǎng)景也設(shè)置為物理體,那么我們就新建以下方法:

func setupWorldPhysics() {
  background.physicsBody =
      SKPhysicsBody(edgeLoopFrom: background.frame)
}

現(xiàn)在我們需要設(shè)置到邊框的constraint了危融,大概的原理就是長(zhǎng)寬都取view和background的最小值雷袋,用這個(gè)范圍設(shè)置為相機(jī)到邊框的約束條件楷怒。最后將相機(jī)的constraints數(shù)組添加edgeConstraint。關(guān)于SKConstraint的用法抱完,以后用到了再詳細(xì)參閱

func setupCamera() {
        
        guard let camera = camera else {
            return
        }
        
        let zeroDistance = SKRange(constantValue: 0)
        
        let playerConstraint = SKConstraint.distance(zeroDistance, to: player)
        
        let xInset = minValue(a: (view?.bounds.width)!/2 * camera.xScale, b: background.frame.width/2)
        
        let yInset = minValue(a: (view?.bounds.width)!/2 * camera.yScale, b: background.frame.height/2)
        
        let constraintRect = background.frame.insetBy(dx: xInset, dy: yInset)
        
        let xRange = SKRange(lowerLimit: constraintRect.minX, upperLimit: constraintRect.maxX)
        
        let yRange = SKRange(lowerLimit: constraintRect.minY, upperLimit: constraintRect.maxY)
        
        let edgeConstraint = SKConstraint.positionX(xRange, y: yRange)
        
        edgeConstraint.referenceNode = background
        
        camera.constraints = [playerConstraint,edgeConstraint]
        
        
    }
    

這樣相機(jī)就能隨著player移動(dòng)巧娱,如果player接近邊框了禁添,相機(jī)就會(huì)停留在依照view的尺寸對(duì)齊background邊框的中心區(qū)域(我擦上荡,好拗口馒闷,還真不好描述纳账,大概能意會(huì)到那個(gè)位置就行),直到player移除了那個(gè)區(qū)域再跟隨player一起動(dòng)(感覺(jué)我的上述描述永罚,我都想到了可以用另外一種實(shí)現(xiàn)方式來(lái)實(shí)現(xiàn)了~~~而不用SKConstraint)

讓player動(dòng)起來(lái)

1. 設(shè)定player運(yùn)動(dòng)的四個(gè)方向及player的動(dòng)畫(huà)素材

新建Type.swift文件呢袱,加入方向的枚舉翅敌,問(wèn)了搞iOS的朋友蚯涮,如果首個(gè)forward的值設(shè)為0卖陵,后面的backward泪蔫,left撩荣,right在沒(méi)有特別指定值的情況下默認(rèn)依次遞增(也就是1饶深,2粥喜,3)


enum Direction: Int {
  case forward = 0, backward, left, right
}

新建Animatable.swift文件额湘,設(shè)置Animatable協(xié)議

protocol Animatable  {
}

然后設(shè)置extension延展規(guī)則锋华,讓遵從Animatable協(xié)議的對(duì)象都可使用以下方法(解釋請(qǐng)查看注釋):

extension Animatable {
    
    func animationDirection(for directionVector: CGVector) -> Direction {
        
        let direction: Direction
        
        if abs(directionVector.dy) > abs(directionVector.dx) {
            
            //當(dāng)Y位移大于X位移時(shí)箭窜,如果Y位移為負(fù)磺樱,則player朝向?yàn)閒orward。否則player朝向?yàn)閎ackward芜辕。
            
            direction = directionVector.dy < 0 ? .forward : .backward
            
        } else {
            
            //當(dāng)Y位移小于X位移時(shí)侵续,如果X位移為負(fù)憨闰,則player朝向?yàn)閘eft。否則player朝向?yàn)閞ight轧坎。

            direction = directionVector.dx < 0 ? .left : .right
            
        }
        
        return direction
        
    }
    
    //加載player行走動(dòng)畫(huà)紋理并添加到animations動(dòng)畫(huà)數(shù)組中眶根。
    func createAnimations(character:String) {
        
        let actionForward: SKAction = SKAction.animate(with: [
            SKTexture(imageNamed: "\(character)_ft1"),
            SKTexture(imageNamed: "\(character)_ft2")
            ], timePerFrame: 0.2)
        
        animations.append(SKAction.repeatForever(actionForward))
        
        
        let actionBackward: SKAction = SKAction.animate(with: [
            SKTexture(imageNamed: "\(character)_bk1"),
            SKTexture(imageNamed: "\(character)_bk2")
            ], timePerFrame: 0.2)
        
        animations.append(SKAction.repeatForever(actionBackward))

        
        
        let actionLeft: SKAction = SKAction.animate(with: [
            SKTexture(imageNamed: "\(character)_lt1"),
            SKTexture(imageNamed: "\(character)_lt2")
            ], timePerFrame: 0.2)
        
        animations.append(SKAction.repeatForever(actionLeft))
        
        
        //這里加兩次的原因是left和right朝向的素材是一個(gè)属百,當(dāng)朝向?yàn)閞ight時(shí),只需要將動(dòng)畫(huà)素材的xScale值設(shè)為-1即可
        animations.append(SKAction.repeatForever(actionLeft))
        
        
    }
    
    
}

然后在Player.swift中添加以下代碼厌丑,讓Player類的對(duì)象遵從Animatable協(xié)議

extension Player : Animatable {}

然后在Animatable.swift的協(xié)議中添加以下成員變量渔呵,使得每一個(gè)遵從該協(xié)議的實(shí)例化對(duì)象都必須要定義承載動(dòng)作的animations數(shù)組(必須實(shí)例化Player類的對(duì)象就必須要定義該數(shù)組)

var animations: [SKAction] {get set}

因?yàn)閜layer對(duì)象需遵從Animatable協(xié)議,所以我們需要在Player類中定義該動(dòng)畫(huà)數(shù)組

var animations: [SKAction] = []

這里有個(gè)細(xì)節(jié)需要說(shuō)明或者說(shuō)是Mark一下耕驰,之前我們定義Animatable的時(shí)候是如下定義的朦肘。

protocol Animatable  {
}

然后我們?cè)趯?xiě)Animatable的extension方法以后發(fā)現(xiàn)變異的時(shí)候會(huì)報(bào)錯(cuò)媒抠,大概報(bào)錯(cuò)的意思就是那兩個(gè)方法返回的數(shù)據(jù)類型是mutable的咏花,但實(shí)際是不允許mutable的,查了一下教程苍匆,原版的解釋如下:

Unfortunately, the protocol no longer compiles. Protocols assume that conforming types may have value semantics (i.e. structures and enumerations) which would make animations immutable. In this situation, the Characters (Player and Bug) are the only classes which will conform to Animatable and, being classes, they have reference semantics. So you can safely inform Animatable that only class types will conform.

翻譯一下

不幸地是锉桑,有了這個(gè)協(xié)議就編譯不過(guò)了窍株。協(xié)議通常會(huì)認(rèn)為遵循協(xié)議的這些類型可能會(huì)包含值語(yǔ)義(比如結(jié)構(gòu)體和枚舉),從而使得animations不可改變后裸。在這種情況下只有 Characters 中的Player微驶、 Bug類將遵循Animatable協(xié)議因苹,正是因?yàn)樗麄儗儆赾lass所以有引用語(yǔ)義,所以你可以告訴Animatable只有class類的對(duì)象才會(huì)遵循該協(xié)議扶檐。(新手表示到這里的時(shí)候有點(diǎn)一臉懵逼,大概的意思就是因?yàn)閜layer是class類的實(shí)例化對(duì)象款筑,而Animatable又是為player量身定制的奈梳,所以讓Animatable只作用class類的對(duì)象,其extension的方法就是mutable的了漆撞?先暫時(shí)這樣理解叫挟,等日后再來(lái)笑話現(xiàn)在的自己限煞,哈哈哈)署驻。

 protocol Animatable: class {
}

2. 讓player動(dòng)起來(lái)

回到Player.swift健霹,在其初始化函數(shù)中添加以下代碼:

  createAnimations(character: "player")

返回createAnimations方法一看就知道糖埋,這樣就把相關(guān)的素材全部合成了動(dòng)畫(huà)并添加到了animations[]數(shù)組中以備后用。

然后就是根據(jù)當(dāng)前player的velocity判斷player的朝向并讓他動(dòng)起來(lái)征候。

func checkDirection() {
        
        guard let physicsBody = physicsBody else { return }
        
        let direction = animationDirection(for: physicsBody.velocity)
        
        if direction == .left {
            
            xScale = abs(xScale)
            
        }
        if direction == .right {
            
            xScale = -abs(xScale)
            
        }
        
        run(animations[direction.rawValue], withKey: "animation")
        
        
        
    }

查了一下rawValue的意思是指返回枚舉對(duì)象的成員值疤坝,那就想通了這里的運(yùn)行原理馆铁。
因?yàn)橹岸x的時(shí)候就將forward、backward历谍、left及right的值分別定義為0、1印蔬、2扛点、3

enum Direction: Int {
    case forward = 0, backward, left, right
}

然后對(duì)應(yīng)的動(dòng)畫(huà)動(dòng)作也是按照f(shuō)orward岂丘、backward奥帘、left及right的順序添加到animations中,所以數(shù)組animation[i]中的動(dòng)畫(huà)對(duì)象就和枚舉中的對(duì)象一一對(duì)應(yīng)松蒜,自然通過(guò)animations[direction.rawValue]就可以找到對(duì)應(yīng)的動(dòng)畫(huà)了秸苗。

因?yàn)榉较蛐r?yàn)是通過(guò)move(target:)中去觸發(fā)的运褪,所以需要將checkDirection()添加到move(target:)中。

現(xiàn)在player不僅僅可以指哪打哪了檀咙,而且可以根據(jù)對(duì)應(yīng)的方向調(diào)整朝向弧可,而且也動(dòng)起來(lái)了


image.png

創(chuàng)建Bug

在challenge中讓添加bug類并添加到場(chǎng)景中棕诵,這個(gè)就沒(méi)什么說(shuō)的了年鸳,代碼如下(留作下一章使用):

class Bug: SKSpriteNode {
    
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("Please use init()")
    }
    
    init() {
        
        let texture = SKTexture(imageNamed: "bug_bk1")
        
        super.init(texture:texture,
                   color:.white,
                   size:texture.size()
                   )
        
        name = "Bug"
        
        zPosition = 49
        
        physicsBody = SKPhysicsBody(circleOfRadius: size.width/2)
        
        physicsBody?.restitution = 0.3
        
        physicsBody?.linearDamping = 0.5
        
        physicsBody?.friction = 0
        
        physicsBody?.allowsRotation = false
        
        
        
    }
    
    
    
    
}

這一章大概就這樣了搔确,話說(shuō)實(shí)際操作一遍膳算,然后邊梳理邏輯邊寫(xiě)筆記好累啊,不過(guò)這樣確實(shí)也很有用华匾,免得無(wú)腦跟著教程敲一遍代碼就over了机隙,接下來(lái)的兩章就是中級(jí)地圖編輯及保存和加載數(shù)據(jù)有鹿。

image.png

年前就先這樣了葱跋,好好過(guò)年放松一下,年后再戰(zhàn)稍味。大家新年快樂(lè)模庐。在此我也給自己樹(shù)立個(gè)小目標(biāo)吧油宜。爭(zhēng)取今年能有兩個(gè)成熟的小游戲成功上架APP STORE吧~新年還要加油

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末验庙,一起剝皮案震驚了整個(gè)濱河市粪薛,隨后出現(xiàn)的幾起案子违寿,更是在濱河造成了極大的恐慌藤巢,老刑警劉巖掂咒,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異温圆,居然都是意外死亡岁歉,警方通過(guò)查閱死者的電腦和手機(jī)锅移,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門非剃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人窍帝,你說(shuō)我怎么就攤上這事努潘。” “怎么了坤学?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵疯坤,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我深浮,道長(zhǎng)压怠,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任飞苇,我火速辦了婚禮菌瘫,結(jié)果婚禮上雨让,老公的妹妹穿的比我還像新娘。我一直安慰自己庵寞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布古沥。 她就那樣靜靜地躺著尊浓,像睡著了一般栋齿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上菇用,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天悍缠,我揣著相機(jī)與錄音滤港,去河邊找鬼溅漾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛暮胧,可吹牛的內(nèi)容都是我干的瞎饲。 我是一名探鬼主播妄田,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼本讥!你這毒婦竟也來(lái)了拷沸?” 一聲冷哼從身側(cè)響起撞芍,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤帝嗡,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后拔莱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡爪幻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年奶甘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了疲陕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诅岩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情懒棉,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站倔韭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏醇疼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望琉兜。 院中可真熱鬧,春花似錦、人聲如沸幌氮。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)机蔗。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嬉挡,已是汗流浹背因谎。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留咸这,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓州丹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蚁鳖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子徙垫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)损肛、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,024評(píng)論 4 62
  • 用到的組件 1、通過(guò)CocoaPods安裝 2、第三方類庫(kù)安裝 3、第三方服務(wù) 友盟社會(huì)化分享組件 友盟用戶反饋 ...
    SunnyLeong閱讀 14,601評(píng)論 1 180
  • 全目錄|【愛(ài)在失憶的日子】 上一章|愛(ài)在失憶的日子(63) 三天過(guò)去了悲雳,婷婷那個(gè)二流子老公都沒(méi)有再來(lái)找過(guò)她。婷婷依...
    小豆利子閱讀 600評(píng)論 14 29
  • "這個(gè)地球離開(kāi)了誰(shuí)依舊照轉(zhuǎn)峭咒。" 大林走了,老何也不在了西壮,如今,你仿佛也畫(huà)下了某一個(gè)句點(diǎn)。 我今天依然在好好生活渠牲,找...
    Enking閱讀 268評(píng)論 0 0
  • 獨(dú)自消磨病未除铣除,功名淡遠(yuǎn)更交疏。 斜陽(yáng)有意催孤雁,落葉無(wú)心宿蔽廬泽铛。 偶得新知秋色晚月褥,共敲殘句月明初舀透。 停杯更向黔山...
    塵埃落定1閱讀 191評(píng)論 4 12