Skip to content

Commit

Permalink
feat: 加入震动
Browse files Browse the repository at this point in the history
  • Loading branch information
Jim-shop committed May 27, 2023
1 parent fb86424 commit d7eab54
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 59 deletions.
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
android:required="true" />

<uses-permission-sdk-23 android:name="android.permission.INTERNET" />
<uses-permission-sdk-23 android:name="android.permission.VIBRATE" />

<application
android:allowAudioPlaybackCapture="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ abstract class AbstractAircraft(

abstract fun setShootNum(shootNum: Int)

fun decreaseHp(decrease: Int) {
open fun decreaseHp(decrease: Int) {
if (decrease > 0) {
this.hp -= decrease
if (this.hp <= 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
}
63 changes: 10 additions & 53 deletions app/src/main/java/net/imshit/aircraftwar/logic/game/Games.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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?
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -114,10 +95,10 @@ sealed class Games(
private var boss: BossEnemy? = null

// bundle of variables
private val heroList = mutableListOf<HeroAircraft>()
private val autoElementLists =
listOf(animations, props, enemyBullets, heroBullets, enemyAircrafts)
listOf(animations, props, enemyBullets, heroBullets, enemyAircrafts, heroList)
private val enemyListenerLists = listOf<List<EnemyListener>>(enemyAircrafts, enemyBullets)
private val heroList = mutableListOf<HeroAircraft>()
private val drawingElementLists =
listOf(enemyBullets, heroBullets, enemyAircrafts, props, animations, heroList)
private val lifeBarElementLists = listOf(heroList, enemyAircrafts)
Expand Down Expand Up @@ -157,44 +138,22 @@ 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)
}

private fun resume() {
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) {
Expand All @@ -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
}
Expand Down

0 comments on commit d7eab54

Please sign in to comment.