js异步编程的方法_JavaScript异步编程

(68) 2024-07-23 23:01:01

一.简介

俄罗斯方块(Tetris, 俄文:Тетрис)是一款风靡全球的电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。由于上手简单、老少皆宜,从而家喻户晓,风靡世界。

 

二.需求分析

(完全按照游戏的制作,如下图:)

 

三.技术分析与实现

1.方块位置定位

解决方案:建立盒子模型

由于长条的存在,所以建立一个4*4的盒子模型,任何一个方块都会存在该盒子当中,方块的定位就===盒子的定位。

 

2.颜色状态的生成与保存

随机生成颜色:

 
function randomColor() {

        
//
16进制方式表示颜色0-F

        
var arrHex = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];

        
var strHex = "#";

        
var index;

        
for (
var i = 0; i < 6; i++) {

            
//
取得0-15之间的随机整数

            index = Math.round(Math.random() * 15);

            strHex += arrHex[index];

        }

        
return strHex;

 } 

    

颜色保存:(那一个方块的一种状态做示例)


   
var diamonds = 
new Array();

    diamonds[0] = { x: appearPosition.position.x + 1, y: appearPosition.position.y, diamondColor: color };

    diamonds[1] = { x: appearPosition.position.x + 0, y: appearPosition.position.y + 1, diamondColor: color };

    diamonds[2] = { x: appearPosition.position.x + 1, y: appearPosition.position.y + 1, diamondColor: color };

    diamonds[3] = { x: appearPosition.position.x + 2, y: appearPosition.position.y + 1, diamondColor: color };

所有生成的方块有个diamondColor属性,用于存颜色。appearPosition.position是盒子模型的位置。

3.碰撞检测

碰撞分两种,一种是元素与左右墙壁和底部的碰撞,另外一种是方块与底部方块的接触碰撞

a.元素与左右墙壁和底部的碰撞

    a.1元素与底部的碰撞检测

  
if (diamonds[i].y * height + height >= canvasHeight) {

        appearPosition.position.x = Math.round(appearPosition.position.x);

        appearPosition.position.y = Math.round(appearPosition.position.y);

        createElement();

        breakTag = 1;

   }  

 

a.2元素与左右墙壁的碰撞检测


   
function returnRightOrLeft() {

        
var max_X = 11;

        
for (i = 0; i < diamonds.length; i++) {

            
if (diamonds[i].x > max_X) {

                max_X = diamonds[i].x;

            }

        }

        
if (max_X != 11) appearPosition.position.x = appearPosition.position.x - (max_X - 11);

        
var min_X = 0;

        
for (i = 0; i < diamonds.length; i++) {

            
if (diamonds[i].x < min_X) {

                min_X = diamonds[i].x;

            }

        }

        
if (min_X != 0) appearPosition.position.x = appearPosition.position.x - min_X;

    }

b.元素与元素碰撞检测


    
//
判断下面是否有元素

    
for (j = 0; j < bottomElement.length; j++) {

        
if (bottomElement[j].x == diamonds[i].x) {

            
if (Math.round(bottomElement[j].y) == Math.round(diamonds[i].y + 1)) {

                appearPosition.position.x = Math.round(appearPosition.position.x);

                appearPosition.position.y = Math.round(appearPosition.position.y);

                createElement();

                breakTag = 1;

            }

        }

    }

    
//
判断arrayOne是否在arrayTwo的右边

    
function IsAtRight(arrayOne, arrayTwo) {

        
for (i = 0; i < arrayOne.length; i++) {

            
for (j = 0; j < arrayTwo.length; j++) {

                
if (Math.round(arrayOne[i].y) == Math.round(arrayTwo[j].y)) {

                    
if (arrayTwo[j].x == arrayOne[i].x + 1) 
return 
true;

                }

            }

        }

        
return 
false;

    }

    
//
判D断arrayOne是否在arrayTwo的左边

    
function IsAtLeft(arrayOne, arrayTwo) {

        
for (i = 0; i < arrayOne.length; i++) {

            
for (j = 0; j < arrayTwo.length; j++) {

                
if (Math.round(arrayOne[i].y) == Math.round(arrayTwo[j].y)) {

                    
if (arrayTwo[j].x == arrayOne[i].x - 1) 
return 
true;

                }

            }

        }

        
return 
false;

    }

4.方块变形


    
var direction = 0;

    
if (e.keyCode == 87) {

        direction++;

        direction %= 4;

    }

W键是变形,0123分别代表四种。

如果是长条或者只有两种状态的直接  if (direction % 2 == 0) {},如果是正方块直接忽略direction,因为它就一种形状。

 

5.键盘捕获(目前WSAD+空格,W是变形,S和空格都是加速,IE9和FF异常,建议在谷歌浏览器下运行)


    document.onkeydown = 
function (e) {

        
if (e.keyCode == 65) {

            
for (i = 0; i < diamonds.length; i++) {

                
if (diamonds[i].x == 0) {

                    
return;

                }

            }

            
if (IsAtLeft(diamonds, bottomElement)) {

                
return;

            }

            appearPosition.position.x -= 1;

        }

        
if (e.keyCode == 87) {

            direction++;

            direction %= 4;

        }

        
if (e.keyCode == 68) {

            
for (i = 0; i < diamonds.length; i++) {

                
if (diamonds[i].x == 11) {

                    
return;

                }

            }

            
if (IsAtRight(diamonds, bottomElement)) {

                
return;

            }

            appearPosition.position.x += 1;

        }

        
if (e.keyCode == 32) {

            delay = 1;

        }

        
if (e.keyCode == 83) {

            delay = 1;

        }

    }

    document.onkeyup = 
function (e) {

        
if (e.keyCode == 32) {

            delay = 20;

        }

        
if (e.keyCode == 83) {

            delay = 20;

        }

    }

  

6.消除加分


    
//
一行满了的话,消除并加分

    
function clearUp() {

        
for (
var line = 0; line < 21; line++) {

            
var count = 0;

            
for (
var i = 0; i < bottomElement.length; i++) {

                
if (bottomElement[i].y == line) {

                    count++;

                }

            }

            
if (count == 12) clearByLineNum(line);

        }

        
//
 if(count==12)

    }

    
function clearByLineNum(num) {

        
//
以上的元素下降一行

        score++;

        
var count = 0;

        
for (i = 0; i < bottomElement.length; i++) {

            
if (bottomElement[i].y == num) {

                count++;

            }

        }

        
for (
var j = 0; j < count; j++) {

            
for (
var i = 0; i < bottomElement.length; i++) {

                
if (bottomElement[i].y == num) {

                    bottomElement.splice(i, 1);

                    
break;

                }

            }

        }

        
for (i = 0; i < bottomElement.length; i++) {

            
if (bottomElement[i].y < num) {

                bottomElement[i].y += 1;

            }

        }

    }

消除加分有一个潜在的逻辑就是,在该行以上的元素的位置下降一个格子。

 

7.控制核心Jscex  Show Time


    
var JropAsync = eval(Jscex.compile("async", 
function () {

        
var breakTag = 0;

        
while (
true) {

            color = randomColor();

            rectBlockIndex = MR() * 7 | 0;

            direction = MR() * 3 | 0;

            $await(Jscex.Async.sleep(1));

            
while (
true) {

                
for (i = 0; i < diamonds.length; i++) {

                    
if (diamonds[i].y * height + height >= 525) {

                        appearPosition.position.x = Math.round(appearPosition.position.x);

                        appearPosition.position.y = Math.round(appearPosition.position.y);

                        createElement();

                        breakTag = 1;

                    }

                    
//
判D断?下?面?是?否?有D元a素?

                    
for (j = 0; j < bottomElement.length; j++) {

                        
if (bottomElement[j].x == diamonds[i].x) {

                            
if (Math.round(bottomElement[j].y) == Math.round(diamonds[i].y + 1)) {

                                appearPosition.position.x = Math.round(appearPosition.position.x);

                                appearPosition.position.y = Math.round(appearPosition.position.y);

                                createElement();

                                breakTag = 1;

                            }

                        }

                    }

                }

                
if (breakTag == 1) {

                    
for (i = 0; i < diamonds.length; i++) {

                        
//
alert(diamonds[i].x + "____" + diamonds[i].y)

                        bottomElement.push(diamonds[i]);

                    }

                    clearUp();

                    
//
清?空?下?降μ的?元a素?

                    diamonds.splice(0, diamonds.length);

                    appearPosition = { position: { x: 4, y: -2 }, direction: 0 };

                    breakTag = 0;

                    
break;

                }

                appearPosition.position.y += step;

                draw();

                $await(Jscex.Async.sleep(delay));

            }

        }

    }));

这是也整个俄罗斯方块的控制核心,由两个while循环构成,简单大方

 

四.在线演示

操作指南:W变形  A左移 D右移     (谷歌浏览器:S加速 空格加速,其他浏览器慎重按此键,该死的浏览器兼容)

火拼俄罗斯

Your browser does not support the canvas element.

得分:
0

 

最新的Jscex 库,请上https://github.com/JeffreyZhao/jscex或者http://www.sndacode.com/projects/jscex/wiki下载吧····

五.同步

本文已同步更新至:

HTML5实验室【目录】:   http://www.cnblogs.com/iamzhanglei/archive/2011/11/06/2237870.html

转载于:https://www.cnblogs.com/iamzhanglei/archive/2011/09/09/2171930.html

THE END

发表回复