65.9K
CodeProject 正在变化。 阅读更多。
Home

适用于平板电脑和智能手机的益智游戏

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (34投票s)

2012 年 6 月 15 日

BSD

5分钟阅读

viewsIcon

66611

downloadIcon

5165

本文介绍如何使用 Moscrif SDK 创建拼图游戏。

目录

引言

拼图是一款适合所有年龄段的简单游戏。游戏的目标是将正确的拼图块放入正确的形状中。每个人在现实生活中都有玩拼图的机会,但手机上的拼图游戏并不多。尽管如此,这款游戏既可以作为儿童独立的娱乐游戏,也可以作为极佳的营销工具。

在本文中,我们希望向您展示如何使用单一代码为多个移动平台创建这款游戏。

背景

为了克服平台差异,我们将使用Moscrif SDK(开源项目免费可用)。该 SDK 配备了面向对象的 JavaScript 和一个易于学习的开源框架。该 SDK 还包含发布工具,可生成原生安装文件。

关于游戏

我们的游戏适用于屏幕分辨率大于 600x900px 的运行 iOS 和 Android 的平板电脑及其他设备。我已在 Amazon Kindle Fire、Galaxy Tab、Nook Color、iPad 2 和 iPhone 4 上进行了测试。

在此案例中,我们将鳄鱼设计为拼图目标,因此每个拼图块都必须放入正确的形状中,才能显示鳄鱼的图片。这款拼图游戏可以以多种方式实现。出于营销目的,您可以使用公司徽标、产品照片等。

用户界面

在开发应用程序时,我们的目标是创建一个简单的用户界面,为用户提供最佳体验。

图 1:用户界面

用户体验

最近,移动行业越来越重视用户体验,因为程序员发现只有用户友好的应用程序才能成功。这意味着应用程序必须按照用户的直觉进行操作,同时保持响应灵敏和流畅。为了实现这种体验,部件可以随着手指的移动而平滑移动,当某个部件靠近其所属位置时,它会自动吸附过去。 

开发流程

使用 Moscrif SDK 可以节省大量时间,因为我们不必为每个平台创建三个独立的应用程序。我们将只创建一个代码,并将其发布到所有目标平台。

为了创建这款游戏,需要解决三个任务。第一个任务是部件分配算法,它需要在游戏开始时进行。在游戏过程中,还需要完成另外两个任务才能使之成为一个好的拼图游戏:部件拖动部件吸附

部件分配

重置功能

当用户点击屏幕或每次用户按下刷新按钮时,所有拼图块都会随机放置在游戏区域。每个拼图块的位置会单独确定。

代码示例 1: 重置功能 - 为每个拼图块调用 _findPosition

/**
Function sets objects to the init state.
*/
function restart()
{
    // go throw all objects in this._parts array
    for (var part in this._parts) {
        part.isOnPlace = false;
        // find new position for this part
        this._findPosition(part);
    }
    this._onPlace = 0;
    this._pulseButtons();
}

函数 _findPosition

函数 _findPosition 更有趣,因为它会循环运行,直到为该特定拼图块找到正确的位置。此循环的每次运行都会生成一个新的随机位置,然后检查它是否与另一个已放置的拼图块重叠。但是,在某些情况下,如上所述的循环可能会永远运行。为防止此严重错误,我们添加了一个计数器属性和最大循环重复次数。

图 2:流程图 - _findPosition

示例代码 2:函数 _findPosition 为拼图块找到合适的位置

/**
Part is set on new position.
@param part Part
*/
function _findPosition(part)
{
    //Helper function
    function random(from, to) { return from + rand(to-from+1); }
 
    // number of while runnings.
    var counter = 0;
    while (counter < 100/*Max repeats*/ ) {
        counter ++;
        //Set random position on axis y.
        part.y = random(part.height/2,System.height-part.height/2);
        //If y coordinate is over crocodile
        if (part.y+part.height/2 < this._finalTop)
            part.x = random(part.width/2, System.width - part.width/2);
        else {
            //Choose one from two areas (left or right from crocodile).
            var area = rand(2);
            if (area == 0)
                part.x = random(part.width/2, this._finalLeft-part.width/2);
            else
                part.x = random(this._finalLeft + this._final.width,
                                        System.width-part.width/2);
        }
        //Check if parts overlay.
        var collision = false;
        for (var p in this._parts) {
            if (part.intersectsBounds(p)) {
                collision = true;
                break;
            }
        }
        //If they do not overlay, it jumps from while loop.
        if (!collision)
            break;
    }
}

部件拖动

平滑的部件拖动对于提供愉快的用户体验至关重要。当用户点击一个拼图块时,手指移动会改变拼图块的位置。

示例代码 3:函数 _getPart - 在点击位置查找拼图块。

/**
Return part by coordinates.
@param x Integer Position on x axis.
@param y Integer Position on y axis.
@return Part
*/
function _getPart(x, y)
{
    //Auxiliary variable remembers picture located on position x y.
    //init state is nothing
    var searchPart = #nothing;
 
    //search image located on position x y
    for (var part in this._parts) {
        if (part.intersectsPoint(x, y))
            searchPart = part;
    }
 
    //If image is found on that position.
    if (searchPart != #nothing) {
        //set relative position
        searchPart.relX = searchPart.x - x;
        searchPart.relY = searchPart.y - y;
 
        //Move up
        this._moveUp(searchPart);
    }
 
    return searchPart;
}

示例代码 4:函数 pointerDragged - 在 pointer-dragged 事件中更改部件位置

/**
Event fired at pointer-dragged.
@param x Integer Position on x axis
@param y Integer Position on y axis
*/
function pointerDragged(x, y)
{
    super.pointerDragged(x, y);
    if (this._catchImage != #nothing) {
        this._catchImage.x = x;
        this._catchImage.y = y;
        this._catchImage.push(this);
    }
}

部件吸附

吸附是另一个提供良好用户体验的功能。当用户拖动部件时,应用程序会计算其与所属位置的距离。如果距离小于 System.width / 38,它将自动吸附到其位置。

示例代码 5:函数 push - 计算与所属位置的距离

/**
Check distance from location where part should be. If it is too close move it to the right place.
@param sender Object
*/
function push(sender)
{
    //Calculate the distance from the position
    //where the image should be placed
    // |draw, loc|
    var sizeX = Math.pow((this.locX + this.width/2) - this.x,2);
    var sizeY = Math.pow((this.locY + this.height/2) - this.y,2);
    var size  = Math.sqrt(sizeX + sizeY);
 
    //If the distance is smaller than constant
    if (size < System.width / 38) {
        //Set picture location on the right position.
        this.x = this.locX + this.width/2 - this.relX;
        this.y = this.locY + this.height/2 - this.relY;
        //If picture wasnt on the right position.
        if (!this.isOnPlace) {
            //Increment variable, which remember count of picture, which are on right position.
            sender._onPlace++;
            this.isOnPlace = true;
        }
    //Picture was on right position, but he is not anymore.
    } else if (this.isOnPlace) {
        sender._onPlace--;
        this.isOnPlace = false;
    }
}
图 3:吸附区域

正如您在上一个示例中看到的,如果一个部件吸附到其位置,_onPlace 变量将增加。_victory 方法会检查所有部件是否都吸附到其位置(_onPlace == 部件数量)。如果 _victory 方法返回 true,则会绘制最终图像的位图。

总结

现在您知道如何创建自己的拼图游戏以及需要哪些功能才能使游戏令人愉快并提供更友好的用户体验。是的,是的,我们知道游戏非常基础,但它是为了学习目的而制作的,应该作为您下一个出色应用程序的基础。正如我们之前提到的,将这样的游戏集成到您现有的业务应用程序中将提高品牌知名度和客户参与度。除此之外,别忘了这款游戏是用面向对象的 JavaScript 制作的,可以在三个平台(iOS、Android 和 Bada)以及平板电脑和智能手机上运行。祝您编码愉快!

更多资源

有关 Moscrif 的更多示例、演示和信息,请访问其主页:www.moscrif.com

© . All rights reserved.