canvas之貪吃蛇

這次我們用canvas來(lái)制作一個(gè)簡(jiǎn)單的貪吃蛇游戲蛋铆。我們需要學(xué)習(xí)了解canvas的基礎(chǔ)知識(shí)和如何來(lái)創(chuàng)建矩形馋评。

1、游戲需要的游戲

? ? (1)蛇

? ? (2)食物

? ? (3)食物被吃掉后隨機(jī)位置出現(xiàn)

? ? (4)食物不能隨機(jī)出現(xiàn)再蛇身上

? ? (5)蛇能動(dòng)刺啦,碰到食物就變長(zhǎng)

? ? (6)蛇頭碰到蛇身和碰到墻就結(jié)束

2、游戲思路

????(1)要有蛇(畫(huà)蛇)

? ? ? ? a.蛇頭

? ? ? ? b.蛇身

? ? (2)讓蛇動(dòng)起來(lái)

? ? ? ? ?a.默認(rèn)的開(kāi)啟游戲的時(shí)候有一個(gè)方向

????????b.鍵盤能控制方向

????????c.animate定時(shí)器

????(3)有食物 隨機(jī)投放

????????a.產(chǎn)生隨機(jī)的位置

? ? ? ? b.判斷位置是否在蛇頭或者蛇身上蜕青,如果在重新產(chǎn)生位置右核,如果不在畫(huà)食物

????(4)吃食物

? ? ? ? ?a.判斷遲到食物 碰撞檢測(cè)

????????b.吃到食物添加蛇身

? ? ?(5)判斷游戲結(jié)束

????????a.蛇頭碰到蛇身

????????b.蛇頭碰到墻壁

3.代碼

我們首先要?jiǎng)?chuàng)建一個(gè)canvas,游戲要在畫(huà)布上實(shí)現(xiàn)宗兼,HTML部分如下:

<!DOCTYPE html>

<html lang="en">

????<head>

????????<meta charset="UTF-8">

????????<title>Document</title>

????????<script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.js"></script>

????????<style>

????????????canvas{

????????????????box-shadow: 0 0? 10px #000;

????????????????display: block;

????????????????margin:20px auto;

? ? ? ? ? ?}

????????</style>

</head>

<body>

????<canvas width="1200" height="800" id="canvas"></canvas>

</body>

</html>

第一步創(chuàng)建蛇頭蛇身?挠他,添加蛇默認(rèn)的運(yùn)動(dòng)方向

// 蛇頭(準(zhǔn)備創(chuàng)建的方塊)的元素

function Rect(x,y,width,height,color){

????this.x = x;

????this.y = y;

????this.width = width;

????this.height = height;

????this.color = color;

}

// 完善矩形 繪制矩形

Rect.prototype.draw = function(){

????// 開(kāi)始繪畫(huà)矩形

????Draw.prototype.xt.beginPath();

????// 畫(huà)筆顏色

????Draw.prototype.xt.fillStyle = this.color;

????// 填充矩形

????Draw.prototype.xt.fillRect(this.x,this.y,this.width,this.height);

????// 描邊

????Draw.prototype.xt.strokeRect(this.x,this.y,this.width,this.height);

}

????// 構(gòu)造對(duì)象蛇

????function Snake(obj){

????// 畫(huà)蛇頭 蛇頭的顏色是紅色的

????this.head = new Rect(obj.canvas.width/2-20,obj.canvas.height/2-20,40,40,'red');

????//定義一個(gè)空數(shù)組存放組成整蛇的方塊對(duì)象

????this.body = [];

????//表示多個(gè)身體

????// 蛇身的x比蛇頭移動(dòng)

????40 var x = this.head.x-40;

????// 距離y不變

????var y = this.head.y;

????// 循環(huán)創(chuàng)建身體 默認(rèn)蛇的長(zhǎng)度是3

????for (var i = 0; i < 3; i++) {

????// 每吃一個(gè)東西蛇身會(huì)加一個(gè) 蛇身的顏色是灰色的

????var rect = new Rect(x,y,40,40,'gray');

????this.body.push(rect);

????x-=40;

}

}

????// 添加蛇默認(rèn)的運(yùn)動(dòng)方向 向右

????// 公有屬性,任何地方能夠修改方向

????Snake.prototype.direction = 1;

????// 定義一個(gè)是否吃到食物的標(biāo)記

????Snake.prototype.isEatFood = false;

????// 畫(huà)蛇方法

????Snake.prototype.draw = function(){

????// 畫(huà)蛇頭

????this.head.draw();

????// 循環(huán)創(chuàng)建蛇身

????for (var i = 0; i < this.body.length; i++) {

????this.body[i].draw();

}

}

第二步讓蛇動(dòng)起來(lái)篡帕,里面包含風(fēng)道墻壁和蛇頭蛇身然后就游戲結(jié)束

// 蛇移動(dòng)的方法

Snake.prototype.move = function(){

????// 檢測(cè)碰撞到墻壁

????if (this.head.x<40 || this.head.y<-40 || this.head.x>$('#canvas')[0].width-40-40 || ????this.head.y>$('#canvas')[0].height-40-40) {

????????return false;

????}

????// 檢測(cè)蛇頭與蛇身

????for (var i =0;i<this.body.length;i++) {

????????console.log(this.body[i])殖侵;

????????if (isRectHit(this.head,this.body[i])) {

????????????return false;

????????}

}

// 加一個(gè)頭

var rect = new Rect(this.head.x,this.head.y,40,40,'gray');

// 添加身體開(kāi)始的地方

this.body.splice(0,0,rect);

// 去掉一個(gè)尾巴,

if (Snake.prototype.isEatFood) {

????Snake.prototype.isEatFood = false;

????// 重新隨機(jī)產(chǎn)生食物

}else{

????this.body.pop();

}

switch(this.direction){

????case 0:

????????this.head.y -= 40

????????break;

????case 1:

????????this.head.x += 40

????????break;

????case 2:

????????this.head.y +=40

????????break;

case 3:

????????this.head.x -= 40

????????break;

}

return true;

第三步食物

// 添加鍵盤監(jiān)聽(tīng)

$(window).keydown(function(e){

????switch(e.keyCode){

????????case 37:

????????// 如果當(dāng)前的方向是向右的,不能改為向左

????????if (Snake.prototype.direction == 1) {

????????????return;

????????}

????????Snake.prototype.direction = 3;

????????break;

????????case 38:

????????// 如果當(dāng)前的方向是向下的镰烧,不能改為向上

????????????if (Snake.prototype.direction == 2) {

????????????????return;

???????????}

????????????Snake.prototype.direction = 0;

????????????break;

????????case 39:

????????????if (Snake.prototype.direction == 3) {

????????????????return;

????????????}

????????????Snake.prototype.direction = 1;

????????????break;

? ? ? ? case 40:

????????????if (Snake.prototype.direction == 0) {

????????????????return;

????????????}

????????????Snake.prototype.direction = 2;

????????????break;

????}

})

// 隨機(jī)產(chǎn)生食物

function randFood(snake){

????// 是否在蛇身上

????isInSnake = true;

????while(isInSnake){

????????// 產(chǎn)生兩個(gè)位置

????????x,y var x = getRandPosition(0,($('#canvas')[0].width-40)/40)*40;

????????var y = getRandPosition(0,($('#canvas')[0].height-40)/40)*40;

????????// 創(chuàng)建食物矩形

????????var food = new Rect(x-20,y-20,40,40,'green');

????????isInSnake = false;

????????// 判斷食物是否在蛇身

????????// 是否是蛇頭

????????if (isRectHit(food,snake.head)) {

????????????isInSnake = true;

????????????continue;

????????}

????????// 是否是蛇身

????????for (var i=0; i < snake.body.length; i++) {

????????????if (isRectHit(food,snake.body[i])) {

????????????????????isInSnake = true;

????????????????????break;

????????????}

????????}

????}

????return food;

}

// 產(chǎn)生隨機(jī)數(shù)的函數(shù)也就是隨機(jī)產(chǎn)生食物

function getRandPosition(min,max){

????return Math.round(Math.random()*(max-min)+min);

}

// 判斷矩形是否重合

function isRectHit(rect1,rect2){

????var R1_min_x = rect1.x;

????var R1_min_y = rect1.y;

????var R2_min_x = rect2.x;

????var R2_min_y = rect2.y;

????var R1_max_x = rect1.x + 20;

????var R2_max_x = rect2.x + 20;

????var R1_max_y = rect1.y + 20;

????var R2_max_y = rect2.y + 20;

// 兩個(gè)圖形的最大邊界和最小邊界? 就是食物和蛇頭的碰撞

????var min_x = Math.max(R1_min_x,R2_min_x);

????var max_x = Math.min(R1_max_x,R2_max_x);

????var min_y = Math.max(R1_min_y,R2_min_y);

????var max_y = Math.min(R1_max_y,R2_max_y);

????if (min_x<max_x&&min_y<max_y) {

????????return true;

????}else{

????????return false;

????}

}

var draw = new Draw($('#canvas')[0]);

//創(chuàng)建一個(gè)繪圖的實(shí)例對(duì)象

draw.main();

//調(diào)用main繪制圖像

});

4拢军、效果圖如下:


以上是貪吃蛇游戲的全部代碼,雖然代碼很詳細(xì)但大家還需要認(rèn)認(rèn)真真理解怔鳖,希望本文對(duì)大家有所啟發(fā)茉唉,不懂的地方可以問(wèn)我。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市度陆,隨后出現(xiàn)的幾起案子艾凯,更是在濱河造成了極大的恐慌,老刑警劉巖懂傀,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趾诗,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蹬蚁,警方通過(guò)查閱死者的電腦和手機(jī)恃泪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)犀斋,“玉大人贝乎,你說(shuō)我怎么就攤上這事∵创猓” “怎么了览效?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)球榆。 經(jīng)常有香客問(wèn)我朽肥,道長(zhǎng)禁筏,這世上最難降的妖魔是什么持钉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮篱昔,結(jié)果婚禮上每强,老公的妹妹穿的比我還像新娘。我一直安慰自己州刽,他們只是感情好空执,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著穗椅,像睡著了一般辨绊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上匹表,一...
    開(kāi)封第一講書(shū)人閱讀 51,727評(píng)論 1 305
  • 那天门坷,我揣著相機(jī)與錄音,去河邊找鬼袍镀。 笑死默蚌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的苇羡。 我是一名探鬼主播绸吸,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了锦茁?” 一聲冷哼從身側(cè)響起攘轩,我...
    開(kāi)封第一講書(shū)人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎码俩,沒(méi)想到半個(gè)月后撑刺,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡握玛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年够傍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挠铲。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡冕屯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拂苹,到底是詐尸還是另有隱情安聘,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布瓢棒,位于F島的核電站浴韭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏脯宿。R本人自食惡果不足惜念颈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望连霉。 院中可真熱鬧榴芳,春花似錦、人聲如沸跺撼。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)歉井。三九已至柿祈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哩至,已是汗流浹背躏嚎。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留憨募,地道東北人紧索。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像菜谣,于是被迫代替她去往敵國(guó)和親珠漂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子晚缩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • HTML canvas 實(shí)現(xiàn)貪吃蛇的效果 思路:1. 畫(huà)蛇 食物被吃掉之后隨機(jī)位置出現(xiàn) 食物不能隨機(jī)在蛇身上...
    Agonl_0929a閱讀 507評(píng)論 0 1
  • 思路: 蛇 食物 食物被吃掉之后隨機(jī)位置出現(xiàn) 食物不能隨機(jī)在蛇身上 蛇頭碰到蛇身就結(jié)束了,碰到墻也結(jié)束了媳危。 碰...
    孤久成癮_63e8閱讀 389評(píng)論 0 0
  • 思路: 1.創(chuàng)建畫(huà)布 2.創(chuàng)建的蛇頭荞彼、身體、食物 3.蛇頭待笑、身體鸣皂、食物隨機(jī)產(chǎn)生坐標(biāo) 4.設(shè)置蛇頭的初始方向 5.設(shè)...
    GY_3ade閱讀 1,033評(píng)論 0 0
  • <!DOCTYPE html> Document canvas{ box-s...
    慌擁_658c閱讀 956評(píng)論 0 0
  • 關(guān)于“筆友”這個(gè)詞,第一次是在小學(xué)的英語(yǔ)書(shū)上看見(jiàn)的暮蹂,pen pal寞缝。 我寄出去過(guò)三封信和一張明信片,卻從未收到過(guò)任...
    陳詞i閱讀 477評(píng)論 7 2