哪些支付一个苹果手机App:俄罗斯方块游戏。Javascript 俄罗斯方 游戏代码解释!

俄罗斯方块游戏,是风靡世界几十年之藏游戏,相信大部分丁还玩过此娱乐,那么她是何许编写出来的,我们怎么样才会协调编排一个这么的玩吗?

俄罗斯方块代码说明

游玩开发步骤

假使修一个游乐,基本以以下一些手续进行:

1.游戏规则定义

游戏规则决定了这游乐怎么玩,好不好玩,也即决定了编写程序实现的目标。不同之急需导致差之规则,不同的规则就是需要不同之法子去贯彻。

例如,俄罗斯方是由于哪类型方块构成,棋盘布局是9*18还是10*20,是否同意旋转,消掉一行获得的分数和博多执获得的分数如何开展添加,等等。

2.抉择游戏运行平台和界面设计

当雅多种平台上都得以玩游戏,常见的依电脑pc或者笔记本上面直接运行游戏exe程序,或者在电脑浏览器被运行flash游戏,或者手机上运行游戏App,或者以特种游戏机比如xbox等齐直接运行游戏程序,或者当VR设备及运行游戏程序。

今非昔比之平台,需要不同的实现方式,也就是得为此不同之次第要出语言开发工具来促成。

例如,在网页上开发娱乐,可以为此html+css+js实现,也堪为此flash实现;在大哥大及开娱乐,可以用java语言在android系统受到实现,也得以据此objective-c在ios系统及贯彻;在微机pc机上得为此c语言在windows系统中实现。

界面设计就是冲游戏规则决定人机交互界面,决定了输入和出口的章程。

诸如,俄罗斯方块可以计划改为左边是棋盘,右侧上面是分,下一个方,还可以推广一个再来平等句按钮,或者暂停按钮等等。

正方设计改为纯一栽颜色块,还是多颜色块,或者是正在的还是应有尽有的,或者是卡通图案,这些虽是界面设计。

3.设想编程思路以及算法设计

若决定了于哪种平台与因此何种开发语言来编程实现游戏,则只要考虑编程的笔触,数据的囤积,以及实际的算法。

比如说,俄罗斯方块根据棋盘大小是为此二维数组来贯彻,还是用同一维数组来落实,还是用字典表来实现

如出一辙小卖部打是定时计算,还是用一个循环来处理

安保存下一个门类,如何计算分数,如何判断一个四方是否生不可知重挪,如何判断一行是否已经让填满,如何判定游戏早已完结

4.比照前面设计之思路编写代码实现

设想好编程思路与算法设计下,可以随设想进行实际的编程开发

切莫停止的认证思路,通过支付中之实际上情况,可能针对编程思路开展修改调整,直到好整个娱乐效果

代码就是单排一行的修出来,直到成为一个足运行的游艺程序

5.游戏测试

测试就是管自己当成实际用户来运行游戏程序,找到打或者存在的问题,避免程序没有循预期执行,防止程序崩溃死机等气象,验证游戏确实仍游戏规则能圆可靠的周转,这个开发人员可以寻找其他人进行测试,防止投机在思维盲区。

6.游戏发布

玩耍测试好以后,就好以游戏发布到对应的沟渠或平台,让还多的食指可打到这娱乐。

例如,苹果手机App可以发表暨苹果之AppStore,安卓手机App可以宣告到各个大应用市场。

极致简单易行的颁发即是直接发送给好之对象,让她们震惊。

/**
    名称:Javascript 俄罗斯方块!
    作者:Gloot
    邮箱:glootz@gmail.com 
     QQ:345268267 
    网站:http://www.cnblogs.com/editor/
*/

OLSFK = {};

游戏规则定义

俄罗斯方游戏有如下规则:

棋盘由涨幅为10格高度也20格底正方构成

方共发出7种植形态:

长条形1个,正方形1个,T型1个,L型2个,S型2个

正方出现于极其上端正中间,同时了解下一个四方是什么

正方往下丢得到,每隔1秒下落一行

方下落中一旦遇有方块阻挡不克下降则停下滑

方停止下落后,判断是否出整行都受方块填满,如果来,则整行消失,上面的全部实行完全低落一行

统计消掉的总局多次

四方在降低过程被,可以以向下方向键让方直接掉落到直到停止职务

得依照向左或朝右侧向键让方进行盘,每本键一次于盘90过

如没足够的空中被方落下则打了

随俄罗斯方代码应用 JavaScript 脚论代码写成,简单好亮;

玩运行平台和界面设计

一旦坐无限风靡的苹果手机当娱乐运行条件,则需要开销一个苹果手机App

苹果手机应用的凡iOS操作系统,开发环境急需Mac电脑以及开发工具软件Xcode

出语言可以运用objective-C,开发娱乐可使出用工具包cocos2d

倘若急需披露暨苹果AppStore,则用一个开发者账号,以及同年99美金

界面设计:

程序启动以后进入主界面,只能竖屏显示游戏

主界面分为横有

左为棋盘:显示整个棋盘,正方形的格子组成,宽10绳高20格

遵照苹果手机尺寸320接触*480触及来计划,20格高度也480碰,则涨幅10格占据240沾

故此左边棋盘占用240点,右侧剩余80接触

下手分为上部跟底下

上部也状态栏靠上显示:最上面显示显示当前消掉的行数,下面显示方块类型小图标

下面为按钮栏靠下显得:从高达往下显得3个按钮,排行榜/关于/重新开始

大约的界面设计如下示意图:

界面运行逻辑:

点击排行榜按钮上一个初页面,上面显示消掉的行数最多的8单行数数字,下面是一个回去按钮

点击关于按钮上一个新页面,上面显示同一摆放说明图片,下面是一个回按钮

点击重新开按钮,将目前棋盘清空并还开始同店打,游戏启动

游戏启动以后,第一独方块从不过上面中间开始往下丢得到,每秒下落一行

并且,上方的状态栏,显示下一个且面世的方框类型小图标

正方下落过程中,在屏幕上但因左滑可以往左逆时针旋转当前方,或者在屏幕及才因右滑得于右侧顺时针旋转当前方

尚得当屏幕上单指下滑可以为眼前方直接掉落到底层

方如果非能够重新为生活动一行的时,则方块停止,同时开判断是否会消掉某些行

假定能消掉某些行,则统计消掉的行数,增加及上边状态栏显示消掉的数字上,刷新显示

消掉的行从屏幕及去掉,同时上之兼具执行向下完整走

加入棋盘最上面中间的供方块出现的地方就于方块占已了,则觉得就无异商家打了

游戏结束则弹来一个窗口亮游戏了信息,显示总共消掉了有点行,然后将欠记录保留到数据库中

弹来窗口及闹返回按钮,点击返回按钮,弹出窗口关闭,回到游戏主界面,主界面停止游戏,点击重新开始按钮开始新一柜

全代码采用静态类及静态变量成员组成;

编程思路以及算法设计

数存储:

设想就此二维列表来存储棋盘上之各一个格子

[[0,0,0,0,0,0,0,0,0,0],

[0,0,0,0,0,0,0,0,0,0],

……

[0,0,0,0,0,0,0,0,0,0]]

二维列表中,第一重叠是放开总计20履,第二叠内是加大每一行的10只格子

若是格子里面来方块,则存放数字1,如果无方块则存放数字0

判定一行要周凡1,则象征该行填满了方格,需要消掉

采用下列数字来针对7栽方块进行分,存储2个变量,当前方和下一个四方

1:长条形 2:正方形 3:T型 4:L型向左 5:L型向右侧 6:S型左上右侧下 7:S型右上左下

生成下一个方则用随机函数生成1到7当被之妄动数

然后不同方块如果进行了兜会出现不同的状态,定义旋转状态如下:

11:竖立长条 12:横排长条

21:正方形

31:T型尖头朝下 32:T型尖头朝左 33:T型尖头朝及 34:T型尖头朝右

41:L型短头向左长头向上 42:L型短头向达长头向右 43:L型短头向右侧长头向下
44:L型短头向下长头向左

51:L型短头向右侧长头向上 52:L型短头向下长头向右 53:L型短头向左长头向下
54:L型短头向达长头向左

61:S型左上右侧下戳 62:S型左上右侧下横排

71:S型右上错误下戳 72:S型右上错误下横排

下2个变量x,y存储时方的左上角的正方的行号和列号

采用变量存储时都破的行数

算法设计:

点击重新开始按钮后,主程序启动

清空整个棋盘,对二维列表全部数字清零

然后生成第1独随机数,赋值给当下方变量

接下来转第2单随机数,赋值给下一个四方变量

刷新显示页面

进入定时处理函数,定时间隔时间为1秒:

定时处理函数:

认清当前方如果得以通往生走,则向下移动,修改二维列表变量

如果未得以下浮了,则判断是否可以免除某行,如果排除了某行则上之所有行的价值完下更换一实行

假设不可以下浮也非得以去掉了,则拿下一个方的数值赋值给当下方,随机数异常成下一个方

然后判断当前方是否可放入棋盘最上方之中等位置,如果可以放入则改二维列表变量,如果无能够放入,则玩结束

看清时方是否可以下转移函数:

因当前方类型变量,以及方块即盘状态,结合二维列表变量判断,举例:

一经是11竖起长条形,则因当下方左上角的行号和列号,可以了解最下方的坐标位置

比如x=0实践,y=5列,则最下方的坐标为(3,5),那么一旦看二维列表的(4,5)如果也1尽管不足下更换,否则可以下浮

准要是31:T型尖头朝下

x=0,y=4,那么下方可能发生3独方块可能碰到阻碍,分别是(0,4)/(1,5)/(0,6)

那一旦看二维列表的(1,4)/(2,5)/(1,6)只要发生一个也1则不得下换,否则可以下浮

认清是否可破某行函数:

对二维列表进行巡回,如果一行当中的具有值都为1,则可打消

直接以有着方面的推行之价值为下复制,最上面一行的值周赋值为0,同时总的消行数变量加1

判定时方是否好放入棋盘最上面的高中级位置函数:

冲当下方类型变量,以及方块即转状态,结合二维列表变量判断,举例:

若是1长带状,默认为11建立长条形

虽然需要判定(0,5)/(1,5)/(2,5)/(3,5)这4独坐标在二维列表中是否也1,只要发生1单职位为1虽然不得放入

按部就班使是3T型尖头朝下

虽说需要判定(0,4)/(0,5)/(0,6)/(1,5)这4独坐标

盘处理:

合允许生3种滑动手指操作,向下/向左/向右侧

朝下滑动手指,表示将手上方直接掉到极致下方直到碰到阻碍停住

于左滑动手指,表示将手上方进行逆时针转动

通向右侧滑动手指,表示将手上方进行顺时针旋转

向下丢得到处理:

又调用前面定义的论断当前方是否好生移函数

起第一实施循环到最后一履坐标,即可得出最多得掉到啊一行

逆时针旋转处理:

根据目前方类型变量,以及方块即转状态,结合二维列表变量判断,举例:

假定是11竖起长条形,旋转中心点取从上向生第2个方块

那根据旋转后要占用的岗位,需要判定(1,4)/(1,6)/(1,7)这3只位置在二维列表中的值必须是0才可以旋转

转完成后当左上角坐标应该打(0,5)变成(1,4),方块时盘状态从11变为12

呼吁看下的示意图:

那,顺时针旋转和斯看似,只是选择后底左上角左边变量变化,以及方块即转状态值变化

全脚本通过落实代码全局配置 OLSFK.Options = {…}

切切实实代码实现

由于篇幅所限,这里不得不约讲述核心之片段代码实现方式

支付准备:

先是得注册一个AppleID

然后以Mac电脑上安好Xcode开发软件

引入相关工具开发包:

导入cocos2d开发工具包以及用之有些网Frameworks

多少操作类:

AllData.h

#define SIZE 24

#define WIDTH 320

#define HEIGHT 480

@interface AllData : NSObject

@property int next;

@property int current;

@property int currentstatus;

@property int posx;

@property int posy;

@property int alllines;

@property (nonatomic,retain) NSMutableArray *numberdatas;

//取得时类似的实例

+(AllData *) sharedAllData;

//初始化棋盘

-(void)initAllData;

//取得下一个四方

-(int) getNextValue;

//逆时针旋转当前方

-(void)changeLeft;

//顺时针旋转当前方

-(void)changeRight;

//判断是否足以下浮当前方

-(boolean)canMoveDown;

//处理消除慢行操作

-(void)removeLines;

@end

储存控制类:

DBUtil.h

@interface DBUtil : NSObject

+ (NSString *)dataFilePath;

+ (void)initDataBase;

//存储一店家打消除行数数字

+(void)insertOneData:(int)topnumber;

//取得最酷的8独记录数:消除行数

+ (NSMutableArray *)getListDataFromDb;

@end

四方绘画类:

#import “CommonUtil.h”

#import “AllData.h”

@implementation CommonUtil

//绘画棋盘中的一个格子

+ (void) drawOneNumber:(int)number pos:(CGPoint)pos
layer:(CCLayer*)layer {

CCSpriteBatchNode *numbatch = [CCSpriteBatchNode
batchNodeWithFile:[NSString stringWithFormat:@”num_%d.png”,number]
capacity:15];

numbatch.anchorPoint = CGPointZero;

[numbatch setPosition:pos];

[layer addChild:numbatch];

CCSprite *sprite1 = [CCSprite spriteWithTexture:numbatch.texture
rect:CGRectMake(0, 0, SIZE-2, SIZE-2)];

sprite1.position = ccp(0,0);

sprite1.anchorPoint = CGPointZero;

[numbatch addChild:sprite1];

}

// 绘画整个棋盘

……

起先进入主界面:

@implementation AppDelegate

– (void) applicationDidFinishLaunching:(UIApplication*)application

{

……

[[AllData sharedAllData] initAllData];

[DBUtil initDataBase];

[[CCDirector sharedDirector] runWithScene: [MainLayer scene]];

…….

状态栏和工具栏:

@interface ToolLayer : CCLayer {

}

@implementation ToolLayer

– (void) drawTool {

[self removeAllChildrenWithCleanup:YES];

//画底部背景

CCSprite *bg = [CCSprite spriteWithFile:@”tool_bootom_back.png”];

bg.anchorPoint = CGPointZero;

[self addChild:bg z:0 tag:0];

//排行按钮

CCMenuItem *gold = [CCMenuItemImage itemFromNormalImage:@”gold.png”
selectedImage:@”gold_pressed.png” target:self
selector:@selector(gold:)];

//关于按钮

CCMenuItem *about = [CCMenuItemImage itemFromNormalImage:@”about.png”
selectedImage:@”about_pressed.png” target:self
selector:@selector(about:)];

//重新开按钮

CCMenuItem *restart = [CCMenuItemImage
itemFromNormalImage:@”restart.png” selectedImage:@”restart_pressed.png”
target:self selector:@selector(restart:)];

……

// 绘画消除行数的图标

// 绘画消除行数的数字

// 绘画下一个方的图标

– (void) restart:(id) sender

{

[[AllData sharedAllData] initAllData];

MapLayer *mapLayer = (MapLayer *)[[CCDirector
sharedDirector].runningScene getChildByTag:0];

[mapLayer startGame];

[self drawTool];

}

棋盘滑动手势控制措施:

– (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

NSSet *allTouches = [event allTouches];

switch ([allTouches count])

{

case 1:

{

UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];

single = [touch1 locationInView:[touch1 view]];

} break;

default:

break;

}

}

– (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

NSSet *allTouches = [event allTouches];

switch ([allTouches count])

{

case 1:

{

UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];

CGPoint singleend = [touch1 locationInView:[touch1 view]];

float x = single.x – singleend.x;

float y = single.y – singleend.y;

if (x*x > y*y && x*x > 2500 && x > 0) {

//向左横向滑动超过50

NSLog(@”左”);

[self changeLeft];

}else if (x*x > y*y && x*x > 2500 && x < 0) {

//向右侧横向滑动超过50

NSLog(@”右”);

[self changeRight];

}else if (x*x < y*y && y*y > 2500 && y < 0) {

//向下虽为滑动超过50

NSLog(@”下”);

[self moveDown];

}

} break;

default:

break;

}

}

主界面程序:

@interface MapLayer : CCLayer {

}

@implementation MapLayer

-(void) startGame{

[self removeAllChildrenWithCleanup:YES];

int toppos = 0;

for (NSMutableArray *onerow in [AllData sharedAllData].numberdatas) {

int leftpos = 0;

toppos = toppos + SIZE + 1;

for (NSNumber *onepos in onerow) {

leftpos = leftpos + SIZE + 1;

[CommonUtil drawOneNumber:[onepos intValue] pos:CGPointMake(leftpos,
toppos) layer:self];

}

}

// 设置定时器处理函数,定时间隔时间1秒

……

}

//定时器处理函数

//判断当前方如果可以向下活动,则为下活动,修改二维列表变量

//如果无可以下浮了,则判断是否可免去某行,如果排除了某行则上的所有行的价值完下换一实践

//如果未得以下浮也未可以消除了,则以下一个四方的数值赋值给当下方,随机数异常成下一个四方

//然后判断时方是否足以放入棋盘最上方的中等位置,如果得以放入则改二维列表变量,如果不能够放入,则打了

……

切切实实代码这里不贴了,有了详尽的算法程序设计与数目存储类型,要贯彻出来并无是最最碍事,只是要耐心细心而已。

概念方块起始坐标及定义各自的转点;

戏测试

一日游之重心程序完成后,就好一边测试一边改

测试的时候如果小心测试各种边界情况,例如

以眼前方移动及最好左边,看看碰到边界的当儿会不见面错

以手上方卡入一个正要插入的空槽形状中,看程序是未是会错

待时方掉入一个空槽,然后马上转,理论及应有无克转了,测试看看程序会不会见出错

测试一次性消掉4实施,看看程序是未是碰头拧

比方协调测试的差不多了,就得以先后打包发送给爱人测试

偶尔,开发的食指分外为难测试自己编排的顺序,但是反而为别人可以测试出多题目

从今初始化俄罗斯方界面开始,再监听键盘事件;以及左右,向下及旋转动作判断,重新渲染方块位置;

娱发布

脚介绍一下大概的颁发流程,让大家发出个起来印象,详细的揭晓流程网上可查找到无数

玩测试到核心无不当后,就足以将戏发布暨苹果之AppStore了

发布App需要购置苹果的开发者账号,一年是99美金,目前于是信用卡支出为蛮便利

然后登陆https://developer.apple.com,进行一些证书的设置

转移好关系后,将证件下充斥至Mac电脑遭到导入到Xcode之中

下一场使用Xcode进行编译和包裹好一个ipa文件

然后登陆https://itunesconnect.apple.com创建一个App,填写一些介绍信息,需要一些App的截图

下一场回到Xcode使用Application
Loader这个工具软件将ipa文件上传到itunesconnect当中

然后回来itunesconnect网站上提交App

然后便等苹果AppStore的审核,一般7-10独工作日可以好查处

成功对之后,你的App就见面出现在苹果手机的AppStore里面了,就可找寻到了

下一场就是得告诉你的爱侣等,让他们吃惊吧。

=

认清是否消行,以及对应的加级判断,执行进度,加分操作来推行;

末段因为判断是否当前级别大于所定义的不过酷级别来判定是否结束;

代码说明讲解

OLSFK.Options = { //相关参数
    width:12,//界面横向方块数
    height:20,//界面纵向方块数
    boxWidth : '16px',
    curLevel:1,
    speed : 1000, //setInterval,setTimeout
    direct : { //可以设定是A S D W, 还是← ↓ → 
        Down: 40 , /*run speed*/
        Left: 37,
        Right: 39,
        Rotate: 38
    },
    Move:true,//是否正在移动
    Eventing:false,
    Levels: {
        1:1000,
        2:900,
        3:800,
        4:700,
        5:600,
        6:500,
        7:400,
        8:300,
        9:200,
        10:100
    },
    curBlock:4, //当前移动的图形名称
    nextBlock:0,
    GampMap:new Object(),
    Timer:null,
    deline:0,
    Score:0,
    Deling:false,
    Start:false,
    lineNum:10, //删除几行了,加级
    ScoreNum:40 //消一行加分
}

direct 代表 使用键盘方位键来操作方块的运动方向;

用啊种方向键按擅自喜欢配置,比如许母键的A, S, D, W;
或右小数字键盘的数字键各自的键盘编码;

仍 上(旋转)、下、左、右 方向键的编码分别吗:38、40、37、39;

Levels:表示级别配备,本配置并分为10层,每个级别所对应的下落速度,即定时执行间隔;

curBlock:表示手上移动的四方;

nextBlock:表示接下去执行的方索引,并显示界面右上较量的预览框中;

GampMap:用于保存在根据定义行列数形成的游玩表格中保留每个约的数目信息;

OLSFK.Options.GampMap[x+'_'+y] = 0;

对象表格为: id: “box_”+x+”_”+y;

初始化数据吧 ‘0’;  表示该表还非占用;当有占用时,设置值为 ‘1’;

Timer:为定时执行器;setTimeout
定时实行方下落的底频率;定时时间越聊,速度越快;

Deling:当在推行消行操作时,下次临时未形并退;

lineNum:表示消超过 10 行,加一级;

ScoreNum:表示每消一行所加的分数;

 

OLSFK.ReItems = function (cur){ //key旋转点

    switch (cur)
    {
        case 1:
            OLSFK.Items[1] = {//长块 LongBlock
                                1:{x:4,y:0},
                                2:{x:5,y:0},
                                3:{x:6,y:0},
                                4:{x:7,y:0},
                                5:{x:5,y:0} //旋转点
                            };
            break;
                        //....
        }
}

拖欠办法用于恢复方块的起来设置;

OLSFK.Next = { //key旋转点
    //长块 LongBlock
    1: {
        1:{x:0,y:1},
        2:{x:1,y:1},
        3:{x:2,y:1},
        4:{x:3,y:1}
    },
        //...
}

也免了无与娱乐方块的安装冲突,独立出来下次即兴方块的目标配置;

OLSFK.Items = { //key旋转点
    //长块 LongBlock
    1: {
        1:{x:4,y:0},
        2:{x:5,y:0},
        3:{x:6,y:0},
        4:{x:7,y:0},
        5:{x:5,y:0}
    },
    //方块Box
    2: {
        1:{x:4,y:0},
        2:{x:5,y:0},
        3:{x:4,y:1},
        4:{x:5,y:1},
        5:{x:0,y:0}
    },
    //凸块 TuBlock
    3: {
        1:{x:4,y:1},
        2:{x:5,y:0},
        3:{x:5,y:1},
        4:{x:6,y:1},
        5:{x:5,y:1}
    },
    //L块 LBlock
    4: {
        1:{x:5,y:0},
        2:{x:5,y:1},
        3:{x:5,y:2},
        4:{x:6,y:2},
        5:{x:5,y:2}
    },
    5: { //反向L块 FLBlock
        1:{x:5,y:2},
        2:{x:6,y:2},
        3:{x:6,y:1},
        4:{x:6,y:0},
        5:{x:6,y:2}
    },
    //Z块 ZBlock
    6: {
        1:{x:4,y:0},
        2:{x:5,y:0},
        3:{x:5,y:1},
        4:{x:6,y:1},
        5:{x:5,y:0}
    },
    7: {//反向Z块 FZBlock
        1:{x:4,y:1},
        2:{x:5,y:1},
        3:{x:5,y:0},
        4:{x:6,y:0},
        5:{x:5,y:1}
    }
}

方共分为:长段,方块,凸块(T块),L块,反L块,Z块,反Z片几栽;

同台7栽方块,以1,2,3,4,5,6,7
索引键表示,方块是四只小片组成,每块都有各自的坐标,1-4象征结合该块的起坐标位置,5代表旋转点;

OLSFK.Init = function() { //初始化界面
    //...
}

俄罗斯方块的界面初始化方法;将当 window.onload 中调用执行;

var w = OLSFK.Options.width;
    var h = OLSFK.Options.height;
    var total = w * h;

    var x=0,y=0;
    for (var i=0; i<total; i++)
    {

        OLSFK.Options.GampMap[x+'_'+y] = 0;

        Lib.Tag('SPAN',{id:"box_"+x+"_"+y,name:"cbox",style:{
            width:OLSFK.Options.boxWidth,
            height:OLSFK.Options.boxWidth,
            border:"2px outset #669",
            background:"#ddd",
            float:"left",
            overflow:"hidden"
        },innerHTML:"&nbsp;",className:"cssbox"},back);

        var end = i + 1;
        x++;
        if (end >= w && end % w == 0)
        {
            x=0;
            y++;
            Lib.Tag('DIV',{style:{
                clear:"both"
            }},back);
        }

    }

透过设置的 Options.width, Options.height
列数与行数,以及安装的小方格宽度,初始化了一个富饶:Options.width列,高也
Options.height 的表界面出来;

Lib.Tag 用于创造标签对象;

Lib.Tag = function(TAG,json,pnode) {
    //...
}

TAG为标签名,比如: div, span 等;

json为设置标签样式 style;

pnode 是拖欠创建所于的父容器;

OLSFK.Init = function() {}
还创造主游戏区域边缘的下次擅自方块预览区,当前级别,及分,以及操作“开始”,“暂停”按钮等;

图片 1

娱初起称口点

window.onload = function() {
    if (window.isIE)
    {
        document.attachEvent("onkeydown",function(e) {
            if (OLSFK.Options.Start)
            {
                var E = OLSFK.KeyCode();
                OLSFK.EventFunc(E);
            }

        });

        document.attachEvent("onkeyup",function(e) {
            if (!OLSFK.Options.Move && OLSFK.Options.Start)
            {
                OLSFK.Options.Move = true;
                OLSFK.Options.Eventing = false;

                OLSFK.Options.Timer = setTimeout(function() {
                    OLSFK.play();
                }, OLSFK.Options.Levels[OLSFK.Options.curLevel]);
            }
        });
    } else {
        document.addEventListener("keydown",function(e) {

            if (OLSFK.Options.Start)
            {
                var E = OLSFK.KeyCode();
                OLSFK.EventFunc(E);
            }

        },false);

        document.addEventListener("keyup",function(e) {
            if (!OLSFK.Options.Move && OLSFK.Options.Start)
            {
                OLSFK.Options.Move = true;
                OLSFK.Options.Eventing = false;

                OLSFK.Options.Timer = setTimeout(function() {
                    OLSFK.play();
                }, OLSFK.Options.Levels[OLSFK.Options.curLevel]);
            }
        },false);
    }
    OLSFK.Init();
}

最主要是监听键盘事件,根据 键盘事件 返回的按钮编码与 OLSFK.Options.direct
设置方向键匹配来操作方块的运动,旋转等;

keydown 用于操作下落方块的位移方向,旋转等;并重复绘制方块位置;

keyup 后连续以本级速度往下落;

OLSFK.Options.Levels[OLSFK.Options.curLevel]

表示目前级别相应的速度,即定时器间隔执行时(毫秒);

OLSFK.EventFunc = function(code) {
    switch (code)
    {
        case OLSFK.Options.direct.Left: //LEFT
            if (!OLSFK.Options.Deling)
            {
                clearTimeout(OLSFK.Options.Timer);
                OLSFK.Options.Eventing = true;
                OLSFK.Options.Move = false;
                OLSFK.Left();
            }

            break;
            //...
        }
}

拖欠法是 监听 keydown 事件实施之动作;code 为依照键 编码;

当判断不在消行动作常常,清除定时器,OLSFK.Options.Eventing 设置也事件备受
true,OLSFK.Options.Move 为 false 表示已运动;

入 向左移动方法 OLSFK.Left();

OLSFK.Left = function() {
    var block = OLSFK.Items[OLSFK.Options.curBlock];

    if (block)
    {
        var flag = true;
        for (var i=1; i<=4; i++)
        {
            var x = block[i].x;
            var y = block[i].y;

            if (x-1 < 0)
            {
                flag = false;
                break;
            }

            if (OLSFK.Options.GampMap[(x-1)+'_'+y] == 1 && !OLSFK.isMe(x-1,y))
            {
                flag = false;
                break;
            }
        }

        if (flag)
        {
            for (var i=1; i<=4; i++) //清除图形
            {
                var itm = block[i];
                var box = Lib.Getid('box_'+itm.x+'_'+itm.y);

                box.style.background = '#ddd';
                OLSFK.Options.GampMap[itm.x+'_'+itm.y] = 0;
            }

            for (var i=1; i<=5; i++)
            {
                var x = block[i].x;
                var y = block[i].y;

                OLSFK.Items[OLSFK.Options.curBlock][i] = {x:(x-1),y:y};
            }

            OLSFK.draw();
        } 
    }
}

var block = OLSFK.Items[OLSFK.Options.curBlock];
表示收获当前倒方块;

if (OLSFK.Options.GampMap[(x-1)+'_'+y] == 1 && !OLSFK.isMe(x-1,y))
{
    flag = false;
    break;
}

判断该方块四只小方块左边是否有受挤占的四方,也即: OLSFK.Options.GampMap[(x-1)+’_’+y]
为 1; 并且该职位块不属方块自己之;

当左边方向无占用格时,清除当前方四单稍方块位置,重新绘制方块新坐标位置;并重置
相应的 OLSFK.Options.GameMap [x+y] 相应格的值;

当按钮 keyup 时,继承正常为下落;

OLSFK.isMe 代码:

OLSFK.isMe = function(x,y) {
    var block = OLSFK.Items[OLSFK.Options.curBlock];

    if (block)
    {
        for (var i=1; i<=4; i++)
        {
            if (block[i].x == x && block[i].y == y)
            {
                return true;
            }
        }
    }

    return false;
}

纵然指定的 x,y (参数值) 是否还以手上方四单坐标内;

OLSFK.Right () 与 Left() 一样;

盘方块代码;

OLSFK.Rotate = function() {
    var block = OLSFK.Items[OLSFK.Options.curBlock];

    if (block)
    {
        var flag = true;

        var R = block[5];
        for (var i=1; i<=4; i++)
        {
            var x = block[i].x;
            var y = block[i].y;

            if (R.x == x && R.y == y)
            {

            } else {
                var nson = new Object();

                nson.x = R.x + R.y - y;
                nson.y = R.y - R.x + x;

                if ( nson.x < 0 || nson.y < 0 || nson.x >= OLSFK.Options.width || nson.y >= OLSFK.Options.height )
                {
                    flag = false;
                    break;
                }

                if (OLSFK.Options.GampMap[nson.x+'_'+nson.y] == 1 && !OLSFK.isMe(nson.x,nson.y))
                {
                    flag = false;
                    break;
                }
            }
        }

        if (flag)
        {
            for (var i=1; i<=4; i++) //清除图形
            {
                var itm = block[i];
                var box = Lib.Getid('box_'+itm.x+'_'+itm.y);

                box.style.background = '#ddd';
                OLSFK.Options.GampMap[itm.x+'_'+itm.y] = 0;
            }

            var Pnt = 1;

            for (var i=1; i<=4; i++)
            {
                var x = block[i].x;
                var y = block[i].y;

                if (R.x == x && R.y == y)
                {
                    Pnt = i;
                } else {
                    var nson = new Object();

                    nson.x = R.x + R.y - y;
                    nson.y = R.y - R.x + x;
                    OLSFK.Items[OLSFK.Options.curBlock][i] = {x:nson.x,y:nson.y};
                }
            }

            OLSFK.Items[OLSFK.Options.curBlock][5] = OLSFK.Items[OLSFK.Options.curBlock][Pnt];

            OLSFK.draw();
        } 
    }
}

var R = block[5]; 就是取得旋转点;

即使起对方块四只小片以旋转点为主导,逆时针旋转(并无备是 90
度);当当前块不也转点时,旋转公式;

var nson = new Object();

nson.x = R.x + R.y - y;
nson.y = R.y - R.x + x;

是公式要这么看; 

ResultX = RotateX + (RotateY - CurrentY);
ResultY = RotateY - (RotateX - CurrentX);

//Y的偏移量,就是X的增加值;
//反之同

当盘四周都管占用物时;清除当前图,重绘旋转后底图形位置;

重置 OLSFK.Options.GampMap[itm.x+’_’+itm.y] 各个方块的占用值;

OLSFK.Random = function() {

    if (OLSFK.Options.nextBlock != 0)
    {
        OLSFK.Options.curBlock = OLSFK.Options.nextBlock;

        var block = OLSFK.Next[OLSFK.Options.nextBlock];
        if (block)
        {
            for (var i=1; i<=4; i++)
            {
                var itm = block[i];
                var box = Lib.Getid('cur_'+itm.x+'_'+itm.y);

                box.style.background = '#ddd';
                //OLSFK.Options.GampMap[itm.x+'_'+itm.y] = 0;
            }
        }
    } else {
        OLSFK.Options.curBlock = Math.floor(Math.random() * 7 + 1);
    }
    OLSFK.Options.nextBlock = Math.floor(Math.random() * 7 + 1);

    OLSFK.drawNext();
}

轻易大成下次预下落的方;并出示到右上较量的预览表格里;

OLSFK.play = function(speed) {
    var block = OLSFK.Items[OLSFK.Options.curBlock];

    if (block && OLSFK.Options.Move)
    {

        var flag = true;
        for (var i=1; i<=4; i++)
        {
            var x = block[i].x;
            var y = block[i].y;

            if (y+1 >= OLSFK.Options.height)
            {
                flag = false;
                break;
            }

            if (OLSFK.Options.GampMap[x+'_'+(y+1)] == 1 && !OLSFK.isMe(x,y+1))
            {
                flag = false;
                break;
            }
        }

        if (flag)
        {
            for (var i=1; i<=4; i++) //清除图形
            {
                var itm = block[i];
                var box = Lib.Getid('box_'+itm.x+'_'+itm.y);

                box.style.background = '#ddd';
                OLSFK.Options.GampMap[itm.x+'_'+itm.y] = 0;
            }

            for (var i=1; i<=5; i++)
            {
                var x = block[i].x;
                var y = block[i].y;

                OLSFK.Items[OLSFK.Options.curBlock][i] = {x:x,y:(y+1)};
            }
            OLSFK.draw();

            var S = OLSFK.Options.Levels[OLSFK.Options.curLevel];
            if (speed)
            {
                S = 50;
            }
            OLSFK.Options.Timer = setTimeout(function() {
                OLSFK.play();
            }, S);
        } else {
            OLSFK.ReItems(OLSFK.Options.curBlock);
            OLSFK.newRun();
        }
    }
}

OLSFK.play
正常下落的办法,也得判断下落一格是否发生被霸占的封锁,如果没有,清除当前方,绘制方块新岗位;

当方片不克重复降低时(flag = false),重置当前方坐标配置;
OLSFK.ReItems(OLSFK.Options.curBlock);

进去 OLSFK.newRun(); 新下落方块下落过程准备;

OLSFK.newRun = function() {

    clearTimeout(OLSFK.Options.Timer);
    OLSFK.DelFunc();
    if (OLSFK.Options.deline >= 10)
    {
        OLSFK.Options.deline = 0;
        OLSFK.Options.curLevel ++;
        OLSFK.Element.CurLevel.setHTML("级:"+OLSFK.Options.curLevel);
    }
    OLSFK.Element.Score.setHTML("分:"+OLSFK.Options.Score);

    if (OLSFK.Options.curLevel <= OLSFK.Options.lineNum)
    {
        OLSFK.Random();
        //判断是否结束
        OLSFK.ChkEnd();
    } else {
        OLSFK.Options.Move = false;
        OLSFK.Options.Start = false;
        OLSFK.Options.Eventing = false;
        OLSFK.Options.Deling = false;
        Lib.Getid('spn').innerHTML = 'Game Is Over! You Win the Game!';

        Lib.Getid('dobtn').innerHTML = ' 开始 ';
    }

}

当退结束时,清除定时器,暂停新方块下落,检测是否发可破的实行;减了多少行;

各减去一行 加分 OLSFK.Options.Score += OLSFK.Options.ScoreNum;

此办法在 : 

OLSFK.DelFunc = function() {
    OLSFK.Options.Deling = true;
    OLSFK.Options.Move = false;
    OLSFK.Options.Eventing = false;
    var Fn = 0;
    for (var i=OLSFK.Options.height-1; i>=0; i--)
    {
        Fn = 0;
        for (var j=0; j<OLSFK.Options.width; j++)
        {
            if (OLSFK.Options.GampMap[j+'_'+i] == 1)
            {
                Fn++;
            }
        }

        if (Fn == OLSFK.Options.width)
        {
            OLSFK.Options.deline ++;
            OLSFK.Options.Score += OLSFK.Options.ScoreNum;
            OLSFK.DelLine(i);
            i++;
        }
    }
    OLSFK.Options.Deling = false;
    OLSFK.Options.Move = true;
    OLSFK.Options.Eventing = true;
}

中执行;

减了一行,就重置该行以上有行往下降一行;并重置 :

OLSFK.Options.GampMap[x+’_’+y] =
OLSFK.Options.GampMap[x+’_’+(y-1)];

该减行为上行的数目;

if (Fn == OLSFK.Options.width)
        {
            OLSFK.Options.deline ++;
            OLSFK.Options.Score += OLSFK.Options.ScoreNum;
            OLSFK.DelLine(i);
            i++;
        }

该论断表示该行上富有格都被占据到;

回来 newRun 上,当判断消行超过几行时,即加级;

if (OLSFK.Options.curLevel <= OLSFK.Options.lineNum)
    {
        OLSFK.Random();
        //判断是否结束
        OLSFK.ChkEnd();
    }

一经级数小于配置的总级数,则进入 OLSFK.random();

安当前降方块,并擅自大成下次跌方块并预览右上角表格上;

OLSFK.ChkEnd = function() {
    var block = OLSFK.Items[OLSFK.Options.curBlock];

    if (block && OLSFK.Options.Move)
    {

        var flag = true;
        for (var i=1; i<=4; i++)
        {
            var x = block[i].x;
            var y = block[i].y;

            if (OLSFK.Options.GampMap[x+'_'+y] == 1)
            {
                flag = false;
                break;
            }
        }
    }

    if (flag )
    {
        OLSFK.draw();

        //定时往下掉
        OLSFK.Options.Timer = setTimeout(function() {
            OLSFK.play();
        }, OLSFK.Options.Levels[OLSFK.Options.curLevel]);
    } else {
        OLSFK.Options.Move = false;
        OLSFK.Options.Start = false;
        OLSFK.Options.Eventing = false;
        OLSFK.Options.Deling = false;
        Lib.Getid('spn').innerHTML = 'Game Is Over';

        Lib.Getid('dobtn').innerHTML = ' 开始 ';
    }
}

当当前暴跌的四方进入表格上产生深受占用的格子,即受堵塞,游戏了;

相反的 则 setTimeout 开始新方块的退动作;

外方法求证

OLSFK.Event = function() {
    if (window.isIE)
        return window.event;
    func = OLSFK.Event.caller; 

    while(func!=null) 
    {
        var arg0=func.arguments[0]; 
        if(arg0) 
        {
            return arg0; 
        }
        func=func.caller; 
    }
    return null; 
}

OLSFK.KeyCode = function() {
    return OLSFK.Event().keyCode || OLSFK.Event().which;
}

OLSFK.Event = function();

立是千篇一律栽获得当前风波的措施,可以于配合获取当前之事件;

俄罗斯四方 JavaScript 代码

http://files.cnblogs.com/editor/OLSFK.rar 


相关文章