存档

2014年3月 的存档

【cocos2d-x 仙凡奇缘-网游研发(2) 角色换线系统】

2014年3月31日 没有评论

转载请注明出处:http://www.cnblogs.com/zisou/p/xianfan01.html

一款游戏就先得制作好策划文档,和基本的人物世界构架的设计,然后架空在这样一个虚拟的世界中每一个环节都需要考虑到。

这些设计节点,都是环环相扣,相互影响依赖的关系;那么我想让我认识的同学,朋友一起相约到游戏世界中,并且能看到他和

他做交互呢?仙凡游戏的定义就是一款弱联网的游戏(HTTP为主要连接方式),那么弱联网怎么做这样一个交互非常强得功能呢?

看似不可能,不过作为手游,一切可以从简接近去模仿那种效果;

仙凡奇缘这款游戏的角色系统主要有这样一些功能:

人物基本信息

1,角色名称,性别,级别,称谓,账户ID,血,蓝,攻击,防御,攻速,经验值,移动速度;

2,技能ID(4个3个基本,一个必杀技),乘骑状态,坐骑ID,法宝ID,防具ID,首饰ID,背包格子数;

3,人物坐标,所在地图ID,所在地图坐标,场景名称等;

有很多没有列举出来,多达几十个字段的人物信息表,人物属性现在非常清晰了,每个字段都有它的功能;

详细说一下我自己对服务器端设计的架构:

1,服务器提供.aspx的post请求页面;由于C#有强大的托管机制,可以请求过程中运用反射+工厂

给服务器减轻了多人请求复杂数据,查询SQL速度快带来的优越;

【cocos2d-x 仙凡奇缘-网游研发(2) 角色换线系统】

2,socket辅助,提供心跳连接,和发送部分即使消息;

【cocos2d-x 仙凡奇缘-网游研发(2) 角色换线系统】

 

客户端通过http登陆后,会建立一个强连接socket连接我们的sockeserver服务器端,只是保持心跳,服务器,会一直

发送客户端心跳信息;实际上这块功能只是出发一些即时消息使用,如果玩家断线,失去连接,照样可以玩游戏,因为

主要通信还是http处理的主要业务;

看一个登陆模块的服务器代码,我在mac上用的是MonoDevelop开发环境,来开发服务器:

【cocos2d-x 仙凡奇缘-网游研发(2) 角色换线系统】

 

客户端创建角色:

【cocos2d-x 仙凡奇缘-网游研发(2) 角色换线系统】

【cocos2d-x 仙凡奇缘-网游研发(2) 角色换线系统】

ok,这就是基本创建角色部分;在之后进入游戏之后玩家就需要登陆了,登陆进入游戏前已经拿到了人物信息;

接下来就是进入场景之后,需要同步一次玩家(只同步一次即可),不需要玩家每一次的操作都去同步,那样

HTTP根本做不到,那么我们就把这个模拟出来,客户端同步其他玩家时,拿到其他玩家,在服务器上最后一次

切场景的坐标,然后进行本地客户端的AI操作,进行简单的移动即可;

部分代码如下:

【cocos2d-x 仙凡奇缘-网游研发(2) 角色换线系统】【cocos2d-x 仙凡奇缘-网游研发(2) 角色换线系统】

void Maps_XianFanTing::UpdataPlayerList(float time)
{
    CCPoint randomrange = ccp(100,30);
    CCPoint randomrange2 = ccp(169,139);
    vector<MainRoledata> rolelist = GlobalInfo::getInstance()->get_playerlist();
    for (int i = ROLE_PLAYERLIST; i <ROLE_PLAYERLIST+rolelist.size(); i++)
    {
        int add_x = (int)(CCRANDOM_MINUS1_1()*randomrange.x);
        int add_y =(int)(CCRANDOM_MINUS1_1()*randomrange.y);
        float acttodo = CCRANDOM_MINUS1_1();
        CCPoint npc_nowp =randomrange2;
        CCPoint role_move_pc = ccp(npc_nowp.x+add_x,npc_nowp.y+add_y);//此处需要通过地图的视角把人物移动的坐标转化一下。
        if(this->getChildByTag(i)!=NULL)
        {
            if(acttodo>0)
            {
                this->getChildByTag(i)->setZOrder(100);
                SpiritsPlayer::movemethod_Sp((CCSprite*)this->getChildByTag(i),3,role_move_pc,rolelist.at(i-ROLE_PLAYERLIST));
            }
            else
            {
                this->getChildByTag(i)->setZOrder(99);
            }
        }
    }
}

void Maps_XianFanTing::MapUserListState(float time)
{
    //加载其他玩家列表
    if(GlobalInfo::getInstance()->getInstance()->get_mapuserlistflag()==true)
    {
        CCPoint randomrange = ccp(100,30);
        CCPoint randomrange2 = ccp(169,139);
        if(GlobalInfo::getInstance()->get_mapuserlistjsonlist().length()>0)
        {
            vector<MainRoledata> rolelist = JsonPush::ToGetRoleListdata(GlobalInfo::getInstance()->get_mapuserlistjsonlist());
            vector<MainRoledata> oldrolelist = GlobalInfo::getInstance()->get_playerlist();
            
            if(oldrolelist.size()>0)
            {
                for (int i = 0; i < oldrolelist.size(); i++)
                {
                    if(this->getChildByTag(ROLE_PLAYERLIST+i)!=NULL)
                    {
                        this->removeChildByTag(ROLE_PLAYERLIST+i);
                    }
                }
            }
            if(rolelist.size()>0)
            {
                for (int i = 0; i < rolelist.size(); i++)
                {
                    
                    SpiritsPlayer* roles = new SpiritsPlayer(rolelist.at(i),1);
                    int add_x = (int)(CCRANDOM_MINUS1_1()*randomrange.x);
                    int add_y =(int)(CCRANDOM_MINUS1_1()*randomrange.y);
                    roles->npc->setPosition(ccp(randomrange2.x+add_x,randomrange2.y+add_y));
                    this->addChild(roles->npc,99,ROLE_PLAYERLIST+i);
                }
            }
            GlobalInfo::getInstance()->set_playerlist(rolelist);
        }
        GlobalInfo::getInstance()->set_mapuserlistflag(false);
    }
}

View Code

效果:玩家可以做简单的移动,模仿出了玩家都在线的感觉就行;

【cocos2d-x 仙凡奇缘-网游研发(2) 角色换线系统】

换线的思路是在服务器中建立一个地图的分线表,里面的字段只有人物ID和地图ID和所在线ID,如果达到同屏,那就

在换线的时候,切换自己的线的ID,然后同步一次其他玩家数据(同步和自己所在一个线ID)的玩家,客户端做相应

的刷新,同步操作!

 

【cocos2d-x 仙凡奇缘-网游研发(2) 角色换线系统】

刚才我们看到1线人是非常多的,而且服务器根本不可能给我们提供所有玩家同屏信息,那么我约好一个朋友去2线;

就可以同屏看到我的小伙伴了,效果如下图:

【cocos2d-x 仙凡奇缘-网游研发(2) 角色换线系统】

上图可以清晰看到,我成功换到了2线,并且服务器给我同步了一次玩家操作,我来到2线后就可以看到想找的小伙伴!

这一篇大概介绍了一下制作这个游戏角色系统功能的详细方法和思路,其实这样看上去弱联网的游戏也能有非常好的

效果,下一篇我会说一下,弱联网情况下聊天制作,聊天同步的操作;

ps:仙凡奇缘官网 http://www.xianfancoco.com

仙凡奇缘开发版1.0已上线:百度云盘下载体验

cocos2dxQQ交流群:41131516
   

分类: 未分类 标签:

Quick-Cocos2d-X 捋一捋框架流程

2014年3月24日 没有评论

猴子原创,欢迎转载。转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢!

原文地址: http://www.cocos2dev.com/?p=535

一直比较关注Quick Lua,但是项目中一直使用的公司自有的Lua框架,所以一直没机会在实际中使用下Quick Lua。看到群里很多人都在用这个,我在这里梳理下开始使用的流程吧,我主要是说下实际使用上的流程问题。

比如很多学习者甚至不知道enterScene("MainScene") 为什么里面可以是个字符串?当然如果你已经很熟悉框架了,这篇文章就可以跳过了,呵呵。

下面开始吧!

一、前置准备
1、安装下载之类的,官方论坛写的很清楚了,我就不说了。http://wiki.quick-x.com/doku.php?id=zh_cn:get_started_create_new_project
2、关于IDE,我使用的IEDA,配置导出的api代码提示,还是挺方便的。http://wiki.quick-x.com/doku.php?id=zh_cn:get_started_install_intellij_idea

二、新建一个工程

新建之后,你首先看到的main.lua启动到MyApp.lua。

require("app.MyApp").new():run()

看MyApp.lua文件:
1、require("app.MyApp")
这里执行的MyApp.lua的代码是:

local MyApp = class("MyApp", cc.mvc.AppBase)  -- 继承cc.mvc.AppBase
return MyApp

这时候,你得到了MyApp这个类(lua关于类的实现网上很多)。

2、require("app.MyApp").new()

MyApp.new()执行后,执行的代码是:

function MyApp:ctor()
    MyApp.super.ctor(self)
end

为什么new()了之后会执行MyApp:ctor()?请看function.lua下的function class(classname, super)方法:

function cls.new(...)
            local instance = cls.__create(...)
            -- copy fields from class to native object
            for k,v in pairs(cls) do instance[k] = v end
            instance.class = cls
            instance:ctor(...)
            return instance
end


可以看到,在class的实现方法里面,给每个创建的类声明了一个new()方法,方法里面调用了ctor()构造方法(ctor只是个名字,所以不是有些人认为的new了之后,当然会调用构造方法,lua没有类,只是我们模仿了类)

3、require("app.MyApp").new():run()

这时候调用了

function MyApp:run()
    CCFileUtils:sharedFileUtils():addSearchPath("res/")
    self:enterScene("MainScene")
end


所以进到了MainScene.lua。

对于MyApp.lua文件,如果我修改成下面的样子,是不是你就理解了上面所做的事情:
 

-- 声明类
MyApp = class("MyApp", cc.mvc.AppBase) 


--- 类构造方法
--
function MyApp:ctor()
    MyApp.super.ctor(self)
end


--- 对应cpp版的static create()方法
--
function MyApp:create()
    local myApp = MyApp.new()
    myApp:init()
end


--- 你自己的方法
-- @param self 
--
local function launchMainScene(self)
    CCFileUtils:sharedFileUtils():addSearchPath("res/")
    self:enterScene("MainScene")
end


--- init 方法
--
function MyApp:init()
    -- add code here
    launchMainScene(self)
end

对应的main.lua将原来的require("app.MyApp").new():run()

修改为:

require("app.MyApp")
MyApp:create()


这样你是不是更容易理解了,哈哈。

三、MainScene.lua
enterScene("MainScene") 为什么可以切换场景?
我们看下MyApp的父类AppBase里面:

function AppBase:enterScene(sceneName, args, transitionType, time, more)
    local scenePackageName = self. packageRoot .. ".scenes." .. sceneName
    local sceneClass = require(scenePackageName)
    local scene = sceneClass.new(unpack(totable(args)))
    display.replaceScene(scene, transitionType, time, more)
end

 

这样你能理解了为什么连require文件都没有就能调用MainScene,当然你要留意下,它require时候的文件路径,scene默认写的app/scenes文件夹

好了,其他的应该按照上面的思路基本都能知道为什么了。我就不一一列举了。

分类: cocos2d, cocos2d-lua 标签:

Cocos2d-x 添加iOS7默认分享/AirDrop

2014年3月22日 没有评论

猴子原创,欢迎转载。转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢!

原文地址: http://www.cocos2dev.com/?p=530

Cocos2d-x 添加iOS7默认分享/AirDrop


下午添加分享的时候,看着这么多第三方sdk,我还是喜欢ios7默认的分享功能,简洁大方。它也能显示你已安装的社交app。

下面我说下如何在cocos2dx里面使用。

下面是封装好的IOSShareManager.h/m ,这个是一个oc单例类,负责调用分享和保存rootViewController。代码很少,看注释就可以了明白了。

IOSShareManager.h


//
//  IOSShareManager.h
//  IOS7ShareSample
//
//  Created by LiuYanghui on 14-3-22.
//
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface IOSShareManager : NSObject

+ (IOSShareManager *) getInstance;
- (void)share:(CGPoint)pos;

@property (nonatomic, readwrite, retain) id viewController;

@end

IOSShareManager.m

//
//  IOSShareManager.m
//  IOS7ShareSample
//
//  Created by LiuYanghui on 14-3-22.
//
//

#import "IOSShareManager.h"

@interface IOSShareManager()
@property (strong, nonatomic) UIPopoverController *activityPopover;
@end

@implementation IOSShareManager

+ (IOSShareManager *) getInstance
{
    static IOSShareManager* gameMgr = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        gameMgr = [[self alloc] init];
    });
    return gameMgr;
}

- (void)share:(CGPoint)pos
{
    // 你可以先截屏保存到document下,这里的image读取document下面。
    UIImage *image = [UIImage imageNamed:@"HelloWorld.png"];
    NSString *mesg = @"You can add some description info here!";

    UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[image, mesg] applicationActivities:nil];

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        //iPhone 从底部向上滑出view
        [self.viewController presentViewController:activityViewController animated:YES completion:nil];
    } else {
        //iPad, 弹出view
        if (![self.activityPopover isPopoverVisible]) {
            self.activityPopover = [[UIPopoverController alloc] initWithContentViewController:activityViewController];
            [self.activityPopover presentPopoverFromRect:CGRectMake(pos.x, pos.y, 0, 0) inView:((UIViewController *)self.viewController).view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
        } else {
            //Dismiss view,当重复点击时
            [self.activityPopover dismissPopoverAnimated:YES];
        }
    }
}

- (id)init
{
    self = [super init];
    if (self) {
        // init code here

    }
    return self;
}

- (void) dealloc
{
    [super dealloc];
}

@end


上面的是oc的类,下面添加中间层接口,供cpp调用。IOSShare.h/mm 就是我们需要添加的中间层类方法。

IOSShare.h

//
//  IOSShare.h
//  IOS7ShareSample
//
//  Created by LiuYanghui on 14-3-22.
//
//

#ifndef __IOS7ShareSample__IOSShare__
#define __IOS7ShareSample__IOSShare__

class IOSShare {
public:

/*! @brief share
 *
 * 显示分享view,如果是ipad,则从设置位置弹出view
 * @param posX
 * @param posY
 */
    static void share(float posX, float posY);
};

#endif /* defined(__IOS7ShareSample__IOSShare__) */

IOSShare.mm

//
//  IOSShare.cpp
//  IOS7ShareSample
//
//  Created by LiuYanghui on 14-3-22.
//
//

#include "IOSShare.h"
#import "IOSShareManager.h"

void IOSShare::share(float posX, float posY)
{
    [[IOSShareManager getInstance] share:CGPointMake(posX, posY)];
}


ok,下面就是如何使用。

第一步:设置IOSShareManager 的rootViewController。
请在AppController.mm,添加:#import “IOSShareManager.h”, 并在下面函数中设置IOSShareManager 的rootViewController

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{
    // ....
    [[IOSShareManager getInstance] setViewController:viewController];
}


第二步:cpp中调用分享,参数坐标当在ipad下的时候,以该坐标为弹出点,弹出分享视图。

IOSShare::share(300, 300);


分类: 未分类 标签:

cocos2d-x-3.0 draw vs onDraw

2014年3月21日 没有评论

I’m using cocos2d-x v3.0 and in some test project I’m doing some custom drawing by overriding Node‘s draw method, but in the DrawPrimitives example provided they do something like this:

void DrawPrimitivesTest::draw()
{
    _customCommand.init(_globalZOrder);
    _customCommand.func = CC_CALLBACK_0(DrawPrimitivesTest::onDraw, this);
    Director::getInstance()->getRenderer()->addCommand(&_customCommand);
}

void DrawPrimitivesTest::onDraw()
{
    // drawing code here, why?
}

From reading the header and source files it seems like this may be some way of sending render commands straight to the renderer, is that correct?

Should I be using this method to do custom drawing? What’s the difference between draw an onDraw?

EDIT:

As @Pedro Soares mentioned, since Cocos2D-X 3.0 you can’t override draw() anymore. you have to use draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) instead.

In future, cocos2d-x 3.x renderer will be multithreaded with command pool.

draw method called by visit method, to create new command. When command is performed by command pool, onDraw is called. At this moment, commands are performed in single thread, but in overloaded onDraw method you should assume, that it will be called in another thread to simplify future migration.

There is sample on cocos2d-x RC0 package that shows how to use the DrawPrimitives on top of other layers.

On your Layer .h add the following:

private:
    void onDrawPrimitives(const kmMat4 &transform, bool transformUpdated);
    CustomCommand _customCommand;

Now in the cpp of the Layer, override the layer draw method and include the onDrawPrimitives method:

void MyLayer::onDrawPrimitives(const kmMat4 &transform, bool transformUpdated)
{
    kmGLPushMatrix();
    kmGLLoadMatrix(&transform);

    //add your primitive drawing code here
    DrawPrimitives::drawLine(ccp(0,0), ccp(100, 100));
}

void MyLayer::draw(Renderer *renderer, const kmMat4& transform, bool transformUpdated)
{
    _customCommand.init(_globalZOrder);
    _customCommand.func = CC_CALLBACK_0(MyLayer::onDrawPrimitives, this, transform, transformUpdated);
    renderer->addCommand(&_customCommand);
}

I use draw method for debugDraw Like this It may be helpful

void HelloWorld::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
    Layer::draw(renderer, transform, flags);
    Director* director = Director::getInstance();
    GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION );
    director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    world->DrawDebugData();
    director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}

The draw() expression should be the same as the base class function.
The draw method of Node for cocos 3.3rc is:
virtual void draw(Renderer *renderer, const Mat4& transform, uint32_t flags);

分类: stackoverflow精选, unity3d 标签:

Cocos2d-x 3.0 开发(十七)使用Cocos2d-x 3.0rc,一条命令打包Android

2014年3月15日 没有评论

1、目录改动

每个版本都会有目录变动,这次的版本也不例外。最显眼的就是,在文件的根目录中增加了一个名为setup.py的配置文件。运行它可以配置系统的一些环境变量。

2、创建项目

新的版本我们来动手创建一个新项目吧。找到tools文件夹….额 打包的那个名为create-project.py的文件似乎木有了!原来,在新版本中,创建新项目已经可以通过命令行来创建了,相对于先前版本的图形界面,命令行更简洁。我们要在setup.py中设置参数。以mac平台为例,我们进入到对应目录,运行脚本setup.py:

Setting up cocos2d-x...

-> Adding COCOS2D_CONSOLE_ROOT environment variable... OK
-> Added: COCOS_CONSOLE_ROOT = /Users/fansy/Documents/cocos2d-x-3.0rc0/tools/cocos2d-console/bin

-> Looking for NDK_ROOT envrironment variable... FOUND

-> Looking for ANDROID_SDK_ROOT envrironment variable... NOT FOUND
Please enter its path (or press Enter to skip): /Users/fansy/lib/android-sdk-macosx 
ADDED
  -> Added: ANDROID_SDK_ROOT = /Users/fansy/lib/android-sdk-macosx
  -> Looking for ANT_ROOT envrironment variable... NOT FOUND
Please enter its path (or press Enter to skip): /Users/fansy/Documents/ant-1.9.3/bin
ADDED
-> Added: ANT_ROOT = /Users/fansy/Documents/ant-1.9.3/bin

Set up successfull:
ANT_ROOT was added into /Users/fansy/.bash_profile

Please execute command: "source /Users/fansy/.bash_profile" to make added system variables take effect

显然,我们在这里设置了cocos2dx命令行的路径,android_sdk的路径,ant_root的路径。这些路径都是打Android包需要使用的。接下来我们运行:

source ~/.bash_profile

这样就可以将变量配置到bash_profile中。接下来我们就可以创建项目了,这里使用了一个cocos new命令,有点像c++的分配一块内存 哈 触控的程序员兄弟挺幽默呢。

localhost:~ fansy$ cocos new
Runing command: new
usage: cocos new [-h] [-p PACKAGE_NAME] -l {cpp,lua,js} [-d DIRECTORY]
             [-t TEMPLATE_NAME] [--no-native]
             [PROJECT_NAME]
cocos new: error: argument -l/--language is required
localhost:~ fansy$ cocos new HelloNew2dx -p com.fansy.hello -l cpp -d ~/Documents/Code/
Runing command: new
> Copy template into /Users/fansy/Documents/Code/HelloNew2dx
> Copying cocos2d-x files...
> Rename project name from 'HelloCpp' to 'HelloNew2dx'
> Replace the project name from 'HelloCpp' to 'HelloNew2dx'
> Replace the project package name from 'org.cocos2dx.hellocpp' to 'com.fansy.hello'

这样我们的项目就创建好了。

3、打包运行

进入项目目录,我们可以直接运行"cocos run"命令行,在各平台上运行。

localhost:~ fansy$ cd ~/Documents/Code/HelloNew2dx/
localhost:HelloNew2dx fansy$ cocos run 
Runing command: compile
The target platform is not specified.
You can specify a target platform with "-p" or "--platform".
Available platforms : win32, android, ios, mac, linux
localhost:HelloNew2dx fansy$ cocos run -p ios

命令通过“-p”来设置平台,设置成ios的话,在一段编译的信息后,会自动打开模拟器。

......blablabla......
** BUILD SUCCEEDED **

build succeeded.
Runing command: deploy
Deploying mode: debug
Runing command: run
starting application
running: '/Users/fansy/Documents/cocos2d-x-3.0rc0/tools/cocos2d-console/bin/../plugins/project_run/bin/ios-sim launch /Users/fansy/Documents/Code/HelloNew2dx/bin/debug/ios/HelloNew2dx.app &'

localhost:HelloNew2dx fansy$ 2014-03-15 19:08:35.432 HelloNew2dx iOS[1522:80b] cocos2d: surface size: 960x640

cocos2d: 
{
    cocos2d.x.version: 3.0-rc0
    cocos2d.x.compiled_with_gl_state_cache: true
    cocos2d.x.build_type: DEBUG
    gl.supports_vertex_array_object: true
    cocos2d.x.compiled_with_profiler: false
    gl.renderer: Apple Software Renderer
    gl.vendor: Apple Computer, Inc.
    gl.max_texture_size: 4096
    gl.max_samples_allowed: 4
    gl.version: OpenGL ES 2.0 APPLE-9.2.1
    gl.supports_S3TC: false
    gl.supports_ATITC: false
    gl.supports_ETC1: false
    gl.max_texture_units: 8
    gl.supports_PVRTC: true
    gl.supports_NPOT: true
    gl.supports_discard_framebuffer: true
    gl.supports_BGRA8888: false
}


libpng warning: iCCP: known incorrect sRGB profile

然后就是我们熟悉的日志了。

Cocos2d-x 3.0 开发(十七)使用Cocos2d-x 3.0rc,一条命令打包Android

接下来测试Android打包。同样运行“cocos run”。会打出debug的apk,并自动连接到设备上。

localhost:HelloNew2dx fansy$ cocos run -p android -j 4
Runing command: compile
Building mode: debug
building native
The Selected NDK toolchain version was 4.7 !

......blablabla..........
BUILD SUCCESSFUL
Total time: 4 seconds
Move apk to /Users/fansy/Documents/Code/HelloNew2dx/bin/debug/android
build succeeded.
Runing command: deploy
Deploying mode: debug
installing on device
running: '/Users/fansy/lib/android-sdk-macosx/platform-tools/adb uninstall com.fansy.hello'

- waiting for device -

这时我们打开android模拟器,或连接真机,即可安装运行我们的apk了。

4、遇到的小问题

我运行Android模拟器时黑屏,查看logcat显示:

E/libEGL  (  331): called unimplemented OpenGL ES API

目测是openGL调用的问题。我又连接真机,发现可以运行,估计有可能是模拟器配置的问题?希望有知道的童鞋留言告诉我。

另外在win32平台上运行setup.py报错该问题是由于python的版本引起的,将python版本从3.3更改到2.7可以修复

C:/OutFile/cocos2d-x-3.0rc0>python setup.py
  File "setup.py", line 114
    print 'Warning: Could not add "%s" into registry' % key
                                                    ^
SyntaxError: invalid syntax

我看了一下代码,似乎是取注册表时出问题了。

def _set_environment_variable_win32(self, key, value):

    import _winreg
    try:
        env = None
        env = _winreg.OpenKeyEx(_winreg.HKEY_CURRENT_USER,
                            'Environment',
                            0,
                            _winreg.KEY_SET_VALUE | _winreg.KEY_READ)
        _winreg.SetValueEx(env, key, 0, _winreg.REG_SZ, value)
        _winreg.FlushKey(env)
        _winreg.CloseKey(env)

    except Exception:
        if env:
            _winreg.CloseKey(env)
        print 'Warning: Could not add "%s" into registry' % key
        return False
    return True

我的环境是win7 64位。已关360,管理员权限运行也无效,不知是怎么回事。可能是我注册表比较诡异?也希望知道如何解决这个问题的童鞋留言~

    本篇博客出自阿修罗道,转载请注明出处,禁止用于商业用途:http://blog.csdn.net/fansongy/article/details/21297445 

分类: 未分类 标签:

ARC semantic issue “multiple methods named 'setRotation' ” while archiving only

2014年3月14日 没有评论

My project in cocos2dv3 is throwing ARC Sematic Issue
Multiple methods named ‘setRotation:’ found with mismatched result, parameter type or attributes
while archiving(release mode). It runs fine while deploying to simulator/device (debug mode).
In release mode compiler gets confused between the implementation of rotation in UIRotationGestureRecognizer and CCNode.
When I got the error in CCBAnimationManager.m , I typecasted the object calling the selector setRotation to (CCNode*) but then the error crept up in CCActionInterval. I’m hoping there is a better solution than typecasting everywhere in cocos2d library.

What am i doing wrong?
Thankyou for your time.

EDIT

@interface CCAction : NSObject <NSCopying> {
    id          __unsafe_unretained _originalTarget;
    id          __unsafe_unretained _target;
    NSInteger   _tag;
}
@property (nonatomic,readonly,unsafe_unretained) id target;
@property (nonatomic,readonly,unsafe_unretained) id originalTarget;
@property (nonatomic,readwrite,assign) NSInteger tag;

in

CCAction.m
@synthesize tag = _tag, target = _target, originalTarget = _originalTarget;


-(void) startWithTarget:(id)aTarget
{
    _originalTarget = _target = aTarget;
}

-(void) startWithTarget:(id)aTarget
{
    _originalTarget = _target = aTarget;
}

Class Hierarchy

@interface CCActionFiniteTime : CCAction <NSCopying> 
@interface CCActionInterval: CCActionFiniteTime <NSCopying>
@interface CCBRotateTo : CCActionInterval <NSCopying>

CCBRotateTo.m {

   -(void) startWithTarget:(CCNode *)aTarget
   {
      [super startWithTarget:aTarget];
      startAngle_ = [self.target rotation];
      diffAngle_ = dstAngle_ - startAngle_;
   }

   -(void) update: (CCTime) t
   {
      [self.target setRotation: startAngle_ + diffAngle_ * t];
   }

}

update your cocos2dv3 to latest (RC4 for now).

I was using Xcode 5.0 and cocos2dv3 RC1 with no problem.
But updating Xcode to 5.1 I had this problem.
So I updated the cocos2dv3 to RC4 and now it’s working fine.

You can find cocos 2d latest versions from here.

This problem gave me a big headache. Though I’ve upgraded cocos2d to v2.2 version for my old project (too complex to update to v3), I still got this warning. And any animation I created use rotation in the SpriteBuilder does act oddly, as I described here:
Rotation animation issue on iPhone5S with cocos2d 2.0

Finally I used type casting to solve it as following in CCBAnimationManager.m

@implementation CCBRotateTo
-(void)startWithTarget:(CCNode *)aTarget
{
    [super startWithTarget:aTarget];
    starAngle_ = [(CCNode *)self.target rotation];
    diffAngle_ = dstAngle_ - startAngle_;
}

-(void)update:(ccTime)t
{
    [(CCNode *)self.target setRotation: startAngle_ + diffAngle_ * t];
}

With this change, now I can support arm64 too.

分类: stackoverflow精选, unity3d 标签:

【cocos2d-x 仙凡奇缘-网游研发(1) 登录&注册】

2014年3月13日 没有评论

转载请注明出处:http://www.cnblogs.com/zisou/p/xianfan01.html

公司的项目总算告一段落了,年前憋到年后,总算要上线了,所以我也有了时间来搞我自己的游戏项目了,和大多数开发者一样,或许每个做游戏的心里面都有自己的一个世界属于自己的一个梦,这次我还要继续做梦,呵呵。

《仙凡奇缘》官方网站

www.xianfancoco.com

好了,下面我赘述一下这个RPG网游的架构,服务器端由socket+http,语言我用c#,因为以前有了一套比较成熟的后台系统附带了一个tcp通讯协议的轻量级服务监控端。服务端主要还是以HTTP为主,C#的托管机制让我开发服务器变得相当快捷,相当顺当;

【cocos2d-x 仙凡奇缘-网游研发(1) 登录&amp;注册】

有了上图,大家应该知道了做一个网游不易,一个人恐怕撸不起来。确实,这需要非常多的时间精力,和技术支持;但是我们从简化,从策划,服务端,客户端,任何模块我们都从简(从简不等于不做,是少做,而且做精一个就行),毕竟我们有雄心壮志,也难免实现宏伟目标;

回归这次主要正题:注册登录;

服务器端我已经做了提供了如下接口HTTP协议,采用POST协议方式获取客户端的消息:

【cocos2d-x 仙凡奇缘-网游研发(1) 登录&amp;注册】

部分核心代码内容:

【cocos2d-x 仙凡奇缘-网游研发(1) 登录&amp;注册】【cocos2d-x 仙凡奇缘-网游研发(1) 登录&amp;注册】

 1 if (!IsPostBack)
 2             {
 3                 APIId = Convert.ToInt32(Request.Form["APIId"]);
 4                 switch (APIId)
 5                 {
 6                     //注册
 7                     case 10000:
 8                         useremail = Request.Form["useremail"];
 9                         pwd = Request.Form["pwd"];
10                         phonenumber = Request.Form["phonenumber"];
11                         username = Request.Form["username"];
12                         returnstring = APIId + "|" + C_user.reguser(useremail, pwd, phonenumber, username) + "|";
13                         break;
14                     //登陆
15                     case 10001:
16                         useremail = Request.Form["useremail"];
17                         pwd = Request.Form["pwd"];
18                         returnstring = APIId+ "|" + C_user.userlogin(useremail, pwd)+ "|" ;
19                         break;
20                     //创建角色
21                     case 10002:
22                         gamename = Request.Form["gamename"];
23                         number = Request.Form["number"];
24                         sex = Request.Form["sex"];
25                         zhiye = Request.Form["zhiye"];
26                         returnstring = APIId + "|" + C_user.reguser_passuserinfo(number,gamename,sex,zhiye) + "|";
27                         break;
28                     default:
29                         returnstring = "数据有误";
30                         break;
31                 }
32             }

View Code

目前主要开发了:登录,注册,和创建角色这三个协议,里面都是POST协议;

客户端代码又如何呢?首先我们得有重要的利器(curl)的访问方式,我建立了HttpWebServer.cpp类,并且进行了封装;

核心代码我贴出来:

【cocos2d-x 仙凡奇缘-网游研发(1) 登录&amp;注册】【cocos2d-x 仙凡奇缘-网游研发(1) 登录&amp;注册】

//回调
size_t HttpWebServer::writehtml(uint8_t* ptr,size_t size,size_t number,void *stream)
{
    CCLog("%s",ptr);
    string reuturndata = (char*)ptr;
    ToDo::showTip(reuturndata);
    return size*number;//这里一定要放回实际返回的字节数
}

string HttpWebServer::getReadyForPostData(CCArray* arraydata)
{
    string datastr = "";
    for (int i = 0; i < arraydata->count(); i++)
    {
        CCString* ccdatastr = (CCString*)arraydata->objectAtIndex(i); 
        if(i==0)
        {
            datastr = ccdatastr->getCString();
        }
        else
        {
            datastr = datastr + "&" + ccdatastr->getCString();
        }
    }
    return datastr;
}

void HttpWebServer::CurlPost(string url,string postdata)
{
    //APIId=10000&useremail=747204@qq.com&pwd=ysj55555&phonenumber=18618169949&username=ysj5555520
    //http://www.xianfancoco.com/AListenAPIweb/userComment.aspx

    CURL *curl;
    CURLcode res;
    std::string cc;
    curl=curl_easy_init();
    if(curl)
    {
        curl_easy_setopt( curl, CURLOPT_URL, url.c_str()); //请求的地址
        curl_easy_setopt(curl, CURLOPT_POST, true); 
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata.c_str());
        //启用POST提交 
        curl_easy_setopt( curl, CURLOPT_FOLLOWLOCATION, 23L); 
        curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,writehtml); //处理的函数
        curl_easy_setopt( curl, CURLOPT_WRITEDATA, &cc);        //缓冲的内存
        res=curl_easy_perform(curl);
        if(res!=CURLE_OK)
        {
            //CCLog("联网超时 %i",res);
        }
        curl_easy_cleanup(curl);
    }
    else
    {
        //CCLog("curl is null");
        return ;
    }
}

View Code

里面我封装了如何发送包POST方法和如何组合包的方法,这样使用起来就会相当的简便;

如服务器需要传:useremail = Request.Form[“useremail”];
那客户端也有对应的POST方式,下面就是我如何发送客户端登录的请求方式:

CCArray * senddata = CCArray::create();
    string data;
    senddata->addObject(CCString::create("APIId=10001"));
    senddata->addObject(CCString::create("useremail=747204@qq.com"));
    senddata->addObject(CCString::create("pwd=ysj55555"));
    data =  HttpWebServer::getReadyForPostData(senddata);
    HttpWebServer::CurlPost(SERVICES_NAME_USER,data);
    senddata->release();
    TipBaseShowText(this,CCString::create("aaa"),CCString::create("SSS"),1.0f,1.0f,UI_TIP,true);

这样的封装将是以后我大量的使用的标本,登录和注册是简单的必要的用户操作行为,用户在么有用户名之前需要点击注册;
注册如下图:

 【cocos2d-x 仙凡奇缘-网游研发(1) 登录&amp;注册】

登录界面如下图

【cocos2d-x 仙凡奇缘-网游研发(1) 登录&amp;注册】

输入框,以及登录或注册返回

【cocos2d-x 仙凡奇缘-网游研发(1) 登录&amp;注册】

声明一下这次写这系列博客主要是为了分享游戏制作经验,由于这次是个人项目,和公司无关,是否开源还得看游戏3个月以后的情况而定,本游戏所用资源全部来自于商业内部资源;

2014扬帆起航…

 

 

 

分类: 未分类 标签:

Cocos2dx-截屏并设置图片尺寸

2014年3月10日 没有评论

猴子原创,欢迎转载。转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢!

原文地址: http://www.cocos2dev.com/?p=522

前几天添加微信图片分享的时候,发现全屏截图超出了微信的数据包大小,所以截屏的时候可以考虑缩小尺寸到0.5倍。
下面的截屏代码:

void LHUtil::screenShoot()
{
    Size visibleSize = Director::getInstance()->getVisibleSize();
    
    //定义一个屏幕大小的渲染纹理
    RenderTexture* renderTexture = RenderTexture::create(visibleSize.width * .5, visibleSize.height * .5, Texture2D::PixelFormat::RGBA8888);

    Scene* curScene = Director::getInstance()->getRunningScene();
    Point ancPos = pCurScene->getAnchorPoint();

    //渲染纹理开始捕捉
    renderTexture->begin();

    // 缩小屏幕截屏区域
    curScene->setScale(.5);
    curScene->setAnchorPoint(cocos2d::Point(0, 0));

    //绘制当前场景
    curScene->visit();

    //结束
    renderTexture->end();

    //保存png
    renderTexture->saveToFile("screenshoot.png", Image::Format::PNG);

    // 恢复屏幕尺寸
    curScene->setScale(1);
    curScene->setAnchorPoint(ancPos);
    CC_SAFE_DELETE(curScene);
}

上面是cocos2dx的获取截屏的方法。

我顺便写下如何用OC的UIGraphicsBeginImageContext获取UIView转化成UIImage.
下面是ios方法:

-(void)screenShot:(CGRect)rect{
    // 开始设置截屏区域
    UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0);
    [[self.view layer] renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    // 获取image,可以根据需要进行尺寸修改
    CGImageRef imageRef = viewImage.CGImage;
    CGImageRef imageRefRect =CGImageCreateWithImageInRect(imageRef, rect);
    UIImage *image = [[UIImage alloc] initWithCGImage:imageRefRect];
    
    // 保存图片到相册, 这里会提示用户授权,不需要保存的话,可以取消
    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
    
    // 获取Documents目录
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:@"temScreenShot.png"];
    
    // 保存image到Documents目录
    NSData *imageData = UIImagePNGRepresentation(image);
    [imageData writeToFile:savedImagePath atomically:YES];
    CGImageRelease(imageRefRect);
}

分类: 未分类 标签:

Multiple screen resolution support in cocos2d v3?

2014年3月9日 没有评论

I am little confused with cocos2d v3’s support for multiple screen resolutions. If I use CCSetupScreenMode: CCScreenModeFlexible, what should be the default resolution of the image that I provide?

Currently, I have provided assets for all the iOS device resolutions along with suffixes and the correct images are loaded on iPhone “3.5inch” and iPad. However, the “-568h@2x” suffix for iPhone “4 inch” is not working fine. Am i using the wrong suffix?

I would like to avoid the need to use macros to determine which device the game is running on and load the images accordingly.

Thank you for your time!

The ScreenMode only defines if the screen scales up with the device size or not.

The fixed screen mode provides you with a stage that has a safe area and an unsafe area but the complete stage always has the same size.

In the flexible screen mode the root node of your scene will resize with the actual screen size, so you have to deal with dynamic sizing.

You can read more about the screen modes, image sizes and how to design a game for multiple screen resolutions in our tutorial.

In Cocos2D the suffixes are different from the ones UIKit uses. The suffixes are:

  • -ipad
  • -ipadhd
  • -hd
  • -iphone5hd
分类: cocos2d, stackoverflow精选 标签:

sublime text3的Package Control安装

2014年3月6日 没有评论

1、点击菜单 View -> Show Console ,显示console面板

2、在命令输入框中输入

import urllib.request,os,hashlib; h = '7183a2d3e96f11eeadd761d777e62404' + 'e330c659d4bb41d3bdf022e94cab3cd0'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://sublime.wbond.net/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by) 

回车,等待一会儿后,即可在Preferences中看到Package Control

分类: 未分类 标签: