lifelong learner — urip iku urup, currently working on accenture.

canvas 2d – point gamification

0
Degananda.com -

Setiap aplikasi pasti memiliki susuatu yang memacu usernya untuk selalu menggunakannya (aplikasi). Konsep seperti ini bernama gamifikasi. Biasannya gamifikasi ini berbentuk poin yang didapatkan oleh pengguna namun tidak hanya itu kembali lagi ke bantuk dari game tersebut.

Pada canvas kita dapat menampilkan point tersebut langsung (di canvas) melalui object tulisan/font. Namun yang menjadi masalah adalah kita harus secara terus menerus melakukan render tulisan itu ketika object sedang bergerak. Karena untuk menggerakan object kita akan menghapus seluruh object yang berada pada canvas. Hal ini tentunnya akan menambahkan proses yang harus dikerjakan oleh browser dan programmer. Solusinnya adalah kita meletakan poin tersebut tidak menggunakan object font yang berada pada canvas.

Model pertama adalah kita membuat elemen (dapat berupa div atau span) diluar canvas yang akan menampilkan nilai/poin yang didapatkan oleh user. Selanjutnya terdapat model kedua yakni membuat elemen(div) yang letaknya “overlay” terhadap canvas tersebut. Kita akan memanfaatkan css(cassading stylesheet).

Mendapatkan point

Kita akan membuat canvas yang mana user dapat menggerakan object dengan menggunakan control keyboard. Object tersebut jika ditabrakan dengan object lain(food) akan meningkatkan poin yang didapatkan. Berikut ini adalah kode dari kasus tersebut

game.js

// membuat canvas
var canvas = document.createElement('canvas');
canvas.width = 900;
canvas.height = 450;
canvas.className = 'myCanvas';
document.body.appendChild(canvas);

var contex = canvas.getContext("2d");
var score = 0;
var pos = {
    x : 30,
    y : 30
}

var posFood = {
    x : 150,
    y : 150
}

function drawFood(){
    contex.beginPath();
    contex.arc(posFood.x,posFood.y,30,0,7);
    contex.stroke();
    contex.fillStyle = 'red';
    contex.fill();
    contex.closePath();
}

function drawCircle(){
    contex.beginPath();
    contex.arc(pos.x,pos.y,30,0,7);
    contex.stroke();
    contex.fillStyle = 'green';
    contex.fill();
    contex.closePath();
}

// membuat object pertama kali
drawFood();
drawCircle();

function doRender(){
    if(pos.x == posFood.x && pos.y == posFood.y){
    // clear canvas
        contex.clearRect(0,0,canvas.width,canvas.height);
        drawCircle();
        posFood.x = 90+(Math.floor(Math.random() * 5)+1)*60;
        posFood.y = 90+(Math.floor(Math.random() * 5)+1)*60;
        score=score+1;
    } else {
        contex.clearRect(0,0,canvas.width,canvas.height);
        drawCircle();
    }
    drawFood();
}

addEventListener("keydown", function(res){

    if(res.key == "ArrowRight"){
        pos.x += 60;
        doRender();
    } else if(res.key == "ArrowLeft"){
        pos.x -= 60;
        doRender();
    } else if(res.key == "ArrowDown"){
        pos.y += 60;
        doRender();
    } else if(res.key == "ArrowUp"){
        pos.y -= 60;
        doRender();
    }
    

});

Kita memiliki variable “score” yang berfungsi untuk menyimpan score dari permainan. Score ini akan didapatkan ketika user menabrakan object yang digerakan dengan object yang diam. Ketika object belum bertabrakan maka score tidak akan bertambah. Object yang bergerak ini akan berwarna hijau sementara object yang diam atau sasaran yang akan ditabrak akan berwarna merah.

Problem yang muncul adalah bagaimana cara menampilkan score tersebut dalam permainan. Kita memiliki dua model yang telah dibahas diatas. Model pertama ditampilkan dibawah canvas (elemen div dibawah canvas). Dan model kedua adalah dengan melakukan overlay.

Model 1 – Diluar canvas

pada model 1 ini kita akan membuat satu elemen div yang berada dibawah atapun diatas canvas (tergantung dari selera).

<div class="score_box">
Score : <span id="score">0</span>
</div>

isinnya sangat sederhana yakni hanya berupa tulisan score yang nantinnya akan mengambil nilai dari variabel score pada javascript. Untuk dapat mengupdate  nilai pada id score di element span diatas maka kita memerlukan akses pada DOM. Kita akan update innerHtml dari elemen yang memiliki id score. Kita menggunakan id bukan class karena id bersifat unik. Berikut adalah kode untuk mengubah nilai score pada dom.

function doRender(){
 if(pos.x == posFood.x && pos.y == posFood.y){
 // clear canvas
 contex.clearRect(0,0,canvas.width,canvas.height);
 drawCircle();
 posFood.x = 90+(Math.floor(Math.random() * 5)+1)*60;
 posFood.y = 90+(Math.floor(Math.random() * 5)+1)*60;
 score=score+1;
 document.getElementById('score').innerHTML = score;
 } else {
 contex.clearRect(0,0,canvas.width,canvas.height);
 drawCircle();
 }
 drawFood();
}

itulah cara menampilkan score atau point dengan menggunakan model yang pertama yakni memisahkan antara canvas dan elemen yang menampilkan score.

anda dapat mengakses secara online untuk melihat demonstrasi “game” sederhana yang kita buat dengan menggunakan sistem poin (gamafikasi) pada link js fiddle dibawah ini.

Model 2 – overlay canvas

untuk dapat melakukan overlay suatu elemen(misalkan div) pada canvas kita membutuhkan suatu container. Container ini harus berupa div dan canvas beserta elemen yang digunakan untuk menampilkan div haruslah berada dicontainer tersebut. Selanjutnya, elemen score harus memiliki style position berupa absolute. Maka nantinnya dia akan berada didalam canvas karena score dan canvas menjadi satu bagian dengan container. Untuk lebih jelasnya maka perhatikan kode dibawah

index.html


kemudian untuk stylesheet nya sebagai berikut ini

.myCanvas {
    background: #E4F1FE;
}

.game_container {
    position: relative;
}

.score_box {
    margin-top: 15px;
    font-size: 25px;
    font-weight: bold;
    position: absolute;
}

maka sekarang score akan berada didalam canvas yang ditampilkan secara overlay. Sehingga ketika object bergerak dicanvas ataupun saat canvas didelete/dihapus score tidak akan hilang karena score hanya elemen html biasa bukan bagian object dari canvas.