HTML5 游戏开发实战 | 俄罗斯方块_俄罗斯方块h5(1),2024年最新你有过迷茫吗

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注大数据)
img

正文

分数

设计脚本


### 1. 设计方块类Block


方块类Block中定义方块的类型ID,存储方块的形状二维数组data以及颜色。设计了将形状自身的坐标系转换为屏幕的坐标系的translate(row,col)函数,参数(row,col)为当前形状方块的原点在屏幕Map中的位置。rotate()函数可以获取当前形状方块旋转后的坐标数组。



x
*方块类
*说明:各种形状的方块
function Block(
//this.data=[[],[],[],[]];
Block.prototype.Block = function ()this.born();
//产生一个新的形状方块Block.prototype.born = function () //随机选择一个形状this.shape id = Math.floor(Math.random() * 7)+1;this.data = Shapes[ this.shape id];this.color = Colors[ this.shape id];console.log(this.data);
//产生1~7的数
//存储方块部件的形状
//存储方块部件的颜色
//将形状自身的坐标系转换为屏幕 Map 的坐标系//(row,col)为当前形状的方块的原点在 Map 中的位置Block.prototype.translate = function (row,col)var copy=[l;
for(var i=0;i<4;i++) (
var temp =;
temp.row = this.datali][1] + row;
temp.col = this.datalill0]+ col;
copy.push(temp)
return copy;
//向右旋转一个形状:x’= y,y’= -x,得到旋转后的 dataBlock.prototype.rotate = function (){var copy=[[],[],[],[]];for(var i=0;i<4; i++) !copy[i][0]= this.datal i][1];copy[ i][1]=- this.datailol;
return copy;


另外,程序中将各方块形状编号:Z形编号1,S形编号2,竖条形编号3,T形编号4,正方形编号5,L形编号6,反L形编号7。所有方块的形状采用数组Shapes存储。通过编号从数组Shapes中获取方块的形状信息。



//每一格的间距,即一个小方块的尺寸Spacing=20;
//各种形状的编号,0 代表没有形状
NoShape = 0;
ZShape = 1;
SShape = 2;
LineShape = 3;
IShape = 4;
SquareShape = 5;
LShape = 6;
MirroredLShape = 7
//各种形状的数据描述
Shapes =
[[O,0],[0,0],[0,0],[0,0]],[[O,-1],[0,0],[-1,0],[-1,1]],
[[o,-1],[0,0],[1,0],[1,1]],[[O,-1],[0,0],[0,1],[0,2]][[-1,0],[0,0],[1,0],[0,1]],[[O,0],[1,0],[0,1],[1,1]],[[-1,-1],[0,-1],[0,0],[0,1]],[[1,-1],[0,-1],[0,0],[0,1]]
//各种形状的颜色
Colors =[“black”“fuchsia”,“#cff”,“red”,“orange”,“aqua”,“green”,"yellow"l;


### 2. 设计游戏容器Map类


游戏容器Map类是游戏实例,应先定义游戏面板大小,在游戏面板中存储所有方块的“容器”——二维数组lines,初始时每个元素存储为NoShape(0),表示此格子处无方块。



  • Map类说明:由m行 Line 组成的格子阵*
    function Map(w,h) [
    //游戏区域的长度和宽度
    this.width = w;
    this.height = h;
    //生成 height 个 line 对象,每个 line 宽度为 widththis.lines =];for(var row= 0; row < h; row++this.lines[row]= this.newLine():
    //说明:由 n个格子组成的一行Map.prototype.newLine = function ()var shapes =;for(var col= 0; col < this.width; col++)shapes[ col]= NoShape;return shapes;

isFullLine (row)函数判断一行是否全部被占用(满行),如果有一个格子为 NoShape 则返回 False。



Map.prototype.isFullLine = function (row) !var line = this.lines row];for(var col= 0; col < this.width; col++ )if(line[col]== NoShape)return false
return true;


预先移动或者旋转形状,调用isCollide(data)函数分析形状中的4个点是否有以下碰撞情况。


(1) col<0 || col>this.width,说明超出左右边界。


(2) row==this.height,说明形状已经到最底部。


(3) 任意一点的shape\_id不为NoShape,则发生碰撞。


如果发生碰撞,则放弃移动或者旋转。



Map.prototype.isCollide = function (data)for(var i=0;i<4;i++)fvar row = data il.row;var col = data[i].col;//console.log(row,col);if(col < 0col== this.width) return true;if(row == this.height) return true;
if(row <0) continue;
else
if(this.lines[row][col != 0)//NoShapereturn true;
return false;


形状在向下移动的过程中发生碰撞,appendShape=function (shape\_id,data)则将形状加入lines容器中固定下来。



Map.prototype.appendShape = function( shape id,data)
//对于形状的 4个点
for(var i=0;i<4;i++)/
var row = datai].row;
var col = datalil.col;
//找到所在的格子,将格子的颜色改为形状的颜色
this.lines[row][col]= shape id;
//形状被加入 lines 容器中后,要进行逐行检测,发现满行则消除for(var row = 0; row < this.height; row++)
if(this.isFullLine(row))
//绘制消除效果
onClearRow(row);
/将满行删除
this.lines.splice(row,1);
//第一行添加新的一行
this.lines.unshift(this.newLine());


### 3. 设计游戏逻辑类GameModel


游戏逻辑类GameModel实现游戏控制,首先定义游戏面板map、当前的俄罗斯方块currentBlock、下一个的俄罗斯方块nextBlock以及当前的俄罗斯方块所在位置等。



function GameModel(w,h)
this.map = new Map(w,h);
this.currentBlock = new Block();
this.currentBlock.Block();
this.row = 1;
this.col= Math.floor(this.map.width / 2);this.nextBlock = new Block();
//当前的俄罗斯方块
//当前的俄罗斯方块所在位置(顶端中央)
//下一个俄罗斯方块
this.nextBlock.Block();


其次调用CreateNewBlock()函数产生新的俄罗斯方块。它先复制下一个形状this.nextBlock,再产生下一个俄罗斯方块。



GameModel.prototype.CreateNewBlock = function()
this.currentBlock = this.nextBlock;
this.row = 1;
this.col = Math.floor(this.map.width / 2);
//复制预览区形状
//重置形状的位置为出生地点(顶端中央)
this.nextBlock = new Block();
this.nextBlock.Block();


以下是控制形状方块左右移动、旋转和下移,并且保证左右移动时和lines中存储的固定方块、边界不碰撞。如果碰撞则恢复数据放弃移动。



//向左移动
GameModel.prototype.left = function()
this.col-- ;var temp = this.currentBlock.translate(this.row,this.col);if(this.map.isCollide(temp))
//发生碰撞则放弃移动
this.col++;
//通知数据发生了更新
else
onUpdate();
//向右移动
GameModel.prototype.right = function()this.col++;
var temp= this.currentBlock.translate(this.row,this.col);if(this.map.isCollide(temp))this.col-- ;
else
onUpdate();


同样保证旋转时和lines中存储的固定方块、边界不碰撞。如果碰撞则恢复数据放弃旋转。



//旋转
GameModel.prototype.rotate = function()
//正方形不旋转
if(this.currentBlock.shape id== SquareShape) return;//获得旋转后的数据
var copy = this.currentBlock.rotate();
//转换坐标系
var temp = this.currentBlock.translate(this.row, this.col);//发生碰撞则放弃旋转
if(this.map.isCollide(temp))
return;
//将旋转后的数据设为当前数据this.currentBlock.data = copy;//通知数据发生了更新


方块下落需判断是否“触底”或接触到其他已落方块。如果“触底”则固定到游戏面板上,此时要处理满行和游戏结束的判断,同时产生新的俄罗斯方块。



//下落
GameModel.prototype.down = function()
var old= this.currentBlock.translate(this.row,this.col);this.row++ ;
var temp= this.currentBlock.translate(this.row,this.col);if(this.map.isCollide(temp)) //发生碰撞则放弃下落this.row-- ;//如果在 1 也无法下落,则说明游戏结束if(this.row== 1)(
//通知游戏结束
onGameOver();
return;
//无法下落则将当前形状加入 Map 中this.map.appendShape(this.currentBlock.shape id,old);this.CreateNewBlock();
//产生新的俄罗斯方块
//通知数据发生了更新
onUpdate();


### 4. 游戏主程序


在定时事件中,完成下落功能。



var display = document.getElementById(“htm15 09 1”);var display2 = document.getElementById(“htm15_09 2”);
var model = null;
//游戏面板//预览区域
var loop interval= null;
var tick interval = null:
var waiting = false;
var speed = 500;
v珠跋糊傲安把奥樊喽唉哎啊爱碍暗跋拔敖稗傲八core = 0;
var textmsg = document.getElementById("textmsg”);function start)!
model = new GameModel(display.width / Spacing,display.height / Spacing);loop(;
function pause()waiting =!waiting;if(waiting)document.getElementById(“btnPause”).value ="继续”;else
document.getElementById(“btnPause”).value ="暂停”;
//消息循环function loop(){tick interval= setInterval(function()if(waiting) return;onTick() ;
//时钟事件即下落


以下是消息事件处理。



//消息处理//更新事件
function onUpdate() {
paint();
//清除行事件
function onClearRow(row) !clearline(row);
score = score +10:
textmsq.innerHTML = score +“分”
/游戏结束事件function onGameOver()alert(“Game Over”);clearInterval(tick interval);
//时钟事件function onTick()model.down();
//按键事件
function onKevPress(evt) evt.preventDefault():move(evt.which);
function move(which) !

switch(which)
case 37: model.left(); break;
case 39: model.right(); break;
case 38: model.rotate(); break;
case 40: model.down(); break;


以下才是真正的绘制代码,调用clearline(row)函数绘制清除行的暂停效果。



function clearline(row)
//增加速度
clearInterval(tick interval);
speed = speed -10;
loop();
//音效
document.getElementById(“snd”).play()//停顿效果
waiting = true;
var ctx = display.getContext(“2d”);
ctx.fillRect(0,row * Spacing,display.width,Spacing,“black”);setTimeout(“waiting = false;”,50);


调用paint()函数绘制游戏屏幕。它将lines存储的所有固定方块画到游戏面板中,同时当前方块画到游戏面板中和下一个方块画到游戏面板右侧提示预览区中。



function paint()
var map = model.map;
var data = model.currentBlock.translate(model.row,model.col);var nextdata = model.nextBlock.translate(1,2);//在预览区(1,2)处位置//清屏
var ctx = display.getContext(“2d”);
ctx.clearRect(0,0,display.width,display.height);
var ctx2 = display2.getContext(“2d”);ctx2.clearRect(0,0,display2.width,display2.height);
var lines = map.lines;
//游戏面板中依次绘制每一个非空的格子(固定的方块)for(var row= 0; row < map.height; row++)
for(var col=0; col < map.width; col++)[
var shape id= lines[ row] coll;if(shape id != NoShape) {
var y=row * Spacing;var x=col * Spacing;
var color = Colors[ shape id];
var ctx = display.getContext(“2d”);
ctx.fillStyle =“rgba(255,255,255,0.2)”;
ctx.fillRect(x,y,Spacing,Spacing);
//形状前景色
ctx.fillStyle= color;
ctx.fillRect(x+1,y+1,Spacing - 2,Spacing - 2);
//绘制当前的方块

for(var i=0;i<4;i++)
var y=datalil.row * Spacing;
var x= data[i].col * Spacing;
var color = model.currentBlock.color:
var ctx = display.getContext(“2d”);
ctx.fillStyle=“rgba(255,255,255,0.2)”;
/Colors[model. currentBlock. shape id];
ctx.fillRect(x,y,Spacing,Spacing);
//形状前景色ctx.fillRect(x+1,y+1,Spacing -2,Spacing - 2);
ctx.fillStyle = color;
//绘制预览区中下个方块
for(var i=0;i<4;i++) !
var y= nextdatali].row * Spacing;
var x= nextdatali].col * Spacing;
/display2.draw( Rects[model.nextshape id],x,y);//Colors[model.nextBlock.shape id];
var color = model.nextBlock.color;
var ctx2 = display2.getContext(“2d”);
ctx2.fillStyle=“rqba(255,255,255,0.2)”
ctx2.fillRect(x,y,Spacing,Spacing);
ctx2.fillStyle= color;
//形状前景色
ctx2.fillRect(x+1,y+1,Spacing - 2,Spacing - 2);


至此,俄罗斯方块游戏编写完成。


**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)**
![img](https://img-blog.csdnimg.cn/img_convert/f90720c3a2d12bb428cbbae4c4edb87b.png)

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

ng,Spacing);
ctx2.fillStyle= color;
//形状前景色
ctx2.fillRect(x+1,y+1,Spacing - 2,Spacing - 2);

至此,俄罗斯方块游戏编写完成。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
[外链图片转存中…(img-49w83wro-1713298292716)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 0
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值