feat:完善提前中端结果展示
This commit is contained in:
@@ -14,7 +14,7 @@ import com.chwl.app.base.BaseViewBindingActivity
|
||||
import com.chwl.app.common.widget.dialog.DialogManager
|
||||
import com.chwl.app.game.core.engine.GameEngineAbility
|
||||
import com.chwl.app.game.data.bean.GameInfoUiState
|
||||
import com.chwl.app.game.data.bean.GameResultBean
|
||||
import com.chwl.core.bean.game.GameResultBean
|
||||
import com.chwl.app.game.ui.game.GameViewModel
|
||||
import com.chwl.app.game.ui.result.GameResultDialog
|
||||
import com.chwl.app.ui.pay.ChargeActivity
|
||||
@@ -24,7 +24,6 @@ import com.chwl.core.support.room.RoomWidget
|
||||
import com.chwl.core.utils.net.BalanceNotEnoughExeption
|
||||
import com.chwl.core.utils.net.ServerException
|
||||
import com.chwl.library.utils.ResUtil
|
||||
import com.chwl.library.utils.SingleToastUtil
|
||||
import com.netease.nim.uikit.StatusBarUtil
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.zip
|
||||
@@ -87,6 +86,12 @@ abstract class BaseGameActivity<T : ViewBinding> : BaseViewBindingActivity<T>(),
|
||||
onMatchFailed()
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
it.gameResultFlow.collectLatest { list ->
|
||||
onGameResult(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
initGameEngine(gameContext)
|
||||
}
|
||||
@@ -103,6 +108,7 @@ abstract class BaseGameActivity<T : ViewBinding> : BaseViewBindingActivity<T>(),
|
||||
}
|
||||
|
||||
is GameInfoUiState.Success -> {
|
||||
matchFailedDialogManager?.dismissDialog()
|
||||
dialogManager?.dismissDialog()
|
||||
resultDialog?.dismissAllowingStateLoss()
|
||||
gameInfoDialogManager?.dismissDialog()
|
||||
@@ -150,11 +156,6 @@ abstract class BaseGameActivity<T : ViewBinding> : BaseViewBindingActivity<T>(),
|
||||
}
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
gameEngineAbility?.gameResultFlow?.collectLatest {
|
||||
onGameResult(it)
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
gameEngineAbility?.gameViewFlow?.collectLatest {
|
||||
onGameViewChanged(it)
|
||||
|
||||
@@ -3,8 +3,10 @@ package com.chwl.app.game.core
|
||||
import com.chwl.app.game.data.GameModel2
|
||||
import com.chwl.app.game.data.bean.GameInfoUiState
|
||||
import com.chwl.app.game.ui.game.GameIntent
|
||||
import com.chwl.core.bean.game.GameResultBean
|
||||
import com.chwl.core.bean.game.GameRoomInfo
|
||||
import com.chwl.core.im.custom.bean.CustomAttachment
|
||||
import com.chwl.core.im.custom.bean.GameForcedEndAttachment
|
||||
import com.chwl.core.im.custom.bean.GameQueueChangedAttachment
|
||||
import com.chwl.core.support.room.RoomAbility
|
||||
import com.chwl.core.support.room.RoomContext
|
||||
@@ -46,6 +48,8 @@ class GameStateAbility : RoomAbility(), GameIMEngineAbility.Listener {
|
||||
|
||||
val scoresFlow = MutableStateFlow<List<Double>?>(null)
|
||||
|
||||
val gameConfigFlow = MutableStateFlow<String?>(null)
|
||||
|
||||
@Deprecated("里面的属性有可能不是最新的,建议通过具体属性flow获取数据")
|
||||
val gameInfoFlow = MutableStateFlow<GameRoomInfo?>(null)
|
||||
|
||||
@@ -53,6 +57,8 @@ class GameStateAbility : RoomAbility(), GameIMEngineAbility.Listener {
|
||||
|
||||
val matchFailedFlow = MutableSharedFlow<Boolean>()
|
||||
|
||||
val gameResultFlow = MutableSharedFlow<List<GameResultBean>?>()
|
||||
|
||||
private val queueAbility get() = roomContext?.findAbility<GameQueueAbility>(GameQueueAbility::class.java.simpleName)
|
||||
|
||||
override fun onStart(context: RoomContext) {
|
||||
@@ -90,13 +96,14 @@ class GameStateAbility : RoomAbility(), GameIMEngineAbility.Listener {
|
||||
}
|
||||
|
||||
private suspend fun syncRoomInfo(info: GameRoomInfo) {
|
||||
roomContext?.roomId = info.chatRoomId ?: 0
|
||||
roomContext?.roomId = info.roomId ?: 0
|
||||
gameInfoFlow.value = info
|
||||
roomIdFlow.value = info.chatRoomId
|
||||
roomIdFlow.value = info.roomId
|
||||
imIdFlow.value = info.roomId
|
||||
gameIdFlow.value = info.data?.mgId
|
||||
gameIconFlow.value = info.data?.gameRoomIcon
|
||||
scoresFlow.value = info.data?.scores
|
||||
gameConfigFlow.value = info.data?.configJson
|
||||
syncGameState(info.data?.matchStatus)
|
||||
syncQueue(info)
|
||||
}
|
||||
@@ -112,38 +119,45 @@ class GameStateAbility : RoomAbility(), GameIMEngineAbility.Listener {
|
||||
|
||||
override fun onReceiveMessage(messages: List<ChatRoomMessage>) {
|
||||
messages.forEach {
|
||||
onReceiveMessage(it)
|
||||
if (it.msgType == MsgTypeEnum.custom) {
|
||||
val attachment: CustomAttachment = (it.attachment as? CustomAttachment) ?: return
|
||||
onReceiveCustomMessage(it, attachment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onReceiveMessage(message: ChatRoomMessage) {
|
||||
if (message.msgType == MsgTypeEnum.custom) {
|
||||
val attachment: CustomAttachment = (message.attachment as? CustomAttachment) ?: return
|
||||
when (attachment.first) {
|
||||
CustomAttachment.CUSTOM_MSG_MINI_GAME -> {
|
||||
when (attachment.second) {
|
||||
// 麦位变更
|
||||
CustomAttachment.CUSTOM_MSG_MINI_GAME_QUEUE_CHANGED -> {
|
||||
val gameInfo =
|
||||
(attachment as? GameQueueChangedAttachment)?.gameInfo ?: return
|
||||
safeLaunch {
|
||||
syncQueue(gameInfo)
|
||||
}
|
||||
private fun onReceiveCustomMessage(message: ChatRoomMessage, attachment: CustomAttachment) {
|
||||
when (attachment.first) {
|
||||
CustomAttachment.CUSTOM_MSG_MINI_GAME -> {
|
||||
when (attachment.second) {
|
||||
// 麦位变更
|
||||
CustomAttachment.CUSTOM_MSG_MINI_GAME_QUEUE_CHANGED -> {
|
||||
logD("onReceiveMessage 麦位变更")
|
||||
val gameInfo =
|
||||
(attachment as? GameQueueChangedAttachment)?.gameInfo ?: return
|
||||
safeLaunch {
|
||||
syncQueue(gameInfo)
|
||||
}
|
||||
}
|
||||
|
||||
// 匹配失败
|
||||
CustomAttachment.CUSTOM_MSG_MINI_GAME_MATCH_FAILED -> {
|
||||
safeLaunch {
|
||||
gameStateFlow.value = 3
|
||||
matchFailedFlow.emit(true)
|
||||
}
|
||||
// 匹配失败
|
||||
CustomAttachment.CUSTOM_MSG_MINI_GAME_MATCH_FAILED -> {
|
||||
logD("onReceiveMessage 匹配失败")
|
||||
safeLaunch {
|
||||
syncGameState(STATE_MATCH_FAILED)
|
||||
matchFailedFlow.emit(true)
|
||||
}
|
||||
}
|
||||
|
||||
// 提前结束
|
||||
CustomAttachment.CUSTOM_MSG_MINI_GAME_FORCED_END -> {
|
||||
safeLaunch {
|
||||
gameStateFlow.value = 2
|
||||
}
|
||||
// 提前结束
|
||||
CustomAttachment.CUSTOM_MSG_MINI_GAME_FORCED_END -> {
|
||||
logD("onReceiveMessage 提前结束")
|
||||
val data =
|
||||
(attachment as? GameForcedEndAttachment)?.msgData ?: return
|
||||
val results = data.results
|
||||
safeLaunch {
|
||||
gameResultFlow.emit(results)
|
||||
syncGameState(data.matchStatus)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,27 @@ package com.chwl.app.game.core.engine
|
||||
|
||||
import com.chwl.app.game.core.GameQueueAbility
|
||||
import com.chwl.app.game.core.GameStateAbility
|
||||
import com.chwl.app.game.data.bean.GameResultBean
|
||||
import com.chwl.core.bean.game.GameResultBean
|
||||
import com.chwl.core.bean.game.SudGameConfigBean
|
||||
import com.chwl.core.sud.state.SudMGPMGState
|
||||
import com.chwl.core.support.room.RoomContext
|
||||
import com.chwl.library.utils.json.JsonUtils
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import tech.sud.mgp.core.ISudFSMStateHandle
|
||||
|
||||
class GameEngineAbility : SudEngineAbility() {
|
||||
val gameResultFlow = MutableSharedFlow<List<GameResultBean>?>()
|
||||
|
||||
private val stateAbility get() = roomContext?.findAbility<GameStateAbility>(GameStateAbility::class.java.simpleName)
|
||||
|
||||
private var gameConfig: SudGameConfigBean? = null
|
||||
|
||||
override fun onStart(context: RoomContext) {
|
||||
super.onStart(context)
|
||||
safeLaunch {
|
||||
stateAbility?.gameConfigFlow?.collectLatest {
|
||||
parseGameConfig(it)
|
||||
}
|
||||
}
|
||||
safeLaunch {
|
||||
stateAbility?.gameStateFlow?.collectLatest {
|
||||
logD("GameEngineAbility gameStateFlow state:${it}")
|
||||
@@ -42,6 +50,14 @@ class GameEngineAbility : SudEngineAbility() {
|
||||
private fun tryStopGame() {
|
||||
}
|
||||
|
||||
private fun parseGameConfig(json: String?) {
|
||||
if (json != null) {
|
||||
gameConfig = JsonUtils.fromJson(json, SudGameConfigBean::class.java)
|
||||
} else {
|
||||
gameConfig = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun autoPlayGame() {
|
||||
val stateAbility = stateAbility ?: return
|
||||
logD("autoPlayGame state:${stateAbility.gameStateFlow.value}")
|
||||
@@ -69,6 +85,14 @@ class GameEngineAbility : SudEngineAbility() {
|
||||
override fun onGameStarted() {
|
||||
super.onGameStarted()
|
||||
autoJoinGame()
|
||||
updateGameSettingSelectConfig()
|
||||
}
|
||||
|
||||
private fun updateGameSettingSelectConfig() {
|
||||
val configStr = gameConfig?.getGameSettingSelectConfigStr()
|
||||
if (!configStr.isNullOrEmpty()) {
|
||||
sudFSTAPP.notifyStateChange("app_common_game_setting_select_info", configStr)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPlayerMGCommonPlayerReady(
|
||||
@@ -96,17 +120,29 @@ class GameEngineAbility : SudEngineAbility() {
|
||||
val queueItem = queueAbility?.findQueueItem(uid)
|
||||
val scores = scoresList?.getOrNull(index)
|
||||
val item = GameResultBean().apply {
|
||||
this.uid = it.uid
|
||||
this.uid = it.uid.toLongOrNull()
|
||||
this.rank = it.rank
|
||||
this.score = it.score
|
||||
this.nick = queueItem?.micUser?.nick
|
||||
this.avatar = queueItem?.micUser?.avatar
|
||||
this.coins = scores
|
||||
this.winNum = scores
|
||||
// 目前1v1:第一名成功(后面需要调整这个逻辑)
|
||||
this.isWin = index == 0
|
||||
this.isEscaped = it.isEscaped == 1
|
||||
}
|
||||
list.add(item)
|
||||
}
|
||||
safeLaunch {
|
||||
gameResultFlow.emit(list)
|
||||
stateAbility?.gameResultFlow?.emit(list)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onGetGameCfg(handle: ISudFSMStateHandle, p1: String?) {
|
||||
val configStr = gameConfig?.getGameConfigStr()
|
||||
logD("onGetGameCfg() configStr:$configStr")
|
||||
if (configStr.isNullOrEmpty()) {
|
||||
super.onGetGameCfg(handle, p1)
|
||||
} else {
|
||||
handle.success(configStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import com.chwl.core.room.game.bean.GameCfg
|
||||
import com.chwl.core.sud.decorator.SudFSMMGDecorator
|
||||
import com.chwl.core.sud.decorator.SudFSMMGListener
|
||||
import com.chwl.core.sud.decorator.SudFSTAPPDecorator
|
||||
import com.chwl.core.sud.model.GameConfigModel
|
||||
import com.chwl.core.sud.model.GameViewInfoModel
|
||||
import com.chwl.core.sud.state.MGStateResponse
|
||||
import com.chwl.core.sud.state.SudMGPMGState
|
||||
@@ -192,7 +193,7 @@ open class SudEngineAbility : RoomAbility(), SudFSMMGListener, ILog {
|
||||
}
|
||||
|
||||
override fun onGetGameCfg(handle: ISudFSMStateHandle, p1: String?) {
|
||||
handle.success(JsonUtils.toJson(GameCfg()))
|
||||
handle.success(JsonUtils.toJson(GameConfigModel()))
|
||||
}
|
||||
|
||||
override fun onGameMGCommonSelfClickJoinBtn(
|
||||
|
||||
@@ -6,32 +6,39 @@ import android.widget.TextView
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter
|
||||
import com.chad.library.adapter.base.BaseViewHolder
|
||||
import com.chwl.app.R
|
||||
import com.chwl.app.game.data.bean.GameResultBean
|
||||
import com.chwl.core.bean.game.GameResultBean
|
||||
import com.chwl.app.ui.utils.loadAvatar
|
||||
|
||||
class GameResultAdapter :
|
||||
BaseQuickAdapter<GameResultBean, BaseViewHolder>(R.layout.game_result_item) {
|
||||
override fun convert(helper: BaseViewHolder, item: GameResultBean?) {
|
||||
helper.setText(R.id.tv_name, item?.nick ?: "")
|
||||
helper.setText(R.id.tv_coins, item?.getCoinsStr() ?: "0")
|
||||
helper.setText(R.id.tv_coins, item?.getScoreStr() ?: "0")
|
||||
helper.getView<ImageView>(R.id.iv_user_avatar).loadAvatar(item?.avatar)
|
||||
val rank = helper.bindingAdapterPosition
|
||||
val rank = item?.rank ?: (helper.bindingAdapterPosition + 1)
|
||||
val rankView = helper.getView<TextView>(R.id.tv_rank)
|
||||
val rootView = helper.getView<View>(R.id.layout_root)
|
||||
if (rank == 0) {
|
||||
val coinsBgView = helper.getView<View>(R.id.iv_coins_bg)
|
||||
val avatarBorderView = helper.getView<View>(R.id.iv_user_avatar_border)
|
||||
if (rank == 1) {
|
||||
avatarBorderView.setBackgroundResource(R.drawable.game_result_avatar_border_top_1)
|
||||
rankView.setBackgroundResource(R.drawable.game_result_ic_top1)
|
||||
rankView.text = ""
|
||||
} else if (rank == 1) {
|
||||
} else if (rank == 2) {
|
||||
avatarBorderView.setBackgroundResource(R.drawable.game_result_avatar_border_top_2)
|
||||
rankView.setBackgroundResource(R.drawable.game_result_ic_top2)
|
||||
rankView.text = ""
|
||||
} else {
|
||||
avatarBorderView.background = null
|
||||
rankView.background = null
|
||||
rankView.text = "${(rank + 1)}"
|
||||
rankView.text = "$rank"
|
||||
}
|
||||
if (rank % 2 == 0) {
|
||||
if (rank % 2 == 1) {
|
||||
rootView.setBackgroundResource(R.drawable.game_result_item_bg_top1)
|
||||
coinsBgView.setBackgroundResource(R.drawable.game_result_coins_top1)
|
||||
} else {
|
||||
rootView.setBackgroundResource(R.drawable.game_result_item_bg_top2)
|
||||
coinsBgView.setBackgroundResource(R.drawable.game_result_coins_top2)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import android.view.WindowManager
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.chwl.app.R
|
||||
import com.chwl.app.databinding.GameResultDialogBinding
|
||||
import com.chwl.app.game.data.bean.GameResultBean
|
||||
import com.chwl.core.bean.game.GameResultBean
|
||||
import com.chwl.app.ui.widget.recyclerview.decoration.SpacingDecoration
|
||||
import com.chwl.core.auth.AuthModel
|
||||
import com.chwl.library.common.util.Utils
|
||||
@@ -28,12 +28,11 @@ class GameResultDialog(
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
initView()
|
||||
adapter.setNewData(list)
|
||||
var isSuccess = false
|
||||
if (list.firstOrNull()?.uid?.toLongOrNull() == AuthModel.get().currentUid) {
|
||||
isSuccess = true
|
||||
}
|
||||
if (isSuccess) {
|
||||
adapter.setNewData(list.sortedBy { it.rank })
|
||||
val isWin = list.firstOrNull {
|
||||
it.uid == AuthModel.get().currentUid
|
||||
}?.isWin
|
||||
if (isWin == true) {
|
||||
binding?.ivState?.setBackgroundResource(R.drawable.game_result_bg_win)
|
||||
} else {
|
||||
binding?.ivState?.setBackgroundResource(R.drawable.game_result_bg_lose)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.chwl.app.game.data.bean
|
||||
package com.chwl.core.bean.game
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import java.io.Serializable
|
||||
@@ -7,23 +7,24 @@ import java.math.BigDecimal
|
||||
@Keep
|
||||
class GameResultBean : Serializable {
|
||||
var rank: Int? = null
|
||||
var uid: String? = null
|
||||
var uid: Long? = null
|
||||
var avatar: String? = null
|
||||
var nick: String? = null
|
||||
var score: Int? = null
|
||||
var coins: Double? = null
|
||||
var winNum: Double? = null
|
||||
var isWin: Boolean? = null
|
||||
var isEscaped: Boolean? = null
|
||||
|
||||
fun getCoinsStr(): String {
|
||||
val coinsValue = coins ?: return "0"
|
||||
fun getScoreStr(): String {
|
||||
val number = winNum ?: return "0"
|
||||
try {
|
||||
val bigDecimal = BigDecimal.valueOf(coinsValue)
|
||||
val bigDecimal = BigDecimal.valueOf(number)
|
||||
val coinsStr = bigDecimal.stripTrailingZeros().toPlainString()
|
||||
if (coinsValue > 0) {
|
||||
if (number > 0) {
|
||||
return "+$coinsStr"
|
||||
}
|
||||
return coinsStr
|
||||
} catch (e: Exception) {
|
||||
return coins?.toString() ?: "0"
|
||||
return number.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ class GameRoomData : Serializable {
|
||||
val mgId: String? = null
|
||||
val gameRoomIcon: String? = null
|
||||
val configJson: String? = null
|
||||
val gameSelectCfg: String? = null
|
||||
val scores: MutableList<Double>? = null
|
||||
|
||||
// 匹配状态(0:匹配中、1:匹配成功、2:游戏结束、3:匹配失败)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.chwl.core.bean.game
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.chwl.library.utils.json.JsonUtils
|
||||
|
||||
@Keep
|
||||
class SudGameConfigBean {
|
||||
private val app_common_game_setting_select_info: HashMap<String, Any>? = null
|
||||
|
||||
private val ui: HashMap<String, Any>? = null
|
||||
|
||||
fun getGameSettingSelectConfigStr(): String? {
|
||||
return JsonUtils.toJson(app_common_game_setting_select_info)
|
||||
}
|
||||
|
||||
fun getGameConfigStr(): String? {
|
||||
val uiMap = ui
|
||||
if (uiMap.isNullOrEmpty()) {
|
||||
return null
|
||||
}
|
||||
return JsonUtils.toJson(ConfigModel(uiMap))
|
||||
}
|
||||
|
||||
@Keep
|
||||
private data class ConfigModel(var ui: HashMap<String, Any>)
|
||||
}
|
||||
@@ -11,7 +11,6 @@ abstract class BaseRoomInfo<T> : Serializable {
|
||||
|
||||
val chatRoomId: Long? = null
|
||||
|
||||
// 云信ID
|
||||
val roomId: Long? = null
|
||||
|
||||
val roomMics: MutableList<RoomMicBean>? = null
|
||||
|
||||
@@ -2,13 +2,19 @@ package com.chwl.core.im.custom.bean
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.alibaba.fastjson.JSONObject
|
||||
import com.chwl.core.bean.game.GameRoomInfo
|
||||
import com.chwl.library.utils.json.JsonUtils
|
||||
import com.google.gson.Gson
|
||||
|
||||
@Keep
|
||||
class GameForcedEndAttachment : CustomAttachment {
|
||||
|
||||
var msgData: GameForcedEndMsgBean? = null
|
||||
|
||||
constructor() : super()
|
||||
constructor(first: Int, second: Int) : super(first, second)
|
||||
|
||||
override fun parseData(data: JSONObject?) {
|
||||
msgData = JsonUtils.fromJson(data?.toJSONString(), GameForcedEndMsgBean::class.java)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.chwl.core.im.custom.bean
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.chwl.core.bean.game.GameResultBean
|
||||
|
||||
@Keep
|
||||
class GameForcedEndMsgBean {
|
||||
val results: List<GameResultBean>? = null
|
||||
val matchStatus: Int? = null
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.chwl.core.im.custom.bean
|
||||
import androidx.annotation.Keep
|
||||
import com.alibaba.fastjson.JSONObject
|
||||
import com.chwl.core.bean.game.GameRoomInfo
|
||||
import com.chwl.library.utils.json.JsonUtils
|
||||
import com.google.gson.Gson
|
||||
|
||||
@Keep
|
||||
@@ -13,10 +14,6 @@ class GameQueueChangedAttachment : CustomAttachment {
|
||||
constructor(first: Int, second: Int) : super(first, second)
|
||||
|
||||
override fun parseData(data: JSONObject?) {
|
||||
try {
|
||||
gameInfo = Gson().fromJson(data?.toJSONString(), GameRoomInfo::class.java)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
gameInfo = JsonUtils.fromJson(data?.toJSONString(), GameRoomInfo::class.java)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user