导言
在一个风和日丽的一天,看完了疯狂HTML 5+CSS 3+JavaScript讲义,跟着做了书里最后一章的俄罗斯方块小游戏,并做了一些改进,作为自己前端学习的第一站。
游戏效果:
制作思路
因为书里的俄罗斯方块比较普通,太常规了,不是很好看,所以我在网上找了上面那张图片,打算照着它来做。(请无视成品和原图的差距)
然后便是游戏界面和常规的俄罗斯方块游戏逻辑。
接着便是游戏结束界面了。
原本想做个弹出层,但觉得找图片有点麻烦,所以就在网上找了文字特效,套用了一下。
代码实现:
首先是html文件和css文件,主要涉及了布局方面。作为新手,在上面真的是翻来覆去的踩坑。o(╥﹏╥)o
index.html
<!DOCTYPE html> <html> <head> <title>俄罗斯方块</title> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> <link rel=stylesheet type="text/css" href="teris.css"> <style type="text/css"> /*导入外部的字体文件*/ @font-face{ font-family:tmb;/*为字体命名为tmb*/ src:url("DS-DIGIB.TTF") format("TrueType");/*format为字体文件格式,TrueType为ttf*/ } div>span{ font-family:tmb; font-size:18pt; color:green; } </style> </head> <body> <div id="container" class="bg"> <!--ui--> <div class="ui_bg"> <div style="float:left;margin-right:4px;"> 速度:<span id="cur_speed">1</span> </div> <div style="float:left;"> 当前分数:<span id="cur_points">0</span> </div> <div style="float:right;"> 最高分数:<span id="max_points">0</span> </div> </div> <canvas id="text" width="500" height="100" style="position:absolute;"></canvas> <canvas id="stage" width="500" height="100" style="position:absolute;"></canvas> </div> <script src='EasePack.min.js'></script> <script src='TweenLite.min.js'></script> <script src='easeljs-0.7.1.min.js'></script> <script src='requestAnimationFrame.js'></script> <script type="text/javascript" src="jquery-3.4.1.min.js"></script> <script type="text/javascript" src="teris.js"></script> </body> </html>
teris.css
*{ margin:0; padding:0; } html, body{ width:100%; height:100%; } .bg{ font-size:13pt; background-color:rgb(239, 239, 227); /*好看的渐变色*/ background-image:radial-gradient(rgb(239, 239, 227), rgb(230, 220, 212)); /*阴影*/ box-shadow:#cdc8c1 -1px -1px 7px 0px; padding-bottom:4px; } .ui_bg{ border-bottom:1px #a69e9ea3 solid; padding-bottom:2px; overflow:hidden;/*没有这句的话因为子div都设置了float,所以是浮在网页上的,所以父div就没有高度,这句清除了浮动,让父div有了子div的高度*/ }
然后是重头戏,teris.js
游戏变量
//游戏设定 var TETRIS_ROWS = 20; var TETRIS_COLS = 14; var CELL_SIZE = 24; var NO_BLOCK=0; var HAVE_BLOCK=1; // 定义几种可能出现的方块组合 var blockArr = [ // Z [ {x: TETRIS_COLS / 2 - 1 , y:0}, {x: TETRIS_COLS / 2 , y:0}, {x: TETRIS_COLS / 2 , y:1}, {x: TETRIS_COLS / 2 + 1 , y:1} ], // 反Z [ {x: TETRIS_COLS / 2 + 1 , y:0}, {x: TETRIS_COLS / 2 , y:0}, {x: TETRIS_COLS / 2 , y:1}, {x: TETRIS_COLS / 2 - 1 , y:1} ], // 田 [ {x: TETRIS_COLS / 2 - 1 , y:0}, {x: TETRIS_COLS / 2 , y:0}, {x: TETRIS_COLS / 2 - 1 , y:1}, {x: TETRIS_COLS / 2 , y:1} ], // L [ {x: TETRIS_COLS / 2 - 1 , y:0}, {x: TETRIS_COLS / 2 - 1, y:1}, {x: TETRIS_COLS / 2 - 1 , y:2}, {x: TETRIS_COLS / 2 , y:2} ], // J [ {x: TETRIS_COLS / 2 , y:0}, {x: TETRIS_COLS / 2 , y:1}, {x: TETRIS_COLS / 2 , y:2}, {x: TETRIS_COLS / 2 - 1, y:2} ], // □□□□ [ {x: TETRIS_COLS / 2 , y:0}, {x: TETRIS_COLS / 2 , y:1}, {x: TETRIS_COLS / 2 , y:2}, {x: TETRIS_COLS / 2 , y:3} ], // ┴ [ {x: TETRIS_COLS / 2 , y:0}, {x: TETRIS_COLS / 2 - 1 , y:1}, {x: TETRIS_COLS / 2 , y:1}, {x: TETRIS_COLS / 2 + 1, y:1} ] ]; // 记录当前积分 var curScore=0; // 记录曾经的最高积分 var maxScore=1; var curSpeed=1; //ui元素 var curSpeedEle=document.getElementById("cur_speed"); var curScoreEle=document.getElementById("cur_points"); var maxScoreEle=document.getElementById("max_points"); var timer;//方块下落控制 var myCanvas; var canvasCtx; var tetris_status;//地图数据 var currentFall;//当前下落的block
游戏界面的完善
//create canvas function createCanvas(){ myCanvas=document.createElement("canvas"); myCanvas.width=TETRIS_COLS*CELL_SIZE; myCanvas.height=TETRIS_ROWS*CELL_SIZE; //绘制背景 canvasCtx=myCanvas.getContext("2d"); canvasCtx.beginPath(); //TETRIS_COS for(let i=1; i<TETRIS_COLS; i++){ canvasCtx.moveTo(i*CELL_SIZE, 0); canvasCtx.lineTo(i*CELL_SIZE, myCanvas.height); } for(let i=1; i<TETRIS_ROWS; i++){ canvasCtx.moveTo(0, i*CELL_SIZE); canvasCtx.lineTo(myCanvas.width, i*CELL_SIZE); } canvasCtx.closePath(); canvasCtx.strokeStyle="#b4a79d"; canvasCtx.lineWidth=0.6; canvasCtx.stroke(); //第一行,最后一行,第一列,最后一列粗一点。 canvasCtx.beginPath(); canvasCtx.moveTo(0, 0); canvasCtx.lineTo(myCanvas.width, 0); canvasCtx.moveTo(0, myCanvas.height); canvasCtx.lineTo(myCanvas.width, myCanvas.height); canvasCtx.moveTo(0, 0); canvasCtx.lineTo(0, myCanvas.height); canvasCtx.moveTo(myCanvas.width, 0); canvasCtx.lineTo(myCanvas.width, myCanvas.height); canvasCtx.closePath(); canvasCtx.strokeStyle="#b4a79d"; canvasCtx.lineWidth=4; canvasCtx.stroke(); //设置绘制block时的style canvasCtx.fillStyle="#201a14"; }