Trong bài này chúng ta sẽ thêm 1 số thành phần để game hoàn thiện hơn.
Count The Score
Đầu tiên là thêm phần tính điểm vào game, chúng ta cũng sẽ dùng canvas để vẽ. Ta thêm các thành phần sau:
var myScore;
function startGame() {
myGamePiece = new component(30, 30, "red", 10, 120);
myScore = new component("30px", "Consolas", "black", 280, 40, "text");
myGameArea.start();
}
Thành phần "text" định nghĩa canvas này khác canvas rectangle của chim và vật cản, do đó ta cũng thay đổi trong function component 1 tí
function component(width, height, color, x, y,type) {
this.type = type;
this.gamearea = myGameArea;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
if (this.type == "text") {
ctx.font = this.width + " " + this.height;
ctx.fillStyle = color;
ctx.fillText(this.text, this.x, this.y);
} else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
Cuối cùng ta add thêm vài dòng trong updateGameArea, ta sử dụng frameNo để tính điểm.
Thêm 2 dòng này vào cuối updateGameArea:
myScore.text="SCORE: " + myGameArea.frameNo;
myScore.update();
myScore.update();
Refresh lại trang và xem kết quả:
Phần game đến đây cơ bản là hoàn thành rồi đấy chúc mừng các bạn :))))
Trong các phần tiếp theo chúng ta sẽ tìm hiểu thêm các thành phần bổ sung để các bạn có thể cải tiện game hoàn hảo hơn cũng như dùng để viết các game khác hay hơn.
Chèn hình vào component
Bài này dùng source khác bài trên bạn có thể copy ra file mới để tiện làm thử, hoặc bạn có thể áp dụng lên bài hiện tại nếu hiểu hết code rồi, mục đích hoàn thiện game hơn:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
canvas {
border:1px solid #d3d3d3;
background-color: #f1f1f1;
}
</style>
</head>
<body onload="startGame()">
<script>
var myGamePiece;
function startGame() {
myGamePiece = new component(30, 30, "smiley.gif", 10, 120, "image");
myGameArea.start();
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 480;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.frameNo = 0;
this.interval = setInterval(updateGameArea, 20);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
stop : function() {
clearInterval(this.interval);
}
}
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "image") {
this.image = new Image();
this.image.src = color;
}
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
if (type == "image") {
ctx.drawImage(this.image,
this.x,
this.y,
this.width, this.height);
} else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
}
}
function updateGameArea() {
myGameArea.clear();
myGamePiece.newPos();
myGamePiece.update();
}
function moveup() {
myGamePiece.speedY = -1;
}
function movedown() {
myGamePiece.speedY = 1;
}
function moveleft() {
myGamePiece.speedX = -1;
}
function moveright() {
myGamePiece.speedX = 1;
}
function clearmove() {
myGamePiece.speedX = 0;
myGamePiece.speedY = 0;
}
</script>
<div style="text-align:center;width:480px;">
<button onmousedown="moveup()" onmouseup="clearmove()" ontouchstart="moveup()">UP</button><br><br>
<button onmousedown="moveleft()" onmouseup="clearmove()" ontouchstart="moveleft()">LEFT</button>
<button onmousedown="moveright()" onmouseup="clearmove()" ontouchstart="moveright()">RIGHT</button><br><br>
<button onmousedown="movedown()" onmouseup="clearmove()" ontouchstart="movedown()">DOWN</button>
</div>
<p>The component constructor uses the built-in image object to draw images onto the canvas.</p>
</body>
</html>
Để chèn hình vào component, ta thay đổi type của component như ta làm với "text" và chuẩn bị 1 tấm hình để chèn vào.
function startGame() {
myGamePiece = new component(30, 30, "smiley.gif", 10, 120, "image");
myGameArea.start();
}
Trong component ta thêm type image vào:function startGame() {
myGamePiece = new component(30, 30, "smiley.gif", 10, 120, "image");
myGameArea.start();
}
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "image") {
this.image = new Image();
this.image.src = color;
} this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
if (type == "image") {
ctx.drawImage(this.image,
this.x,
this.y,
this.width, this.height);
} else { ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
}
Các bạn nhớ đổi lại source hình thành hình của bạn.
Kết quả:
Change Images
Để góp thêm phần sinh động cho game, giờ mỗi lần mặt cười di chuyển nó sẽ biến thành 1 hình khác, ta sẽ thay đổi source image mỗi lần mặt cười di chuyển. Chúng ta sẽ thay đổi code lại 1 chút:
function move(dir) {
myGamePiece.image.src = "angry.gif";
if (dir == "up") {myGamePiece.speedY = -1; }
if (dir == "down") {myGamePiece.speedY = 1; }
if (dir == "left") {myGamePiece.speedX = -1; }
if (dir == "right") {myGamePiece.speedX = 1; }
}
function clearmove() {
myGamePiece.image.src = "smiley.gif";
myGamePiece.speedX = 0;
myGamePiece.speedY = 0;
}
</script>
<div style="text-align:center;width:480px;">
<button onmousedown="move('up')" onmouseup="clearmove()" ontouchstart="move('up')">UP</button><br><br>
<button onmousedown="move('left')" onmouseup="clearmove()" ontouchstart="move('left')">LEFT</button>
<button onmousedown="move('right')" onmouseup="clearmove()" ontouchstart="move('right')">RIGHT</button><br><br>
<button onmousedown="move('down')" onmouseup="clearmove()" ontouchstart="move('down')">DOWN</button>
</div>
Giờ các bạn refresh lại và test kết quả, khi di chuyển mặt cười sẽ biến thành mặt angry
function move(dir) {
myGamePiece.image.src = "angry.gif";
if (dir == "up") {myGamePiece.speedY = -1; }
if (dir == "down") {myGamePiece.speedY = 1; }
if (dir == "left") {myGamePiece.speedX = -1; }
if (dir == "right") {myGamePiece.speedX = 1; }
}
function clearmove() {
myGamePiece.image.src = "smiley.gif";
myGamePiece.speedX = 0;
myGamePiece.speedY = 0;
}
</script>
<div style="text-align:center;width:480px;">
<button onmousedown="move('up')" onmouseup="clearmove()" ontouchstart="move('up')">UP</button><br><br>
<button onmousedown="move('left')" onmouseup="clearmove()" ontouchstart="move('left')">LEFT</button>
<button onmousedown="move('right')" onmouseup="clearmove()" ontouchstart="move('right')">RIGHT</button><br><br>
<button onmousedown="move('down')" onmouseup="clearmove()" ontouchstart="move('down')">DOWN</button>
</div>
Background Images.
Bây giờ chúng ta sẽ thêm background vào game, background này cũng sẽ là 1 component như chim và vật cản. Ta thêm component như sau:
var myGamePiece;
var myBackground;
function startGame() {
myGamePiece = new component(30, 30, "smiley.gif", 10, 120, "image");
myBackground = new component(656, 270, "citymarket.jpg", 0, 0, "image"); myGameArea.start();
}
function updateGameArea() {var myBackground;
function startGame() {
myGamePiece = new component(30, 30, "smiley.gif", 10, 120, "image");
myBackground = new component(656, 270, "citymarket.jpg", 0, 0, "image"); myGameArea.start();
}
myGameArea.clear();
myBackground.newPos();
myBackground.update(); myGamePiece.newPos();
myGamePiece.update();
}
Các bạn đổi src hình thành của bạn rồi refresh lại test kết quả.
Background Loop
Giờ chúng ta sẽ làm cho background di chuyển theo 1 vòng lặp, đoạn code khá phức tạp các bạn chịu khó xem kĩ:
unction component(width, height, color, x, y, type) {
this.type = type;
if (type == "image" || type == "background") {
this.image = new Image();
this.image.src = color;
}
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
if (type == "image" || type == "background") {
ctx.drawImage(this.image,
this.x, this.y, this.width, this.height);
if (type == "background") {
ctx.drawImage(this.image,
this.x + this.width, this.y, this.width, this.height);
} } else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
if (this.type == "background") {
if (this.x == -(this.width)) {
this.x = 0;
}
} }
}
this.type = type;
if (type == "image" || type == "background") {
this.image = new Image();
this.image.src = color;
}
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
if (type == "image" || type == "background") {
ctx.drawImage(this.image,
this.x, this.y, this.width, this.height);
if (type == "background") {
ctx.drawImage(this.image,
this.x + this.width, this.y, this.width, this.height);
} } else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
if (this.type == "background") {
if (this.x == -(this.width)) {
this.x = 0;
}
} }
}
Sau khi refresh lại ta sẽ thấy background chuyển động.
Viết game flappy bird bằng HTML và JavaScript (P.7) - thêm sound vào game
Tạm ngưng tại đây nha, mai mình viết tiếp.Các bạn không hiểu gì comment ở dưới mình sẽ trả lời sớm nhất có thể :), không hỏi gì cũng để lại comment để mình có động lực viết tiếp nhá. Chúc các bạn học tốt.
CÓ PHẦN 7 KHÔNG ANH
Trả lờiXóaÀ có nha bạn, dạo này mình đang viết mấy bài mới nên chưa update chuỗi bài này, 2 3 bữa nữa mình sẽ viết part7 bạn đón đọc nha, cảm ơn bạn!
XóaChào bác. Tôi là người mới học. Chưa hiểu gì về JS.
Trả lờiXóaMà làm theo bài bác, tôi thấy hiểu ra nhiều thứ.
Bác viết hay!
- Trình bày khoa học.
- Mỗi phần là một bước nhỏ, thay đổi code để người ta nhìn thấy người ta đang làm gì.
- Ngôn ngữ giải thích đơn giản, chính xác (tôi toàn học bằng English, không hiểu, nên đọc được bài bác tôi sướng lắm).
Thank bác