diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6d86594..e1c1db6 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -17,6 +17,7 @@
android:required="true" />
+
0) {
this.hp -= decrease
if (this.hp <= 0) {
diff --git a/app/src/main/java/net/imshit/aircraftwar/element/aircraft/hero/HeroAircraft.kt b/app/src/main/java/net/imshit/aircraftwar/element/aircraft/hero/HeroAircraft.kt
index 2352bbc..10a46e4 100644
--- a/app/src/main/java/net/imshit/aircraftwar/element/aircraft/hero/HeroAircraft.kt
+++ b/app/src/main/java/net/imshit/aircraftwar/element/aircraft/hero/HeroAircraft.kt
@@ -7,10 +7,7 @@ import net.imshit.aircraftwar.element.shoot.hero.HeroShootStrategyFactory
import net.imshit.aircraftwar.logic.game.Games
class HeroAircraft(
- game: Games,
- maxHp: Int,
- power: Int,
- shootNum: Int
+ game: Games, maxHp: Int, power: Int, shootNum: Int, private val controller: HeroController
) : AbstractAircraft(
game = game,
initialX = game.width / 2f,
@@ -22,7 +19,9 @@ class HeroAircraft(
) {
override val image = game.images.aircraftHero
override fun forward(timeMs: Int) {
- // 英雄机由触控控制,不通过forward函数移动
+ this.controller.calcForward(timeMs)
+ this.x = this.controller.x
+ this.y = this.controller.y
}
private val shootStrategyFactory = HeroShootStrategyFactory(game)
@@ -40,6 +39,11 @@ class HeroAircraft(
return this.shootStrategy.shoot(this.x, this.y, this.speedY, this.power)
}
+ override fun decreaseHp(decrease: Int) {
+ super.decreaseHp(decrease)
+ this.controller.onHit()
+ }
+
fun increaseHp(increment: Int) {
if (increment > 0) {
this.hp += increment
diff --git a/app/src/main/java/net/imshit/aircraftwar/element/aircraft/hero/HeroController.kt b/app/src/main/java/net/imshit/aircraftwar/element/aircraft/hero/HeroController.kt
new file mode 100644
index 0000000..3201a62
--- /dev/null
+++ b/app/src/main/java/net/imshit/aircraftwar/element/aircraft/hero/HeroController.kt
@@ -0,0 +1,122 @@
+package net.imshit.aircraftwar.element.aircraft.hero
+
+import android.content.Context
+import android.hardware.Sensor
+import android.hardware.SensorEvent
+import android.hardware.SensorEventListener
+import android.hardware.SensorManager
+import android.os.VibrationEffect
+import android.os.VibratorManager
+import android.view.MotionEvent
+import android.view.View
+import kotlin.math.absoluteValue
+import kotlin.math.pow
+import kotlin.math.sign
+
+class HeroController(private val context: Context) : SensorEventListener, View.OnTouchListener {
+ var x = 0f
+ private set
+ var y = 0f
+ private set
+ private var vx = 0f
+ private var vy = 0f
+
+ private var isTouching = false
+ private var touchX = 0f
+ private var touchY = 0f
+
+ private var gravityAx = 0f
+ private var gravityAy = 0f
+
+ private lateinit var game: View
+ private val sensorManager =
+ this.context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
+ private val gravitySensor = this.sensorManager.run {
+ getDefaultSensor(Sensor.TYPE_GRAVITY) ?: getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
+ }
+ private val vibrator =
+ (this.context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager).defaultVibrator
+
+ fun init(game: View) {
+ this.game = game
+ this.x = game.width / 2f
+ this.y = game.height / 2f
+ // 触摸屏
+ game.setOnTouchListener(this)
+ }
+
+ fun start() {
+ gravitySensor?.let {
+ sensorManager.registerListener(
+ this, it, SensorManager.SENSOR_DELAY_NORMAL
+ )
+ }
+ }
+
+ fun stop() {
+ if (gravitySensor != null) {
+ sensorManager.unregisterListener(this)
+ }
+ }
+
+ fun calcForward(timeMs: Int) {
+ if (isTouching) {
+ val diffX = (touchX - x) / game.width * 20
+ val diffY = (touchY - y) / game.width * 20
+ vx = 0.05f * (diffX.absoluteValue).pow(2) * diffX.sign
+ vy = 0.05f * (diffY.absoluteValue).pow(2) * diffY.sign
+ } else {
+ vx += gravityAx * 0.01f
+ vy += gravityAy * 0.01f
+ }
+ x += vx * timeMs
+ y += vy * timeMs
+ if (x < 0f) {
+ x = 0f
+ vx = 0f
+ } else if (x > game.width) {
+ x = game.width.toFloat()
+ vx = 0f
+ }
+ if (y < 0f) {
+ y = 0f
+ vy = 0f
+ } else if (y > game.height) {
+ y = game.height.toFloat()
+ vy = 0f
+ }
+ }
+
+ fun onHit() {
+ vibrator.vibrate(
+ VibrationEffect.createPredefined(VibrationEffect.EFFECT_DOUBLE_CLICK)
+ )
+ }
+
+ // 处理重力事件
+ override fun onSensorChanged(event: SensorEvent?) {
+ this.gravityAx = -(event?.values?.get(0) ?: 0.0f)
+ this.gravityAy = event?.values?.get(1) ?: 0.0f
+ }
+
+ override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
+
+ // 处理触摸事件
+ override fun onTouch(v: View?, event: MotionEvent?): Boolean {
+ v?.performClick()
+ event?.let {
+ when (it.action) {
+ MotionEvent.ACTION_UP -> {
+ isTouching = false
+ }
+
+ else -> {
+ isTouching = true
+ touchX = it.x
+ touchY = it.y
+ }
+ }
+ }
+ return true
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/net/imshit/aircraftwar/logic/game/Games.kt b/app/src/main/java/net/imshit/aircraftwar/logic/game/Games.kt
index ea2eef4..6c7e32c 100644
--- a/app/src/main/java/net/imshit/aircraftwar/logic/game/Games.kt
+++ b/app/src/main/java/net/imshit/aircraftwar/logic/game/Games.kt
@@ -6,10 +6,6 @@ import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Typeface
-import android.hardware.Sensor
-import android.hardware.SensorEvent
-import android.hardware.SensorEventListener
-import android.hardware.SensorManager
import android.os.Handler
import android.os.Message
import android.util.AttributeSet
@@ -28,6 +24,7 @@ import net.imshit.aircraftwar.element.AbstractFlyingObject
import net.imshit.aircraftwar.element.aircraft.enemy.BossEnemy
import net.imshit.aircraftwar.element.aircraft.enemy.Enemies
import net.imshit.aircraftwar.element.aircraft.hero.HeroAircraft
+import net.imshit.aircraftwar.element.aircraft.hero.HeroController
import net.imshit.aircraftwar.element.animation.DyingAnimation
import net.imshit.aircraftwar.element.bullet.Bullets
import net.imshit.aircraftwar.element.bullet.EnemyBullet
@@ -40,8 +37,6 @@ import net.imshit.aircraftwar.logic.music.BasicMusicStrategy
import net.imshit.aircraftwar.logic.music.BgmType
import net.imshit.aircraftwar.logic.music.MusicStrategies
import net.imshit.aircraftwar.logic.music.MuteMusicStrategy
-import kotlin.math.max
-import kotlin.math.min
sealed class Games(
context: Context, attrs: AttributeSet?, soundMode: Boolean, private val handler: Handler?
@@ -71,22 +66,8 @@ sealed class Games(
const val SCORE_Y = SCORE_SIZE + 10f
}
- class AccelerateSensorListener(val callback: (Float, Float, Float) -> Unit) :
- SensorEventListener {
- override fun onSensorChanged(event: SensorEvent?) {
- val ax = event?.values?.get(0) ?: 0.0f
- val ay = event?.values?.get(1) ?: 0.0f
- val az = event?.values?.get(2) ?: 0.0f
- callback(ax, ay, az)
- }
-
- override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
- }
-
// utils
- private lateinit var sensorManager: SensorManager
- private var gravitySensor: Sensor? = null
- private lateinit var gravitySensorListener: AccelerateSensorListener
+ private val heroController = HeroController(context)
lateinit var images: ImageManager
private var logicJob: Job? = null
@@ -114,10 +95,10 @@ sealed class Games(
private var boss: BossEnemy? = null
// bundle of variables
+ private val heroList = mutableListOf()
private val autoElementLists =
- listOf(animations, props, enemyBullets, heroBullets, enemyAircrafts)
+ listOf(animations, props, enemyBullets, heroBullets, enemyAircrafts, heroList)
private val enemyListenerLists = listOf>(enemyAircrafts, enemyBullets)
- private val heroList = mutableListOf()
private val drawingElementLists =
listOf(enemyBullets, heroBullets, enemyAircrafts, props, animations, heroList)
private val lifeBarElementLists = listOf(heroList, enemyAircrafts)
@@ -157,32 +138,14 @@ sealed class Games(
}
}
- private fun initHeroController() {
- // 触摸屏
- setOnTouchListener { view, motionEvent ->
- view.performClick()
- this.heroAircraft.x = motionEvent.x
- this.heroAircraft.y = motionEvent.y
- true
- }
- // 重力感应
- sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
- with(sensorManager) {
- gravitySensor =
- getDefaultSensor(Sensor.TYPE_GRAVITY) ?: getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
- }
- gravitySensorListener = AccelerateSensorListener { ax, ay, _ ->
- this.heroAircraft.x = min(max(0f, this.heroAircraft.x - ax), this.width.toFloat())
- this.heroAircraft.y = min(max(0f, this.heroAircraft.y + ay), this.height.toFloat())
- }
- }
-
open fun init() {
this.images = ImageManager(context.applicationContext, width)
- this.heroAircraft = HeroAircraft(game = this, maxHp = 1000, power = 50, shootNum = 1)
+ this.heroAircraft = HeroAircraft(
+ game = this, maxHp = 1000, power = 50, shootNum = 1, controller = this.heroController
+ )
this.heroList.add(this.heroAircraft)
this.holder.addCallback(this)
- initHeroController()
+ this.heroController.init(this)
this.musicStrategy.setBgm(BgmType.NORMAL)
}
@@ -190,11 +153,7 @@ sealed class Games(
if (!isGameOver) {
this.isStopped = false
this.musicStrategy.setBgm(BgmType.NORMAL)
- gravitySensor?.let {
- sensorManager.registerListener(
- gravitySensorListener, it, SensorManager.SENSOR_DELAY_NORMAL
- )
- }
+ this.heroController.start()
this.logicJob?.cancel()
this.logicJob = launch {
while (!isStopped) {
@@ -211,9 +170,7 @@ sealed class Games(
private fun stop() {
this.isStopped = true
this.musicStrategy.setBgm(BgmType.NONE)
- if (gravitySensor != null) {
- sensorManager.unregisterListener(gravitySensorListener)
- }
+ this.heroController.stop()
this.logicJob?.cancel()
this.logicJob = null
}