Skip to content

Instantly share code, notes, and snippets.

@Mikkareem
Last active December 11, 2023 12:05
Show Gist options
  • Save Mikkareem/3cb6a1fa91d476a2b6016ed8e9c768c5 to your computer and use it in GitHub Desktop.
Save Mikkareem/3cb6a1fa91d476a2b6016ed8e9c768c5 to your computer and use it in GitHub Desktop.
Random Movers(Particles) in Jetpack Compose
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.DrawScope
import com.techullurgy.composeuisapplication.particlesystems.utils.x
import com.techullurgy.composeuisapplication.particlesystems.utils.xTimes
import com.techullurgy.composeuisapplication.particlesystems.utils.y
import com.techullurgy.composeuisapplication.particlesystems.utils.yTimes
import kotlin.random.Random
class RandomMover {
private var acceleration: Offset = Offset.Zero
private var velocity: Offset = Offset.Zero
private var position: Offset by mutableStateOf(Offset.Zero)
private val color: Color
= Color(
red = Random.nextInt(255),
green = Random.nextInt(255),
blue = Random.nextInt(255)
)
private val radius: Float = Random.nextDouble(10.0, 20.0).toFloat()
private fun DrawScope.edgeDetectionChanges() {
if(position.x < 0f || position.x > size.width) {
position = if(position.x < 0f) {
position.x(0f)
} else {
position.x(size.width)
}
velocity = velocity.xTimes(-1f)
} else if(position.y < 0f || position.y > size.height) {
position = if(position.y < 0f) {
position.y(0f)
} else {
position.y(size.height)
}
velocity = velocity.yTimes(-1f)
}
}
fun setInitialPosition(startPosition: Offset) {
position = startPosition
}
fun applyForce(force: Offset) {
acceleration = acceleration.plus(force)
}
fun update() {
velocity = velocity.plus(acceleration)
position = position.plus(velocity)
acceleration = acceleration.times(0f)
}
fun show(scope: DrawScope) {
scope.showParticle()
}
private fun DrawScope.showParticle() {
edgeDetectionChanges()
drawCircle(
color = color,
radius = radius,
center = position
)
}
}
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.tooling.preview.Preview
import kotlinx.coroutines.delay
import kotlin.random.Random
@Preview
@Composable
fun RandomMoverView() {
val particles: Array<RandomMover> = remember { Array(500) { RandomMover() } }
LaunchedEffect(
key1 = Unit,
block = {
for (particle in particles) {
particle.applyForce(
Offset(
Random.nextDouble(-15.0, 15.0).toFloat(), Random.nextDouble(-15.0, 25.0).toFloat())
)
}
}
)
LaunchedEffect(
key1 = Unit,
block = {
while (true) {
delay(10L)
for (particle in particles) {
particle.update()
}
}
}
)
Canvas(
modifier = Modifier
.onSizeChanged {
for (particle in particles) {
particle.setInitialPosition(
Offset(
x = Random.nextInt(it.width).toFloat(),
y = Random.nextInt(it.height).toFloat()
)
)
}
}
.fillMaxSize()
.background(Color.Black),
onDraw = {
for (particle in particles) {
particle.show(this)
}
}
)
}
@Mikkareem
Copy link
Author

RandomMovers.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment