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 cb7d643

Browse files
add ParticlePhysics
1 parent 1bf48e0 commit cb7d643

File tree

1 file changed

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

1 file changed

+151
-0
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package com.smarttoolfactory.tutorial1_1basics.chapter6_graphics
2+
3+
import android.content.res.Resources
4+
import androidx.compose.foundation.Canvas
5+
import androidx.compose.foundation.border
6+
import androidx.compose.foundation.layout.Arrangement
7+
import androidx.compose.foundation.layout.BoxWithConstraints
8+
import androidx.compose.foundation.layout.Column
9+
import androidx.compose.foundation.layout.Spacer
10+
import androidx.compose.foundation.layout.fillMaxSize
11+
import androidx.compose.foundation.layout.fillMaxWidth
12+
import androidx.compose.foundation.layout.height
13+
import androidx.compose.foundation.layout.padding
14+
import androidx.compose.foundation.layout.size
15+
import androidx.compose.material.Slider
16+
import androidx.compose.material.Text
17+
import androidx.compose.runtime.Composable
18+
import androidx.compose.runtime.getValue
19+
import androidx.compose.runtime.mutableFloatStateOf
20+
import androidx.compose.runtime.remember
21+
import androidx.compose.runtime.setValue
22+
import androidx.compose.ui.Alignment
23+
import androidx.compose.ui.Modifier
24+
import androidx.compose.ui.geometry.Offset
25+
import androidx.compose.ui.graphics.Color
26+
import androidx.compose.ui.platform.LocalDensity
27+
import androidx.compose.ui.tooling.preview.Preview
28+
import androidx.compose.ui.unit.Dp
29+
import androidx.compose.ui.unit.dp
30+
import androidx.compose.ui.unit.sp
31+
import java.util.Random
32+
33+
@Preview
34+
@Composable
35+
fun ControlledExplosion() {
36+
Column(
37+
modifier = Modifier.fillMaxSize().padding(16.dp),
38+
horizontalAlignment = Alignment.CenterHorizontally
39+
) {
40+
var progress by remember { mutableFloatStateOf(0f) }
41+
42+
Explosion(progress)
43+
44+
Spacer(Modifier.height(16.dp))
45+
Text(text = "Progress: $progress", fontSize = 18.sp)
46+
Slider(
47+
modifier = Modifier.fillMaxWidth(),
48+
value = progress,
49+
onValueChange = {
50+
progress = it
51+
}
52+
)
53+
Spacer(Modifier.height(16.dp))
54+
}
55+
}
56+
57+
@Composable
58+
fun Explosion(
59+
progress: Float
60+
) {
61+
BoxWithConstraints {
62+
63+
val sizeDp = maxWidth
64+
val density = LocalDensity.current
65+
val sizePx = with(density) {
66+
sizeDp.toPx()
67+
}
68+
val sizePxHalf = sizePx / 2
69+
val particles = remember {
70+
List(150) {
71+
ExplodingParticle(
72+
color = Color(listOf(0xffea4335, 0xff4285f4, 0xfffbbc05, 0xff34a853).random()),
73+
startXPosition = sizePxHalf.toInt(),
74+
startYPosition = sizePxHalf.toInt(),
75+
maxHorizontalDisplacement = sizePxHalf,
76+
maxVerticalDisplacement = sizePxHalf
77+
)
78+
}
79+
}
80+
particles.forEach { it.updateProgress(progress) }
81+
82+
Canvas(
83+
modifier = Modifier
84+
.border(width = 1.dp, color = Color(0x26000000))
85+
.size(sizeDp)
86+
) {
87+
drawLine(
88+
color = Color.Black,
89+
start = Offset(sizePxHalf, 0f),
90+
end = Offset(sizePxHalf, sizePx),
91+
strokeWidth = 2.dp.toPx()
92+
)
93+
drawLine(
94+
color = Color.Black,
95+
start = Offset(0f, sizePxHalf),
96+
end = Offset(sizePx, sizePxHalf),
97+
strokeWidth = 2.dp.toPx()
98+
)
99+
particles.forEach { particle ->
100+
drawCircle(
101+
alpha = particle.alpha,
102+
color = particle.color,
103+
radius = 5.dp.toPx(),
104+
center = Offset(particle.currentXPosition, particle.currentYPosition),
105+
)
106+
}
107+
}
108+
}
109+
}
110+
111+
class ExplodingParticle(
112+
val color: Color,
113+
val startXPosition: Int,
114+
val startYPosition: Int,
115+
val maxHorizontalDisplacement: Float,
116+
val maxVerticalDisplacement: Float
117+
) {
118+
private val velocity = 4 * maxVerticalDisplacement
119+
private val acceleration = -2 * velocity
120+
var currentXPosition = 0f
121+
var currentYPosition = 0f
122+
123+
var alpha = 1f
124+
125+
fun updateProgress(explosionProgress: Float) {
126+
val currentTime = explosionProgress * 1f
127+
128+
val verticalDisplacement =
129+
currentTime * velocity + 0.5 * acceleration * currentTime * currentTime
130+
131+
currentXPosition = startXPosition + maxHorizontalDisplacement * explosionProgress
132+
currentYPosition = (startYPosition - verticalDisplacement).toFloat()
133+
134+
}
135+
}
136+
137+
fun Float.mapInRange(inMin: Float, inMax: Float, outMin: Float, outMax: Float): Float {
138+
return outMin + (((this - inMin) / (inMax - inMin)) * (outMax - outMin))
139+
}
140+
141+
fun Int.dpToPx() = toFloat().dpToPx()
142+
fun Dp.toPx() = value.dpToPx()
143+
144+
fun Float.dpToPx() = this * Resources.getSystem().displayMetrics.density
145+
146+
147+
private val random = Random()
148+
fun Float.randomTillZero() = this * random.nextFloat()
149+
fun randomInRange(min: Float, max: Float) = min + (max - min).randomTillZero()
150+
fun randomBoolean(trueProbabilityPercentage: Int) =
151+
random.nextFloat() < trueProbabilityPercentage / 100f

0 commit comments

Comments
(0)

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