Code Sketch
Hill Towns
Category: Art
size(900, 600)
cleari()
initRandomGenerator(818828412154425840L)
val cb = canvasBounds
val n = 6
def height = random(10, 50)
val width = cb.width / n
val groundZoneHeight = 220
val mountainZoneHeight = 200
val skyZoneHeight = 400
def backdropFill = cm.linearMultipleGradient(
0, 0, 0, cb.height,
Seq(0, 0.25, 0.67, 0.671, 1),
Seq(
ColorMaker.hsl(50, 0.8, 0.1),
ColorMaker.hsl(60, 1.00, 0.07),
ColorMaker.hsl(80, 1.00, 0.03),
ColorMaker.hsl(30, 0.85, 0.65),
ColorMaker.hsl(220, 0.81, 0.40),
),
false
)
def backdrop = Picture.rectangle(cb.width, cb.height)
.withPenColor(noColor)
.withFillColor(backdropFill)
.thatsTranslated(-cb.width / 2, -cb.height / 2)
def mountain(h: Double) = Picture.fromVertexShape { s =>
import s._
beginShape()
curveVertex(-100, 0)
curveVertex(0, 0)
curveVertex(width / 2, h)
curveVertex(width, 0)
curveVertex(width + 100, 0)
endShape()
}.withPenColor(ColorMaker.hsl(0, 0.60, 0.15)).withFillColor(mountainFill)
def mountains(n: Int): Picture = {
if (n == 1) {
mountain(height)
}
else {
picStack(mountain(height), mountains(n - 1).withTranslation(width, 0))
}
}
val mountainFill = cm.linearGradient(0, 0, ColorMaker.hsl(100, 1.00, 0.03), 0, 50, ColorMaker.hsl(120, 1.00, 0.01), false)
def lights(num: Int, width: Double, height: Double) = picStack(
for {
n <- 1 to num
x = randomDouble(0, width)
y = randomDouble(0, height)
p = Picture.circle(.8).withFillColor(cm.gold).thatsTranslated(x, y).withPenColor(noColor)
} yield p
)
def building = {
val w = randomDouble(20, 40)
val h = randomDouble(15, 40)
val w10 = w / 10
val h10 = h / 10
def wdelta = randomDouble(-w10, w10)
def hdelta = randomDouble(-h10, h10)
picStack(
Picture.rectangle(w, h).withPenColor(noColor)
.withFillColor(ColorMaker.hsla(50, 1.00, 0.08, 0.80)),
Picture.rectangle(3, 3).withPenColor(noColor).withFillColor(cm.gold)
.thatsTranslated(w / 3 + wdelta, h / 2.0 + hdelta),
Picture.rectangle(3, 3).withPenColor(noColor).withFillColor(cm.gold)
.thatsTranslated(2 * w / 3 + wdelta, h / 2.0 + hdelta),
)
}
def buildings(n: Int): Picture = {
if (n == 1) {
building
}
else {
picStack(building, buildings(n - 1).withTranslation(random(20, 40), random(-7, 8)))
}
}
def fgbs(n: Int): Picture = {
if (n == 1) {
Picture.rectangle(30, 70).withPenColor(black).withFillColor(black)
}
else {
picStack(
Picture.rectangle(30, 70).withPenColor(black).withFillColor(black),
fgbs(n - 1).thatsTranslated(50, 0)
)
}
}
val drawing = picStack(
backdrop,
mountains(6).withTranslation(-cb.width / 2, 102),
lights(50, 100, 50).thatsTranslated(-cb.width / 2 + 20, 50),
lights(50, 100, 50).thatsTranslated(-cb.width / 2 + 180, 60),
lights(50, 80, 40).thatsTranslated(-cb.width / 2 + 335, 70),
lights(80, 150, 50).thatsTranslated(-cb.width / 2 + 460, 40),
lights(110, 180, 50).thatsTranslated(-cb.width / 2 + 670, 40),
lights(200, cb.width - 50, 20).thatsTranslated(-cb.width / 2 + 20, -30),
buildings(30).withTranslation(-cb.width / 2 + 40, -90),
buildings(29).withTranslation(-cb.width / 2 + 20, -120),
fgbs(18).withTranslation(-cb.width / 2 + 10, -cb.height / 2),
Picture.rectangle(cb.width, 20).withPenColor(noColor).withFillColor(black)
.thatsTranslated(-cb.width / 2, -cb.height / 2 + 30)
)
draw(drawing)