Code Sketch
Chandrayaan-3 Simulation & Moon Defender Game (CLSMD)
Category: Programming
//https://drive.google.com/drive/folders/1Axc5jfRHE2MTurGiP5IEhd3lmc3mzJ0V?usp=drive_link
//Chandrayaan-3 Simulation & Moon Defender Game (CLSMD)
//Version 1.0
//Instructions to start and play the game:
//Download the files from the link at the top
//and put them into your downloads folder
//Run the code and play :)
//Chandrayaam-3 Lander Simulation
//Use the right arrow key to land the Vikram lander
//on the blue platform on the same time controlling velocity
//Don't let the velocity meter turn red
//otherwise the lander will crash
//Moon Defender Game
//Use left and right arrow keys to navigate the space satellite
//Use space key to shoot the asteroids
//You have 3 lives and 30 seconds to win
//If asteroid collides with Moon your score will be -1
//If you miss a shot or bring the missile and satellite too close
//Your score will start decreasing
//If you hit an asteroid your score will increase by 2
//Enjoy the game :)
cleari()
clearOutput()
toggleFullScreenCanvas()
disablePanAndZoom()
drawStage(black)
//Assets Directory
val assetsDirectory = "~/Downloads"
//Life Stuff
var lifeCount = 3
//Canvas Bounds
val cb = canvasBounds
//Help us to shoot missile
var shootMissile = false
//Score
var score = 0
//Stars area
def height = random(10, 50)
def width = cb.width / 100
//Intro
val intro = picStack(
Picture.image(s"$assetsDirectory/CYan3.png").withScaling(0.6).withTranslation(100, 0),
Picture.text(s"Chandrayaan-3 Lander Simulation", Font("Agency FB", 40)).withPenColor(white).withTranslation(100, 0),
Picture.text("& Moon Defender Game", Font("Agency FB", 40)).withPenColor(white).withTranslation(175, -50)
)
drawCentered(intro)
val about = picStack(
Picture.text("Code : Soham Dabral", Font("Agency FB", 25)).withPosition(-140, -250),
Picture.text("AUGIC Devikhet, Dwarikhal, Pauri Garhwal, Uttarakhand, India", Font("Agency FB", 25)).withPosition(-300, -280),
).withPenColor(white).withPosition(50, 50)
draw(about)
showFps(green, 20)
pause(5)
cleari()
clearOutput()
disablePanAndZoom()
setBackground(cm.black)
showFps(green, 20)
//Box color
val boxclr = cm.linearGradient(0, 50, ColorMaker.hsl(105, 1.00, 0.50), 0, 0, cm.black, false)
//Box
def box = Picture {
repeat(2) {
forward(50)
right(90, 10)
forward(500)
right(90, 10)
}
}.withFillColor(boxclr)
//Play box
val playButton = picStack(
box.withPenColor(black).withFillColor(boxclr).withPenThickness(1).withOpacity(0.75),
Picture.text("Play", Font("Cooper Black", 30)).withPenColor(white).withPosition(225, 47)
)
drawCentered(playButton)
//Quit Game button
val quitGameButton = picStack(
box.withPenColor(black).withFillColor(boxclr).withPenThickness(1).withOpacity(0.75),
Picture.text("Quit Game", Font("Cooper Black", 30)).withPenColor(white).withTranslation(175, 50)
).withTranslation(-260, -100)
quitGameButton.draw()
//Intro's background
def Stars(num: Int, width: Double, height: Double) = fillColor(cm.silver) * trans(-800, -500) -> picStack(
for {
n <- 1 to num
x = randomDouble(0, width)
y = randomDouble(0, height)
p = Picture.circle(random(1, 3)).thatsTranslated(x, y).withPenColor(noColor)
} yield p
)
Stars(10000, 10000, 1000).draw()
//If there is a mouse click on play
playButton.onMouseClick { (x, y) =>
cleari()
clearOutput()
disablePanAndZoom()
drawStage(ColorMaker.hsl(240, 0.20, 0.16))
def xCenteredPosition(picWidth: Double) = {
cb.x + (cb.width - picWidth) / 2
}
class Rocket {
val rocketWidth = 40; val rocketHeight = 70
val thrusterWidth = 20; val thrusterHeight = 35
//Rocket
val rocket = Picture.image(s"$assetsDirectory/Rocket.png").withScaling(0.2)
rocket.setPosition(xCenteredPosition(75), cb.y + cb.height - 750)
//Thrusters
val thruster1 = Picture.image(s"$assetsDirectory/Thruster.png").withScaling(0.7)
setThrusterPosition1()
val thruster2 = Picture.image(s"$assetsDirectory/Thruster.png").withScaling(0.7)
setThrusterPosition2()
val thruster3 = Picture.image(s"$assetsDirectory/Thruster.png")
setThrusterPosition3()
val gravity = Vector2D(0, -0.1)
var velocity = Vector2D(0, 0)
val zeroThrust = Vector2D(0, 0)
//Movement of the rocket upwards
val upThrust = new Vector2D(0, 0.25)
//Movement of rocket downward
var thrust = zeroThrust
//Thrusters positions
def setThrusterPosition1() {
thruster1.setPosition(
rocket.position.x + (rocketWidth - thrusterWidth + 15) / 2,
rocket.position.y - (thrusterHeight)
)
}
def setThrusterPosition2() {
thruster2.setPosition(
rocket.position.x + (rocketWidth - thrusterWidth + 57) / 2,
rocket.position.y - (thrusterHeight)
)
}
def setThrusterPosition3() {
thruster3.setPosition(
rocket.position.x + (rocketWidth - thrusterWidth + 27) / 2,
rocket.position.y - (thrusterHeight + 10)
)
}
def draw() {
rocket.draw()
thruster1.draw()
thruster2.draw()
thruster3.draw()
thruster3.invisible()
}
def step() {
//Moves the rocket upwards
if (isKeyPressed(Kc.VK_UP)) {
inThrust()
thruster3.visible()
}
else {
noThrust()
thruster3.invisible()
}
velocity = velocity + gravity
velocity = velocity + thrust
rocket.translate(velocity)
setThrusterPosition1()
setThrusterPosition2()
setThrusterPosition3()
//If rocket collides with stage border
if (rocket.collidesWith(stageBorder)) {
cleari()
clearOutput()
disablePanAndZoom()
drawStage(black)
showFps(green, 20)
Stars(10000, 10000, 1000).draw()
//Chandrayaan-3 Lander Simulation
val CLS = picStack(
box.withFillColor(boxclr).withPenThickness(1).withOpacity(0.75).withPenColor(cm.white).withTranslation(-240, -85).withPenColor(black),
Picture.text("Chandrayaan-3 Lander Simulation", Font("Cooper Black", 28)).withPenColor(cm.white).withPosition(-232, -35)
)
drawCentered(CLS)
//Moon defender
val moonDefender = picStack(
box.withPenColor(black).withFillColor(boxclr).withPenThickness(1).withOpacity(0.75).withTranslation(-250, -67),
Picture.text("Moon Defender", Font("Cooper Black", 30)).withPenColor(cm.white).withPosition(-110, -15)
).withTranslation(-10, -25)
moonDefender.draw()
//If there is a mouse click on CLS
CLS.onMouseClick { (x, y) =>
cleari()
clearOutput()
drawStage(ColorMaker.hsl(240, 0.20, 0.16))
def xCenteredPosition(picWidth: Double) = {
cb.x + (cb.width - picWidth) / 2
}
//Class Lander
class Lander {
val satelliteWidth = 40; val satelliteHeight = 90
val thrusterWidth = 20; val thrusterHeight = 35
//Satellite
val satellite = Picture.image(s"$assetsDirectory/Lander.png").withScaling(0.2)
satellite.setPosition(xCenteredPosition(satelliteWidth), cb.y + cb.height - satelliteHeight - 10)
//Thrusters
val thruster = Picture.image(s"$assetsDirectory/Thruster.png").withScaling(0.01)
setThrusterPosition()
val gravity = Vector2D(-0.1, -0.01)
var velocity = Vector2D(0, 0)
val zeroThrust = Vector2D(0, 0)
//Movement of satellite towards right
val upThrust = new Vector2D(0.2, 0)
//Movement of satellite towards left
var thrust = zeroThrust
//The black box at the bottom
val blackBox = Picture.rectangle(1920, 75).withFillColor(black).withPenColor(noColor).withTranslation(-960, -390)
blackBox.draw()
//Thruster position
def setThrusterPosition() {
thruster.setPosition(
satellite.position.x + 19,
satellite.position.y - (thrusterHeight + 6)
)
}
def draw() {
satellite.draw()
}
def step() {
if (isKeyPressed(Kc.VK_RIGHT)) {
//Moves the rocket towards right
inThrust()
satellite.rotate(0.15)
thruster.visible()
thruster.rotate(0.1)
}
else {
//Moves the rocket towards left
noThrust()
satellite.rotate(-0.1)
thruster.rotate(-0.1)
thruster.invisible()
}
velocity = velocity + gravity
velocity = velocity + thrust
satellite.translate(velocity)
setThrusterPosition()
//If the satellite collides with stage border
if (satellite.collidesWith(stageBorder)) {
val fail = Picture.text("Mission Failed!", 30).withTranslation(-100, 300)
fail.draw()
satellite.erase()
thruster.erase()
stopAnimation()
}
}
def inThrust() {
thrust = upThrust
}
def noThrust() {
thrust = zeroThrust
thruster.invisible()
}
}
val moonImg = Picture.image(s"$assetsDirectory/Moon.png").withTranslation(-1000, -500)
moonImg.draw()
//Class Moon
class Moon {
val platform = Picture.ellipse(15, 8).withTranslation(355, -200).withFillColor(blue).withPenColor(noColor)
platform.setPosition(xCenteredPosition(710), 0)
def draw() {
platform.draw()
}
//Checking the lander
def check(l: Lander) {
//If the satellite collides with the platform with the velocity more than 8
if (l.satellite.collidesWith(platform)) {
if (l.velocity.y.abs > 8) {
val lv = l.velocity.y.abs
val fail = Picture.text(s"Mission Failed!", 30).withTranslation(-100, 300)
fail.draw()
l.thruster.invisible()
}
//If the satellite collides with the platform with the velocity less than 8
else {
val success = Picture.text("Mission Successful!", 30).withTranslation(-150, 300).withPenColor(green)
success.draw()
l.thruster.invisible()
}
stopAnimation()
}
}
}
val l = new Lander()
l.draw()
val m = new Moon()
m.draw()
showFps(green, 20)
setRefreshRate(200)
animate {
l.step()
m.check(l)
//Velocity text
val velTxt = Picture.text("Velocity: ", Font("Cambaria", 20)).withPenColor(white).withTranslation(-600, -335)
velTxt.draw()
//Indicates the velocity
val indicator = Picture.circle(10).withPenColor(noColor).withTranslation(-500, -345)
//If the velocity is less than 8
if (l.velocity.y.abs < 8) {
indicator.setFillColor(green)
indicator.draw()
}
//If the velocity is more than 8
else {
indicator.setFillColor(red)
indicator.draw()
}
}
activateCanvas()
}
//If there is a mouse click on Moon Defender
moonDefender.onMouseClick { (x, y) =>
cleari()
clearOutput()
setBackground(cm.black)
//Velocity and Gravity
var velocity = Vector2D(0, -1)
val gravity = Vector2D(0, 0.5)
//Stage
val bg = Picture.rectangle(cwidth * 1.5, cheight * 2)
bg.setPosition(-cwidth / 1.4, -cheight)
bg.setPenColor(noColor)
bg.draw()
//Celestial bodies
//Stars
def stars(num: Int, width: Double, height: Double) = fillColor(cm.silver) * trans(-100000 / 2, -500) -> picStack(
for {
n <- 1 to num
x = randomDouble(0, width)
y = randomDouble(0, height)
p = Picture.circle(random(1, 3)).thatsTranslated(x, y).withPenColor(noColor)
} yield p
)
val allStars = stars(9000, 100000, 900)
allStars.draw()
//Moon
val moonImg = Picture.image(s"$assetsDirectory/moon2.png")
.withTranslation(75, -300)
.withScaling(1.9)
moonImg.draw()
//Semi circle
val Moon = Picture {
right(180, 400)
}
Moon.setPenColor(noColor)
Moon.setPosition(700, -415)
Moon.rotate(90)
Moon.draw()
//Asteroids
//Asteroid1
val asteroid1 = Picture.image(s"$assetsDirectory/Asteroid.png")
asteroid1.setPosition(random(-800, -900), -150)
asteroid1.scale(0.25)
asteroid1.draw()
//Asteroid2
val asteroid2 = Picture.image(s"$assetsDirectory/Asteroid.png")
asteroid2.setPosition(random(-800, -900), -150)
asteroid2.scale(0.25)
asteroid2.draw()
//spaceship
val spaceship = Picture.image(s"$assetsDirectory/space ship.png")
spaceship.setPosition(0, 350)
spaceship.scale(0.25)
spaceship.flipX()
spaceship.draw()
//hearts
val heart = Picture.image(s"$assetsDirectory/hearts.png")
heart.setPosition(-675, 300)
heart.scale(0.2)
heart.draw()
//Column
val Column = Picture.text(":", Font("Cambria", 40))
Column.setPosition(-630, 350)
Column.setPenColor(ColorMaker.hsl(18, 0.60, 0.40))
Column.draw()
//Life Count Text
val lifeCountText = Picture.text(s"$lifeCount", Font("Serif", 40))
lifeCountText.setPosition(-615, 345)
lifeCountText.setPenColor(cm.silver)
lifeCountText.draw()
//missile
val missile = Picture.image(s"$assetsDirectory/missile.png")
missile.setPosition(spaceship.position.x + 23, spaceship.position.y - 115)
missile.flipX()
missile.scale(0.15)
missile.draw()
missile.invisible()
showFps(green, 20)
//PART - 2 Animating and Controls
animate {
//Speed of Asetroids
asteroid1.translate(random(1, 45), 0)
asteroid2.translate(random(1, 45), 0)
//Speed of stars
allStars.translate(1, 0)
// Controling spaceship and missile :)
if (isKeyPressed(Kc.VK_LEFT)) {
spaceship.translate(-25, 0)
missile.translate(-26, 0)
}
if (isKeyPressed(Kc.VK_RIGHT)) {
spaceship.translate(25, 0)
missile.translate(26, 0)
}
//Calculating velocity
velocity = velocity - gravity
//Shoot missile!!!
if (isKeyPressed(Kc.VK_SPACE)) {
shootMissile = true
}
if (shootMissile == true) {
missile.visible()
missile.translate(-velocity)
}
//Collison part
//Collison with stage
if (missile.collidesWith(bg)) {
missile.invisible()
missile.setPosition(spaceship.position.x + 30, spaceship.position.y - 115)
score -= 1
shootMissile = false
}
//Collison with missile
if (missile.collidesWith(asteroid1)) {
missile.invisible()
asteroid1.setPosition(random(-800, -900), -150)
missile.setPosition(spaceship.position.x + 30, spaceship.position.y - 115)
shootMissile = false
score += 2
}
if (missile.collidesWith(asteroid2)) {
missile.invisible()
asteroid2.setPosition(random(-800, -900), -150)
missile.setPosition(spaceship.position.x + 30, spaceship.position.y - 115)
shootMissile = false
score += 2
}
//Collison with Moon2
if (asteroid1.collidesWith(Moon)) {
missile.invisible()
asteroid1.setPosition(random(-800, -900), -150)
missile.setPosition(spaceship.position.x + 30, spaceship.position.y - 115)
lifeCount -= 1
score -= 1
lifeCountText.update(lifeCount)
shootMissile = false
}
if (asteroid2.collidesWith(Moon)) {
missile.invisible()
asteroid2.setPosition(random(-800, -900), -150)
missile.setPosition(spaceship.position.x + 30, spaceship.position.y - 115)
lifeCount -= 1
score -= 1
lifeCountText.update(lifeCount)
shootMissile = false
}
if (missile.collidesWith(Moon)) {
missile.invisible()
missile.setPosition(spaceship.position.x + 30, spaceship.position.y - 115)
score -= 1
shootMissile = false
}
if (spaceship.collidesWith(Moon)) {
missile.invisible()
missile.setPosition(spaceship.position.x + 30, spaceship.position.y - 115)
score -= 1
shootMissile = false
}
if (isKeyPressed(Kc.VK_ESCAPE)) {
missile.invisible()
drawCenteredMessage(s"You Lose :( \n Your Score is $score", red, 40)
shootMissile = false
stopAnimation()
activateEditor()
}
//Lifes Part
if (lifeCount == 0) {
missile.invisible()
drawCenteredMessage(s"You Lose :( \n Your Score is $score", red, 40)
shootMissile = false
stopAnimation()
}
}
showGameTimeCountdown(30, s"You Win :) \n Your score is $score", green, 30, 20, 50)
activateCanvas()
}
}
}
def inThrust() {
thrust = upThrust
thruster1.visible()
thruster2.visible()
}
def noThrust() {
thrust = zeroThrust
}
if (isKeyPressed(Kc.VK_ESCAPE)) {
stopAnimation()
activateEditor()
}
}
//Launchpad
class LaunchPad {
//Launch pad
val launchpad = Picture.image(s"$assetsDirectory/launchpad.png")
launchpad.setPosition(-xCenteredPosition(-105), cb.y + 50)
launchpad.scale(0.25)
def draw() {
launchpad.draw()
}
//The place where rocket is standing
val land = Picture.rectangle(10000, 100)
land.setPosition(-10000 / 2, -414)
land.setPenColor(noColor)
land.draw()
def check(r: Rocket) {
if (r.rocket.collidesWith(land)) {
val rocketWidth = 40; val rocketHeight = 70
r.rocket.setPosition(xCenteredPosition(80), cb.y + cb.height - rocketHeight - 625)
}
}
if (isKeyPressed(Kc.VK_ESCAPE)) {
stopAnimation()
activateEditor()
}
}
//Background of the rocket
val background = Picture.image(s"$assetsDirectory/launchbg.png")
background.setPosition(-750, -375)
background.scale(1.6)
background.draw()
val l = new LaunchPad()
l.draw()
val r = new Rocket()
r.draw()
//Clouds
val clouds = picStack(
Picture.image(s"$assetsDirectory/clouds.png").withScaling(0.8),
Picture.image(s"$assetsDirectory/clouds.png").withPosition(-300, 100)
)
clouds.draw()
//People
val people = picStack(
Picture.image(s"$assetsDirectory/people.png").withPosition(-680, -390).withScaling(0.72),
Picture.image(s"$assetsDirectory/people.png").withPosition(160, -390).withFlippedX.withScaling(0.72),
Picture.image(s"$assetsDirectory/people.png").withPosition(160, -390).withScaling(0.72)
)
draw(people)
showFps(green, 20)
animate {
r.step()
l.check(r)
if (isKeyPressed(Kc.VK_ESCAPE)) {
stopAnimation()
activateEditor()
}
clouds.translate(-0.2, 0)
}
activateCanvas()
}
//If there is a mouse click on Quit game
quitGameButton.onMouseClick { (x, y) =>
clear()
toggleFullScreenCanvas()
activateEditor()
}