安卓手机:俄罗斯方块游戏

俄罗斯方块游戏,是风靡世界几十年的经典游戏,相信绝大多数人都玩过这个游戏,那么它是怎样编写出来的,我们如何才能自己编写一个这样的游戏呢?

题目描述

Mayan puzzle是最近流行起来的一个游戏。游戏界面是一个 7 行5
列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上。游戏通关是指在规定的步数内消除所有的方块,消除方块的规则如下:

1
、每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交换位置(参见输入输出样例说明中的图6
到图7
);如果目标位置上没有方块,那么被拖动的方块将从原来的竖列中抽出,并从目标位置上掉落(直到不悬空,参见下面图1
和图2);

安卓手机 1

2
、任一时刻,如果在一横行或者竖列上有连续三个或者三个以上相同颜色的方块,则它们将立即被消除(参见图1
到图3)。

安卓手机 2

注意:

a) 如果同时有多组方块满足消除条件,几组方块会同时被消除(例如下面图4
,三个颜色为1 的方块和三个颜色为 2
的方块会同时被消除,最后剩下一个颜色为 2 的方块)。

b)
当出现行和列都满足消除条件且行列共享某个方块时,行和列上满足消除条件的所有方块会被同时消除(例如下面图5
所示的情形,5 个方块会同时被消除)。

3
、方块消除之后,消除位置之上的方块将掉落,掉落后可能会引起新的方块消除。注意:掉落的过程中将不会有方块的消除。

上面图1 到图 3
给出了在棋盘上移动一块方块之后棋盘的变化。棋盘的左下角方块的坐标为(0, 0
),将位于(3, 3 )的方块向左移动之后,游戏界面从图 1 变成图 2
所示的状态,此时在一竖列上有连续三块颜色为4
的方块,满足消除条件,消除连续3 块颜色为4 的方块后,上方的颜色为3
的方块掉落,形成图 3 所示的局面。

#include<stdio.h>

游戏开发步骤

要编写一个游戏,基本按照以下一些步骤进行:

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可以发布到各大应用市场。

最简单的发布就是直接发送给自己的朋友,让他们大吃一惊。

输入输出格式

输入格式:

 

输入文件mayan.in,共 6 行。

第一行为一个正整数n ,表示要求游戏通关的步数。

接下来的5 行,描述 7*5
的游戏界面。每行若干个整数,每两个整数之间用一个空格隔开,每行以一个0
结束,自下向上表示每竖列方块的颜色编号(颜色不多于10种,从1
开始顺序编号,相同数字表示相同颜色)。

输入数据保证初始棋盘中没有可以消除的方块。

 

输出格式:

 

输出文件名为mayan.out。

如果有解决方案,输出 n 行,每行包含 3 个整数x,y,g
,表示一次移动,每两个整数之间用一个空格隔开,其中(x
,y)表示要移动的方块的坐标,g 表示移动的方向,1
表示向右移动,-1表示向左移动。注意:多组解时,按照 x 为第一关健字,y
为第二关健字,1优先于-1
,给出一组字典序最小的解。游戏界面左下角的坐标为(0 ,0 )。

如果没有解决方案,输出一行,包含一个整数-1。

 

#include<stdlib.h>

游戏规则定义

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

棋盘由宽度为10格高度为20格的方块组成

方块共有7种形态:

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

方块出现在最上方正中间,同时知道下一个方块是什么

方块往下掉落,每隔1秒下落一行

方块下落中如果碰到有方块阻挡不能下落则停止下落

方块停止下落后,判断是否有整行都被方块填满,如果有,则整行消失,上面的全部行整体下落一行

统计消掉的总行数

方块在下落过程中,可以按向下方向键让方块直接掉落到直到停止位置

可以按向左或者向右方向键让方块进行旋转,每按键一次旋转90度

如果没有足够的空间让方块落下则游戏结束

输入输出样例

输入样例#1:

3
1 0
2 1 0
2 3 4 0
3 1 0
2 4 3 4 0

输出样例#1:

2 1 1
3 1 1
3 0 1

#include<conio.h>

游戏运行平台和界面设计

如果以最流行的苹果手机作为游戏运行环境,则需要开发一个苹果手机App

苹果手机使用的是iOS操作系统,开发环境需要Mac电脑和开发工具软件Xcode

开发语言可以使用objective-C,开发游戏可以使开发用工具包cocos2d

如果需要发布到苹果AppStore,则需要一个开发者账号,以及一年99美金

界面设计:

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

主界面分为左右部分

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

按照苹果手机尺寸320点*480点来设计,20格高度为480点,则宽度10格占用240点

因此左边棋盘占用240点,右侧剩余80点

右边分为上部和下部

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

下部为按钮栏靠下显示:从上往下显示3个按钮,排行榜/关于/重新开始

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

界面运行逻辑:

点击排行榜按钮进入一个新页面,上面显示消掉的行数最多的8个行数数字,下面是一个返回按钮

点击关于按钮进入一个新页面,上面显示一张说明图片,下面是一个返回按钮

点击重新开始按钮,将当前棋盘清空并重新开始一局游戏,游戏启动

游戏启动之后,第一个方块从最上面中间开始往下掉落,每秒下落一行

同时,上方的状态栏,显示下一个即将出现的方块类型小图标

方块下落过程中,在屏幕上单指左滑可以向左逆时针旋转当前方块,或者在屏幕上单指右滑可以向右顺时针旋转当前方块

还可以在屏幕上单指下滑可以让当前方块直接掉落到底部

方块如果不能再往下移动一行的时候,则方块停止,同时开始判断是否能够消掉某些行

如果能够消掉某些行,则统计消掉的行数,增加到上方状态栏显示消掉的数字上,刷新显示

消掉的行从屏幕上消除,同时上方的所有行往下整体移动

加入棋盘最上方中间的供方块出现的地方已经被方块占住了,则认为这一局游戏结束

游戏结束则弹出一个窗口显示游戏结束信息,显示总共消掉了多少行,然后将该记录保存到数据库中

弹出窗口上有返回按钮,点击返回按钮,弹出窗口关闭,回到游戏主界面,主界面停止游戏,点击重新开始按钮开始新一局

说明

【输入输出样例说明】

按箭头方向的顺序分别为图6 到图11

安卓手机 3

样例输入的游戏局面如上面第一个图片所示,依次移动的三步是:(2 ,1
)处的方格向右移动,(3,1 )处的方格向右移动,(3
,0)处的方格向右移动,最后可以将棋盘上所有方块消除。

【数据范围】

对于30% 的数据,初始棋盘上的方块都在棋盘的最下面一行;

对于100%的数据,0 < n≤5 。

noip2011提高组day1第3题

/*
定义的ans数组有x,y,移动方向
读入
dfs(步数)
  当步数大于n时,判断是否完全消除(),若完全消除,输出
  统计是否有数的个数已经小于3,若有,退出
  没有
    遍历所有点,当此点与右边的点不同颜色时
    加入answer
    交换
    下落(多次下落,下落消除后,继续下落)
    while(消除()) 下落()

    dfs(步数 + 1)
    回溯
*/

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <iostream>

using namespace std;
const int N = 10;

struct Node{
    int x, y, ho;
}answer[N];
int n;
int a[N][N];

inline int read()
{
    int x = 0; char c = getchar();
    while(c < '0' || c > '9')c = getchar();
    while(c >= '0' && c <= '9')x = x * 10 + c - '0', c = getchar();
    return x;
}

void drop()
{
    int num[N][N];
    memset(num, -1, sizeof(num));
    for(int i = 0; i < 5; i ++)
    {
        int h = 0;
        for(int j = 0; j < 7; j ++)
            if(a[i][j])
                num[i][h ++] = j;
    }
    for(int i = 0; i < 5; i ++)
        for(int j = 0; j < 7; j ++)
            a[i][j] = num[i][j] == -1 ? 0 : a[i][num[i][j]];
    return ;
}

bool empty()
{
    for(int i = 0; i < 5; i ++)
        for(int j = 0; j < 7; j ++)
            if(a[i][j])
                return 0;
    return 1;
}

bool clear()
{
    bool ret_flag = 0;
    for(int i = 0; i < 3; i ++)
        for(int j = 0; j < 7; j ++)
            if(a[i][j])
            {
                int x = i;
                while(x < 4 && a[i][j] == a[x + 1][j]) x ++;
                if(x - i >= 2)
                {
                    for(int xx = i; xx <= x; xx ++)
                    {
                        int up = j;
                        int dn = j;
                        while(a[xx][up + 1] == a[i][j] && up < 6) up ++;
                        while(a[xx][dn - 1] == a[i][j] && dn > 0) dn --;
                        if(up - dn >= 2)
                            for(int y_ = dn; y_ <= up; y_ ++)
                                a[xx][y_] = 0;
                    }
                    for(int x_ = i; x_ <= x;  x_ ++)
                        a[x_][j] = 0;
                    ret_flag = 1;
                }
            }
    for(int i = 0; i < 5; i ++)
        for(int j = 0; j < 5; j ++)
            if(a[i][j])
            {
                int y = j;
                while(a[i][y + 1] == a[i][j] && y < 6) y ++;
                if(y - j >= 2)
                {
                    for(int yy = j; yy <= y; yy ++)
                    {
                        int lef = i;
                        int rig = i;
                        while(a[lef - 1][yy] == a[i][j] && lef > 0) lef --;
                        while(a[rig + 1][yy] == a[i][j] && rig < 6) rig ++;
                        if(rig - lef >= 2)
                            for(int x_ = lef; x_ <= rig; x_ ++)
                                a[x_][yy] = 0;
                    }
                    for(int y_ = j; y_ <= y; y_ ++)
                        a[i][y_] = 0;
                    ret_flag = 1;
                }
            }
    if(ret_flag) return 1;
    else return 0;
}

void dfs(int tot)
{
    if(tot > n)
    {
        if(empty())
        {
            for(int i = 1; i <= n; i ++) 
            {
                if(answer[i].ho)
                    printf("%d %d %d\n", answer[i].x + 1, answer[i].y, -1);
                else
                    printf("%d %d %d\n", answer[i].x, answer[i].y, 1);
            }
            exit(0);
        }
        return ;
    }        
    int sum[N + 1];
    memset(sum, 0, sizeof(sum));
    for(int i = 0; i < 5; i ++)
        for(int j = 0; j < 7; j ++)
            sum[a[i][j]] ++;
    for(int i = 1; i <= 10; i ++)
        if(sum[i] && sum[i] <= 2)
            return ;
    for(int i = 0; i < 4; i ++)
        for(int j = 0; j < 7; j ++)
            if(a[i][j] != a[i + 1][j])
            {
                answer[tot].x = i;
                answer[tot].y = j;
                answer[tot].ho = (!a[i][j]);
                int tmp[N][N];
                memcpy(tmp, a, sizeof(tmp));
                swap(a[i][j], a[i + 1][j]);
                drop();
                while(clear()) drop();
                dfs(tot + 1);
                answer[tot].x = 0;
                answer[tot].y = 0;
                answer[tot].ho = 0;
                memcpy(a, tmp, sizeof(a));
            }
}

int main()
{
    n = read();
    for(int i = 0; i < 5; i ++)
    {
        for(int j = 0; ; j ++)
        {
            a[i][j] = read();
            if(!a[i][j]) break;
        }    
    }
    dfs(1);
    printf("-1\n"); 
    return 0;
}
/*
3
1 0
2 1 0
2 3 4 0
3 1 0
2 4 3 4 0
*/

 

#include<string.h>

编程思路和算法设计

数据存储:

考虑用二维列表来存储棋盘上的每一个格子

[[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

请看下面的示意图:

那么,顺时针旋转和这个类似,只是选择后的左上角左边变量变化,以及方块当前旋转状态值变化

#define MAXIMUS 15 //定义棋盘大小

具体代码实现

由于篇幅所限,这里只能大概描述核心的一些代码实现方式

开发准备:

首先取注册一个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秒

……

}

//定时器处理函数

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

//如果不可以下移了,则判断是否可以消除某行,如果消除了某行则上方的所有行的值整体下移一行

//如果不可以下移也不可以消除了,则将下一个方块的数值赋值给当前方块,随机数生成下一个方块

//然后判断当前方块是否可以放入棋盘最上方的中间位置,如果可以放入则修改二维列表变量,如果不能放入,则游戏结束

……

具体代码这里不贴了,有了详细的算法程序设计和数据存储类型,要实现出来并不是太难,只是需要耐心细心而已。

int p[MAXIMUS][MAXIMUS];//存储对局信息

游戏测试

游戏的主体程序完成后,就可以一边测试一边修改

测试的时候要注意测试各种边界情况,例如

将当前方块移动到最左边,看看碰到边界的时候会不会出错

将当前方块卡入一个正好插入的空槽形状中,看程序是不是会出错

等待当前方块掉入一个空槽,然后立刻旋转,理论上应该不能旋转了,测试看看程序会不会出错

测试一次性消掉4行,看看程序是不是会出错

如果自己测试的差不多了,就可以将程序打包发送给朋友测试

有时候,开发的人很难测试自己编写的程序,但是反而让别人可以测试出来很多问题

char buff[MAXIMUS*2+1][MAXIMUS*4+3];//输出缓冲器

游戏发布

下面介绍一下大概的发布流程,让大家有个初步印象,详细的发布流程网上可以搜索到很多

游戏测试到基本没有错误之后,就可以将游戏发布到苹果的AppStore了

发布App需要购买苹果的开发者账号,一年是99美金,目前用信用卡支付也很方便

然后登陆

生成好证书之后,将证书下载到Mac电脑中导入到Xcode之中

然后使用Xcode进行编译和打包好一个ipa文件

然后登陆

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

然后回到itunesconnect网站上提交App

然后就是等待苹果AppStore的审核,一般7-10个工作日可以完成审核

完成审核之后,你的App就会出现在苹果手机的AppStore里面了,就可以搜索到了

然后就可以告诉你的朋友们,让他们大吃一惊吧。

=

int Cx,Cy;//当前光标位置

int Now;//当前走子的玩家,1代表黑,2代表白

int wl,wp;//当前写入缓冲器的列数和行数位置

char* showText;//在棋盘中央显示的文字信息

int count;//回合数

char* Copy(char* strDest,const char*
strSrc)//修改过的字符串复制函数,会忽略末端的\0

{

char* strDestCopy = strDest;

while (*安卓手机:俄罗斯方块游戏。strSrc!=’\0′)

{

*strDest++=*strSrc++;

}

return strDestCopy;

}

void Initialize()//初始化一个对局函数

{

int i,j;//循环变量

showText=””;//重置显示信息

count=0;//回合数归零

for(i=0;i

{

for(j=0;j

{

p[i][j]=0;

}

}

Cx=Cy=MAXIMUS/2;//重置光标到中央

Now=1;//重置当前为黑方

}

char* getStyle(int i,int
j)//获得棋盘中指定坐标交点位置的字符,通过制表符拼成棋盘

{

if(p[i][j]==1)//1为黑子

return “●”;

else if(p[i][j]==2)//2为白子

return “○”;

else if(i==0&&j==0)//以下为边缘棋盘样式

return “┏”;

else if(i==MAXIMUS-1&&j==0)

return “┓”;

else if(i==MAXIMUS-1&&j==MAXIMUS-1)

return “┛”;

else if(i==0&&j==MAXIMUS-1)

return “┗”;

else if(i==0)

return “┠”;

安卓手机:俄罗斯方块游戏。else if(i==MAXIMUS-1)

return “┨”;

else if(j==0)

return “┯”;

else if(j==MAXIMUS-1)

return “┷”;

return “┼”;//中间的空位

}

char* getCurse(int i,int
j){//获得指定坐标交点位置左上格的样式,通过制表符来模拟光标的显示

if(i==Cx){

if(j==Cy)

return “┏”;

else if (j==Cy+1)

return “┗”;

}

else if(i==Cx+1)

{

if(j==Cy)

return “┓”;

else if (j==Cy+1)

return “┛”;

}

return “ ”;//如果不在光标附近则为空

}

void write(char* c)//向缓冲器写入字符串

{

Copy(buff[wl]+wp,c);

wp+=strlen(c);

}

void ln()//缓冲器写入位置提行

{

wl+=1;

wp=0;

}

void Display()//将缓冲器内容输出到屏幕

{

int i,l=strlen(showText);//循环变量,中间文字信息的长度

相关文章