| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608 |
- package com.yingyangfly.game.play
- import android.annotation.SuppressLint
- import android.app.Activity
- import android.app.ActivityManager
- import android.content.Context
- import android.content.Intent
- import android.os.Build
- import android.os.Bundle
- import android.text.TextUtils
- import android.util.Log
- import android.view.MotionEvent
- import android.view.View
- import android.view.ViewTreeObserver
- import android.webkit.WebResourceRequest
- import android.webkit.WebSettings
- import android.webkit.WebView
- import android.webkit.WebViewClient
- import android.widget.FrameLayout
- import androidx.constraintlayout.widget.ConstraintLayout
- import androidx.constraintlayout.widget.ConstraintSet
- import com.alibaba.android.arouter.facade.annotation.Route
- import com.alibaba.android.arouter.launcher.ARouter
- import com.bumptech.glide.Glide
- import com.yingyangfly.baselib.bean.GameDataBean
- import com.yingyangfly.baselib.bean.GetSaveGameRecordBean
- import com.yingyangfly.baselib.db.VoicePlayerBean
- import com.yingyangfly.baselib.ext.*
- import com.yingyangfly.baselib.mvvm.BaseMVVMActivity
- import com.yingyangfly.baselib.player.VoicePlayer
- import com.yingyangfly.baselib.router.RouterUrlCommon
- import com.yingyangfly.baselib.utils.GsonUtil
- import com.yingyangfly.baselib.utils.LiveEventBusUtil
- import com.yingyangfly.baselib.utils.RxBusCodes
- import com.yingyangfly.baselib.utils.img.ImgUtil
- import com.yingyangfly.game.R
- import com.yingyangfly.game.databinding.ActivityPlayGameBinding
- import com.yingyangfly.game.dialog.CompletionTrainingDialog
- import com.yingyangfly.game.dialog.CountdownDialog
- import com.yingyangfly.game.dialog.GameResultDialog
- import com.yingyangfly.game.utils.AndroidToJs
- /**
- * 玩游戏页面
- */
- @Route(path = RouterUrlCommon.playGame)
- class PlayGameActivity : BaseMVVMActivity<ActivityPlayGameBinding, PlayGameViewModel>(),
- View.OnTouchListener {
- /**
- * 游戏是否加载完成
- */
- private var loadingOver = false
- /**
- * 是否第一次启动activity
- */
- private var newStartGame = true
- /**
- * 倒计时是否结束
- */
- private var countdownSuccess = false
- private var gameCode: String = ""
- private var playClass: String = ""
- private var gameType: String = ""
- private var url: String = ""
- private var gameTotalScore: String = ""
- private var gameInbetweenImage = ""
- private var gameBackgroundImage = ""
- private var gameShortDesn = ""
- private lateinit var webSettings: WebSettings
- private var voicePlayer: VoicePlayer? = null
- private var gameResultDialog: GameResultDialog? = null
- var mWebViewHeight = 0
- var mWebViewWidth = 0
- private var mConstrainSet_one: ConstraintSet? = ConstraintSet()
- override fun onCreate(savedInstanceState: Bundle?) {
- gameCode = intent.getStringExtra("gameCode") ?: ""
- playClass = intent.getStringExtra("playClass") ?: ""
- url = intent.getStringExtra("url") ?: ""
- gameType = intent.getStringExtra("gameType") ?: ""
- gameTotalScore = intent.getStringExtra("gameTotalScore") ?: ""
- gameInbetweenImage = intent.getStringExtra("gameInbetweenImage") ?: ""
- gameBackgroundImage = intent.getStringExtra("gameBackgroundImage") ?: ""
- gameShortDesn = intent.getStringExtra("gameShortDesn") ?: ""
- super.onCreate(savedInstanceState)
- }
- override fun initViews() {
- voicePlayer = VoicePlayer.getInstance(mContext)
- if (TextUtils.isEmpty(url).not()) {
- initWebView(url)
- }
- ImgUtil.loadGameBackground(mContext, gameInbetweenImage, binding.imageBg)
- if (TextUtils.isEmpty(gameShortDesn).not()) {
- binding.tvPlay.text = gameShortDesn
- binding.tvIntroduce.text = gameShortDesn
- }
- }
- @SuppressLint("ClickableViewAccessibility")
- override fun initListener() {
- binding {
- tvPause.setOnTouchListener(this@PlayGameActivity)
- tvPauses.setOnTouchListener(this@PlayGameActivity)
- tvFullScreen.setOnTouchListener(this@PlayGameActivity)
- tvReduce.setOnSingleClickListener {
- setReduce(true)
- }
- }
- binding.gameLayout.viewTreeObserver.addOnGlobalLayoutListener(object :
- ViewTreeObserver.OnGlobalLayoutListener {
- override fun onGlobalLayout() {
- mWebViewHeight = binding.gameLayout.height
- mWebViewWidth = binding.gameLayout.width
- binding.gameLayout.viewTreeObserver.removeGlobalOnLayoutListener(this)
- }
- })
- }
- @SuppressLint("SetTextI18n")
- override fun initData() {
- Glide.with(mContext)
- .asGif()
- .load(R.drawable.fish)
- .into(binding.loadingImage)
- initLiveData()
- }
- override fun onNewIntent(intent: Intent?) {
- super.onNewIntent(intent)
- newStartGame = false
- runOnUiThread {
- binding.webView.evaluateJavascript(
- "javascript:CallContinueGame()"
- ) {
- }
- }
- }
- /**
- * 保存游戏进度
- */
- private fun saveData(gameDataBean: GameDataBean) {
- val requestBean = GetSaveGameRecordBean()
- requestBean.gameCode = gameCode
- requestBean.playClass = playClass
- requestBean.isPass = gameDataBean.isPass
- requestBean.duration = gameDataBean.curLevelTime
- requestBean.gameLevel = gameDataBean.curLevel
- requestBean.gameScore = gameDataBean.curLevelScore
- LiveEventBusUtil.send(RxBusCodes.REPORTGAMERECORDS, requestBean)
- }
- @SuppressLint("JavascriptInterface", "SetJavaScriptEnabled")
- private fun initWebView(gameUrl: String) {
- webSettings = binding.webView.settings
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- webSettings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
- }
- val ua = webSettings.userAgentString
- //必须设置
- webSettings.userAgentString = "$ua; app/lottchina Android"
- webSettings.javaScriptCanOpenWindowsAutomatically = true
- webSettings.javaScriptEnabled = true
- webSettings.setAppCacheEnabled(true)
- webSettings.loadWithOverviewMode = true
- webSettings.allowFileAccess = true
- webSettings.allowUniversalAccessFromFileURLs = true
- webSettings.cacheMode = WebSettings.LOAD_DEFAULT
- webSettings.builtInZoomControls = false
- webSettings.setSupportZoom(false)
- webSettings.displayZoomControls = false
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- webSettings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
- }
- webSettings.layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN
- webSettings.useWideViewPort = true//关键点
- //视频自动播放
- webSettings.mediaPlaybackRequiresUserGesture = false
- /**必须的设置, 访问网页版的H5,一定要设置。该方法是设置支持DomStorage,
- * DOM Storage 分为 sessionStorage 和 localStorage。
- * localStorage 对象和 sessionStorage 对象使用方法基本相同,它们的区别在于作用的范围不同。
- * sessionStorage 用来存储与页面相关的数据,它在页面关闭后无法使用。而 localStorage 则持久存在,在页面关闭后也可以使用。
- */
- webSettings.domStorageEnabled = true
- // 通过addJavascriptInterface()将Java对象映射到JS对象 下面一行代码是 JS调用原生方法
- binding.webView.addJavascriptInterface(AndroidToJs(), "AndroidInterface")
- binding.webView.isDrawingCacheEnabled = true
- binding.webView.buildDrawingCache()
- binding.webView.buildLayer()
- binding.webView.webViewClient = object : WebViewClient() {
- override fun shouldOverrideUrlLoading(
- view: WebView?,
- request: WebResourceRequest?
- ): Boolean {
- if (request != null) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- view?.loadUrl(request.url.toString())
- } else {
- view?.loadUrl(request.toString())
- }
- } else {
- gameUrl.let {
- view?.loadUrl(it)
- }
- }
- return true
- }
- override fun onPageFinished(view: WebView?, url: String?) {
- super.onPageFinished(view, url)
- }
- }
- binding.webView.loadUrl(gameUrl)
- }
- @SuppressLint("ClickableViewAccessibility")
- override fun onTouch(v: View, event: MotionEvent): Boolean {
- when (event.action) {
- MotionEvent.ACTION_DOWN -> {
- if (v.id == R.id.tvPause || v.id == R.id.tvPauses || v.id == R.id.tvFullScreen) {
- v.startAnimation(getScaleAnimation())
- }
- }
- MotionEvent.ACTION_UP -> {
- v.startAnimation(getEndAnimation())
- if (v.id == R.id.tvPause || v.id == R.id.tvPauses) {
- runOnUiThread {
- binding.webView.evaluateJavascript(
- "javascript:CallPauseGame()"
- ) {
- ARouter.getInstance().build(RouterUrlCommon.gameIntroduction)
- .withString("gameCode", gameCode)
- .withString("playClass", playClass)
- .withTransition(R.anim.leftin, R.anim.leftout)
- .navigation(mContext)
- }
- }
- } else if (v.id == R.id.tvFullScreen) {
- setReduce(false)
- }
- }
- MotionEvent.ACTION_CANCEL -> {
- if (v.id == R.id.tvPause || v.id == R.id.tvPauses || v.id == R.id.tvFullScreen) {
- v.startAnimation(getEndAnimation())
- }
- }
- }
- return true
- }
- override fun onResume() {
- super.onResume()
- if (newStartGame) {
- newStartGame = false
- val countdownDialog = CountdownDialog()
- countdownDialog.setContentBackground(gameInbetweenImage)
- countdownDialog.onDialogClickListener = {
- if (loadingOver) {
- callStartGame()
- }
- }
- countdownDialog.show(supportFragmentManager, "countdownDialog")
- }
- mConstrainSet_one?.clone(binding.gameParentLayout)
- }
- override fun onDestroy() {
- destoryWebView()
- super.onDestroy()
- }
- /**
- * 结束webview清空缓存
- */
- private fun destoryWebView() {
- binding.webView.stopLoading() // 停止加载
- binding.webView.clearCache(true) // 清除缓存
- binding.webView.clearHistory() // 清楚历史
- binding.webView.loadUrl("about:blank")
- binding.webView.onPause()
- binding.webView.removeAllViews() // 移除webview上子view
- binding.webView.destroy() // 销毁WebView自身
- }
- /**
- * webview调用游戏中方法
- */
- private fun loadJs(it: String) {
- if (TextUtils.equals("0", it)) {
- binding.webView.evaluateJavascript(
- "javascript:CallNextLevel()"
- ) {
- }
- } else {
- binding.webView.evaluateJavascript(
- "javascript:CallRestartGame()"
- ) {
- }
- }
- }
- override fun onPause() {
- super.onPause()
- if (voicePlayer != null) {
- if (voicePlayer!!.isPlaying) {
- voicePlayer?.stop()
- }
- }
- }
- /**
- * 游戏开始
- */
- private fun callStartGame() {
- runOnUiThread {
- binding.webView.evaluateJavascript(
- "javascript:CallStartGame()"
- ) {
- }
- }
- }
- /**
- * 游戏进度监听
- */
- @SuppressLint("SetTextI18n")
- private fun initLiveData() {
- //游戏时间
- LiveEventBusUtil.observer<String>(this, RxBusCodes.SETTIME) {
- binding.tvTime.post {
- if (TextUtils.isEmpty(it).not()) {
- binding.tvTime.text = it
- binding.tvTimes.text = it
- }
- }
- }
- //分数
- LiveEventBusUtil.observer<String>(this, RxBusCodes.SETSCORE) {
- binding.tvScore.post {
- if (TextUtils.isEmpty(it).not()) {
- binding.tvScore.text = it
- binding.tvScores.text = "得分 $it"
- }
- }
- }
- //游戏关卡
- LiveEventBusUtil.observer<String>(this, RxBusCodes.SETLEVEL) {
- binding.tvGameLevel.post {
- if (TextUtils.isEmpty(it).not()) {
- binding.tvGameLevel.text = "第" + it + "关"
- binding.tvGameLevels.text = "第" + it + "关"
- }
- }
- }
- //游戏进度
- LiveEventBusUtil.observer<String>(this, RxBusCodes.SAVEDATA) {
- binding.tvScore.postDelayed({
- if (TextUtils.isEmpty(it).not()) {
- Log.e("wpp", "-----------" + it)
- val gameDataBean = GsonUtil.GsonToBean(it, GameDataBean::class.java)
- if (gameDataBean != null) {
- val isPass = gameDataBean.isPass
- if (TextUtils.equals("4", gameDataBean.isPass) || TextUtils.equals(
- "2",
- gameDataBean.isPass
- )
- ) {
- gameDataBean.isPass = "1"
- } else if (TextUtils.equals("3", gameDataBean.isPass)) {
- gameDataBean.isPass = "0"
- }
- saveData(gameDataBean)
- parsingData(gameDataBean, isPass)
- }
- }
- }, 100)
- }
- //游戏加载完成
- LiveEventBusUtil.observer<String>(this, RxBusCodes.LOADINGOVER) {
- loadingOver = true
- if (countdownSuccess) {
- callStartGame()
- }
- }
- //播放语音
- LiveEventBusUtil.observer<String>(this, RxBusCodes.PLAYVOICE) {
- if (it.isNullOrEmpty().not()) {
- val msg = it.split("voice:")
- if (msg.isNullOrEmpty().not()) {
- binding.tvIntroduce.text = msg[1]
- speak(msg[1])
- }
- }
- }
- //游戏超时退出
- LiveEventBusUtil.observer<String>(this, RxBusCodes.GAMEOVERTIME) {
- finish()
- }
- //返回首页结束游戏
- LiveEventBusUtil.observer<String>(this, RxBusCodes.CALLQUITGAME) {
- runOnUiThread {
- binding.webView.evaluateJavascript(
- "javascript:CallQuitGame()"
- ) {
- }
- }
- }
- //结束游戏
- LiveEventBusUtil.observer<String>(this, RxBusCodes.FINISHGAME) {
- runOnUiThread {
- finish()
- }
- }
- //游戏倒计时弹框消失
- LiveEventBusUtil.observer<String>(this, RxBusCodes.COUNTDOWNSUCCESS) {
- countdownSuccess = true
- }
- }
- /**
- * 语音合成
- */
- private fun speak(desn: String) {
- if (db != null) {
- val voicePlayerDao = db?.getVoicePlayerDao()
- if (voicePlayerDao != null) {
- val voicePlayerBean = voicePlayerDao.getVoicePlayerBean(desn)
- if (voicePlayerBean != null) {
- if (voicePlayer != null) {
- if (isTopActivity(this)) {
- voicePlayer?.play(voicePlayerBean.url) {
- binding.tvIntroduce.text = gameShortDesn
- callPlayBgMusic()
- }
- }
- }
- } else {
- getVoiceUrl(desn)
- }
- } else {
- getVoiceUrl(desn)
- }
- } else {
- getVoiceUrl(desn)
- }
- }
- /**
- * 获取声音url
- */
- private fun getVoiceUrl(taskDesn: String) {
- viewModel.getVoiceUrl(taskDesn, fail = {
- it.toast()
- }, success = {
- if (TextUtils.isEmpty(it).not()) {
- if (db != null) {
- val voicePlayerDao = db?.getVoicePlayerDao()
- if (voicePlayerDao != null) {
- val voicePlayerBean = VoicePlayerBean().apply {
- url = it
- words = taskDesn
- }
- voicePlayerDao.insert(voicePlayerBean)
- }
- }
- if (voicePlayer != null) {
- if (isTopActivity(this)) {
- voicePlayer?.play(it) {
- }
- }
- }
- }
- })
- }
- /**
- * 开启游戏音乐
- */
- private fun callPlayBgMusic() {
- runOnUiThread {
- binding.webView.evaluateJavascript(
- "javascript:CallPlayBgMusic()"
- ) {
- }
- }
- }
- /**
- * 游戏保存接口
- */
- private fun parsingData(gameDataBean: GameDataBean, isPass: String) {
- runOnUiThread {
- runOnUiThread {
- if (TextUtils.equals("2", isPass)) {
- LiveEventBusUtil.send(RxBusCodes.QUITGAME, "")
- finish()
- } else if (TextUtils.equals("3", isPass)) {
- val score: Int = gameTotalScore.toInt() + gameDataBean.curLevelScore.toInt()
- gameTotalScore = score.toString()
- if (TextUtils.equals("A", playClass)) {
- showCompletionTrainingDialog(gameDataBean)
- } else {
- //游戏通关
- ARouter.getInstance().build(RouterUrlCommon.gameSettlement)
- .withString("gameCode", gameCode)
- .withString("playClass", playClass)
- .withString("gameType", gameType)
- .withTransition(R.anim.leftin, R.anim.leftout)
- .navigation(mContext)
- }
- } else {
- val score: Int = gameTotalScore.toInt() + gameDataBean.curLevelScore.toInt()
- gameTotalScore = score.toString()
- if (TextUtils.equals("A", playClass)) {
- showCompletionTrainingDialog(gameDataBean)
- } else {
- //游戏成功/失败
- gameResultDialog = GameResultDialog()
- gameResultDialog?.setData(
- gameDataBean.curLevel,
- gameTotalScore,
- gameDataBean.curLevelScore,
- gameDataBean.isPass
- )
- gameResultDialog?.onBackHomeDialogClickListener = {
- finish()
- LiveEventBusUtil.send(RxBusCodes.GAMEOVERTIME, "")
- }
- gameResultDialog?.onGameDialogClickListener = {
- loadJs(it)
- }
- gameResultDialog?.show(supportFragmentManager, "gameResultDialog")
- }
- }
- }
- }
- }
- /**
- * 展示游戏结束弹窗
- */
- private fun showCompletionTrainingDialog(gameDataBean: GameDataBean) {
- val completionTrainingDialog = CompletionTrainingDialog()
- completionTrainingDialog.setData(
- gameTotalScore,
- gameDataBean.curLevelScore
- )
- completionTrainingDialog.onDialogClickListener = {
- finish()
- LiveEventBusUtil.send(RxBusCodes.GAMEOVERTIME, "")
- }
- completionTrainingDialog.show(
- supportFragmentManager,
- "completionTrainingDialog"
- )
- }
- /**
- * 判断当前activity是否位于栈顶
- */
- private fun isTopActivity(activity: Activity): Boolean {
- val am = activity.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
- val cn = am.getRunningTasks(1)[0].topActivity
- return cn!!.className == activity.javaClass.name
- }
- /**
- * 是否缩放
- */
- private fun setReduce(isReduce: Boolean) {
- binding.webView.post {
- binding.tvFullScreen.show(isReduce)
- binding.tvReduce.show(isReduce.not())
- if (isReduce) {
- val params = ConstraintLayout.LayoutParams(
- mWebViewWidth,
- mWebViewHeight
- )
- binding.gameLayout.radius = 49F
- binding.gameLayout.layoutParams = params
- binding.gameFullLayout.show(isReduce)
- mConstrainSet_one?.applyTo(binding.gameParentLayout)
- } else {
- val params = FrameLayout.LayoutParams(
- FrameLayout.LayoutParams.MATCH_PARENT,
- FrameLayout.LayoutParams.MATCH_PARENT
- )
- binding.gameLayout.radius = 0F
- binding.gameLayout.layoutParams = params
- binding.gameFullLayout.show(isReduce.not())
- }
- }
- }
- }
|