<!--
--  Uploaded on : https://haxor.my.id/open/project.html
--  Official Web : https://prinsh.com
--  script-deface-generator.prinsh.com
-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Project My Games</title>
</head>

<style type="text/css">
    body{
margin:0px;
background: #222;
position: relative;
}
*{box-sizing: border-box;}
canvas{
width: 100%;
 display: none; 
position: absolute;
top:0;
left:0;    
}
#banner{
display: none;
width:100%;
height:100%;
position: absolute;
top:0px;
left:0px;
padding:50px 25px 20px 25px; 
}
#bannerInfo > .score{
color:aqua;
display: block;
text-align: center;
padding: 20px;
margin-bottom:10px;
font-size:1.1rem;
line-height: 1.8rem;
}
#banner > button{
background: linear-gradient(to top right,salmon,hotpink);
box-shadow: 0px 0px 10px salmon,0px 0px 20px hotpink;
border:none;
font-size:1.1rem;
margin-left:50%;
transform: translateX(-50%);
color:#fff;
padding:10px 25px;
border-radius: 10px;
margin-bottom: 20px;
}
#loadStatus{
text-shadow: none;
display: block;
position:fixed;
bottom:-150px;
left:0px;
max-height: 140px;
font-size:0.8rem;
color:aquamarine;
}
#loader{
display: block;
position: fixed;
top:50%;
left:50%;
transform: translate(-50%,-50%);
color:white;
/* text-shadow:1px 1px 2px #000,-1px -1px 2px #555,0px 0px 55px brown,0px 0px 85px red; */
font-size: 2rem;
background:#2a2a2a;
padding:25px;
padding-bottom:100px;
border-radius:10px;
box-shadow: 2px 2px 4px #555,-2px -2px 4px #000,inset 2px 2px 6px #555,inset -2px -2px 6px #000;
}
#loader::before{
content: "";
display: block;
position: absolute;
bottom:5px;
left:50%;
width:50px;
height:50px;
transform:translate(-50%,-50%);
border:4px solid #aaa;
border-right-color: transparent;
border-radius: 100%;
animation:cubic-bezier(0.175, 0.885, 0.32, 1.275) 2s spin infinite;
}
@keyframes spin{
0%{
    transform: translate(-50%,-50%) rotate(0deg);
}
100%{
    transform: translate(-50%,-50%) rotate(360deg);
}
}
h1{
margin-top:0px;
margin-bottom: 45px;
color:#fff;
text-align: center;
position: relative;
}
h1::before{
content:"";
display: block;
width:50%;
max-width: 350px;
height:4px;
border-radius:100%;
left:50%;
bottom:-8px;
transform: translate(-50%,-50%);
position: absolute;
background: linear-gradient(to left,salmon,hotpink);
}
h3{
color:#fff;
margin:20px 0px;
}
h3:before{
content:"";
display: inline-block;
margin-right:8px;
border-radius:100%;
width:10px;
height:10px;
box-shadow: 0px 0px 10px salmon,0px 0px 20px hotpink;
background: linear-gradient(to top right,salmon,hotpink);
}
small{
color:#aaa;
font-size:0.8rem;
}
a{
text-decoration: none;
}
</style>

<body>
    <canvas id="cnvs"></canvas>
      <div id="banner">
        <div id="bannerInfo">
            <h1>Welcome</h1>
            <p>
                <h3>
                    Follow My Instagram <a href="https://www.instagram.com/itsmeiky____" > >>FOLLOW<< </a><br>
                

                </h3>
               <h3> Jadi Lu Tinggak Ketuk Di Layar Buat Lompat Ke Bunderan Selanjutnya </h3> <h3> Untuk pengguna pc pake spasi atau panah atas </h3> <h3> Bulan yang berputar di sekitar plannet itu adalah musuh jadi jangan sampe kena </h3> <small> Kalo Mainin Nya Di Pc Pasti Mantep </small>
            </p>

            <script language="javascript" type="text/javascript">
const { PI, sin, cos, atan2, hypot, floor, random } = Math;

function $(_el){
    return document.getElementById(_el);
}

class Moon {
    constructor(r, angle,omega=1) {
        
        this.r = r;
        this.angle = angle;
        this.type = rand(0, 2);
        this.color = "ghostwhite";
        this.l=0;
        this.x=0;
        this.y=0;
        this.omega=omega || 1;
    }


    update() {
        this.angle += this.omega*(-PI / 360);
    }
    setPos(x, y){
        this.x=x;
        this.y=y;
    }
    draw() {

        //x,y will be passed from Parent
        //face
        ctx.strokeStyle="#faa";
        ctx.fillStyle = this.color;
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.r, 0, 2 * PI); //will be image later
        ctx.fill();
        ctx.stroke();
        //left eye
        ctx.fillStyle = "red";
        ctx.beginPath();
        ctx.arc((this.x-this.r/4), this.y-this.r/4, 2, 0, 2 * PI); //will be image later
        ctx.fill();
        //right eye
        ctx.fillStyle = "red";
        ctx.beginPath();
        ctx.arc((this.x+this.r/4), this.y-this.r/4, 2, 0, 2 * PI); //will be image later
        ctx.fill();
        //mouth
        ctx.fillStyle = "red";
        ctx.beginPath();
        ctx.moveTo(this.x-this.r/4, this.y+this.r/3); //will be image later
        ctx.lineTo(this.x+this.r/4, this.y+this.r/3);
        ctx.stroke();
        
        
    }

    pop() {
        this.color = "red";
    }

    checkCollision(orb) {
        
        var dist = hypot(this.x - orb.x, this.y - orb.y);
        if (dist <= orb.r + this.r) {
            return 1;
        } else {
            return 0;
        }

    }

}

class Plannet {

    constructor(x, y, r,difficulty=1) {
        this.x = x;
        this.y = y;
        this.r = r;
        this.moonRadius = (this.r/5);
        this.moonMargin = 24;
        this.moons = [];
        this.difficulty = difficulty ;
        var totalR = this.r + this.moonRadius + this.moonMargin;
        this.maxMoons = (floor(2 * PI * totalR / (this.moonRadius + this.moonMargin * 2)));
        this.hue=Math.floor(Math.random()*360);
        this.pullDown=0;
        this.pullTillEnd=1;
        this.dead=0;
        //hsl(0, 100%, 50%)
    }

    generateMoons() {
        var moonCount = rand(2, this.maxMoons - 4, 1);
        
        var _omega=(rand(-1,1,1))*this.difficulty;
        // rand(-(this.difficulty+1),(this.difficulty+1),1);
        if(_omega==0) _omega=1;
        if(this.difficulty >=20) _omega=rand(-1,1,1)* 20;
        for (var a = 0; a < moonCount; a += 1) {
            this.moons.push(new Moon(this.moonRadius, a * (2 * PI / moonCount) , _omega));
        }
    }

    checkCollision(orb) {
        this.moons.forEach(m => {
            if (m.checkCollision(orb)) {
                m.pop();
                m.draw();
                orb.dead=1;
                orb.vx=0;
                orb.vy=0;
                orb.launched=0;
                return 1;
            }
        });
        return 0;
    }

    update(updateMoons=1){
        if(this.pullTillEnd && this.pullDown){
            if(this.y>=innerHeight+this.r){
                this.dead=1;
                this.pullDown=0;
            } else {
                this.y+=7.5;
            }
        } else if(!this.pullTillEnd && this.pullDown){
                if(this.y >= h-this.r*2){
                    this.pullDown=0;
                    this.pullTillEnd=1;
                    orbia.score+=this.difficulty;
                    orbia.difficultyLevel+=0.25;
                } else {
                    this.y+=5.5;
                    orbia.y=this.y;
                }
        }
        
        this.moons.forEach(m => {
            if(updateMoons){
                m.update();
            }
            m.setPos(
                this.x + (this.r + this.moonMargin + m.r) * cos(m.angle),
                this.y + (this.r + this.moonMargin + m.r) * sin(m.angle)
            );
            m.draw();
        });
    
    }

    draw() {
        ctx.lineWidth=2;
        ctx.strokeStyle="hsl("+this.hue+",100%,50%)";
        this.hue++;
        this.hue%=360;
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.r, 0, 2 * PI);
        ctx.stroke();
    }
    
}

class Orbia {

    constructor(plannet0) {
        this.x = plannet0.x;
        this.y = plannet0.y;
        this.r = 25;
        this.plannet = plannet0;
        this.nextPlannet = null;
        this.vx = 0;
        this.vy = 0;
        this.score = 0;
        this.launched = 0;
        this.dead = 0;
        this.difficultyLevel=0;
        this.frame=0;
        this.theta=0;
        this.omega=0.05;
        this.incScore=0;
    }

    pullTo(nextPlannet) {
        this.nextPlannet = nextPlannet;
        this.launched = 1;
    }

    update() {
        if(this.dead) {this.draw();return};
        this.frame++;
        this.theta+=this.omega;
        if (this.launched) { 
            
            sounds.play("fall");                
            var dist = hypot(this.x - this.nextPlannet.x, this.y - this.nextPlannet.y);
            if (dist >= 0.5) {
                var dx = -1 * (this.x - this.nextPlannet.x) / 5;
                var dy = -1 * (this.y - this.nextPlannet.y) / 5; //in 5 steps
                this.vx = dx;
                this.vy = dy;
                this.incScore=1;
            } else {
                this.launched = 0;
                this.vx = 0;
                this.vy = 0;
                this.plannet.pullDown=1;  
                this.nextPlannet.pullDown=1;
                this.nextPlannet.pullTillEnd=0;
                if(this.incScore){
                    
                    this.incScore=0;
                    this.score += Math.floor(rand(10, 100, 1)*(5*this.difficultyLevel+1));
                }
            }

            //check collision
            if(this.plannet){
                this.plannet.checkCollision(this);
            }
            this.nextPlannet.checkCollision(this);
            
        }
        this.x += this.vx;
        this.y += this.vy;

    }

    gameOver() {
        // dead animation
        if(this.frame >=351){
            sounds.pauseAll();
            sounds.play("dash");
            this.frame=0;
        }
        this.frame++;
        
        if(this.frame>=70){
            // this.vy = 2.5;
            this.y+=this.vy;
            this.vy+=1.5;       
            sounds.play("fall");
        }
        if(this.y>=innerHeight || this.frame >=350){
            this.dead=2;
        }
    }

    draw() {
        if (this.dead) {
            ctx.strokeStyle = "salmon";
            ctx.fillStyle = "hotpink";
        } else {
            ctx.strokeStyle = "aqua";
            ctx.fillStyle = "aqua";
        }
     
        // this.theta=0;
     
        ctx.save();
        ctx.translate(this.x,this.y)
        ctx.rotate(this.theta);
        
        ctx.shadowOffsetX=0;
        ctx.shadowOffsetY=0;
        ctx.shadowColor=ctx.strokeStyle;
        ctx.shadowBlur=50;

        //face
        ctx.beginPath();
        ctx.arc(0, 0, this.r, 0, 2 * PI);
        ctx.fill();
        ctx.stroke();
        
        
        ctx.shadowOffsetX=null;
        ctx.shadowOffsetY=null;
        ctx.shadowColor=null;
        ctx.shadowBlur=null;
        
        //left eye
        ctx.beginPath();
        ctx.arc(-(this.r/3), -this.r/4, 3, 0, 2 * PI);
        ctx.fillStyle = "white";
        ctx.fill();

        //right eye
        ctx.beginPath();
        ctx.arc((this.r/3), -this.r/4, 3, 0, 2 * PI);
        ctx.fillStyle = "white";
        ctx.fill();

        //smile
        ctx.beginPath();
        ctx.arc(0, 2, 10, 20*(PI/180),  (160)*(PI/180));
        ctx.strokeStyle = "white";
        ctx.stroke();
        
        ctx.restore();
    }
}

class Background {
    constructor(x = 0, y = 0) {
        this.x = x;
        this.y = y;
    }
    
    draw(dx, dy) {
        dx *= 20;
        dy /= 2;
        var _w = innerWidth, _h = innerHeight;
        var grad = ctx.createRadialGradient((_w / 2) - dx, (_h / 2) + dy, 0, (_w / 2) - dx, (_h / 2) + dy, Math.max(_w / 2, _h / 2));
        grad.addColorStop(0, "ghostWhite");
        grad.addColorStop(0.5, "indigo");
        grad.addColorStop(1, "indigo");
        ctx.fillStyle = grad;
        ctx.fillRect(0, 0, _w, _h);
        dx *= 100 / 20;
        dy *= 2;
        
        ctx.shadowOffsetX=0;
        ctx.shadowOffsetY=0;
        ctx.shadowColor="#000";
        ctx.shadowBlur=100;
        ctx.fillStyle = "#000000";
        ctx.beginPath();
        ctx.moveTo((-50) - dx, (_h) + dy);
        // ctx.lineTo((_w/4)-dx,((_h/2)+40)+dy);
        ctx.arcTo((_w / 4) - dx, ((_h / 2) + 40) + dy, ((_w / 2) + 100) - dx, (_h) + dy, 50);
        ctx.lineTo(((_w / 2) + 100) - dx, (_h) + dy);
        ctx.fill();
        
        dx/=(100/20);
        ctx.beginPath();
        ctx.moveTo((_w / 2) + (-50) - dx, (_h) + dy);
        // ctx.lineTo((_w/4)-dx,((_h/2)+40)+dy);
        ctx.arcTo((_w / 2) + (_w / 4) - dx, ((_h / 2) + 100) + dy, (_w / 2) + ((_w / 2) + 100) - dx, (_h) + dy, 50);
        ctx.lineTo((_w / 2) + ((_w / 2) + 100) - dx, (_h) + dy);
        ctx.fill();

        ctx.shadowOffsetX=null;
        ctx.shadowOffsetY=null;
        ctx.shadowColor=null;
        ctx.shadowBlur=null;
    }
}

class Sound{
    constructor(){
        this.queue=[];
        this.totalLoaded=0;
    }
    load(callback,replayCallback){
        // console.log("load Init");
        var _this=this;
        this.replayCallback=replayCallback;
        this.queue.forEach(function(a){
            a.sound.oncanplaythrough=function(){_this.loadE(callback,a)};
        });        
    }
    loadE(callback,s){
        this.totalLoaded++;
        $('loadStatus').innerHTML+=("loading..." + s.name+" done.. "+sounds.totalLoaded+"/"+sounds.queue.length)+"<br>";
        if(this.totalLoaded==this.queue.length)
            callback();
        
    }
    add(name,path){
        this.queue.push({"name":name,"sound":new Audio(path)});
    }
    play(name,sp=1){
        for(var i=0;i<this.queue.length;i++){
            if(this.queue[i]["name"]==name){
                if(sp && !this.queue[i]["sound"].paused) return;
                this.queue[i]["sound"].play();
                // .then(e=>console.log("playing"));
                if(name.match("bgm"))
                    this.queue[i]["sound"].onended=this.replayCallback;
            }
        }
    }
    pauseAll(){
        for(var i=0;i<this.queue.length;i++){
            this.queue[i]["sound"].pause()
        }
    }
}
  
var cnvs,ctx,w,h;

var sounds;

onload=function(){
    sounds=new Sound();
    var baseUrl="https://github.com/PrashanthKumar0/Orbia-Game/raw/master/";
    sounds.add("bgm0",baseUrl+"assets/title.ogg");
    sounds.add("bgm1",baseUrl+"assets/game_w0.ogg");
    sounds.add("bgm2",baseUrl+"assets/game_w1.ogg");
    sounds.add("bgm3",baseUrl+"assets/game_w1000.ogg");
    sounds.add("fall",baseUrl+"assets/level_started.ogg");
    sounds.add("dash",baseUrl+"assets/pet_monster_touched.ogg");
    sounds.load(loadFunction,rePlayAudioFunction);
}

function rePlayAudioFunction (){
    sounds.play("bgm"+rand(0,3,1));
}

function loadFunction() {
    $('loadStatus').innerHTML+=("all Done.. <br> initializing the game");
    setTimeout(function(){

        $('loader').style.display="none";
        $('banner').style.display="block";
    
    },400) //just to add a little fun ;)
    // init();  
}


var orbia;

var plannets=[];

function init(){
    $('banner').style.display="none";
    cnvs=$('cnvs');
    cnvs.style.display="block";
    rePlayAudioFunction();
    ctx=cnvs.getContext("2d");
    w=cnvs.width=innerWidth;
    h=cnvs.height=innerHeight;

    var p=new Plannet((w/2)-100,h-200,80);
    p.generateMoons();
    
    plannets.push(p); //current
    
    var p2=new Plannet((w/2)+150,(h/2)-150,80);
    p2.generateMoons();

    plannets.push(p2); //next

    orbia=new Orbia(p);

    addEvents();

    looper();
}

function restart(){
    
    orbia=null;
    plannets=[];
    init();
}

const background=new Background();

function drawBg() {
    var mag=((orbia.x**2)+(orbia.y**2))**(1/2);
    var dx=orbia.x/mag;
    var dy=orbia.x/mag;
    background.draw(dx,dy);
}

function looper(){
    managePlannets();
    if(!orbia.dead){
        drawAll();        
    } else {
        orbia.gameOver();
        drawAll(1);
        if(orbia.dead==2){
            gameOver();
            return;
        }
    }
    requestAnimationFrame(looper);
}

function drawAll(gameOver=0){
    ctx.clearRect(0,0,w,h);
    drawBg();
    plannets[0].update(!gameOver);
    plannets[1].update(!gameOver);
    plannets[0].draw();
    plannets[1].draw();
    orbia.update();
    orbia.draw();
    ctx.font="15px sans-serif";
    ctx.fillStyle="aqua";
    ctx.fillText("Score:"+Math.floor(orbia.score),w-140,h-100);
    ctx.fillText("Difficulty:"+(orbia.difficultyLevel),w-140,h-50);
}
function gameOver(){
    ctx.font="20px sans-serif";
    ctx.fillStyle="rgba(0,0,0,0.5)";
    var bw=ctx.measureText("Game Over").width;
    ctx.fillRect(((w/2)-bw/2)-50,(h/2)-50,bw+100,100);
    ctx.fillStyle="aqua";
    ctx.fillText("Game Over",(w/2)-bw/2,h/2);
    sounds.pauseAll();
    sounds.play("dash");
    setTimeout(function(){
        $("restartBtn").onclick=restart;
        $("restartBtn").innerHTML="Mulai Lagi Bang?";
        $("banner").style.display="block";
        $("bannerInfo").innerHTML="<h1>Game Over</h1><span class='score'>Final Score:"+orbia.score+"<br> Difficulty Reached : "+orbia.difficultyLevel+" </span>"
        $("cnvs").style.display="none";
    },500);
}

function managePlannets() {
    if(plannets[0].dead){
        plannets.splice(0,1);
        plannets[1]=(new Plannet(rand(80*2,(w-80*2)),(h/2)-150,80,orbia.difficultyLevel));
        plannets[1].generateMoons();
        orbia.plannet=plannets[0];
    }
}


function addEvents(){
    cnvs.onclick=function(){
        orbia.launched=1;
        orbia.pullTo(plannets[1]);    
    }
    onkeydown=(e)=>{
        // console.log(e.keyCode)
        if(e.keyCode==32 || e.keyCode==38) {//up arrow or space bar
            orbia.launched=1;
            orbia.pullTo(plannets[1]);    
                
        }
    }
}


function rand(min,max,_floor){

    var num=(min+(random()*(max-min)))
    return _floor==1?Math.round(num):num;

}

alert("Created by itsmeiky✓");
            </script>

        </div>
        <button onclick="init()" id="restartBtn">Mulai</button>
    </div>
    
    <div id="loader">
        <div id="loadStatus">
        </div>
        Loading
    </div>
    


</body>
</html>