html畫布製作貪吃蛇小遊戲
最終效果:
做貪吃蛇遊戲需要Html5,部分Css美化,重要的是JavaScript的應用,因為我們主要是運用Html5的Canvas標籤來打造遊戲的,所以還是在JavaScript上的筆墨較多
首先搭建好框架:
<!DOCTYPE html> <html> <head> <title>snake</title> <style type="text/css"> #canvas_frame{ height:500px; width:500px; margin:auto; background:#444; border-radius:8px; box-shadow:0px 0px 15px #000; } canvas{ background:#21F; margin:25px 25px; } #start_button{ height:40px; width:150px; border:0px; background:#000; color:white; line-height:40px; font-size:15px; } </style> </head> <body> <div id="canvas_frame"> <canvas id="mycanvas" width="450" height="450"></canvas> </div> <section style="height:40px;width:100%;text-align:center;"> <button id="start_button" onclick="moveSnake();">start</button> </section> <script type="text/javascript"> /*javascript程式碼區*/ </script> </body> </html>
然後在javascript程式碼區建立畫布Dom物件:
var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
建立蛇物件:
var snake = {
head : { x : 15 * 3, y : 0 },
body : [{ x : 15 * 2, y : 0 },{ x : 15 * 1, y : 0 },{ x : 0, y : 0 }],
speed : 100,
direction: "right",
};
注意點:蛇物件中的body是一個陣列,陣列內的元素是代表蛇每個節在畫布上的X座標和Y座標,snake.body[0]為最靠近head的節,依此類推。。
描繪蛇:
function drawSnake(){
ctx.clearRect( 0, 0, 450, 450 );
var headImg = new Image();
var headSrc = "./snake_head_min_" + snake.direction +".png";/*存貯蛇圖片的位置,用於動態改變head的圖片位置*/
headImg.src= headSrc;
ctx.drawImage(headImg, snake.head.x, snake.head.y );
for( var i = 0; i <= snake.body.length - 1; i++){
var cell = new Image();
cell.src = "./snake_body_min.png";
ctx.drawImage(cell, snake.body[i].x, snake.body[i].y );
}
}
注意點:
1.每次描繪蛇之前都需要將原有的圖畫清空------ ctx.clearRect( 0, 0, 450, 450); clearRect()用法詳見:HTML5 canvas clearRect() 方法;
2.這裡我採用的不是填充矩形的方法來實現畫蛇,而是採用描繪影象的方法: 用法詳見:HTML 5 <canvas> 標籤
1)建立影象:var Img = new Image();
2)影象位置:Img.src="./img.png";
3)開始描繪:ctx.drawImage( Img, 0, 0);後兩個參數列示的是描繪圖片的x座標的y座標;
在這裡我採用了自己製作的圖片,注意要調整圖片的大小(為展示,此處顯示大圖):
body head
因為蛇頭有方向:所以對於head我們有四張圖片:
建立食物物件:
var food = {
x : 300,
y : 150,
};
描繪食物:
function drawFood(){
if(IsEat()){
food.x = parseInt(Math.random() * 28) * 15;
food.y = parseInt(Math.random() * 28) * 15;
}
var foodImg = new Image();
foodImg.src="./apple_min.png";
ctx.drawImage(foodImg, food.x, food.y );
}
注意點:
1.關於獲取隨機數:Math.random();該函式返回一個區間為(0, 1 )的隨機數;
2.此處我們將隨機數乘以28以放大隨機數的區間為(0, 28 ),總共的格子數為30 * 30 個 即450 / 15 = 30;
3.我們將其隨機數的區間轉化為整數:即1,2,3,4,。。。,27,
4.當food 被蛇吃的時候(snake.head的座標與食物的座標相同的時候),我們要隨機在生成新的食物座標,此處不考慮食物生成的座標與蛇的身體有相同(食物生成在了蛇的body上)
判斷食物是否被吃:
function IsEat(){
if( snake.head.x == food.x && snake.head.y == food.y){
snake.body[snake.body.length] = { x : 0, y : 0};
return 1;
}
return 0;
}
注意點:
1.此處用了if判斷語句,且判斷的表示式需滿足 蛇的頭的座標與食物的座標相同(x座標和y座標);
2.為了在描繪食物的方法(drawFood();)裡更好的判斷,我們設定返回值 1 代表被吃,0代表未被吃;
3.食物被吃之後應該生成一個新的節(此處預設生成的節懂得x座標和y座標都為0(這個不要緊)在蛇移動的時候會自動改變該值)
snake.body[snake.body.length] = { x : 0, y : 0};
開始重頭大戲----移動蛇:
首先移動蛇我們需要的是:不斷地描繪影象,並且不斷的更新蛇的頭的身體各節的座標:
程式碼上:
function moveSnake(){
for( var i = snake.body.length - 1; i > 0 ; i-- ){
snake.body[i].x = snake.body[i - 1].x;
snake.body[i].y = snake.body[i - 1].y;
}
snake.body[0].x = snake.head.x;
snake.body[0].y = snake.head.y;
switch( snake.direction ){
case "right":{
snake.head.x = snake.head.x + 15;
break;
}
case "left":{
snake.head.x = snake.head.x - 15;
break;
}
case "up":{
snake.head.y = snake.head.y - 15;
break;
}
case "down":{
snake.head.y = snake.head.y + 15;
break;
}
}
drawSnake();
drawFood();
IsGameover();
setTimeout( 'moveSnake()', snake.speed );
}
注意點:
1.為了達到更新蛇的頭和蛇的身體各節座標的目標,我們的想法應該是:較後的節繼承較前的節的座標;所以就有for迴圈:
for( var i = snake.body.length - 1; i > 0 ; i-- ){
snake.body[i].x = snake.body[i - 1].x;
snake.body[i].y = snake.body[i - 1].y;
}
snake.body[0].x = snake.head.x;
snake.body[0].y = snake.head.y;
最靠近頭的節將繼承頭的座標。
2.針對頭的座標更新我們根據蛇的方向(snake.direction)來進行判斷:
switch( snake.direction ){}
3.在移動蛇的時候,我們需要不斷的畫蛇,不斷的畫食物,不斷的判斷是否結束遊戲,並且我們需要不斷的呼叫自己這個函式;
更新時間我們用setTimeout();用法詳見:HTML DOM setTimeout() 方法
判斷GameOver:
判斷遊戲結束有兩個標準:
1.碰壁,遊戲結束
2.吃著自己,遊戲結束
程式碼上:
function IsGameover(){
if(snake.head.x == game.width && snake.direction == 'right'){
alert("GameOver!");
}
if(snake.head.x == -15 && snake.direction == 'left'){
alert("GameOver!");
}
if(snake.head.y == game.height && snake.direction == 'down'){
alert("GameOver!");
}
if(snake.head.y == -15 && snake.direction == 'up'){
alert("GameOver!");
}
for( var i = 0; i < snake.body.length; i++ ){
if( snake.head.x == snake.body[i].x && snake.head.y == snake.body[i].y){
alert("GameOver!");
}
}
}
注意點:
1.四個if判斷語句用於判斷碰壁:!!滿足條件為 座標 和 蛇的移動方向(例如 蛇的head的x座標為0,方向向上 =》 碰壁)
2.for迴圈語句:對每個body的節判斷其座標是否與head的座標重合(重合即代表 蛇頭吃到自己的身體了)
監聽鍵盤輸入:
document.onkeydown = function(e){
var code = e.keyCode;
switch(code){
case 38:{
if( snake.direction != 'down'){
snake.direction='up';
}
break;
}
case 39:{
if( snake.direction != 'left'){
snake.direction='right';
}
break;
}
case 40:{
if( snake.direction != 'up'){
snake.direction='down';
}
break;
}
case 37:{
if( snake.direction != 'right'){
snake.direction='left';
}
break;
}
default:break;
}
}
注意點:
1.html Dom document物件的onkeydown事件後的函式需要引入引數(e)
2.對該事件(event)的鍵盤值(keyCode)進行判斷然後改變蛇的方向--snake.direction;
該遊戲的製作就完成了,當然我們也可以把它可以做的更好。
最後上完整程式碼:
<!DOCTYPE html>
<html>
<head>
<title>snake</title>
<style type="text/css">
#canvas_frame{
height:500px;
width:500px;
margin:auto;
background:#444;
border-radius:8px;
box-shadow:0px 0px 15px #000;
}
canvas{
background:#21F;
margin:25px 25px;
}
#start_button{
height:40px;
width:150px;
border:0px;
background:#000;
color:white;
line-height:40px;
font-size:15px;
}
</style>
</head>
<body>
<div id="canvas_frame">
<canvas id="mycanvas" width="450" height="450"></canvas>
</div>
<section style="height:40px;width:100%;text-align:center;">
<button id="start_button" onclick = "moveSnake();">start</button>
</section>
<script type="text/javascript">
var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
/*
//畫格子
ctx.strokeStyle = 'white';
for( var i = 1; i <= 30; i++ ){
ctx.beginPath();
ctx.moveTo( 15 * i, 0 );
ctx.lineTo( 15 * i, 450 );
ctx.closePath();
ctx.stroke();
}
for( var i = 1; i <= 30; i++ ){
ctx.beginPath();
ctx.moveTo( 0, 15 * i );
ctx.lineTo( 450, 15 * i );
ctx.closePath();
ctx.stroke();
}
*/
//建立遊戲物件
var game = {
width : 450,
height : 450,
};
//建立一條蛇
var snake = {
head : { x : 15 * 3, y : 0 },
body : [{ x : 15 * 2, y : 0 },{ x : 15 * 1, y : 0 },{ x : 0, y : 0 }],
length : 4,
speed : 100,
direction: "right",
};
//建立食物
var food = {
x : 300,
y : 150,
color : "green",
};
//描繪蛇
function drawSnake(){
ctx.clearRect( 0, 0, 450, 450 );
var headImg = new Image();
var headSrc = "./snake_head_min_" + snake.direction +".png";
headImg.src= headSrc;
ctx.drawImage(headImg, snake.head.x, snake.head.y );
for( var i = 0; i <= snake.body.length - 1; i++){
var cell = new Image();
cell.src = "./snake_body_min.png";
ctx.drawImage(cell, snake.body[i].x, snake.body[i].y );
}
}
//描繪食物
function drawFood(){
if(IsEat()){
food.x = parseInt(Math.random() * 28) * 15;
food.y = parseInt(Math.random() * 28) * 15;
}
var foodImg = new Image();
foodImg.src="./apple_min.png";
ctx.drawImage(foodImg, food.x, food.y );
}
//移動蛇
function moveSnake(){
for( var i = snake.body.length - 1; i > 0 ; i-- ){
snake.body[i].x = snake.body[i - 1].x;
snake.body[i].y = snake.body[i - 1].y;
}
snake.body[0].x = snake.head.x;
snake.body[0].y = snake.head.y;
switch( snake.direction ){
case "right":{
snake.head.x = snake.head.x + 15;
break;
}
case "left":{
snake.head.x = snake.head.x - 15;
break;
}
case "up":{
snake.head.y = snake.head.y - 15;
break;
}
case "down":{
snake.head.y = snake.head.y + 15;
break;
}
}
drawSnake();
drawFood();
IsGameover();
setTimeout( 'moveSnake()', snake.speed );
}
//判斷遊戲結束
function IsGameover(){
if(snake.head.x == game.width && snake.direction == 'right'){
alert("GameOver!");
}
if(snake.head.x == -15 && snake.direction == 'left'){
alert("GameOver!");
}
if(snake.head.y == game.height && snake.direction == 'down'){
alert("GameOver!");
}
if(snake.head.y == -15 && snake.direction == 'up'){
alert("GameOver!");
}
for( var i = 0; i < snake.body.length; i++ ){
if( snake.head.x == snake.body[i].x && snake.head.y == snake.body[i].y){
alert("GameOver!");
}
}
}
//監聽鍵盤輸入
document.onkeydown = function(e){
var code = e.keyCode;
switch(code){
case 38:{
if( snake.direction != 'down'){
snake.direction='up';
}
break;
}
case 39:{
if( snake.direction != 'left'){
snake.direction='right';
}
break;
}
case 40:{
if( snake.direction != 'up'){
snake.direction='down';
}
break;
}
case 37:{
if( snake.direction != 'right'){
snake.direction='left';
}
break;
}
default:break;
}
}
//判斷是否吃了食物
function IsEat(){
if( snake.head.x == food.x && snake.head.y == food.y){
snake.body[snake.body.length] = { x : 0, y : 0};
return 1;
}
return 0;
}
</script>
</body>
</html>
本文中的超連結指向W3school
相關文章
- GUI 基於Swing製作貪吃蛇小遊戲GUI遊戲
- (完整原始碼)貪吃蛇小遊戲——HTML+CSS+JavaScript實現原始碼遊戲HTMLCSSJavaScript
- javascript貪吃蛇小遊戲程式碼例項JavaScript遊戲
- 貪吃蛇jsJS
- 04 貪吃蛇
- C語言小遊戲------貪吃蛇----小白專用C語言遊戲
- 【Python】 Python小遊戲-貪吃蛇大冒險Python遊戲
- 一個貪吃蛇小遊戲(17行程式碼)遊戲行程
- 閒得無聊寫的一個貪吃蛇小遊戲~遊戲
- Python:遊戲:貪吃蛇Python遊戲
- Java實現貪吃蛇Java
- 貪吃蛇c原始碼原始碼
- 貪吃蛇源程式 (轉)
- JavaScript-開發一個簡單的貪吃蛇小遊戲JavaScript遊戲
- Python3 貪吃蛇Python
- python實現貪吃蛇Python
- jQuery 實現貪吃蛇遊戲jQuery遊戲
- C#貪吃蛇(WPF版)C#
- [譯] RxJS 遊戲之貪吃蛇JS遊戲
- OpenGL實現貪吃蛇程式碼
- C語言貪吃蛇原始碼C語言原始碼
- [原生JS][程式導向]貪吃蛇JS
- Shell寫的貪吃蛇遊戲(轉)遊戲
- 初試javascript :貪吃蛇啊 (轉)JavaScript
- c++經典專案控制檯貪吃蛇小遊戲詳細教程C++遊戲
- WebGL實現HTML5的3D貪吃蛇遊戲WebHTML3D遊戲
- 100行Python程式碼實現貪吃蛇小遊戲(超詳細)Python遊戲
- Android-貪吃蛇小遊戲-分析與實現-Kotlin語言描述Android遊戲Kotlin
- C語言實現桌面貪吃蛇C語言
- Python實現貪吃蛇大作戰Python
- js貪吃蛇遊戲程式碼例項JS遊戲
- canvas貪吃蛇遊戲程式碼例項Canvas遊戲
- 溫習資料演算法—貪吃蛇演算法
- 貪吃蛇大作戰JavaFx版完整原始碼Java原始碼
- H5遊戲開發:貪吃蛇H5遊戲開發
- 貪吃蛇的演算法分析(1) (轉)演算法
- 貪吃蛇的演算法分析(3) (轉)演算法
- 貪吃蛇的演算法分析(4) (轉)演算法