iT邦幫忙

2021 iThome 鐵人賽

DAY 18
0

kotlin

kotlin 也一樣來讓小雞跳起來吧
這邊也一樣有很多種動畫的寫法
同swift來玩玩關鍵影格動畫吧
首先來看看語法

ObjectAnimator.ofPropertyValuesHolder(
    動畫對象, 
    處理動畫的物件+關鍵影格: PropertyValuesHolder  ... Varargs 可變數量的參數
).apply {
    // 此閉包內可設定各種動畫參數
    start() // 開始執行動畫
}

語法上看起來不難對吧~
簡單來說動畫就是 時間點 到 時間點
之間產生屬性(長寬高, 位置, 顏色) 的改變

讓我們再看一次目標動畫的屬性吧

屬性名稱 說明
translationX 透過改變x座標值, 讓小雞呈現左右移動的效果
translationY 透過改變Y座標值, 來實現上下跳動的感覺
rotated 透過變更角度, 讓小雞有種往上跳起, 與往下降落的感覺
scaledX 當小雞跳到最左與最右時, 翻轉小雞, 小雞維持往前的效果, 如果沒有翻轉會看到小雞倒車跑

同上一章~我們把時間表再拿來看一下

時間(用百分比表示) 說明
0% => 10% 小雞往左邊跳起
10% => 20% 小雞往左邊降下
20% => 30% 小雞往左邊跳起
30% => 40% 小雞轉身往右邊降下跳回
40% => 50% 小雞往右邊跳起
50% => 60% 小雞往右邊降下跳回原點
60% => 70% 小雞往右邊跳起
70% => 80% 小雞往右邊降下
80% => 90% 小雞轉身往左邊跳起
90% => 100% 小雞往左邊落下回原點

目前用這樣的思維來讓小雞左右跳動吧
接著我們看看關鍵影格的語法

PropertyValuesHolder.ofKeyframe(屬性名稱,
    Keyframe.ofFloat(0f, 數值), // 0f= 動畫0%時, 
    Keyframe.ofFloat(.1f, 數值),// 0.1f= 動畫10%時,
    ...
)

因為語法的關係
與swift不同
不需要製作資料模型~我們直接開始來撰寫影格吧

// translationX
val pvhtranslationX = PropertyValuesHolder.ofKeyframe("translationX",
    Keyframe.ofFloat(0f, 0f),
    Keyframe.ofFloat(.1f, -33f),
    Keyframe.ofFloat(.2f, -66f),
    Keyframe.ofFloat(.3f, -99f),
    Keyframe.ofFloat(.4f, -66f),
    Keyframe.ofFloat(.5f, -33f),
    Keyframe.ofFloat(.6f, 0f),
    Keyframe.ofFloat(.7f, 40f),
    Keyframe.ofFloat(.8f, 100f),
    Keyframe.ofFloat(.9f, 40f),
    Keyframe.ofFloat(1f, 0f)
)

// translationY
val pvhtranslationY = PropertyValuesHolder.ofKeyframe("translationY",
    Keyframe.ofFloat(0f, 0f),
    Keyframe.ofFloat(.1f, -20f),
    Keyframe.ofFloat(.2f, 0f),
    Keyframe.ofFloat(.3f, -20f),
    Keyframe.ofFloat(.4f, 0f),
    Keyframe.ofFloat(.5f, -20f),
    Keyframe.ofFloat(.6f, 0f),
    Keyframe.ofFloat(.7f, -20f),
    Keyframe.ofFloat(.8f, 0f),
    Keyframe.ofFloat(.9f, -20f),
    Keyframe.ofFloat(1f, 0f)
)
// rotation
val pvhRotation = PropertyValuesHolder.ofKeyframe("rotation",
    Keyframe.ofFloat(0f, 10f),
    Keyframe.ofFloat(.1f, -10f),
    Keyframe.ofFloat(.2f, 10f),
    Keyframe.ofFloat(.3f, -10f),
    Keyframe.ofFloat(.4f, 10f),
    Keyframe.ofFloat(.5f, -10f),
    Keyframe.ofFloat(.6f, 10f),
    Keyframe.ofFloat(.7f, -10f),
    Keyframe.ofFloat(.8f, 10f),
    Keyframe.ofFloat(.9f, -10f),
    Keyframe.ofFloat(1f, 10f)
)
// scaleX
val pvhScaledBy = PropertyValuesHolder.ofKeyframe("scaleX",
    Keyframe.ofFloat(0f, 1f),
    Keyframe.ofFloat(.1f, 1f),
    Keyframe.ofFloat(.2f, 1f),
    Keyframe.ofFloat(.3f, 1f),
    Keyframe.ofFloat(.4f, -1f),
    Keyframe.ofFloat(.5f, -1f),
    Keyframe.ofFloat(.6f, -1f),
    Keyframe.ofFloat(.7f, -1f),
    Keyframe.ofFloat(.8f, -1f),
    Keyframe.ofFloat(.9f, 1f),
    Keyframe.ofFloat(1f, 1f)
)

所有關鍵影格都設定好了
接下來讓我們把關鍵影格設定到動畫物件身上吧
首先我們給小雞圖片一個id 叫做ggView
Kotlin 小雞圖片
接下來就安裝影格吧

// 取得 ggView
val ggView: ImageView = findViewById(R.id.ggView)
// 設定 ggView 關鍵影格
ObjectAnimator.ofPropertyValuesHolder(ggView,
    pvhtranslationY,
    pvhtranslationX,
    pvhRotation,
    pvhScaledBy).apply {
    duration = 4000 // 動畫持續四秒
    repeatCount = ObjectAnimator.INFINITE  // 無限重播
    start()  // 開始播放
}

是的~動畫就這樣做好摟~
讓我們看一下完整程式碼吧

package com.test.chickbb

import android.animation.Keyframe
import android.animation.ObjectAnimator
import android.animation.PropertyValuesHolder
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import java.util.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 透過 R.id.ggButton 取得 Button
        val ggButton: Button = findViewById(R.id.ggButton)
        // 綁定 ggButton onClick 要執行的方法
        ggButton.setOnClickListener{ ggAction() }
        setChickAnimation()
    }

    fun ggAction() {
        // 透過 R.id.ggTextView 取得 TextView
        val ggTextView: TextView = findViewById(R.id.ggTextView)
        // ggTextView 更新  text
        ggTextView.text = ggTextView.text.toString().plus("BB~")
    }

    fun setChickAnimation() {
        // translationX
        val pvhtranslationX = PropertyValuesHolder.ofKeyframe("translationX",
            Keyframe.ofFloat(0f, 0f),
            Keyframe.ofFloat(.1f, -33f),
            Keyframe.ofFloat(.2f, -66f),
            Keyframe.ofFloat(.3f, -99f),
            Keyframe.ofFloat(.4f, -66f),
            Keyframe.ofFloat(.5f, -33f),
            Keyframe.ofFloat(.6f, 0f),
            Keyframe.ofFloat(.7f, 40f),
            Keyframe.ofFloat(.8f, 100f),
            Keyframe.ofFloat(.9f, 40f),
            Keyframe.ofFloat(1f, 0f)
        )

        // translationY
        val pvhtranslationY = PropertyValuesHolder.ofKeyframe("translationY",
            Keyframe.ofFloat(0f, 0f),
            Keyframe.ofFloat(.1f, -20f),
            Keyframe.ofFloat(.2f, 0f),
            Keyframe.ofFloat(.3f, -20f),
            Keyframe.ofFloat(.4f, 0f),
            Keyframe.ofFloat(.5f, -20f),
            Keyframe.ofFloat(.6f, 0f),
            Keyframe.ofFloat(.7f, -20f),
            Keyframe.ofFloat(.8f, 0f),
            Keyframe.ofFloat(.9f, -20f),
            Keyframe.ofFloat(1f, 0f)
        )
        // rotation
        val pvhRotation = PropertyValuesHolder.ofKeyframe("rotation",
            Keyframe.ofFloat(0f, 10f),
            Keyframe.ofFloat(.1f, -10f),
            Keyframe.ofFloat(.2f, 10f),
            Keyframe.ofFloat(.3f, -10f),
            Keyframe.ofFloat(.4f, 10f),
            Keyframe.ofFloat(.5f, -10f),
            Keyframe.ofFloat(.6f, 10f),
            Keyframe.ofFloat(.7f, -10f),
            Keyframe.ofFloat(.8f, 10f),
            Keyframe.ofFloat(.9f, -10f),
            Keyframe.ofFloat(1f, 10f)
        )
        // scaleX
        val pvhScaledBy = PropertyValuesHolder.ofKeyframe("scaleX",
            Keyframe.ofFloat(0f, 1f),
            Keyframe.ofFloat(.1f, 1f),
            Keyframe.ofFloat(.2f, 1f),
            Keyframe.ofFloat(.3f, 1f),
            Keyframe.ofFloat(.4f, -1f),
            Keyframe.ofFloat(.5f, -1f),
            Keyframe.ofFloat(.6f, -1f),
            Keyframe.ofFloat(.7f, -1f),
            Keyframe.ofFloat(.8f, -1f),
            Keyframe.ofFloat(.9f, 1f),
            Keyframe.ofFloat(1f, 1f)
        )
        // 取得 ggView
        val ggView: ImageView = findViewById(R.id.ggView)
        // 設定 ggView 關鍵影格
        ObjectAnimator.ofPropertyValuesHolder(ggView,
            pvhtranslationY,
            pvhtranslationX,
            pvhRotation,
            pvhScaledBy).apply {
            duration = 4000 // 動畫持續四秒
            repeatCount = ObjectAnimator.INFINITE  // 無限重播
            start()  // 開始播放
        }
    }
}

此時只要APP運行
在 onCreate 時會安裝動畫, 之後就不斷播放這則動畫了
kotlin 小雞BB

小碎嘴時間 ヽ(゚´Д`)ノ゚

只要想到關鍵影格
就會想到Flash動畫 ( ≧Д≦)

現在的小朋友應該都不知道了吧?

皮卡丘打排球~
打兔子~
釣魚~
2D CS ~~~~~

童年回憶啊~ 超好玩的

還有阿貴~幹譙龍~
阿罵的腳皮~~

•̀益•́´/ \•̀益•́´/\`•̀益•́´/

不說了~我要來去看幹譙龍的音樂教室了


上一篇
[Day17] swift & kotlin 實作篇!(8) Animation - swift
下一篇
[Day19] swift & kotlin 遊戲篇!(1) 小雞BB-遊戲製作-按鈕排版
系列文
雙平台APP小遊戲開發實作! Swift & Kotlin 攜手出擊~30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言