發(fā)布時間:2023-11-30 12:48:16 瀏覽量:249次
游戲效果演示
游戲動畫其實就是將圖片資源逐幀逐幀地播放,只是在這部游戲中我們并不打算用圖片文件而是用程序代碼手繪畫面,因為是手繪所以畫面簡單了些。好了!照例先定義一個父類,然后再定義其它的動畫類并繼承父類。
import android.graphics.Canvas
abstract class BaseEffect {
// 動畫播放的中心坐標
protected var x: Float = 0f
protected var y: Float = 0f
var free: Boolean = true
abstract fun draw(canvas: Canvas)
}
定義完父類后就可以定義實際的子類了,我們先定義子彈的彈痕類BulletEffect.kt
import android.graphics.*
import com.bamboo.boxspacegame.AppGobal
/**
* 子彈擊中物體時的特效
*/
class BulletEffect : BaseEffect() {
private var currentFrame = 0
companion object {
private const val FRAME_COUNT = 15 // 動畫的總幀數(shù)
/**
* 初始化彈痕的Bitmap并緩存
*/
fun init() {
val paint = Paint()
paint.color = Color.WHITE
paint.style = Paint.Style.FILL
repeat(FRAME_COUNT) {
val bmp = Bitmap.createBitmap(
AppGobal.unitSize.toInt(),
AppGobal.unitSize.toInt(),
Bitmap.Config.ARGB_8888
)
Canvas(bmp).apply {
val unit = AppGobal.unitSize / 2f
paint.alpha = 255 - (255 / FRAME_COUNT * it)
paint.shader = RadialGradient(
unit, unit, unit + 0.1f,
intArrayOf(Color.WHITE, Color.TRANSPARENT), null,
Shader.TileMode.CLAMP
)
this.drawCircle(unit, unit, unit, paint)
}
AppGobal.bmpCache.put("bulletEffect_$it", bmp)
}
}
}
/**
* 根據(jù)當前幀的編號繪制動畫
*/
override fun draw(canvas: Canvas) {
val bmp = AppGobal.bmpCache["bulletEffect_$currentFrame"]
val ex = x - AppGobal.unitSize / 2
val ey = y - AppGobal.unitSize / 2
canvas.drawBitmap(bmp, ex, ey, null)
currentFrame++
if (currentFrame >= FRAME_COUNT) {
currentFrame = 0
free = true
}
}
/**
* 播放動畫并設(shè)置動畫播放的坐標
*/
fun play(x: Float, y: Float) {
free = false
this.x = x
this.y = y
this.currentFrame = 0
}
}
當子彈擊中目標或擊在屏幕邊界的時候就開始播放彈痕動畫。接著定義開始爆炸動畫類BombEffect.kt
import android.graphics.*
import com.bamboo.boxspacegame.AppGobal
/**
* 爆炸動畫特效
*/
class BombEffect : BaseEffect() {
private val paint = Paint()
private var currentFrame = 1
private var onFinished: (() -> Unit)? = null // 動畫播放完畢后的回調(diào)函數(shù)
companion object {
const val FRAME_COUNT = 20 // 動畫的總幀數(shù)
}
/**
* 播放動畫
* @param onFinished 動畫播放完畢后的回調(diào)函數(shù),默認可以不傳
*/
fun play(x: Float, y: Float, onFinished: (() -> Unit)? = null) {
this.free = false
this.x = x
this.y = y
this.currentFrame = 0
this.onFinished = onFinished
}
/**
* 直接在屏幕上繪制圖像,并不在游戲初始化時緩存
*/
override fun draw(canvas: Canvas) {
paint.color = Color.WHITE
paint.strokeWidth = 2f
val inc = AppGobal.unitSize / FRAME_COUNT
currentFrame++
if (currentFrame >= FRAME_COUNT) {
currentFrame = 0
free = true
onFinished?.let { it() }
} else {
paint.style = if (currentFrame >= FRAME_COUNT / 2) Paint.Style.STROKE
else Paint.Style.FILL
canvas.drawCircle(x, y, inc * currentFrame, paint)
}
}
}
接著實現(xiàn)游戲的瞬移動畫類FlashEffect.kt
import android.graphics.*
import com.bamboo.boxspacegame.AppGobal
/**
* 瞬移的動畫特效
* 動畫可以正序或倒序播放
*/
class FlashEffect : BaseEffect() {
private var isInvert: Boolean = false // 判斷動畫是正序播放還是倒序播放
private var currentFrame = 0
private var onFinished: (() -> Unit)? = null // 動畫播放完畢后的回調(diào)函數(shù)
companion object {
private const val FRAME_COUNT = 30
fun init() {
val unit = AppGobal.unitSize / 2
val paint = Paint()
paint.color = Color.WHITE
paint.style = Paint.Style.FILL_AND_STROKE
paint.strokeWidth = 1f
repeat(FRAME_COUNT) {
// 繪制瞬移的各幀圖像
val bmp = Bitmap.createBitmap(
(AppGobal.unitSize * 2).toInt(),
(AppGobal.unitSize * 2).toInt(),
Bitmap.Config.ARGB_8888
)
Canvas(bmp).apply {
paint.shader = RadialGradient(
unit, unit, unit,
intArrayOf(
Color.parseColor("#33FFFFFF"),
Color.parseColor("#66FFFFFF"),
Color.WHITE,
), null,
Shader.TileMode.CLAMP
)
val step = (unit / FRAME_COUNT) * it
this.drawCircle(unit, unit, unit - step, paint)
paint.shader = RadialGradient(
unit, unit, unit,
intArrayOf(Color.WHITE, Color.parseColor("#33FFFFFF")), null,
Shader.TileMode.CLAMP
)
this.drawOval(
unit - (unit + step), unit - 2,
unit + (unit + step) - 1, unit + 2,
paint
)
this.drawOval(unit - 1, unit - 6, unit + 1, unit + 6, paint)
}
AppGobal.bmpCache.put(AppGobal.BMP_FLASH + "_$it", bmp)
}
}
}
override fun draw(canvas: Canvas) {
val bmp = AppGobal.bmpCache[AppGobal.BMP_FLASH + "_$currentFrame"]
canvas.drawBitmap(bmp, x, y, null)
if (isInvert) {
currentFrame--
if (currentFrame < 0) {
currentFrame = 15
free = true
onFinished?.let { it() }
}
} else {
currentFrame++
if (currentFrame >= FRAME_COUNT) {
currentFrame = 0
free = true
onFinished?.let { it() }
}
}
}
/**
* 播放瞬移動畫
* @param isInvert 是否倒置播放動畫
* @param onFinished 動畫播放完畢后響應(yīng)
*/
fun play(x: Float, y: Float, isInvert: Boolean = false, onFinished: (() -> Unit)? = null) {
this.x = x
this.y = y
this.free = false
this.currentFrame = if (isInvert) FRAME_COUNT - 1 else 0
this.isInvert = isInvert
this.onFinished = onFinished
}
}
至此,游戲所需要的三個動畫類就全部完成了?,F(xiàn)在我們要實現(xiàn)了個管理類,對這種特效類進行統(tǒng)一管理。EffectManager.kt
import android.graphics.Canvas
/**
* 特效管理類
*/
object EffectManager {
private val listEffect = mutableListOf<BaseEffect>()
@Synchronized
private inline fun <reified T : BaseEffect> obtain(t: T): BaseEffect {
val effect = listEffect.find {
it.free && (it is T)
}
return effect ?: t.apply { listEffect += this }
}
fun obtainBomb(): BombEffect {
return obtain(BombEffect()) as BombEffect
}
fun obtainFlash(): FlashEffect {
return obtain(FlashEffect()) as FlashEffect
}
fun obtainBullet(): BulletEffect {
return obtain(BulletEffect()) as BulletEffect
}
fun draw(canvas: Canvas) {
try {
listEffect.filter { !it.free }.forEach { it.draw(canvas) }
} catch (e: Exception) {
e.printStackTrace()
}
}
@Synchronized
fun release() {
listEffect.clear()
}
}
下一篇我們就要實現(xiàn)游戲的關(guān)卡類了。
如果對我的文章感興趣或有疑問的話可以加我的公眾號或Q群聊:口袋里的安卓
熱門資訊
探討游戲引擎的文章,介紹了10款游戲引擎及其代表作品,涵蓋了RAGE Engine、Naughty Dog Game Engine、The Dead Engine、Cry Engine、Avalanche Engine、Anvil Engine、IW Engine、Frostbite Engine、Creation引擎、Unreal Engine等引擎。借此分析引出了游戲設(shè)計領(lǐng)域和數(shù)字藝術(shù)教育的重要性,歡迎點擊咨詢報名。
2. 手機游戲如何開發(fā)(如何制作傳奇手游,都需要準備些什么?)
?如何制作傳奇手游,都需要準備些什么?提到傳奇手游相信大家都不陌生,他是許多80、90后的回憶;從起初的端游到現(xiàn)在的手游,說明時代在進步游戲在更新,更趨于方便化移動化。而如果我們想要制作一款傳奇手游的
3. B站視頻剪輯軟件「必剪」:免費、炫酷特效,小白必備工具
B站視頻剪輯軟件「必剪」,完全免費、一鍵制作炫酷特效,適合新手小白。快來試試!
游戲中玩家將面臨武俠人生的掙扎抉擇,戰(zhàn)或降?殺或放?每個抉定都將觸發(fā)更多愛恨糾葛的精彩奇遇。《天命奇御》具有多線劇情多結(jié)局,不限主線發(fā)展,高自由...
5. Bigtime加密游戲經(jīng)濟體系揭秘,不同玩家角色的經(jīng)濟活動
Bigtime加密游戲經(jīng)濟模型分析,探討游戲經(jīng)濟特點,幫助玩家更全面了解這款GameFi產(chǎn)品。
6. 3D動漫建模全過程,不是一般人能學(xué)的會的,會的多不是人?
步驟01:面部,頸部,身體在一起這次我不準備設(shè)計圖片,我從雕刻進入。這一次,它將是一種純粹關(guān)注建模而非整體繪畫的形式。像往常一樣,我從Sphere創(chuàng)建它...
7. 3D動畫軟件你知道幾個?3ds Max、Blender、Maya、Houdini大比拼
當提到3D動畫軟件或動畫工具時,指的是數(shù)字內(nèi)容創(chuàng)建工具。它是用于造型、建模以及繪制3D美術(shù)動畫的軟件程序。但是,在3D動畫軟件中還包含了其他類型的...
?三昧動漫對于著名ARPG游戲《巫師》系列,最近CD Projekt 的高層回應(yīng)并不會推出《巫師4》。因為《巫師》系列在策劃的時候一直定位在“三部曲”的故事框架,所以在游戲的出品上不可能出現(xiàn)《巫師4》
9. 3D打印技巧揭秘!Cura設(shè)置讓你的模型更堅固
想讓你的3D打印模型更堅固?不妨嘗試一下Cura參數(shù)設(shè)置和設(shè)計技巧,讓你輕松掌握!
10. Unity3D入門:手把手帶你開發(fā)一款坦克大戰(zhàn)的游戲
Unity工程創(chuàng)建完成后如圖所示: 接下來應(yīng)該導(dǎo)入此項目所需的Unity Package文件,要用到的Unity package文件大家可以去Unity3D的官方網(wǎng)站下載(地址:ht...
最新文章
同學(xué)您好!