开始自己手写一个好玩的俄罗斯方块吧,上变形,左右移动,下加速,空格瞬移等功能,无聊的时候学习下canvas,f12 修改分数,体验金手指的快乐吧
1、定义界面,和按钮
上
下
左
右
2、js部分
1、先定义每个图形的形状和变化的形状,这里是使用多维数组的方式去保存它图形每个方块的位置(当然这里也可以用循环的方式)
var data=[[[[1,0,0,0],[1,0,0,0],[1,1,0,0],[0,0,0,0]],[[1,1,1,0],[1,0,0,0],[0,0,0,0],[0,0,0,0]],[[1,1,0,0],[0,1,0,0],[0,1,0,0],[0,0,0,0]],[[0,0,1,0],[1,1,1,0],[0,0,0,0],[0,0,0,0]]],
[[[1,0,0,0],[1,1,0,0],[1,0,0,0],[0,0,0,0]],[[1,1,1,0],[0,1,0,0],[0,0,0,0],[0,0,0,0]],[[0,0,1,0],[0,1,1,0],[0,0,1,0],[0,0,0,0]],[[0,0,0,0],[0,1,0,0],[1,1,1,0],[0,0,0,0]]],
[[[0,1,0,0],[0,1,1,0],[0,0,1,0],[0,0,0,0]],[[0,1,1,0],[1,1,0,0],[0,0,0,0],[0,0,0,0]],[[0,1,0,0],[0,1,1,0],[0,0,1,0],[0,0,0,0]],[[0,0,0,0],[0,1,1,0],[1,1,0,0],[0,0,0,0]]],
[[[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]],[[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]],[[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]],[[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]]],
[[[0,0,1,0],[0,1,1,0],[0,1,0,0],[0,0,0,0]],[[1,1,0,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]],[[0,0,1,0],[0,1,1,0],[0,1,0,0],[0,0,0,0]],[[1,1,0,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]]],
[[[0,1,0,0],[0,1,0,0],[0,1,0,0],[0,1,0,0]],[[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]],[[0,1,0,0],[0,1,0,0],[0,1,0,0],[0,1,0,0]],[[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]]],
[[[1,1,0,0],[1,0,0,0],[1,0,0,0],[0,0,0,0]],[[1,1,1,0],[0,0,1,0],[0,0,0,0],[0,0,0,0]],[[0,0,0,0],[0,0,1,0],[0,0,1,0],[0,1,1,0]],[[0,0,0,0],[0,0,0,0],[1,0,0,0],[1,1,1,0]]]
];
2、定义图形的位置和每帧下落的速度
var newX=120;//记录这个图形的左右位置
var count=0; //记录下落的速度
var shape=0; //记录形状
var finallys=new Array(); //记录落下后停止的位置
var re=6; //获取随机数方块
var fat=1; //每帧的速度
var xyg=0; //下一个方块
var dfen=0;//分数
//定义游戏界面
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
//下个方格的画布
var c2=document.getElementById("Canvas");
var ctx2=c2.getContext("2d");
3、定义组成图形的方法
//组成图形的方法
function constitute(){
var Arr=new Array(); // 存储当前下来的方块位置
var y=0; //记录每个小方块组成图形的小方块y下标--相加
for (var i=0;i
3、判断掉落是否到底或者碰撞到上一个底部的方块
//掉落完成后重新调用
function anew (arr){
var da=bottom(arr); //调用判断是否到底
if(da==1){ //如果返回1 则已经是到底部,
finallys.push(arr); // 保存在底部的方块,方便碰撞判断
count=0; //恢复成原来的上下位置
newX=120; //恢复原来的左右位置
re=xyg; //当前的方块变成上一个的下一个
xyg=Math.floor(Math.random()*7); //重新随机获取当前的下一个
ctx2.clearRect(0, 0, c.width,c.height); //清除画布
xygs();//重新绘制预知框的
}
}
//判断是否碰到下面的障碍物
function bottom(arr){ //判断是否掉落底部//返回1表示可以保存起来
for (var i =0;i=c.height-20){//首先判断是否到界面的底部
/*console.log(arr);*/
return 1;
}
for (var t=0;t
4、下落到底部后的方块要保存起来,定义重新渲染的方法
//用来组成下标已经堆积的格子
function ground(finallys){
deletes();//判断是否到达顶部了, 顶部了就直接清除重新开始
for (var i=0;i
5、当横向一行满了后就可以清楚并得到对应的分数
//判断是否组满一行达到清除的位置
function deletes(){
var c=600;//当前横向的宽度
var add=new Array;//记录宽度的每个方块
for (var i=0;i=20){ //如果横向满了调用清除的方法
qc(add[a]);//
cou=0;
}
}
}
//一行满了后清除和上面的向下增加移动
function qc(add){
for (var t=0;t
6、碰撞检测
//判断不能掉出围起来的范围
function crash(count,e){ //count 下落的位置, e 表示当前是什么按钮操作
var newCount=0; //判断是否有下降的数据有就下降
if(count!=0){
newCount=count;
}
var y=0; //记录组成形状的位置--相加
var r=0;
var make=-1;
for (var i=0;ic.width-20){
if(x+newX<0){
newX=newX+20;
r=1;
}else{
newX=newX-20;
r=2;
}
}
if(e==38){
if(y+count>c.height-20){
if(shape!=0){
shape=shape-1;
}else{
shape=3;
}
}
}
////防止突出右边
if(e==39&&c.width-20c.height-20){
count=count-20;
}
var ys=(y+count)%20; //下落的时候可能会一直按着 速度快会直接插到下面,所以这里要求余,当到这个方块的位置的时候取整判断
var es=20-ys;
var newCount=y+count+es;
for (var t=0;t
7、按钮操作
$(document).keydown(function(e){ //电脑键盘的
if(e.keyCode==39){ //右
crash(count,e.keyCode);//判断是否可以加到右边
}else if(e.keyCode==37){ //左
//判断是否可以加到左边
crash(count,e.keyCode);
}else if(e.keyCode==40){ //下
var i=count%10;
count=count-i;
fat=10;
}else if(e.keyCode==38){ //上
shape++;
if(shape>3){
shape=0;
}
crash(count,e.keyCode); //防止变形溢出
}else if(e.keyCode==32){
var i=count%20;
count=count-i;
for (var t=0;t<400;t++) {
count=count+10;
var arr=constitute();
var e=bottom(arr);
if(e==1){
break;
}
}
}
});
//////////////////////////// 手机端的按钮
function under(){
var i=count%10;
count=count-i;
fat=10;
setTimeout(function(){
fat=1;
},100)
}
document.onkeyup=function(){
fat=1;
}
function tops(){
shape++;
if(shape>3){
shape=0;
}
crash(count,38); //防止变形溢出
}
function lefts(){
//判断是否可以加到左边
crash(count,37);
}
function rights(){
crash(count,39);//判断是否可以加到右边
}
8、定义绘制预知框的方法,如上面绘制的方法一样,只是对应的canvas不同
//预知框里面的绘制
function xygs(){
var y=0; //记录组成形状的位置--相加
for (var i=0;i
9、开始运行的方法
function dy(){
ctx.clearRect(0, 0, c.width,c.height); //清除画布
constitute(); //调用组成画布的方法
count=count+fat; // 下落的速度
ground(finallys); //调用已经在底部的方块的方法
ctx.font="20px 微软雅黑";
ctx.fillText("得分:"+dfen+"",20,30);
requestAnimationFrame(dy); //调用循环运行
}
requestAnimationFrame(dy); //开始运行每一帧
if(finallys.length==0){ //获取第一个预知框
xyg=Math.floor(Math.random()*7);//随机获取
xygs();//调用预知框的渲染
}
constitute()//开始绘制