
μ§κΈκΉμ§ λ°°μ΄ κ²λ€μ λͺ¨λ κ°κ³Ό ν¨μλ₯Ό λ€λ£¨λ λ°©λ²μ λλ€.
νμ§λ§ μ λλ¬ν°λΈ μνΈμμλ μ¬λ¬ λ°μ΄ν°λ₯Ό νλλ‘ λ¬Άμ΄μ κ΄λ¦¬ν΄μΌ ν©λλ€.
μλ₯Ό λ€μ΄:
// λμ λ°©λ²: λ°μ΄ν°λ₯Ό ν©μ΄λμ
var x = 100.0
var y = 200.0
var vx = 1.5
var vy = -0.5
var radius = 10.0
var age = 0.0
var lifespan = 100.0
// κ·Έλ¬λ©΄ μ΄ λͺ¨λ λ³μλ€μ ν¨μμ μ λ¬ν΄μΌ ν¨
fun updateParticle(x: Double, y: Double, vx: Double, vy: Double, ...) {
// 볡μ‘ν¨!
}
μ΄κ²μ ν΄κ²°νλ λ°©λ²μ΄ ν΄λμ€μ λλ€:
// μ’μ λ°©λ²: λ°μ΄ν°λ₯Ό νκ³³μ
class Particle(
var x: Double,
var y: Double,
var vx: Double,
var vy: Double,
var radius: Double = 10.0,
var age: Double = 0.0,
val lifespan: Double = 100.0
)
// μ¬μ©
val particle = Particle(100.0, 200.0, 1.5, -0.5)
particle.update()
μ΄ κΈμμλ:
μ λ€λ£¨κ² μ΅λλ€.
ν΄λμ€λ κ΄λ ¨λ λ°μ΄ν°μ ν¨μλ₯Ό νλμ λ¨μλ‘ λ¬Άλ κ²μ λλ€.
class Circle(
var x: Double,
var y: Double,
var radius: Double
) {
// μμ±μ νλΌλ―Έν°κ° μλμΌλ‘ νλ‘νΌν°κ° λ¨
// λ©μλ
fun draw(drawer: Drawer) {
drawer.circle(x, y, radius)
}
fun contains(px: Double, py: Double): Boolean {
val dx = x - px
val dy = y - py
return dx * dx + dy * dy < radius * radius
}
}
// μ¬μ©
val myCircle = Circle(100.0, 200.0, 50.0)
myCircle.draw(drawer)
// μμ±μ νλΌλ―Έν°μ val/varμ λΆμ΄λ©΄ νλ‘νΌν°κ° λ¨
class Point(
val x: Double, // val = μ½κΈ°λ§ κ°λ₯ (λΆλ³)
var y: Double // var = μ½κ³ μ°κΈ° κ°λ₯ (κ°λ³)
)
val p = Point(10.0, 20.0)
println(p.x) // β
OK
p.x = 15.0 // β μλ¬! valμ΄λ―λ‘ μ¬ν λΉ λΆκ°
p.y = 25.0 // β
OK
λ°μ΄ν° ν΄λμ€λ "λ°μ΄ν°λ§ λ΄λ" ν΄λμ€μ λλ€. μ½νλ¦°μ΄ μλμΌλ‘ μ μ©ν λ©μλλ₯Ό λ§λ€μ΄μ€λλ€.
data class Particle(
var position: Vector2,
var velocity: Vector2,
val radius: Double = 10.0,
val lifespan: Double = 100.0
)
toString() β λ¬Έμμ΄ ννval p = Particle(Vector2(100.0, 200.0), Vector2(1.0, 0.5))
println(p) // Particle(position=Vector2(100.0, 200.0), velocity=Vector2(1.0, 0.5), ...)
equals() β κ°μ΄ κ°μμ§ λΉκ΅val p1 = Particle(Vector2(100.0, 200.0), Vector2(1.0, 0.5))
val p2 = Particle(Vector2(100.0, 200.0), Vector2(1.0, 0.5))
val p3 = Particle(Vector2(150.0, 200.0), Vector2(1.0, 0.5))
println(p1 == p2) // true (κ°μ΄ κ°μ)
println(p1 == p3) // false (κ°μ΄ λ€λ¦)
μΌλ° ν΄λμ€λ μ°Έμ‘°λ§ λΉκ΅ν©λλ€:
class RegularParticle(val x: Double, val y: Double)
val r1 = RegularParticle(100.0, 200.0)
val r2 = RegularParticle(100.0, 200.0)
println(r1 == r2) // false! (λ€λ₯Έ κ°μ²΄μ΄λ―λ‘)
copy() β μΌλΆλ§ λ°κΎΌ 볡μ¬λ³Έval original = Particle(
position = Vector2(100.0, 200.0),
velocity = Vector2(1.0, 0.5),
radius = 10.0
)
// μμΉλ§ λ°κΎΌ 볡μ¬λ³Έ
val moved = original.copy(position = Vector2(150.0, 250.0))
// μλ³Έμ λ³νμ§ μμ
println(original.position) // Vector2(100.0, 200.0)
println(moved.position) // Vector2(150.0, 250.0)
ν¨μν νλ‘κ·Έλλ°μμ λ§€μ° μ€μν©λλ€:
// κΈ°μ‘΄ μ
μλ€μ μ
λ°μ΄νΈνμ§λ§, μλ³Έ 보쑴
val updatedParticles = particles.map { p ->
p.copy(
position = p.position + p.velocity,
age = p.age + 1.0
)
}
let particle = {
x: 100,
y: 200,
vx: 1.5,
vy: -0.5,
radius: 10,
age: 0,
update: function() {
this.x += this.vx;
this.y += this.vy;
this.age++;
},
draw: function(ctx) {
ctx.circle(this.x, this.y, this.radius);
}
};
// μ¬μ©
particle.update();
particle.draw(ctx);
data class Particle(
var position: Vector2,
var velocity: Vector2,
val radius: Double = 10.0,
var age: Double = 0.0,
val lifespan: Double = 100.0
) {
fun update() {
position += velocity
age++
}
fun draw(drawer: Drawer) {
drawer.circle(position.x, position.y, radius)
}
}
// μ¬μ©
particle.update()
particle.draw(drawer)
OPENRNDRμ μ₯μ :
toString(), equals(), copy()data class Particle(
var position: Vector2,
var velocity: Vector2,
val radius: Double,
var age: Double = 0.0,
val lifespan: Double
) {
val isAlive: Boolean
get() = age < lifespan
fun update() {
position += velocity
velocity *= 0.99 // λ§μ°°
age++
}
fun draw(drawer: Drawer) {
val alpha = 1.0 - (age / lifespan)
drawer.fill = ColorRGBa(1.0, 1.0, 1.0, alpha)
drawer.circle(position.x, position.y, radius)
}
}
program {
val particles = mutableListOf<Particle>()
extend {
clear(ColorRGBa.BLACK)
// λ§μ°μ€ μμΉμμ μ μ
μ μμ±
repeat(3) {
particles.add(Particle(
position = mouse.position,
velocity = Vector2(random(-2.0, 2.0), random(-2.0, 2.0)),
radius = random(3.0, 8.0),
lifespan = random(30.0, 60.0)
))
}
// μ
μ μ
λ°μ΄νΈ λ° κ·Έλ¦¬κΈ°
particles.forEach { p ->
p.update()
p.draw(drawer)
}
// μ£½μ μ
μ μ κ±°
particles.removeIf { !it.isAlive }
}
}
data class Particle(
var position: Vector2,
var velocity: Vector2,
val radius: Double,
var age: Double = 0.0,
val lifespan: Double
) {
// μ½κΈ° μ μ© νλ‘νΌν°
val isAlive: Boolean
get() = age < lifespan
val alpha: Double
get() = 1.0 - (age / lifespan)
val speed: Double
get() = sqrt(velocity.x * velocity.x + velocity.y * velocity.y)
}
data class SelectableShape(
val position: Vector2,
val radius: Double,
var isSelected: Boolean = false
) {
fun contains(point: Vector2): Boolean {
val dx = position.x - point.x
val dy = position.y - point.y
return dx * dx + dy * dy < radius * radius
}
fun draw(drawer: Drawer) {
drawer.fill = if (isSelected) {
ColorRGBa.RED
} else {
ColorRGBa.WHITE
}
drawer.circle(position.x, position.y, radius)
}
fun toggle() {
isSelected = !isSelected
}
}
program {
val shapes = listOf(
SelectableShape(Vector2(200.0, 200.0), 30.0),
SelectableShape(Vector2(600.0, 200.0), 30.0),
SelectableShape(Vector2(400.0, 600.0), 30.0)
)
extend {
clear(ColorRGBa.BLACK)
// λ§μ°μ€ ν΄λ¦μΌλ‘ μ ν ν κΈ
if (mouse.buttonDown) {
for (shape in shapes) {
if (shape.contains(mouse.position)) {
shape.toggle()
}
}
}
// λͺ¨λ λν 그리기
shapes.forEach { it.draw(drawer) }
}
}
data class Agent(
var position: Vector2,
var target: Vector2? = null,
val speed: Double = 2.0,
val radius: Double = 10.0
) {
fun moveTo(newTarget: Vector2) {
target = newTarget
}
fun update() {
target?.let { t ->
val direction = (t - position).normalized
position += direction * speed
// λͺ©ν κ·Όμ²μ λμ°©νλ©΄ λ©μΆ€
if ((position - t).length < 10.0) {
target = null
}
}
}
fun draw(drawer: Drawer) {
drawer.fill = if (target != null) ColorRGBa.CYAN else ColorRGBa.WHITE
drawer.circle(position.x, position.y, radius)
target?.let { t ->
drawer.stroke = ColorRGBa.GRAY
drawer.lineSegment(position, t)
}
}
}
program {
val agent = Agent(Vector2(400.0, 400.0))
extend {
clear(ColorRGBa.BLACK)
// λ§μ°μ€ ν΄λ¦μΌλ‘ μ΄λ λͺ
λ Ή
if (mouse.buttonDown) {
agent.moveTo(mouse.position)
}
agent.update()
agent.draw(drawer)
}
}
data class Vector(
var x: Double,
var y: Double
) {
operator fun plus(other: Vector): Vector {
return Vector(x + other.x, y + other.y)
}
}
data class Body(
val position: Vector,
var velocity: Vector,
val mass: Double,
val radius: Double
) {
fun applyForce(force: Vector) {
val acceleration = Vector(force.x / mass, force.y / mass)
velocity = velocity + acceleration
}
fun update() {
position.x += velocity.x
position.y += velocity.y
}
fun draw(drawer: Drawer) {
drawer.circle(position.x, position.y, radius)
}
}
data class PhysicsSystem(
val bodies: MutableList<Body> = mutableListOf(),
var gravity: Vector = Vector(0.0, 0.1)
) {
fun update() {
bodies.forEach { body ->
val gravitationalForce = Vector(0.0, body.mass * gravity.y)
body.applyForce(gravitationalForce)
body.update()
}
}
fun draw(drawer: Drawer) {
bodies.forEach { it.draw(drawer) }
}
}
program {
val physics = PhysicsSystem()
extend {
clear(ColorRGBa.BLACK)
// λ§μ°μ€ ν΄λ¦μΌλ‘ 물체 μΆκ°
if (mouse.buttonDown) {
physics.bodies.add(Body(
position = Vector(mouse.position.x, mouse.position.y),
velocity = Vector(random(-1.0, 1.0), random(-1.0, 1.0)),
mass = random(1.0, 5.0),
radius = random(5.0, 15.0)
))
}
physics.update()
physics.draw(drawer)
}
}
λ°μ΄ν° ν΄λμ€μμ κΈ°λ³Έκ°μ μ€μ νλ©΄ μμ± μ μλ΅ν μ μμ΅λλ€.
data class Particle(
var position: Vector2,
var velocity: Vector2,
val radius: Double = 10.0, // κΈ°λ³Έκ°
var age: Double = 0.0, // κΈ°λ³Έκ°
val lifespan: Double = 100.0 // κΈ°λ³Έκ°
)
// μ¬μ©
val p1 = Particle(Vector2(0.0, 0.0), Vector2(1.0, 0.0))
// radius, age, lifespanμ κΈ°λ³Έκ° μ¬μ©
val p2 = Particle(
Vector2(0.0, 0.0),
Vector2(1.0, 0.0),
radius = 20.0
)
// age, lifespanμ κΈ°λ³Έκ°, radiusλ§ λͺ
μ
κ°λ μ±μ μν΄ μΈμμ μ΄λ¦μ λΆμΌ μ μμ΅λλ€.
// μμΉλ‘λ§ μ λ¬ (μ½κΈ° μ΄λ €μ)
val p = Particle(Vector2(100.0, 200.0), Vector2(1.0, 0.5), 15.0, 0.0, 100.0)
// μ΄λ¦κ³Ό ν¨κ» (μ½κΈ° μ¬μ)
val p = Particle(
position = Vector2(100.0, 200.0),
velocity = Vector2(1.0, 0.5),
radius = 15.0,
age = 0.0,
lifespan = 100.0
)
// κΈ°λ³Έκ°μ μ¬μ©νλ©° μΌλΆλ§ λͺ
μ
val p = Particle(
position = Vector2(100.0, 200.0),
velocity = Vector2(1.0, 0.5),
radius = 15.0
)
data class Circle(
val x: Double,
val y: Double,
val radius: Double
) {
fun area(): Double {
return PI * radius * radius
}
fun draw(drawer: Drawer) {
drawer.circle(x, y, radius)
}
}
fun Circle.circumference(): Double {
return 2 * PI * radius
}
// μ¬μ©
val c = Circle(100.0, 100.0, 50.0)
println(c.area()) // λ©μλ
println(c.circumference()) // νμ₯ ν¨μ
μ ν κΈ°μ€:
λ°μ΄ν°λ‘ κ³μ°λλ νλ‘νΌν°λ valλ‘ μ μν μ μμ΅λλ€.
data class Particle(
var position: Vector2,
var velocity: Vector2,
var age: Double = 0.0,
val lifespan: Double = 100.0
) {
// κ³μ°λ νλ‘νΌν°: λ§€λ² κ³μ°λ¨
val isAlive: Boolean
get() = age < lifespan
val alpha: Double
get() = 1.0 - (age / lifespan)
val speed: Double
get() = sqrt(velocity.x * velocity.x + velocity.y * velocity.y)
}
// μ¬μ©
val p = Particle(Vector2(0.0, 0.0), Vector2(1.0, 0.0), 50.0)
println(p.isAlive) // true
println(p.alpha) // 0.5
| κΈ°λ₯ | λ°μ΄ν° ν΄λμ€ | μΌλ° ν΄λμ€ |
|---|---|---|
toString() | μλ μμ± | μλ μ μ |
equals() | μλ μμ± (κ° λΉκ΅) | μλ μ μ (μ°Έμ‘° λΉκ΅) |
copy() | μλ μμ± | μμ |
| λ©μλ | κ°λ₯ | κ°λ₯ |
| μ©λ | λ°μ΄ν° λ΄κΈ° | 볡μ‘ν λμ |
data class Cell(
val x: Int,
val y: Int,
var state: Boolean = false // false = μ£½μ, true = μ΄μμμ
) {
fun draw(drawer: Drawer, size: Double) {
if (state) {
drawer.fill = ColorRGBa.WHITE
} else {
drawer.fill = ColorRGBa.GRAY
}
drawer.rectangle(x * size, y * size, size, size)
}
}
data class Grid(
val cols: Int,
val rows: Int,
val cells: MutableList<Cell> = MutableList(cols * rows) { i ->
Cell(i % cols, i / cols)
}
) {
fun get(x: Int, y: Int): Cell? {
if (x < 0 || x >= cols || y < 0 || y >= rows) return null
return cells[x + y * cols]
}
fun toggle(x: Int, y: Int) {
get(x, y)?.state = !(get(x, y)?.state ?: false)
}
fun draw(drawer: Drawer, cellSize: Double) {
cells.forEach { it.draw(drawer, cellSize) }
}
}
program {
val grid = Grid(10, 10)
val cellSize = 80.0
extend {
clear(ColorRGBa.BLACK)
// ν΄λ¦μΌλ‘ μ
μν ν κΈ
if (mouse.buttonDown) {
val col = (mouse.position.x / cellSize).toInt()
val row = (mouse.position.y / cellSize).toInt()
grid.toggle(col, row)
}
grid.draw(drawer, cellSize)
}
}
| μ₯μ | μ€λͺ |
|---|---|
| κ°κ²°μ± | κΈ°λ³Έ λ©μλ μλ μμ± |
| μμ μ± | νμ 체ν¬, null μμ μ± |
| λΉκ΅ | κ° κΈ°λ° equals() |
| λ³΅μ¬ | copy()λ‘ λΆλ³μ± μ§μ |
| κ°λ μ± | λͺ νν λ°μ΄ν° ꡬ쑰 |
λ€μ κΈμμλ Objectμ μ±κΈν΄μ λ€λ£Ήλλ€.
λλ‘λ μ€μ§ νλμ μΈμ€ν΄μ€λ§ νμν κ²½μ°κ° μμ΅λλ€:
// μμ νλ νΈλ νλ‘μ νΈ μ 체μμ νλλ§ νμ
object ColorPalette {
val primary = ColorRGBa.RED
val secondary = ColorRGBa.BLUE
val accent = ColorRGBa.YELLOW
}
// μ¬μ©
extend {
fill = ColorPalette.primary
}
μ±κΈν΄ ν¨ν΄μ μ μ μνλ₯Ό κ΄λ¦¬νλ κΉλν λ°©λ²μ λλ€.
data class Rectangle(
val x: Double,
val y: Double,
val width: Double,
val height: Double
)
val rect = Rectangle(100.0, 200.0, 150.0, 100.0)
println(rect) // Rectangle(x=100.0, y=200.0, ...)
data class Circle(
val x: Double,
val y: Double,
val radius: Double
) {
fun area(): Double = PI * radius * radius
fun draw(drawer: Drawer) {
drawer.circle(x, y, radius)
}
}
data class Particle(
var position: Vector2,
var velocity: Vector2,
var age: Double = 0.0,
val lifespan: Double = 100.0
) {
val isAlive: Boolean
get() = age < lifespan
val alpha: Double
get() = 1.0 - (age / lifespan)
}
data class Particle(
var position: Vector2,
var velocity: Vector2,
val radius: Double = 5.0,
var age: Double = 0.0,
val lifespan: Double = 60.0
) {
val isAlive: Boolean
get() = age < lifespan
fun update() {
position += velocity
velocity *= 0.99
age++
}
fun draw(drawer: Drawer) {
val alpha = 1.0 - (age / lifespan)
drawer.fill = ColorRGBa(1.0, 1.0, 1.0, alpha)
drawer.circle(position.x, position.y, radius)
}
}
program {
val particles = mutableListOf<Particle>()
extend {
clear(ColorRGBa.BLACK)
// λ§μ°μ€ μμΉμμ μ
μ μμ±
repeat(5) {
particles.add(Particle(
position = mouse.position,
velocity = Vector2(random(-2.0, 2.0), random(-3.0, 0.0))
))
}
particles.forEach { p ->
p.update()
p.draw(drawer)
}
particles.removeIf { !it.isAlive }
}
}
μ§λ "μ ν κ°λ₯ν λν" μμ λ₯Ό νμ₯ν΄μ: