Code Sketch
sniper_0718
Category: Art
// Kojo Killer Room Game - Killers Shoot Back Version
clear()
val cb = canvasBounds
// ?. ???? ?????????? ??? ??? ???? ????
val bg = Picture.rectangle(3000, 3000)
bg.setFillColor(ColorMaker.black)
bg.setPosition(cb.x - 1000, cb.y - 1000)
draw(bg)
// ?. ??????????? ??????
val pHead = Picture.circle(8)
pHead.setFillColor(ColorMaker.cyan)
pHead.setPosition(cb.x + 200, cb.y + 245)
val pBody = Picture.rectangle(18, 30)
pBody.setFillColor(ColorMaker.blue)
pBody.setPosition(cb.x + 191, cb.y + 210)
val pLeg1 = Picture.rectangle(6, 15)
pLeg1.setFillColor(ColorMaker.blue)
pLeg1.setPosition(cb.x + 191, cb.y + 195)
val pLeg2 = Picture.rectangle(6, 15)
pLeg2.setFillColor(ColorMaker.blue)
pLeg2.setPosition(cb.x + 203, cb.y + 195)
val pGun = Picture.rectangle(16, 5)
pGun.setFillColor(ColorMaker.gray)
pGun.setPosition(cb.x + 209, cb.y + 222)
draw(pBody)
draw(pHead)
draw(pLeg1)
draw(pLeg2)
draw(pGun)
var facingRight = true
// ?. ???? ??? ????????? ?????? ?????????? (Max 10 Killers & Bullets)
var currentLevel = 0
var killersLeft = 0
val maxKillers = 10
val killerBodies = new Array[Picture](maxKillers)
val killerHeads = new Array[Picture](maxKillers)
val killerBullets = new Array[Picture](maxKillers)
val killerBulletActive = new Array[Boolean](maxKillers)
val killerBulletDirX = new Array[Double](maxKillers)
val killerBulletDirY = new Array[Double](maxKillers)
for (i <- 0 until maxKillers) {
val kBody = Picture.rectangle(18, 30)
kBody.setFillColor(ColorMaker.red)
kBody.invisible()
draw(kBody)
killerBodies(i) = kBody
val kHead = Picture.circle(8)
kHead.setFillColor(ColorMaker.orange)
kHead.invisible()
draw(kHead)
killerHeads(i) = kHead
val kB = Picture.rectangle(10, 4)
kB.setFillColor(ColorMaker.yellow)
kB.invisible()
draw(kB)
killerBullets(i) = kB
killerBulletActive(i) = false
killerBulletDirX(i) = 0.0
killerBulletDirY(i) = 0.0
}
def setupLevel(level: Int) {
currentLevel = level
for (i <- 0 until maxKillers) {
killerBodies(i).invisible()
killerHeads(i).invisible()
killerBullets(i).invisible()
killerBulletActive(i) = false
}
if (level == 1) {
killersLeft = 3
for (i <- 0 until 3) {
killerBodies(i).setPosition(cb.x + 600 + (i * 70), cb.y + 100 + (i * 60))
killerHeads(i).setPosition(cb.x + 600 + (i * 70), cb.y + 135 + (i * 60))
killerBodies(i).visible()
killerHeads(i).visible()
}
showMsg("Level 1 Started: 3 Killers! They will shoot at you! Arrow Keys: Move | Z: Shoot")
} else if (level == 2) {
killersLeft = 5
for (i <- 0 until 5) {
killerBodies(i).setPosition(cb.x + 500 + ((i % 3) * 80), cb.y + 50 + (i * 50))
killerHeads(i).setPosition(cb.x + 500 + ((i % 3) * 80), cb.y + 85 + (i * 50))
killerBodies(i).visible()
killerHeads(i).visible()
}
showMsg("Level 2 Started: 5 Killers! Arrow Keys: Move | Z: Shoot")
} else if (level == 3) {
killersLeft = 10
for (i <- 0 until 10) {
killerBodies(i).setPosition(cb.x + 400 + ((i % 5) * 70), cb.y + 20 + ((i / 5) * 80))
killerHeads(i).setPosition(cb.x + 400 + ((i % 5) * 70), cb.y + 55 + ((i / 5) * 80))
killerBodies(i).visible()
killerHeads(i).visible()
}
showMsg("Level 3 Started: 10 Killers! Arrow Keys: Move | Z: Shoot")
}
}
// ?. ???????? ???? (Z Key)
val bullet = Picture.rectangle(15, 6)
bullet.setFillColor(ColorMaker.white)
bullet.invisible()
draw(bullet)
var bulletActive = false
var bulletDir = 1
// ????????? ??????
var infoText: Picture = null
def showMsg(msg: String) {
if (infoText != null) {
infoText.erase()
}
infoText = Picture {
setPenFontSize(18)
setPenColor(ColorMaker.yellow)
write(msg)
}
infoText.setPosition(cb.x + 50, cb.y + 530)
draw(infoText)
}
showMsg("PRESS 1 for Level 1 | PRESS 2 for Level 2 | PRESS 3 for Level 3")
var frameCount = 0
// ?. ??? ???
drawLoop {
frameCount += 1
if (currentLevel == 0) {
if (isKeyPressed(Kc.VK_1)) setupLevel(1)
if (isKeyPressed(Kc.VK_2)) setupLevel(2)
if (isKeyPressed(Kc.VK_3)) setupLevel(3)
} else {
// ?????? ?????
val speed = 4.0
var dx = 0.0
var dy = 0.0
if (isKeyPressed(Kc.VK_UP)) dy = speed
if (isKeyPressed(Kc.VK_DOWN)) dy = -speed
if (isKeyPressed(Kc.VK_LEFT)) {
dx = -speed
if (facingRight) {
pHead.translate(-18, 0)
pGun.translate(-34, 0)
facingRight = false
}
}
if (isKeyPressed(Kc.VK_RIGHT)) {
dx = speed
if (!facingRight) {
pHead.translate(18, 0)
pGun.translate(34, 0)
facingRight = true
}
}
if (dx != 0 || dy != 0) {
pBody.translate(dx, dy)
pHead.translate(dx, dy)
pLeg1.translate(dx, dy)
pLeg2.translate(dx, dy)
pGun.translate(dx, dy)
}
// Z ?? ????????? ???????? ???? ??????
if (isKeyPressed(Kc.VK_Z) && !bulletActive) {
bulletActive = true
if (facingRight) {
bullet.setPosition(pGun.position.x + 16, pGun.position.y)
bulletDir = 1
} else {
bullet.setPosition(pGun.position.x - 16, pGun.position.y)
bulletDir = -1
}
bullet.visible()
}
if (bulletActive) {
bullet.translate(20 * bulletDir, 0)
for (i <- 0 until maxKillers) {
if (killerBodies(i).isVisible && bullet.collidesWith(killerBodies(i))) {
killerBodies(i).invisible()
killerHeads(i).invisible()
killerBullets(i).invisible()
killerBulletActive(i) = false
bullet.invisible()
bulletActive = false
killersLeft -= 1
if (killersLeft > 0) {
showMsg(s"Hit! Killers left in Level $currentLevel: $killersLeft")
} else {
showMsg(s"Level $currentLevel Cleared! Press 1, 2 or 3 to play again.")
currentLevel = 0
}
}
}
if (bullet.position.x > cb.x + 1500 || bullet.position.x < cb.x - 1000) {
bullet.invisible()
bulletActive = false
}
}
// ?. ?????? ?????? ??? ?????? ???? ????? (AI Chasing & Shooting)
val kSpeed = 0.35
for (i <- 0 until maxKillers) {
if (killerBodies(i).isVisible) {
val kx = killerBodies(i).position.x
val ky = killerBodies(i).position.y
val px = pBody.position.x
val py = pBody.position.y
// ?????? ????
if (kx < px) killerBodies(i).translate(kSpeed, 0) else killerBodies(i).translate(-kSpeed, 0)
if (ky < py) killerBodies(i).translate(0, kSpeed) else killerBodies(i).translate(0, -kSpeed)
killerHeads(i).setPosition(killerBodies(i).position.x, killerBodies(i).position.y + 35)
// ?????? ?????????? ?????? ???? ????? (?????? ???????)
if (!killerBulletActive(i) && frameCount % 120 == 0) {
killerBullets(i).setPosition(kx, ky + 15)
killerBullets(i).visible()
killerBulletActive(i) = true
val angle = math.atan2(py - ky, px - kx)
killerBulletDirX(i) = math.cos(angle) * 6.0
killerBulletDirY(i) = math.sin(angle) * 6.0
}
// ???????? ?????? ??????
if (killerBulletActive(i)) {
killerBullets(i).translate(killerBulletDirX(i), killerBulletDirY(i))
// ?? ?????? ???? ???????? ?????
if (killerBullets(i).collidesWith(pBody)) {
showMsg(s"Ouch! Hit by killer bullet! Killers left: $killersLeft")
killerBullets(i).invisible()
killerBulletActive(i) = false
}
val kbPos = killerBullets(i).position
if (kbPos.x > cb.x + 1500 || kbPos.x < cb.x - 1000 || kbPos.y > cb.y + 1500 || kbPos.y < cb.y - 1000) {
killerBullets(i).invisible()
killerBulletActive(i) = false
}
}
if (killerBodies(i).collidesWith(pBody)) {
showMsg(s"Warning! Killer touched you! Killers left: $killersLeft")
}
}
}
}
}