cocos2d-x的初步学习二十六之连连看二
发布日期:2022-02-08 18:03:30
浏览次数:42
分类:技术文章
本文共 20387 字,大约阅读时间需要 67 分钟。
这篇文章中,我们将完成剩下的部分,点击首界面进入游戏主界面,我们初始化一些界面元素,实现这样的功能,有暂停功能,背景音乐,进度条等,加上一些动画,下面直接上代码,前面都是一些界面的布局和动画等,比较简单。先新建一个GameLayer类
GameLayer.h
//游戏主界面class GameLayer : public cocos2d::CCLayerColor{public: virtual bool init(); static cocos2d::CCScene* scene(); CREATE_FUNC(GameLayer); private: void initData(void); void initUI(void); void initLoadingUI(void); void playSound1(void); void playSound2(void); void playSound3(void); void initDialog(void); void pausePressed(void); void dialogAnimaton(void); void dialogAnimaton2(void); void dialogAnimaton3(void); void removeDialogLayer(void); void loadingAnimation(void); void removeLoadSprite(void); void functionSpriteAnimation(cocos2d::CCPoint point1,cocos2d::CCPoint point2); void functionPauseSpriteAnimation(cocos2d::CCPoint point1,cocos2d::CCPoint point2); CCLayerColor *dialogLayer; cocos2d::CCString *dialogLevelString; cocos2d::CCString *dialogTishiString; cocos2d::CCSprite *leisureSprite; cocos2d::CCSprite *levelSprite; cocos2d::CCLabelAtlas *levelnumsAtlas; cocos2d::CCString *_level; cocos2d::CCSprite *pauseSprite; cocos2d::CCMenu *pausemenu; cocos2d::CCSprite *loadSprite; };
GameLayer.cpp
CCScene* GameLayer::scene(){ CCScene *scene = CCScene::create(); GameLayer *layer = GameLayer::create(); scene->addChild(layer); return scene; }bool GameLayer::init(){ if ( !CCLayerColor::initWithColor(ccc4(255, 255, 255, 255))) { return false; } this->initLoadingUI(); //循环播放三首背景音乐 this->playSound1(); return true;}void GameLayer::initData(){ dialogLevelString=CCString::create("第一关"); dialogTishiString=CCString::create("王子大人"); // dialogLevelString->retain(); // dialogTishiString->retain(); _level=CCString::create("001");}//load界面void GameLayer::initLoadingUI(){ loadSprite=CCSprite::create("loading_logo-hd.png"); loadSprite->setPosition(ccp(wSize.width/2, wSize.height/2)); this->addChild(loadSprite, 0); this->loadingAnimation();}void GameLayer::initUI(){ CCSprite *bgSprite=NULL; if (wSize.width==1136 && wSize.height==640) { bgSprite=CCSprite::create("background_568-hd.png"); } else { bgSprite=CCSprite::create("background-hd.png"); } bgSprite->setPosition(ccp(wSize.width/2, wSize.height/2)); this->addChild(bgSprite, 0); //白云1 CCSprite *cloudSprite=CCSprite::create("background_cloud_1-hd.png"); cloudSprite->setAnchorPoint(ccp(0, 0)); cloudSprite->setPosition(ccp(0, wSize.height-cloudSprite->getContentSize().height)); this->addChild(cloudSprite, 1); //白云倒影 CCSprite *daoyingloudSprite=CCSprite::create("background_cloud_1-hd.png"); daoyingloudSprite->setAnchorPoint(ccp(0, 0)); //垂直翻转 daoyingloudSprite->setFlipY(true); daoyingloudSprite->setOpacity(40); daoyingloudSprite->setPosition(ccp(wSize.width-cloudSprite->getContentSize().width-40, wSize.height-cloudSprite->getContentSize().height-78*2)); this->addChild(daoyingloudSprite, 1); //白云2 CCSprite *cloud2Sprite=CCSprite::create("background_cloud_2-hd.png"); cloud2Sprite->setAnchorPoint(ccp(0, 0)); cloud2Sprite->setPosition(ccp(cloudSprite->getPosition().x+cloudSprite->getContentSize().width, wSize.height-cloud2Sprite->getContentSize().height)); this->addChild(cloud2Sprite, 1); //岛 CCSprite *landSprite=CCSprite::create("island-hd.png"); landSprite->setAnchorPoint(ccp(0, 0)); landSprite->setPosition(ccp(wSize.width-landSprite->getContentSize().width-20*2, wSize.height-landSprite->getContentSize().height-47*2)); this->addChild(landSprite, 1); //倒影 CCSprite *daoyinglandSprite=CCSprite::create("island-hd.png"); daoyinglandSprite->setAnchorPoint(ccp(0, 0)); daoyinglandSprite->setFlipY(true); daoyinglandSprite->setOpacity(40); daoyinglandSprite->setPosition(ccp(wSize.width-landSprite->getContentSize().width-20*2, wSize.height-landSprite->getContentSize().height-78*2)); this->addChild(daoyinglandSprite, 1); this->initDialog(); //图标1 leisureSprite=CCSprite::create("game_leisure_logo-hd.png"); leisureSprite->setPosition(ccp(leisureSprite->getContentSize().width/2+10*2, wSize.height+leisureSprite->getContentSize().height/2)); this->addChild(leisureSprite, 1); //等级图标 levelSprite=CCSprite::create("orange_font_level-hd.png"); levelSprite->setPosition(ccp(leisureSprite->getContentSize().width/2+8*2, 255*2)); this->addChild(levelSprite, 1); levelSprite->setVisible(false); //等级sprite levelnumsAtlas=CCLabelAtlas::create(_level->getCString(), "small_blue_number_level-hd.png",16, 20, '0'); levelnumsAtlas->setScale(1.2); levelnumsAtlas->setPosition(ccp(leisureSprite->getContentSize().width/2-6*2,levelSprite->getPosition().y-20*2)); levelnumsAtlas->setVisible(false); this->addChild(levelnumsAtlas, 1); //暂停菜单 pauseSprite=CCSprite::create("button_pause-hd.png"); CCSprite *pauseSprite_s=CCSprite::create("button_pause-hd.png"); CCMenuItemSprite *item=CCMenuItemSprite::create(pauseSprite, pauseSprite_s, this, menu_selector(GameLayer::pausePressed)); pausemenu=CCMenu::create(item,NULL); item->setAnchorPoint(ccp(0.5, 0.5)); pausemenu->setPosition(ccp(pauseSprite->getContentSize().width/2+10*2,-pauseSprite->getContentSize().height/2)); this->addChild(pausemenu, 1); this->dialogAnimaton(); }//初始化弹出框void GameLayer::initDialog(){ //弹出框 dialogLayer=CCLayerColor::create(ccc4(0, 0, 0, 0), 333*2, 235*2); dialogLayer->setPosition(ccp(wSize.width/2-dialogLayer->getContentSize().width/2, wSize.height/2-dialogLayer->getContentSize().height/2)); dialogLayer->setScale(0.9); this->addChild(dialogLayer, 1); CCSprite *dialogSprite=CCSprite::create("game_dialog-hd.png"); dialogSprite->setAnchorPoint(ccp(0, 0)); dialogSprite->setPosition(ccp(0, 0)); dialogLayer->addChild(dialogSprite, 1); //标题1 CCLabelTTF *dialoglevel=CCLabelTTF::create(dialogLevelString->getCString(), "Marker Felt", 35); dialoglevel->setAnchorPoint(ccp(0, 0)); dialoglevel->setPosition(ccp(dialogLayer->getContentSize().width/2-dialoglevel->getContentSize().width/2, dialogLayer->getContentSize().height/2-dialoglevel->getContentSize().height/2+30*2)); dialoglevel->setColor(ccWHITE); dialogLayer->addChild(dialoglevel, 1, 310); //标题2 CCLabelTTF *dialogtishi=CCLabelTTF::create(dialogTishiString->getCString(), "Marker Felt", 35); dialogtishi->setAnchorPoint(ccp(0, 0)); dialogtishi->setPosition(ccp(dialogLayer->getContentSize().width/2-dialogtishi->getContentSize().width/2, dialogLayer->getContentSize().height/2-dialogtishi->getContentSize().height/2-15*2)); dialogtishi->setColor(ccWHITE); dialogLayer->addChild(dialogtishi, 1, 311); }//load界面动画void GameLayer::loadingAnimation(){ CCFadeOut *ac1=CCFadeOut::create(3.0f); CCSequence *seq=CCSequence::create(ac1,CCCallFunc::create(this, callfunc_selector(GameLayer::removeLoadSprite)),NULL); loadSprite->runAction(seq);}//移除load界面void GameLayer::removeLoadSprite(){ loadSprite->removeFromParentAndCleanup(true); this->initData(); this->initUI();}void GameLayer::playSound1(){ SimpleAudioEngine::sharedEngine()->stopBackgroundMusic(); SimpleAudioEngine::sharedEngine()->playBackgroundMusic("Back2new.mp3", false); this->scheduleOnce(schedule_selector(GameLayer::playSound2), 60); }void GameLayer::playSound2(){ SimpleAudioEngine::sharedEngine()->stopBackgroundMusic(); SimpleAudioEngine::sharedEngine()->playBackgroundMusic("Back3new.mp3", false); this->scheduleOnce(schedule_selector(GameLayer::playSound3), 62); }void GameLayer::playSound3(){ SimpleAudioEngine::sharedEngine()->stopBackgroundMusic(); SimpleAudioEngine::sharedEngine()->playBackgroundMusic("MainMenu.mp3", false); this->scheduleOnce(schedule_selector(GameLayer::playSound1), 65); }//暂停void GameLayer::pausePressed(){ }//弹出框动画void GameLayer::dialogAnimaton(){ SimpleAudioEngine::sharedEngine()->playEffect("19.wav"); CCShow *ac1=CCShow::create(); CCScaleTo *ac2=CCScaleTo::create(0.1f, 1.0); CCSpawn *spwan=CCSpawn::create(ac1,ac2,NULL); CCSequence *seq=CCSequence::create(spwan,CCCallFunc::create(this, callfunc_selector(GameLayer::dialogAnimaton2)),NULL); dialogLayer->runAction(seq); }void GameLayer::dialogAnimaton2(){ CCScaleTo *ac1=CCScaleTo::create(0.1f, 0.9); CCSequence *seq=CCSequence::create(ac1,CCCallFunc::create(this, callfunc_selector(GameLayer::dialogAnimaton3)),NULL); dialogLayer->runAction(seq);}void GameLayer::dialogAnimaton3(){ CCScaleTo *ac1=CCScaleTo::create(0.1f, 1.0); CCScaleTo *ac2=CCScaleTo::create(0.2f, 1.2); CCFadeTo *ac3=CCFadeTo::create(0.2f, 0); CCSpawn *spwan=CCSpawn::create(ac2,ac3,NULL); CCSequence *seq=CCSequence::create(ac1,CCDelayTime::create(1.5f),spwan,CCCallFunc::create(this, callfunc_selector(GameLayer::removeDialogLayer)),NULL); dialogLayer->runAction(seq); }//移除弹出框void GameLayer::removeDialogLayer(){ SimpleAudioEngine::sharedEngine()->playEffect("16.wav"); dialogLayer->removeFromParentAndCleanup(true); levelSprite->setVisible(true); levelnumsAtlas->setVisible(true); this->functionSpriteAnimation(CCPoint(leisureSprite->getPosition().x, wSize.height-leisureSprite->getContentSize().height/2-15*2) ,CCPoint(leisureSprite->getPosition().x, wSize.height-leisureSprite->getContentSize().height/2-10*2)); this->functionPauseSpriteAnimation(CCPoint(pausemenu->getPosition().x, 34*2), CCPoint(pausemenu->getPosition().x, 29*2)); }//移动动画void GameLayer::functionSpriteAnimation(cocos2d::CCPoint point1, cocos2d::CCPoint point2){ CCMoveTo *ac1=CCMoveTo::create(0.15, point1); CCMoveTo *ac2=CCMoveTo::create(0.15, point2); CCSequence *seq=CCSequence::create(ac1,ac2,NULL); leisureSprite->runAction(seq);}移动动画void GameLayer::functionPauseSpriteAnimation(cocos2d::CCPoint point1, cocos2d::CCPoint point2){ CCMoveTo *ac1=CCMoveTo::create(0.15, point1); CCMoveTo *ac2=CCMoveTo::create(0.15, point2); CCSequence *seq=CCSequence::create(ac1,ac2,NULL); pausemenu->runAction(seq);}
场景切换动画
//开始游戏void HelloWorld::playBack(){ SimpleAudioEngine::sharedEngine()->stopBackgroundMusic(); CCScene *scene=GameLayer::scene(); //旋转动画 CCDirector::sharedDirector()->replaceScene(CCTransitionRotoZoom::create(1.2f, scene)); }以前就是游戏主界面的一些元素布局,跳转进入游戏界面,先出现一个loading界面,加个渐隐的动画,消失后弹出一个关卡提示框,。。。。
效果如下:
~~~~~~~~~接下来,我们加入一个时间进度条,O(∩_∩)O~~~~~~~
在函数initUI()中加入
//进度条背景 progressbgSprite=CCSprite::create("time_slot-hd.png"); progressbgSprite->setAnchorPoint(ccp(0, 0)); progressbgSprite->setPosition(ccp(130, wSize.height-55)); this->addChild(progressbgSprite, 1); progressbgSprite->setVisible(false); CCSprite *progressSprite=CCSprite::create("time_bars-hd.png"); //进度条 progress=CCProgressTimer::create(progressSprite); progress->setAnchorPoint(ccp(0, 0)); progress->setType(kCCProgressTimerTypeBar); progress->setPosition(ccp(130, wSize.height-55)); //进度动画运动方向,可以多试几个值,看看效果 progress->setMidpoint(ccp(0, 0)); //进度条宽高变化 progress->setBarChangeRate(ccp(1, 0)); progress->setPercentage(100); this->addChild(progress, 1); progress->setVisible(false); numsTTF=CCLabelTTF::create("100", "Thonburi", 24); numsTTF->setAnchorPoint(ccp(0, 0)); numsTTF->setPosition(ccp(400, wSize.height-55)); numsTTF->setColor(ccBLACK); this->addChild(numsTTF, 1); numsTTF->setVisible(false);定义刷新函数
this->schedule(schedule_selector(GameLayer::update), 1);
//刷新void GameLayer::update(){ int cu=progress->getPercentage(); cu=cu-1.0f; progress->setPercentage(cu); CCString *str = CCString::createWithFormat("%d",cu); numsTTF->setString(str->getCString()); }一秒钟刷新一次
效果如下
注意,在我现在用的cocos2dx版本中,在ios下,CCLabelTTF没显示出来,如果你升级到2.1.4以上,就没问题了,如果你不想升级,那么网上的解决方法为修改底层源码:
修改CCImage.mm的
static bool _initWithString(constchar * pText, cocos2d::CCImage::ETextAlign eAlign,const char * pFontName,intnSize, tImageInfo* pInfo)
const int _width = dim.width; //Add const int _height = dim.height; //Add unsigned char* data = new unsigned char[(int)(dim.width * dim.height * 4)]; memset(data, 0, (int)(_width * _height * 4)); //Modify // draw text CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(data, _width, _height, 8, _width * 4, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGColorSpaceRelease(colorSpace); //Modify if (! context) { delete[] data; break; }
~~~~~~~~~~~~~~~~接下来我们加入一个暂停的界面,并加入一些动画效果
我们新建一个暂停界面的类,PauseLayer,
PauseLayer.h
class PauseLayer :public cocos2d::CCLayerColor{ public: virtual bool init(); CREATE_FUNC(PauseLayer); cocos2d::CCSprite *pausebgSprite; cocos2d::CCMenuItemSprite *backitem; cocos2d::CCMenuItemSprite *startitem; void restartPressed(void); void helpPressed(void); void musicPressed(void); void soundPressed(void); private: void initUI(void); };
PauseLayer.cpp
bool PauseLayer::init(){ if ( !CCLayerColor::initWithColor(ccc4(255, 255, 255, 0),343,343)) { return false; } this->initUI(); return true; }//UI界面初始化void PauseLayer::initUI(){ pausebgSprite=CCSprite::create("game_menu_background-hd.png"); pausebgSprite->setPosition(ccp(pausebgSprite->getContentSize().width/2, pausebgSprite->getContentSize().height/2)); this->addChild(pausebgSprite, 1); //返回 CCSprite *backSprite=CCSprite::create("button_back-hd.png"); CCSprite *backSprite_s=CCSprite::create("button_back-hd.png"); backitem=CCMenuItemSprite::create(backSprite, backSprite_s); CCMenu *backmenu=CCMenu::create(backitem,NULL); backitem->setAnchorPoint(ccp(0, 0)); backmenu->setPosition(ccp(71*2,3*2)); this->addChild(backmenu, 1); //继续 CCSprite *startSprite=CCSprite::create("button_start.png"); CCSprite *startSprite_s=CCSprite::create("button_start.png"); startitem=CCMenuItemSprite::create(startSprite, startSprite_s); CCMenu *startmenu=CCMenu::create(startitem,NULL); startmenu->setPosition(ccp(pausebgSprite->getContentSize().width/2, pausebgSprite->getContentSize().height/2)); this->addChild(startmenu, 1); //重新开始 CCSprite *restartSprite=CCSprite::create("button_restart.png"); CCSprite *restartSprite_s=CCSprite::create("button_restart.png"); CCMenuItemSprite *restartitem=CCMenuItemSprite::create(restartSprite, restartSprite_s, this, menu_selector(PauseLayer::restartPressed)); CCMenu *restartmenu=CCMenu::create(restartitem,NULL); restartitem->setAnchorPoint(ccp(0, 0)); restartmenu->setPosition(ccp(71*2,129*2)); this->addChild(restartmenu, 1); //帮助 CCSprite *helpSprite=CCSprite::create("button_help-hd.png"); CCSprite *helpSprite_s=CCSprite::create("button_help-hd.png"); CCMenuItemSprite *helpitem=CCMenuItemSprite::create(helpSprite, helpSprite_s, this, menu_selector(PauseLayer::helpPressed)); CCMenu *helpmenu=CCMenu::create(helpitem,NULL); helpitem->setAnchorPoint(ccp(0, 0)); helpmenu->setPosition(ccp(114*2,21*2)); this->addChild(helpmenu, 1); //音乐 CCSprite *musicSprite=CCSprite::create("button_music-hd.png"); CCSprite *musicSprite_s=CCSprite::create("button_music-hd.png"); CCMenuItemSprite *musicitem=CCMenuItemSprite::create(musicSprite, musicSprite_s, this, menu_selector(PauseLayer::musicPressed)); CCMenu *musicmenu=CCMenu::create(musicitem,NULL); musicitem->setAnchorPoint(ccp(0, 0)); musicmenu->setPosition(ccp(127*2,66*2)); this->addChild(musicmenu, 1); //音效 CCSprite *soundSprite=CCSprite::create("button_sound-hd.png"); CCSprite *soundSprite_s=CCSprite::create("button_sound-hd.png"); CCMenuItemSprite *sounditem=CCMenuItemSprite::create(soundSprite, soundSprite_s, this, menu_selector(PauseLayer::soundPressed)); CCMenu *soundmenu=CCMenu::create(sounditem,NULL); sounditem->setAnchorPoint(ccp(0, 0)); soundmenu->setPosition(ccp(114*2,111*2)); this->addChild(soundmenu, 1);}void PauseLayer::restartPressed(){}void PauseLayer::helpPressed(){}void PauseLayer::musicPressed(){}void PauseLayer::soundPressed(){}然后在GameLayer类中加入我们的暂停界面,
GameLayer.h
void backPressed(void); void startPressed(void); void gamePause(void); void gameRestart(void); PauseLayer *pauseLayer;GameLayer.cpp
在函数initUI中加入
//暂停界面 pauseLayer=PauseLayer::create(); pauseLayer->setPosition(ccp(-pauseLayer->getContentSize().width, wSize.height/2-pauseLayer->getContentSize().height/2)); this->addChild(pauseLayer, 1); //设置监听事件 pauseLayer->backitem->setTarget(this, menu_selector(GameLayer::backPressed)); pauseLayer->startitem->setTarget(this, menu_selector(GameLayer::startPressed));点击暂停按钮
//暂停void GameLayer::pausePressed(){ // CCDirector::sharedDirector()->pause(); SimpleAudioEngine::sharedEngine()->playEffect("3.wav"); this->functionSpriteAnimation(CCPoint(leisureSprite->getContentSize().width/2+10*2, wSize.height+leisureSprite->getContentSize().height/2+5*2) ,CCPoint(leisureSprite->getContentSize().width/2+10*2, wSize.height+leisureSprite->getContentSize().height/2)); this->functionPauseSpriteAnimation(CCPoint(pausemenu->getPosition().x, -pauseSprite->getContentSize().height/2-5*2), CCPoint(pausemenu->getPosition().x, -pauseSprite->getContentSize().height/2)); levelSprite->setVisible(false); levelnumsAtlas->setVisible(false); progressbgSprite->setVisible(false); progress->setVisible(false); numsTTF->setVisible(false); CCMoveTo *ac1=CCMoveTo::create(0.15, CCPoint(-44*2, pauseLayer->getPosition().y)); CCMoveTo *ac2=CCMoveTo::create(0.15, CCPoint(-100, pauseLayer->getPosition().y)); CCSequence *seq=CCSequence::create(ac1,ac2,CCCallFunc::create(this, callfunc_selector(GameLayer::gamePause)),NULL); pauseLayer->runAction(seq); }//游戏暂停void GameLayer::gamePause(){ CCDirector::sharedDirector()->pause();}//游戏恢复void GameLayer::gameRestart(){ CCDirector::sharedDirector()->resume(); }点击返回按钮,返回到首界面
//返回void GameLayer::backPressed(){ this->gameRestart(); SimpleAudioEngine::sharedEngine()->stopBackgroundMusic(); SimpleAudioEngine::sharedEngine()->playEffect("2.wav"); CCScene *scene=HelloWorld::scene(); //旋转动画 CCDirector::sharedDirector()->replaceScene(CCTransitionFlipX::create(1.2f, scene));}//继续void GameLayer::startPressed(){ this->gameRestart(); CCMoveTo *ac1=CCMoveTo::create(0.15, CCPoint(-100+4, wSize.height/2-pauseLayer->getContentSize().height/2)); CCMoveTo *ac2=CCMoveTo::create(0.15, CCPoint(-pauseLayer->getContentSize().width, wSize.height/2-pauseLayer->getContentSize().height/2)); CCSequence *seq=CCSequence::create(ac1,ac2,NULL); http://digi.tech.qq.com/zt2013/newipad/live.htm pauseLayer->runAction(seq); levelSprite->setVisible(true); levelnumsAtlas->setVisible(true); progressbgSprite->setVisible(true); progress->setVisible(true); numsTTF->setVisible(true); this->functionSpriteAnimation(CCPoint(leisureSprite->getPosition().x, wSize.height-leisureSprite->getContentSize().height/2-15*2) ,CCPoint(leisureSprite->getPosition().x, wSize.height-leisureSprite->getContentSize().height/2-10*2)); this->functionPauseSpriteAnimation(CCPoint(pausemenu->getPosition().x, 34*2), CCPoint(pausemenu->getPosition().x, 29*2)); }OK。。。。。。。代码不是很复杂,都是一些简单的逻辑,所以不具体细说,大家可以看代码
效果图如下:
@@@@@@@@@@@@
下篇文章会将重点讲游戏逻辑。。。。。。。
转载地址:https://blog.csdn.net/kuloveyouwei/article/details/12950449 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
关注你微信了!
[***.104.42.241]2024年03月28日 20时13分26秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
php反射类 ReflectionClass
2019-04-27
为 PHP 应用提速、提速、再提速
2019-04-27
Linux下gedit显示行号
2019-04-27
《Advanced PHP Programming》读书笔记
2019-04-27
让我们谈谈RAID
2019-04-27
jQuery日期选择器插件date-input
2019-04-27
PHP使用curl_multi_add_handle并行处理
2019-04-27
NP问题
2019-04-27
AT&T与Intel汇编语言的比较
2019-04-27
javascript解析json
2019-04-27
WinDbg安装与使用
2019-04-27
推荐阅读的多核编程技术书籍
2019-04-27
维基百科上的算法和数据结构链接很强大
2019-04-27
选择排序
2019-04-27
PHP session回收机制
2019-04-27
最新的全球编程语言,操作系统,web服务器等使用率分析报告
2019-04-27
用C语言写PHP扩展
2019-04-27
PHP Extension programming
2019-04-27
海量数据处理
2019-04-27
PHP防止注入攻击
2019-04-27