Skip to content

Commit d4d1e62

Browse files
committed
two players running locally works
1 parent 41f2f34 commit d4d1e62

2 files changed

Lines changed: 94 additions & 35 deletions

File tree

watch/app/src/main/java/com/imsproject/watch/view/FlourMillActivity.kt

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.Box
99
import androidx.compose.foundation.layout.fillMaxSize
1010
import androidx.compose.foundation.shape.CircleShape
1111
import androidx.compose.runtime.Composable
12+
import androidx.compose.runtime.LaunchedEffect
1213
import androidx.compose.runtime.collectAsState
1314
import androidx.compose.runtime.getValue
1415
import androidx.compose.runtime.remember
@@ -39,6 +40,7 @@ import com.imsproject.watch.SILVER_COLOR
3940
import com.imsproject.watch.TOUCH_CIRCLE_RADIUS
4041
import com.imsproject.watch.utils.Angle
4142
import com.imsproject.watch.viewmodel.FlourMillViewModel.AxleSide
43+
import kotlinx.coroutines.delay
4244

4345
class FlourMillActivity : GameActivity(GameType.FLOUR_MILL) {
4446

@@ -64,10 +66,29 @@ class FlourMillActivity : GameActivity(GameType.FLOUR_MILL) {
6466
@Composable
6567
fun FlourMill() {
6668
val (centerX, centerY) = remember { polarToCartesian(0f, 0.0) }
69+
val myAxleSide = remember { viewModel.myAxleSide }
6770
val axle = viewModel.axle.collectAsState().value
6871
val myTouchPoint = viewModel.myTouchPoint.collectAsState().value
6972
val opponentTouchPoint = viewModel.opponentTouchPoint.collectAsState().value
7073

74+
LaunchedEffect(Unit){
75+
while(true){
76+
delay(16)
77+
val axle = viewModel.axle.value ?: continue
78+
if(axle.targetAngle != axle.angle){
79+
val diff = axle.targetAngle - axle.angle
80+
val direction = if(Angle.isClockwise(axle.angle,axle.targetAngle)) 1 else -1
81+
if(diff < 1) {
82+
axle.angle = axle.targetAngle
83+
} else if(diff > 4) {
84+
axle.angle += 2f * direction
85+
} else {
86+
axle.angle += 1f * direction
87+
}
88+
}
89+
}
90+
}
91+
7192
Box(
7293
modifier = Modifier
7394
.fillMaxSize()
@@ -84,6 +105,7 @@ class FlourMillActivity : GameActivity(GameType.FLOUR_MILL) {
84105
val relativeRadius = radius / SCREEN_RADIUS
85106
viewModel.setTouchPoint(relativeRadius, angle)
86107
}
108+
87109
PointerEventType.Release -> {
88110
viewModel.setTouchPoint(-1f, Angle.undefined())
89111
}
@@ -133,6 +155,8 @@ class FlourMillActivity : GameActivity(GameType.FLOUR_MILL) {
133155
Canvas(modifier = Modifier.Companion.fillMaxSize()){
134156
if(axle != null){
135157

158+
// ===== Draw the axle without the colored tips ===== |
159+
136160
val axleLeftAngle = axle.angle + -90f
137161
val axleRightAngle = axle.angle + 90f
138162
val (leftTipStartX, leftTipStartY) = polarToCartesian(SCREEN_RADIUS * 0.7f, axleLeftAngle)
@@ -158,20 +182,16 @@ class FlourMillActivity : GameActivity(GameType.FLOUR_MILL) {
158182
style = Stroke(width = AXLE_WIDTH)
159183
)
160184

161-
val sides = listOf(myTouchPoint to axle.mySide, opponentTouchPoint to axle.mySide.otherSide())
162-
for((touchPoint, side) in sides){
163-
val color = if (side == axle.mySide) BRIGHT_CYAN_COLOR else SILVER_COLOR
164-
val path: Path
165-
val sideAngle: Angle
166-
when (side) {
167-
AxleSide.LEFT -> {
168-
path = leftTipPath
169-
sideAngle = axleLeftAngle
170-
}
171-
AxleSide.RIGHT -> {
172-
path = rightTipPath
173-
sideAngle = axleRightAngle
174-
}
185+
val sides = listOf(
186+
Triple(myTouchPoint,myAxleSide,BRIGHT_CYAN_COLOR),
187+
Triple(opponentTouchPoint,myAxleSide.otherSide(),SILVER_COLOR)
188+
)
189+
for((touchPoint, side, color) in sides){
190+
191+
// ===== Draw the colored tips of the axle ====== |
192+
val path = when (side) {
193+
AxleSide.LEFT -> leftTipPath
194+
AxleSide.RIGHT -> rightTipPath
175195
}
176196
drawPath(
177197
path = path,
@@ -181,13 +201,10 @@ class FlourMillActivity : GameActivity(GameType.FLOUR_MILL) {
181201

182202
if(touchPoint.first < 0f) continue
183203

184-
val touchPointDistance = touchPoint.first * SCREEN_RADIUS
185-
val touchPointAngle = touchPoint.second
186-
val touchPointInBounds = (touchPointAngle - sideAngle <= (360f / TOUCH_CIRCLE_RADIUS))
187-
&& touchPointDistance > (SCREEN_RADIUS * 0.7f - TOUCH_CIRCLE_RADIUS)
188-
&& touchPointDistance < (SCREEN_RADIUS * 0.9f + TOUCH_CIRCLE_RADIUS)
204+
// ===== Draw the touch point ====== |
189205

190-
val (x,y) = polarToCartesian(touchPointDistance, touchPointAngle)
206+
val touchPointInBounds = viewModel.isTouchPointInbounds(side)
207+
val (x,y) = polarToCartesian(touchPoint.first * SCREEN_RADIUS, touchPoint.second)
191208

192209
drawCircle(
193210
radius = TOUCH_CIRCLE_RADIUS,

watch/app/src/main/java/com/imsproject/watch/viewmodel/FlourMillViewModel.kt

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,23 @@ import android.util.Log
66
import androidx.compose.runtime.getValue
77
import androidx.compose.runtime.mutableStateOf
88
import androidx.compose.runtime.setValue
9-
import androidx.compose.ui.graphics.Color
109
import androidx.lifecycle.viewModelScope
1110
import com.imsproject.common.gameserver.GameAction
1211
import com.imsproject.common.gameserver.GameType
1312
import com.imsproject.common.gameserver.SessionEvent
1413
import com.imsproject.watch.ACTIVITY_DEBUG_MODE
15-
import com.imsproject.watch.AXLE_STARTING_ANGLE
16-
import com.imsproject.watch.BRIGHT_CYAN_COLOR
1714
import com.imsproject.watch.FLOUR_MILL_SYNC_TIME_THRESHOLD
18-
import com.imsproject.watch.LIGHT_GRAY_COLOR
1915
import com.imsproject.watch.PACKAGE_PREFIX
20-
import com.imsproject.watch.RESET_COOLDOWN_WAIT_TIME
21-
import com.imsproject.watch.STRETCH_PEAK
16+
import com.imsproject.watch.SCREEN_RADIUS
17+
import com.imsproject.watch.TOUCH_CIRCLE_RADIUS
2218
import com.imsproject.watch.utils.Angle
23-
import com.imsproject.watch.utils.toAngle
2419
import com.imsproject.watch.view.contracts.Result
2520
import kotlinx.coroutines.Dispatchers
2621
import kotlinx.coroutines.delay
2722
import kotlinx.coroutines.flow.MutableStateFlow
2823
import kotlinx.coroutines.flow.StateFlow
2924
import kotlinx.coroutines.launch
30-
import kotlinx.coroutines.withContext
31-
import kotlin.math.absoluteValue
25+
import kotlin.math.abs
3226

3327
class FlourMillViewModel : GameViewModel(GameType.FLOUR_MILL) {
3428

@@ -50,7 +44,7 @@ class FlourMillViewModel : GameViewModel(GameType.FLOUR_MILL) {
5044
}
5145
}
5246

53-
class Axle(startingAngle: Angle, val mySide: AxleSide) {
47+
class Axle(startingAngle: Angle) {
5448
var angle by mutableStateOf(startingAngle)
5549
var targetAngle = startingAngle
5650
}
@@ -84,13 +78,25 @@ class FlourMillViewModel : GameViewModel(GameType.FLOUR_MILL) {
8478
override fun onCreate(intent: Intent, context: Context) {
8579
super.onCreate(intent,context)
8680

81+
viewModelScope.launch {
82+
while(true){
83+
delay(16)
84+
updateAxleAngle()
85+
}
86+
}
87+
8788
if(ACTIVITY_DEBUG_MODE) {
8889
myAxleSide = AxleSide.RIGHT
89-
// axle = Axle(AXLE_STARTING_ANGLE.toAngle(), myAxleSide)
9090
viewModelScope.launch(Dispatchers.Default) {
9191
while (true) {
92-
delay(1000)
93-
// TODO: add rotation code
92+
delay(100)
93+
val axle = _axle.value
94+
if(axle == null){
95+
_opponentTouchPoint.value = -1f to Angle.undefined()
96+
} else {
97+
val angle = axle.angle + -80f
98+
_opponentTouchPoint.value = 0.8f to angle
99+
}
94100
}
95101
}
96102
return
@@ -113,9 +119,27 @@ class FlourMillViewModel : GameViewModel(GameType.FLOUR_MILL) {
113119
if(relativeRadius < 0f){
114120
_axle.value = null
115121
} else if (relativeRadius >= 0f && _axle.value == null){
116-
val axleAngle = if(myAxleSide == AxleSide.RIGHT) angle + -90f else angle + 90f
117-
_axle.value = Axle(axleAngle, myAxleSide)
122+
123+
//TODO: do this in the correct place as it won't be local in the future
124+
val axleAngle = angle + if(myAxleSide == AxleSide.RIGHT) -AxleSide.RIGHT.angle else AxleSide.LEFT.angle
125+
_axle.value = Axle(axleAngle)
118126
}
127+
128+
//TODO: network calls
129+
}
130+
131+
fun isTouchPointInbounds(side: AxleSide): Boolean {
132+
val axle = _axle.value ?: return false
133+
134+
val touchPoint = if(side == myAxleSide) _myTouchPoint.value else _opponentTouchPoint.value
135+
if(touchPoint.first < 0f) return false
136+
137+
val touchPointDistance = touchPoint.first * SCREEN_RADIUS
138+
val touchPointAngle = touchPoint.second
139+
val sideAngle = axle.angle + if(side == AxleSide.LEFT) AxleSide.LEFT.angle else AxleSide.RIGHT.angle
140+
return (touchPointAngle - sideAngle <= (360f / TOUCH_CIRCLE_RADIUS))
141+
&& touchPointDistance > (SCREEN_RADIUS * 0.7f - TOUCH_CIRCLE_RADIUS)
142+
&& touchPointDistance < (SCREEN_RADIUS * 0.9f + TOUCH_CIRCLE_RADIUS)
119143
}
120144

121145
// ================================================================================ |
@@ -160,6 +184,24 @@ class FlourMillViewModel : GameViewModel(GameType.FLOUR_MILL) {
160184
}
161185
}
162186

187+
private fun updateAxleAngle(){
188+
val axle = _axle.value ?: return
189+
if(isTouchPointInbounds(AxleSide.LEFT) && isTouchPointInbounds(AxleSide.RIGHT)){
190+
val myAngle = _myTouchPoint.value.second
191+
val opponentAngle = _opponentTouchPoint.value.second
192+
val mySideAngle = axle.angle + myAxleSide.angle
193+
val opponentSideAngle = axle.angle + myAxleSide.otherSide().angle
194+
val myAngleDiff = myAngle - mySideAngle
195+
val opponentAngleDiff = opponentAngle - opponentSideAngle
196+
val myDirection = if(Angle.isClockwise(mySideAngle,myAngle)) 1 else -1
197+
val opponentDirection = if(Angle.isClockwise(opponentSideAngle, opponentAngle)) 1 else -1
198+
if(myAngleDiff > 0 && opponentAngleDiff > 0 && myDirection == opponentDirection){
199+
val amountToRotate = abs(myAngleDiff - opponentAngleDiff)
200+
axle.targetAngle = axle.targetAngle + (amountToRotate * myDirection)
201+
}
202+
}
203+
}
204+
163205
companion object {
164206
private const val TAG = "FlourMillViewModel"
165207
}

0 commit comments

Comments
 (0)