Membangun Game Pertama Anda dengan HTML5

HTML5 tumbuh lebih cepat daripada yang bisa dibayangkan siapa pun. Solusi hebat dan profesional sudah dikembangkan... bahkan di dunia game! Hari ini, Anda akan membuat game pertama Anda menggunakan Box2D dan tag canvas HTML5.
Box2D adalah mesin populer dan open source yang mensimulasikan fisika 2D untuk pembuatan game dan aplikasi. Terutama ditulis di C++, telah diubah ke banyak bahasa oleh kontributor komunitas.
Dengan metode dan objek yang sama, Anda memiliki kemampuan untuk membuat fisika permainan Anda dalam banyak bahasa, seperti Objective C (iPhone/iPad), Actionscript 3.0 (Web), HTML 5 (Web), dll.
Untuk mulai mengembangkan demo Anda, unduh mesin Box2D untuk HTML5 di sini. Selanjutnya, buat file HTML baru dengan struktur berikut (salin direktori js dan lib dari proyek box2d-js ke folder permainan Anda).
Sekarang, Anda harus memasukkan file yang diperlukan untuk menjalankan box2D ke file HTML Anda:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<!--[if IE]><script src="lib/excanvas.js"></script><![endif]-->
 <script src="lib/prototype-1.6.0.2.js"></script>
<!-- box2djs -->
 <script src='js/box2d/common/b2Settings.js'></script>
 <script src='js/box2d/common/math/b2Vec2.js'></script>
 <script src='js/box2d/common/math/b2Mat22.js'></script>
 <script src='js/box2d/common/math/b2Math.js'></script>
 <script src='js/box2d/collision/b2AABB.js'></script>
 <script src='js/box2d/collision/b2Bound.js'></script>
 <script src='js/box2d/collision/b2BoundValues.js'></script>
 <script src='js/box2d/collision/b2Pair.js'></script>
 <script src='js/box2d/collision/b2PairCallback.js'></script>
 <script src='js/box2d/collision/b2BufferedPair.js'></script>
 <script src='js/box2d/collision/b2PairManager.js'></script>
 <script src='js/box2d/collision/b2BroadPhase.js'></script>
 <script src='js/box2d/collision/b2Collision.js'></script>
 <script src='js/box2d/collision/Features.js'></script>
 <script src='js/box2d/collision/b2ContactID.js'></script>
 <script src='js/box2d/collision/b2ContactPoint.js'></script>
 <script src='js/box2d/collision/b2Distance.js'></script>
 <script src='js/box2d/collision/b2Manifold.js'></script>
 <script src='js/box2d/collision/b2OBB.js'></script>
 <script src='js/box2d/collision/b2Proxy.js'></script>
 <script src='js/box2d/collision/ClipVertex.js'></script>
 <script src='js/box2d/collision/shapes/b2Shape.js'></script>
 <script src='js/box2d/collision/shapes/b2ShapeDef.js'></script>
 <script src='js/box2d/collision/shapes/b2BoxDef.js'></script>
 <script src='js/box2d/collision/shapes/b2CircleDef.js'></script>
 <script src='js/box2d/collision/shapes/b2CircleShape.js'></script>
 <script src='js/box2d/collision/shapes/b2MassData.js'></script>
 <script src='js/box2d/collision/shapes/b2PolyDef.js'></script>
 <script src='js/box2d/collision/shapes/b2PolyShape.js'></script>
 <script src='js/box2d/dynamics/b2Body.js'></script>
 <script src='js/box2d/dynamics/b2BodyDef.js'></script>
 <script src='js/box2d/dynamics/b2CollisionFilter.js'></script>
 <script src='js/box2d/dynamics/b2Island.js'></script>
 <script src='js/box2d/dynamics/b2TimeStep.js'></script>
 <script src='js/box2d/dynamics/contacts/b2ContactNode.js'></script>
 <script src='js/box2d/dynamics/contacts/b2Contact.js'></script>
 <script src='js/box2d/dynamics/contacts/b2ContactConstraint.js'></script>
 <script src='js/box2d/dynamics/contacts/b2ContactConstraintPoint.js'></script>
 <script src='js/box2d/dynamics/contacts/b2ContactRegister.js'></script>
 <script src='js/box2d/dynamics/contacts/b2ContactSolver.js'></script>
 <script src='js/box2d/dynamics/contacts/b2CircleContact.js'></script>
 <script src='js/box2d/dynamics/contacts/b2Conservative.js'></script>
 <script src='js/box2d/dynamics/contacts/b2NullContact.js'></script>
 <script src='js/box2d/dynamics/contacts/b2PolyAndCircleContact.js'></script>
 <script src='js/box2d/dynamics/contacts/b2PolyContact.js'></script>
 <script src='js/box2d/dynamics/b2ContactManager.js'></script>
 <script src='js/box2d/dynamics/b2World.js'></script>
 <script src='js/box2d/dynamics/b2WorldListener.js'></script>
 <script src='js/box2d/dynamics/joints/b2JointNode.js'></script>
 <script src='js/box2d/dynamics/joints/b2Joint.js'></script>
 <script src='js/box2d/dynamics/joints/b2JointDef.js'></script>
 <script src='js/box2d/dynamics/joints/b2DistanceJoint.js'></script>
 <script src='js/box2d/dynamics/joints/b2DistanceJointDef.js'></script>
 <script src='js/box2d/dynamics/joints/b2Jacobian.js'></script>
 <script src='js/box2d/dynamics/joints/b2GearJoint.js'></script>
 <script src='js/box2d/dynamics/joints/b2GearJointDef.js'></script>
 <script src='js/box2d/dynamics/joints/b2MouseJoint.js'></script>
 <script src='js/box2d/dynamics/joints/b2MouseJointDef.js'></script>
 <script src='js/box2d/dynamics/joints/b2PrismaticJoint.js'></script>
 <script src='js/box2d/dynamics/joints/b2PrismaticJointDef.js'></script>
 <script src='js/box2d/dynamics/joints/b2PulleyJoint.js'></script>
 <script src='js/box2d/dynamics/joints/b2PulleyJointDef.js'></script>
 <script src='js/box2d/dynamics/joints/b2RevoluteJoint.js'></script>
 <script src='js/box2d/dynamics/joints/b2RevoluteJointDef.js'></script>
Ya, itu sejumlah besar permintaan HTTP!
Perlu diketahui bahwa, untuk penerapannya, sangat disarankan agar Anda menggabungkan semua sumber ini ke dalam satu file script.
Selanjutnya, buat dua skrip lagi di dalam folder /js/, yang disebut "box2dutils.js" dan "game.js".
  • box2dutils.js - ini adalah copy dan paste dari beberapa demo yang disertakan dengan box2dlib, dan penting untuk fungsi menggambar (saya juga akan menjelaskan beberapa bagian penting di sini).
  • game.js - permainannya itu sendiri; di sinilah kita menciptakan platform, pemain, menerapkan interaksi keyboard, dll.
Salin dan tempel kode berikut ke box2dutils.js. Jangan khawatir! Saya akan menjelaskannya sedikit demi sedikit!
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
function drawWorld(world, context) {
  for (var j = world.m_jointList; j; j = j.m_next) {
        drawJoint(j, context);
    }
    for (var b = world.m_bodyList; b; b = b.m_next) {
        for (var s = b.GetShapeList(); s != null; s = s.GetNext()) {
            drawShape(s, context);
        }
    }
}
function drawJoint(joint, context) {
    var b1 = joint.m_body1;
    var b2 = joint.m_body2;
    var x1 = b1.m_position;
    var x2 = b2.m_position;
    var p1 = joint.GetAnchor1();
    var p2 = joint.GetAnchor2();
    context.strokeStyle = '#00eeee';
    context.beginPath();
    switch (joint.m_type) {
    case b2Joint.e_distanceJoint:
        context.moveTo(p1.x, p1.y);
        context.lineTo(p2.x, p2.y);
        break;
 
    case b2Joint.e_pulleyJoint:
        // TODO
        break;
 
    default:
        if (b1 == world.m_groundBody) {
            context.moveTo(p1.x, p1.y);
            context.lineTo(x2.x, x2.y);
        }
        else if (b2 == world.m_groundBody) {
            context.moveTo(p1.x, p1.y);
            context.lineTo(x1.x, x1.y);
        }
        else {
            context.moveTo(x1.x, x1.y);
            context.lineTo(p1.x, p1.y);
            context.lineTo(x2.x, x2.y);
            context.lineTo(p2.x, p2.y);
        }
        break;
    }
    context.stroke();
}
function drawShape(shape, context) {
    context.strokeStyle = '#000000';
    context.beginPath();
    switch (shape.m_type) {
    case b2Shape.e_circleShape:
        {
            var circle = shape;
            var pos = circle.m_position;
            var r = circle.m_radius;
            var segments = 16.0;
            var theta = 0.0;
            var dtheta = 2.0 * Math.PI / segments;
            // draw circle
            context.moveTo(pos.x + r, pos.y);
            for (var i = 0; i < segments; i++) {
                var d = new b2Vec2(r * Math.cos(theta), r * Math.sin(theta));
                var v = b2Math.AddVV(pos, d);
                context.lineTo(v.x, v.y);
                theta += dtheta;
            }
            context.lineTo(pos.x + r, pos.y);
     
            // draw radius
            context.moveTo(pos.x, pos.y);
            var ax = circle.m_R.col1;
            var pos2 = new b2Vec2(pos.x + r * ax.x, pos.y + r * ax.y);
            context.lineTo(pos2.x, pos2.y);
        }
        break;
    case b2Shape.e_polyShape:
        {
            var poly = shape;
            var tV = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[0]));
            context.moveTo(tV.x, tV.y);
            for (var i = 0; i < poly.m_vertexCount; i++) {
                var v = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[i]));
                context.lineTo(v.x, v.y);
            }
            context.lineTo(tV.x, tV.y);
        }
        break;
    }
    context.stroke();
}
 
 
function createWorld() {
    var worldAABB = new b2AABB();
    worldAABB.minVertex.Set(-1000, -1000);
    worldAABB.maxVertex.Set(1000, 1000);
    var gravity = new b2Vec2(0, 300);
    var doSleep = true;
    var world = new b2World(worldAABB, gravity, doSleep);
    return world;
}
 
function createGround(world) {
    var groundSd = new b2BoxDef();
    groundSd.extents.Set(1000, 50);
    groundSd.restitution = 0.2;
    var groundBd = new b2BodyDef();
    groundBd.AddShape(groundSd);
    groundBd.position.Set(-500, 340);
    return world.CreateBody(groundBd)
}
 
function createBall(world, x, y) {
    var ballSd = new b2CircleDef();
    ballSd.density = 1.0;
    ballSd.radius = 20;
    ballSd.restitution = 1.0;
    ballSd.friction = 0;
    var ballBd = new b2BodyDef();
    ballBd.AddShape(ballSd);
    ballBd.position.Set(x,y);
    return world.CreateBody(ballBd);
}
 
function createBox(world, x, y, width, height, fixed, userData) {
    if (typeof(fixed) == 'undefined') fixed = true;
    var boxSd = new b2BoxDef();
    if (!fixed) boxSd.density = 1.0;
     
    boxSd.userData = userData;
     
    boxSd.extents.Set(width, height);
    var boxBd = new b2BodyDef();
    boxBd.AddShape(boxSd);
    boxBd.position.Set(x,y);
    return world.CreateBody(boxBd)
}
Advertisement
Buka file index.html yang telah Anda buat sebelumnya, dan tambahkan elemen canvas (600x400) di dalam elemen body. Di sinilah kita akan bekerja dengan API menggambar HTML5:
1
<canvas id="game" width='600' height='400'></canvas>
Juga, saat Anda berada di sini, referensikan game.js dan box2dutils.js.
1
2
<script src='js/box2dutils.js'></script>
<script src='js/game.js'></script>
Itu akan melakukannya untuk HTML! Mari kerjakan JavaScript yang menyenangkan sekarang juga!
Buka game.js, dan masukkan kode di bawah ini:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// some variables that we gonna use in this demo
var initId = 0;
var player = function(){
    this.object = null;
    this.canJump = false;
};
var world;
var ctx;
var canvasWidth;
var canvasHeight;
var keys = [];
 
// HTML5 onLoad event
Event.observe(window, 'load', function() {
    world = createWorld(); // box2DWorld
    ctx = $('game').getContext('2d'); // 2
    var canvasElm = $('game');
    canvasWidth = parseInt(canvasElm.width);
    canvasHeight = parseInt(canvasElm.height);
    initGame(); // 3
    step(); // 4
     
// 5
    window.addEventListener('keydown',handleKeyDown,true);
    window.addEventListener('keyup',handleKeyUp,true);
});
Oke, mari kita cari tahu apa isi kode ini!
Box2DWorld adalah salah satu kelas yang tersedia, melalui inti box2d. Fungsinya sederhana: menggabungkan semuanya menjadi satu kelas. Di box2DWorld, Anda memiliki definisi tubuh dan manajer benturan dari permainan atau aplikasi Anda.
Jaga file game.js dan box2dutils.js terbuka, dan cari fungsi createWorld() di dalam box2dutils.js.
01
02
03
04
05
06
07
08
09
10
11
12
function createWorld() {
    // here we create our world settings for collisions
    var worldAABB = new b2AABB();
    worldAABB.minVertex.Set(-1000, -1000);
    worldAABB.maxVertex.Set(1000, 1000);
    // set gravity vector
    var gravity = new b2Vec2(0, 300);
    var doSleep = true;
    // init our world and return its value
    var world = new b2World(worldAABB, gravity, doSleep);
    return world;
}
Ini cukup sederhana untuk membuat box2DWorld.
Lihat nomor komentar di dua blok kode di atas. Pada nomor dua, kita mengambil konteks elemen canvas dengan menggunakan API penyeleksi (terlihat seperti penyeleksi jQuery atau MooTools, bukan?). Pada nomor tiga, kita memiliki fungsi baru yang menarik: initGame(). Di sinilah kita menciptakan pemandangannya.
Salin dan sisipkan kode di bawah ini ke dalam game.js, lalu kita akan mengulasnya bersama-sama.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function initGame(){
    // create 2 big platforms  
    createBox(world, 3, 230, 60, 180, true, 'ground');
    createBox(world, 560, 360, 50, 50, true, 'ground');
     
    // create small platforms
    for (var i = 0; i < 5; i++){
        createBox(world, 150+(80*i), 360, 5, 40+(i*15), true, 'ground');   
    }
     
    // create player ball
    var ballSd = new b2CircleDef();
    ballSd.density = 0.1;
    ballSd.radius = 12;
    ballSd.restitution = 0.5;
    ballSd.friction = 1;
    ballSd.userData = 'player';
    var ballBd = new b2BodyDef();
    ballBd.linearDamping = .03;
    ballBd.allowSleep = false;
    ballBd.AddShape(ballSd);
    ballBd.position.Set(20,0);
    player.object = world.CreateBody(ballBd);
     
}
 
<p> Inside <code>box2dutils.js</code>, we've created a function, called <code>createBox</code>. This creates a static rectangle body. </p>
 
function createBox(world, x, y, width, height, fixed, userData) {
    if (typeof(fixed) == 'undefined') fixed = true;
    //1
var boxSd = new b2BoxDef();
    if (!fixed) boxSd.density = 1.0;
    //2
    boxSd.userData = userData;
    //3
    boxSd.extents.Set(width, height);
 
    //4
    var boxBd = new b2BodyDef();
    boxBd.AddShape(boxSd);
    //5
    boxBd.position.Set(x,y);
    //6
    return world.CreateBody(boxBd)
}
Box2DBody memiliki beberapa karakteristik unik:
  • Hal ini dapat bersifat statis (tidak terpengaruh oleh dampak benturan), kinematik (tidak terpengaruh benturan, namun dapat dipindah oleh mouse Anda, misalnya), atau dinamis (berinteraksi dengan segalanya)
  • Harus memiliki definisi bentuk, dan harus menunjukkan bagaimana objeknya muncul
  • Mungkin ada lebih dari satu perlengkapan, yang menunjukkan bagaimana objeknya akan berinteraksi dengan benturan
  • Posisinya diatur oleh pusat objek Anda, bukan tepi kiri atas seperti banyak mesin lainnya.
  1. Di sini, kita membuat satu definisi bentuk yang akan berbentuk persegi atau persegi panjang, dan mengatur kerapatannya (seberapa sering ia akan dipindahkan, atau diputar dengan kekuatan).
  2. Kami mengatur userData, biasanya Anda mengatur objek grafis di sini, namun dalam contoh ini, saya hanya mengatur string yang akan menjadi pengidentifikasi dari tipe objek untuk tabrakan. Parameter ini tidak mempengaruhi algoritma fisika.
  3. Mengatur setengah dari ukuran kotak saya (ini adalah garis dari titik posisi, atau titik pusat objek ke sebuah sudut)
  4. Kami menciptakan definisi body, dan menambahkan definisi bentuk kotak.
  5. Mengatur posisi.
  6. Membuat body di world dan mengembalikan nilainya.
Saya telah mengkodekan pemain (bola) langsung di file game.js. Ini mengikuti urutan yang sama dari pembuatan kotak, tapi, kali ini, ini adalah sebuah bola.
01
02
03
04
05
06
07
08
09
10
11
12
var ballSd = new b2CircleDef();
    ballSd.density = 0.1;
    ballSd.radius = 12;
    ballSd.restitution = 0.5;
    ballSd.friction = 1;
    ballSd.userData = 'player';
    var ballBd = new b2BodyDef();
    ballBd.linearDamping = .03;
    ballBd.allowSleep = false;
    ballBd.AddShape(ballSd);
    ballBd.position.Set(20,0);
    player.object = world.CreateBody(ballBd);
Jadi bagaimana kita menciptakan tubuh, selangkah demi selangkah?
  1. Membuat bentuk, perlengkapan dan definisi sensor
  2. Membuat definisi tubuh
  3. Menambahkan ke tubuh bentuk, perlengkapan atau sensor Anda (tidak dijelaskan dalam artikel ini)
  4. Membuat tubuh di dunia
Seperti yang saya catat sebelumnya, ini mengikuti proses pembuatan yang sama dari sebuah kotak, tapi sekarang Anda harus mengatur beberapa parameter baru.
  • radius - Ini adalah panjang garis dari tengah lingkaran ke titik manapun di tepiannya.
  • restitution - Bagaimana bola akan kehilangan, atau mendapatkan kekuatan saat bertabrakan dengan tubuh lain.
  • friction - Bagaimana bola akan berguling.
  • damping digunakan untuk mengurangi kecepatan tubuh - ada redaman sudut dan redaman linier.
  • sleep di box2D, tubuh bisa sleep untuk memecahkan masalah kinerja. Sebagai contoh, misalkan Anda sedang mengembangkan game platform, dan levelnya ditentukan oleh layar 6000x400. Mengapa Anda perlu melakukan fisika untuk objek yang berada di luar layar? Anda tidak perlu; itulah intinya! Jadi pilihan yang tepat adalah membuat mereka dalam kondisi sleep, dan memperbaiki performa permainan Anda.
Kita sudah menciptakan dunia kita; Anda bisa menguji kode yang Anda miliki sejauh ini. Anda akan melihat pemain jatuh di atas platform barat.
Nah, jika Anda mencoba menjalankan demonya, Anda pasti bertanya-tanya, mengapa halaman itu gersang seperti kertas putih?
Selalu ingat: Box2D tidak me-render; ia hanya menghitung fisika.
Selanjutnya, mari kita me-render box2DWorld.
Buka skrip game.js Anda, dan tambahkan kode berikut:
01
02
03
04
05
06
07
08
09
10
11
12
13
function step() {
     
    var stepping = false;
    var timeStep = 1.0/60;
    var iteration = 1;
    // 1
    world.Step(timeStep, iteration);
    // 2
    ctx.clearRect(0, 0, canvasWidth, canvasHeight);
    drawWorld(world, ctx);
    // 3
    setTimeout('step()', 10);
}
  1. Menginstruksikan box2dWorld untuk melakukan simulasi fisika
  2. Membersihkan layar kanvas dan menggambar lagi
  3. Menjalankan fungsi step() lagi dalam sepuluh milidetik
Dengan sedikit kode ini, kita sekarang bekerja dengan fisika dan menggambar. Anda bisa mengujinya sendiri, dan melihat bola jatuh, seperti yang ditunjukkan di bawah ini:
01
02
03
04
05
06
07
08
09
10
function drawWorld(world, context) {
    for (var j = world.m_jointList; j; j = j.m_next) {
        drawJoint(j, context);
    }
    for (var b = world.m_bodyList; b; b = b.m_next) {
        for (var s = b.GetShapeList(); s != null; s = s.GetNext()) {
            drawShape(s, context);
        }
    }
}
Apa yang telah kami tulis di atas adalah fungsi debug yang menggambar dunia kita ke dalam kanvas, menggunakan API grafis yang disediakan oleh API Canvas HTML5.
Perulangan pertama menggambar semua sambungan. Kami tidak menggunakan sambungan dalam artikel ini. Mereka agak rumit untuk demo pertama, tapi tetap saja itu penting untuk game Anda. Mereka memungkinkan Anda menciptakan tubuh yang sangat menarik.
Perulangan kedua menggambar semua benda, itulah sebabnya mengapa kita ada di sini!
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
function drawShape(shape, context) {
    context.strokeStyle = '#000000';
    context.beginPath();
    switch (shape.m_type) {
    case b2Shape.e_circleShape:
        {
            var circle = shape;
            var pos = circle.m_position;
            var r = circle.m_radius;
            var segments = 16.0;
            var theta = 0.0;
            var dtheta = 2.0 * Math.PI / segments;
            // draw circle
            context.moveTo(pos.x + r, pos.y);
            for (var i = 0; i < segments; i++) {
                var d = new b2Vec2(r * Math.cos(theta), r * Math.sin(theta));
                var v = b2Math.AddVV(pos, d);
                context.lineTo(v.x, v.y);
                theta += dtheta;
            }
            context.lineTo(pos.x + r, pos.y);
     
            // draw radius
            context.moveTo(pos.x, pos.y);
            var ax = circle.m_R.col1;
            var pos2 = new b2Vec2(pos.x + r * ax.x, pos.y + r * ax.y);
            context.lineTo(pos2.x, pos2.y);
        }
        break;
    case b2Shape.e_polyShape:
        {
            var poly = shape;
            var tV = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[0]));
            context.moveTo(tV.x, tV.y);
            for (var i = 0; i < poly.m_vertexCount; i++) {
                var v = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[i]));
                context.lineTo(v.x, v.y);
            }
            context.lineTo(tV.x, tV.y);
        }
        break;
    }
    context.stroke();
}
Kami melakukan perulangan melalui setiap simpul objek dan menggambarnya dengan garis (context.moveTo dan context.lineTo). Nah, ini berguna untuk memiliki sebuah contoh... tapi tidak begitu berguna dalam latihan. Bila Anda menggunakan grafis, Anda hanya perlu memperhatikan posisi tubuh. Anda tidak perlu melakukan perulangan pada simpul, seperti demo ini.
Sebuah game tanpa interaktivitas adalah sebuah film, dan sebuah film dengan interaktivitas adalah sebuah permainan.
Mari kembangkan fungsi panah keyboard untuk melompat dan memindahkan bola.
Tambahkan kode berikut ke file game.js Anda:
01
02
03
04
05
06
07
08
09
10
11
function handleKeyDown(evt){
    keys[evt.keyCode] = true;
}
 
 
function handleKeyUp(evt){
    keys[evt.keyCode] = false;
}
 
// disable vertical scrolling from arrows :)
document.onkeydown=function(){return event.keyCode!=38 && event.keyCode!=40}
Dengan handleKeyDown dan handleKeyUp, kami mengatur sebuah array yang melacak setiap tombol yang diketikkan pengguna. Dengan document.onkeydown, kita menonaktifkan fungsi scroll vertikal bawaan browser untuk panah atas dan bawah. Pernahkah Anda memainkan game HTML5, dan saat Anda melompat, pemain, musuh dan objek berada diluar layar? Itu tidak akan menjadi masalah sekarang.
Tambahkan sedikit kode berikut ke awal fungsi step() Anda:
1
handleInteractions();
Dan di luar, nyatakan fungsinya:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
function handleInteractions(){
    // up arrow
    // 1
    var collision = world.m_contactList;
    player.canJump = false;
    if (collision != null){
        if (collision.GetShape1().GetUserData() == 'player' || collision.GetShape2().GetUserData() == 'player'){
            if ((collision.GetShape1().GetUserData() == 'ground' || collision.GetShape2().GetUserData() == 'ground')){
                var playerObj = (collision.GetShape1().GetUserData() == 'player' ? collision.GetShape1().GetPosition() :  collision.GetShape2().GetPosition());
                var groundObj = (collision.GetShape1().GetUserData() == 'ground' ? collision.GetShape1().GetPosition() :  collision.GetShape2().GetPosition());
                if (playerObj.y < groundObj.y){
                    player.canJump = true;
                }
            }
        }
    }
    // 2
    var vel = player.object.GetLinearVelocity();
    // 3
    if (keys[38] && player.canJump){
        vel.y = -150;  
    }
     
    // 4
    // left/right arrows
    if (keys[37]){
        vel.x = -60;
    }
    else if (keys[39]){
        vel.x = 60;
    }
     
    // 5
    player.object.SetLinearVelocity(vel);
}
Bagian paling rumit dari kode di atas adalah yang pertama, dimana kita memeriksa tumbukan, dan menulis beberapa kondisi untuk menentukan apakah shape1 atau shape2 adalah pemainnya. Jika ya, kita verifikasi jika shape1 atau shape2 adalah object tanah. Sekali lagi, jika demikian, pemain bertabrakan dengan tanah. Selanjutnya, kita periksa apakah pemain berada di atas tanah. Jika itu yang terjadi, maka pemain bisa melompat.
Pada baris komentar kedua (2), kita mengambil LinearVelocity pemain.
Daerah komentar yang ketiga dan seterusnya memeriksa jika panah ditekan, dan menyesuaikan vektor kecepatannya.
Di wilayah kelima, kita mengatur pemain dengan vektor kecepatan baru.
Interaksi sekarang sudah selesai! Tapi tidak ada tujuan, kita hanya melompat, melompat, melompat... dan melompat!
Tambahkan kode di bawah ini ke awal fungsi LinearVelocity Anda:
1
2
3
4
5
6
7
if (player.object.GetCenterPosition().y > canvasHeight){
    player.object.SetCenterPosition(new b2Vec2(20,0),0)
}  
else if (player.object.GetCenterPosition().x > canvasWidth-50){
    showWin();
    return;
}
  • Kondisi pertama menentukan apakah pemain jatuh, dan harus dibawa kembali ke titik awal (di atas platform barat).
  • Kondisi kedua memeriksa apakah pemain berada di atas platform kedua, dan memenangkan permainannya. Inilah fungsi showWin().
1
2
3
4
5
6
7
8
function showWin(){
    ctx.fillStyle    = '#000';
    ctx.font         = '30px verdana';
    ctx.textBaseline = 'top';
    ctx.fillText('Ye! you made it!', 30, 0);
    ctx.fillText('thank you, andersonferminiano.com', 30, 30);
    ctx.fillText('@andferminiano', 30, 60);
}
Dan itu saja! Anda baru saja menyelesaikan game sederhana pertama Anda dengan HTML5 dan Box2D. Selamat!

No comments for "Membangun Game Pertama Anda dengan HTML5"