Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9207c7f

Browse files
update particle samples
1 parent 8a64f10 commit 9207c7f

File tree

1 file changed

+141
-54
lines changed
  • Tutorial1-1Basics/src/main/java/com/smarttoolfactory/tutorial1_1basics/chapter6_graphics

1 file changed

+141
-54
lines changed

‎Tutorial1-1Basics/src/main/java/com/smarttoolfactory/tutorial1_1basics/chapter6_graphics/ParticlePhysics.kt‎

Lines changed: 141 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,22 @@ package com.smarttoolfactory.tutorial1_1basics.chapter6_graphics
33
import android.content.res.Resources
44
import androidx.compose.foundation.Canvas
55
import androidx.compose.foundation.border
6-
import androidx.compose.foundation.layout.BoxWithConstraints
76
import androidx.compose.foundation.layout.Column
87
import androidx.compose.foundation.layout.Spacer
98
import androidx.compose.foundation.layout.fillMaxSize
109
import androidx.compose.foundation.layout.fillMaxWidth
1110
import androidx.compose.foundation.layout.height
1211
import androidx.compose.foundation.layout.padding
1312
import androidx.compose.foundation.layout.size
13+
import androidx.compose.foundation.rememberScrollState
14+
import androidx.compose.foundation.verticalScroll
1415
import androidx.compose.material.Slider
1516
import androidx.compose.material.Text
1617
import androidx.compose.runtime.Composable
1718
import androidx.compose.runtime.getValue
1819
import androidx.compose.runtime.mutableFloatStateOf
1920
import androidx.compose.runtime.remember
2021
import androidx.compose.runtime.setValue
21-
import androidx.compose.ui.Alignment
2222
import androidx.compose.ui.Modifier
2323
import androidx.compose.ui.geometry.Offset
2424
import androidx.compose.ui.graphics.Color
@@ -32,77 +32,137 @@ import java.util.Random
3232
@Preview
3333
@Composable
3434
fun ControlledExplosion() {
35+
36+
var progress by remember { mutableFloatStateOf(0f) }
37+
38+
var visibilityThresholdLow by remember {
39+
mutableFloatStateOf(0f)
40+
}
41+
42+
var visibilityThresholdHigh by remember {
43+
mutableFloatStateOf(1f)
44+
}
45+
46+
val particleCount = 1
47+
48+
val density = LocalDensity.current
49+
50+
val sizeDp = with(density) {
51+
1000f.toDp()
52+
}
53+
val sizePx = with(density) {
54+
sizeDp.toPx()
55+
}
56+
val sizePxHalf = sizePx / 2
57+
58+
val particles = remember(
59+
visibilityThresholdLow,
60+
visibilityThresholdHigh
61+
) {
62+
List(particleCount) {
63+
ExplodingParticle(
64+
color = Color(listOf(0xffea4335, 0xff4285f4, 0xfffbbc05, 0xff34a853).random()),
65+
startXPosition = sizePxHalf.toInt(),
66+
startYPosition = sizePxHalf.toInt(),
67+
maxHorizontalDisplacement = sizePxHalf,
68+
maxVerticalDisplacement = sizePxHalf,
69+
visibilityThresholdLow = visibilityThresholdLow,
70+
visibilityThresholdHigh = visibilityThresholdHigh
71+
)
72+
}
73+
}
74+
3575
Column(
36-
modifier = Modifier.fillMaxSize().padding(16.dp),
37-
horizontalAlignment = Alignment.CenterHorizontally
76+
modifier = Modifier.fillMaxSize()
77+
.verticalScroll(rememberScrollState())
78+
.padding(vertical = 16.dp, horizontal = 8.dp),
3879
) {
39-
var progress by remember { mutableFloatStateOf(0f) }
4080

41-
Explosion(progress)
81+
Explosion(
82+
progress = progress,
83+
particles = particles,
84+
sizeDp = sizeDp
85+
)
4286

4387
Spacer(Modifier.height(16.dp))
44-
Text(text = "Progress: $progress", fontSize = 18.sp)
88+
89+
val particle = particles.first()
90+
Text(
91+
text = "Progress: ${(progress * 100).toInt() / 100f}\n" +
92+
"trajectory: ${(particle.trajectoryProgress * 100).toInt() / 100f}\n" +
93+
"currentTime: ${(particle.currentTime * 100f).toInt() / 100f}\n",
94+
fontSize = 18.sp
95+
)
4596
Slider(
4697
modifier = Modifier.fillMaxWidth(),
4798
value = progress,
4899
onValueChange = {
49100
progress = it
50101
}
51102
)
103+
104+
Text("visibilityThresholdLow: $visibilityThresholdLow")
105+
Slider(
106+
modifier = Modifier.fillMaxWidth(),
107+
value = visibilityThresholdLow,
108+
onValueChange = {
109+
visibilityThresholdLow = it
110+
},
111+
valueRange = 0f..visibilityThresholdHigh
112+
)
113+
114+
Text("visibilityThresholdHigh: $visibilityThresholdHigh")
115+
Slider(
116+
modifier = Modifier.fillMaxWidth(),
117+
value = visibilityThresholdHigh,
118+
onValueChange = {
119+
visibilityThresholdHigh = it
120+
},
121+
valueRange = visibilityThresholdLow..1f
122+
)
52123
Spacer(Modifier.height(16.dp))
53124
}
54125
}
55126

56127
@Composable
57128
fun Explosion(
129+
sizeDp: Dp,
130+
particles: List<ExplodingParticle>,
58131
progress: Float
59132
) {
60-
BoxWithConstraints {
133+
val density = LocalDensity.current
134+
val sizePx = with(density) {
135+
sizeDp.toPx()
136+
}
61137

62-
val sizeDp = maxWidth
63-
val density = LocalDensity.current
64-
val sizePx = with(density) {
65-
sizeDp.toPx()
66-
}
67-
val sizePxHalf = sizePx / 2
68-
val particles = remember {
69-
List(150) {
70-
ExplodingParticle(
71-
color = Color(listOf(0xffea4335, 0xff4285f4, 0xfffbbc05, 0xff34a853).random()),
72-
startXPosition = sizePxHalf.toInt(),
73-
startYPosition = sizePxHalf.toInt(),
74-
maxHorizontalDisplacement = sizePxHalf,
75-
maxVerticalDisplacement = sizePxHalf
76-
)
77-
}
78-
}
79-
particles.forEach { it.updateProgress(progress) }
80-
81-
Canvas(
82-
modifier = Modifier
83-
.border(width = 1.dp, color = Color(0x26000000))
84-
.size(sizeDp)
85-
) {
86-
drawLine(
87-
color = Color.Black,
88-
start = Offset(sizePxHalf, 0f),
89-
end = Offset(sizePxHalf, sizePx),
90-
strokeWidth = 2.dp.toPx()
91-
)
92-
drawLine(
93-
color = Color.Black,
94-
start = Offset(0f, sizePxHalf),
95-
end = Offset(sizePx, sizePxHalf),
96-
strokeWidth = 2.dp.toPx()
138+
val sizePxHalf = sizePx / 2
139+
140+
particles.forEach { it.updateProgress(progress) }
141+
142+
Canvas(
143+
modifier = Modifier
144+
.border(width = 1.dp, color = Color(0x26000000))
145+
.size(sizeDp)
146+
) {
147+
drawLine(
148+
color = Color.Black,
149+
start = Offset(sizePxHalf, 0f),
150+
end = Offset(sizePxHalf, sizePx),
151+
strokeWidth = 2.dp.toPx()
152+
)
153+
drawLine(
154+
color = Color.Black,
155+
start = Offset(0f, sizePxHalf),
156+
end = Offset(sizePx, sizePxHalf),
157+
strokeWidth = 2.dp.toPx()
158+
)
159+
particles.forEach { particle ->
160+
drawCircle(
161+
alpha = particle.alpha,
162+
color = particle.color,
163+
radius = 5.dp.toPx(),
164+
center = Offset(particle.currentXPosition, particle.currentYPosition),
97165
)
98-
particles.forEach { particle ->
99-
drawCircle(
100-
alpha = particle.alpha,
101-
color = particle.color,
102-
radius = 5.dp.toPx(),
103-
center = Offset(particle.currentXPosition, particle.currentYPosition),
104-
)
105-
}
106166
}
107167
}
108168
}
@@ -112,7 +172,9 @@ class ExplodingParticle(
112172
val startXPosition: Int,
113173
val startYPosition: Int,
114174
val maxHorizontalDisplacement: Float,
115-
val maxVerticalDisplacement: Float
175+
val maxVerticalDisplacement: Float,
176+
val visibilityThresholdLow: Float,
177+
val visibilityThresholdHigh: Float
116178
) {
117179
private val velocity = 4 * maxVerticalDisplacement
118180
private val acceleration = -2 * velocity
@@ -121,13 +183,38 @@ class ExplodingParticle(
121183

122184
var alpha = 1f
123185

186+
var currentTime: Float = 0f
187+
private set
188+
var trajectoryProgress: Float = 0f
189+
private set
190+
124191
fun updateProgress(explosionProgress: Float) {
125-
val currentTime = explosionProgress * 1f
192+
193+
// Trajectory progress translates progress from 0f-1f to
194+
// visibilityThresholdLow-visibilityThresholdHigh
195+
// range. For instance, 0.1-0.6f range movement starts when
196+
// explosionProgress is at 0.1f and reaches 1f
197+
// when explosionProgress reaches 0.6f and trajectoryProgress .
198+
199+
// Each 0.1f change in trajectoryProgress 0.5f total range
200+
// corresponds to 0.2f change of current time
201+
trajectoryProgress =
202+
if (explosionProgress < visibilityThresholdLow ||
203+
(explosionProgress > visibilityThresholdHigh)
204+
) {
205+
return
206+
} else {
207+
explosionProgress
208+
.mapInRange(visibilityThresholdLow, visibilityThresholdHigh, 0f, 1f)
209+
}
210+
211+
currentTime = trajectoryProgress
212+
// .mapInRange(0f, 1f, 0f, 1.4f)
126213

127214
val verticalDisplacement =
128215
currentTime * velocity + 0.5 * acceleration * currentTime * currentTime
129216

130-
currentXPosition = startXPosition + maxHorizontalDisplacement * explosionProgress
217+
currentXPosition = startXPosition + maxHorizontalDisplacement * trajectoryProgress
131218
currentYPosition = (startYPosition - verticalDisplacement).toFloat()
132219

133220
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /