Thứ tư, ngày 20 tháng 9 năm 2017

HTML5-Canvas: Viết game Mario – Part 2

Ngày đăng: 6/7/2012, 8:36:28PM | Lượt xem: 4,564
Hot!

 Tiếp theo phần 1, trong phần này ta sẽ tìm hiểu cách thêm vào hai đối tượng đặc trưng của game Mario là như nấm và vàng.

 

Demo

 

Tạo lớp Mushroom

 

Bạn có thể thấy là cách hoạt động của các cây nấm (thức ăn của Mario) không khác gì so với các đối tượng Monster. Vì vậy việc tạo lớp này cũng tương tự:

function Mushroom(map,left,top){
	// call the super-constructor
	Character.call(this,map,{
		left: left,
		top: top,
		speed: 1,
		isAutoMoving: true
	});
}
Mushroom.prototype = new Character();
Mushroom.prototype.draw = function(context){

	context.save();
	context.beginPath();
	var left = this.left-this.map.offsetX;
	var top = this.top-this.map.offsetY;
	var right = left+this.width;
	var bottom = top+this.height;
	var hw = this.width/2;
	var cx = left+hw;

	context.fillStyle = "red";
	context.arc(cx,top+hw,hw-2,0,Math.PI*2,true);
	context.fill();
	context.restore();
} 

 

Thay đổi lớp Map

 

Dữ liệu của lớp Map cần được thay đổi để bổ sung các loại đối tượng mới: vàng (gold), gạch chứa nấm và một loại gạch không thể phá hủy.

 

var BRICK = 2;

var HARD_BRICK= 3;

var MUSHROOM_BRICK = 4;

// …

var GOLD = 7;

 

Để vẽ được hình ellipse (gold), tôi bổ sung một phương thức drawEllipse vào lớp CanvasRenderIngContext2D:

CanvasRenderingContext2D.prototype.drawEllipse = function(centerX, centerY, width, height) {

  this.beginPath();

  this.moveTo(centerX, centerY - height/2);

  this.bezierCurveTo(
    centerX + width/2, centerY - height/2,
    centerX + width/2, centerY + height/2,
    centerX, centerY + height/2);

  this.bezierCurveTo(
    centerX - width/2, centerY + height/2,
    centerX - width/2, centerY - height/2,
    centerX, centerY - height/2);

	this.closePath();
  this.fill();
} 

 

Phương thức quan trọng của lớp này là kiểm tra va chạm, dựa vào thuộc tính canEat của lớp Character, ta sẽ xác định được một nhân vật có thể “ăn” được một đối tượng nào đó hay không (như nấm, vàng).

- Trong trường hợp ô bị va chạm là vàng, ta cộng thêm 100 điểm và trả về void, có nghĩa là coi như không va chạm.

- Nếu đó là gạch chứa nấm, thêm một đối tượng Mushroom vào tại vị trí phía trên viên gạch.

// map
this.colllide = function(x,y,canDestroy,canEat){
	var b = this.contain(x,y);

	if(b)
	{
		if(b.type==GOLD)
		{
			if(canEat)
			{
				this.scores += 100;
				clearCell(b.left,b.top,b.col,b.row);
			}
			return;
		}

		if(canDestroy && b.type!=HARD_BRICK)
		{
			if(b.type==BRICK)
			{
				clearCell(b.left,b.top,b.col,b.row);
			}
			else if(b.type==MUSHROOM_BRICK) // add new mushroom
			{
				data[b.col+b.row*COLS] = HARD_BRICK;
				context.fillStyle = "Brown";
				context.fillRect(b.left,b.top,CELL_SIZE,CELL_SIZE);

				this.mushrooms.push(new Mushroom(this,b.left,b.top-CELL_SIZE));
			}

		}
		return b;
	}
	return false;
}; 

Phương thức update() của lớp này tương như phần trước ngoại trừ thêm phần cập nhật các Mushroom vào.

var i=0;
var length = this.mushrooms.length;
while(i<length){
	if(this.mushrooms[i].isDead)
	{
		this.mushrooms.splice(i,1);
		length--;
	}else
	{
		this.mushrooms[i].update();
		i++;
	}
} 

 

Làm nhân vật lớn lên hoặc nhỏ lại

 

Đối với lớp Player, tôi tạo thêm một thuộc tính isChild để xác định kích thước của nhân vật này. Sau đó tạo một hàm để thay đổi các thuộc tính cần thiết khi Player chạm phải nấm hay kẻ địch. Trong trường hợp Player đang là người lớn và bị va chạm với kẻ địch, ta sẽ cho Player “bất tử” trong vòng 1 giây để họ có thời gian né sang vị trí khác:

Player.prototype.grow = function(){

	if(this.isChild) // grow up
	{
		this.height *= 1.5;
		this.width *= 1.5;
	}else	// grow down
	{
		this.height /= 1.5;
		this.width /= 1.5;
		this.immuneCount = FPS; // make character immune for 1 seconds
	}
	this.top = this.bottom - this.height;
	this.isChild = !this.isChild;
} 

Phương thức update() mới:

Player.prototype.collide = function(monsters,mushrooms){
	for(m in monsters)
	{
		var mon = monsters[m];

		if(!(this.left > mon.right ||
			this.right < mon.left ||
			this.top > mon.bottom ||
			this.bottom < mon.top))
			{
				if(this.bottom<mon.bottom&& this.speedY>0)
				{
					mon.die();
				}
				else
				{
					if(this.isChild)
					{
						if(this.immuneCount==0)
						{
							this.die();
							break;
						}
					}
					else
						this.grow(); // grow down
				}
			}

	}

	for(var i=0;i<mushrooms.length;i++)
	{
		var m = mushrooms[i];

		if(!(this.left > m.right ||
			this.right < m.left ||
			this.top > m.bottom ||
			this.bottom < m.top))
			{
				if(this.isChild)
					this.grow();
				else
					this.map.scores+=1000;
				m.die();
			}

	}
} 

 

Trong game này, tôi cũng thay đổi một chút để cho phép Monster có thể lớn lên khi ăn được nấm.

 

YinYangIt’s Blog

 

 

 

 

 

 Chia sẻ qua: 
Hot!
Ý kiến bạn đọc

These items will be permanently deleted and cannot be recovered. Are you sure?

Gallery

image

Maecenas viverra rutrum pulvinar

Maecenas viverra rutrum pulvinar! Aenean vehicula nulla sit amet metus aliquam et malesuada risus aliquet. Vestibulum rhoncus, dolor sit amet venenatis porta, metus purus sagittis nisl, sodales volutpat elit lorem…

Read more

Text Links

Thiết kế logo chuyên nghiệp Insky
DAFABET
W88 w88b.com/dang-ky-tai-khoan-w88
W88
ca do bong da online
Copyright © 2011 - 2012 vietshare.vn by phamkhuong102@gmail.com doanhkisi2315@gmail.com. All rights reserved.