我们将使用cocos2d-x制作一个简单的射击游戏。

本文所用的制作环境是cocos2d x 2.0.4,VS2010。

参考资料:

1、本文的原型其实是来自cocos2d-2.0-x-2.0.4官方下载的安装软件,解压缩后可以看到该例子,即在根目录下的Samples示例文件夹里面的SimpleGame。

2、博客无幻的SimpleGame制作的文章,这里是传送门:  http://blog.csdn.net/akof1314/article/details/8268882

我这里只是把他们横版的游戏变成竖版,取消白色游戏背景改为用图片背景,而图片素材则换成微信飞机的图片。将原本走掉1个就结束的游戏规则改为如果超过3个敌机跑到屏幕下方里,则游戏结束。飞机的速度和显示时间也稍做了调整。此外本文修改了以上两文中子弹路径算法的一个细微的小错漏,详情请看下文关于子弹路径的算法。

下面我们直接进入主题。制作方法如下:

1、创建工程。新建Cocos2d-win32工程,工程名为"Star Fighter",去除"Box2D"选项(该项目不需要用),勾选"Simple Audio Engine in Cocos Denshion"选项;

2、编译运行,查看HelloWorld是否正常显示。可以看到如下图所示:

3、下载本游戏所需的资源,将资源放置"Resources"目录下;

4、设置游戏屏幕尺寸。

打开main.cpp文件设置分辨率,

找到 setFrameSize函数把其括号里的数据,设置成你要的分辨率,用于开发。

市场上装有Andriod系统的手机分辨率常用的主要为240*320、320*480、480*800三种。

修改后的main.cpp文件代码为:

eglView->setFrameSize(320, 480); //本文采用(320, 480);像素开发。

5、设置游戏背景,最简单的方法是将原本HelloWorldScene.cpp里面的HelloWorld.png文件名,直接替换为我们的背景图片bg_01.jpg。

我们可以看到修改后的代码为:

        // 添加背景Add a splash screen, show the cocos2d splash image.
CCSprite* pSprite = CCSprite::create("bg_01.jpg");
CC_BREAK_IF(! pSprite);
// 设置坐标位置Place the sprite on the center of the screen
pSprite->setPosition(ccp(size.width/2, size.height/2));
// 添加到图层显示出来Add the sprite to HelloWorld layer as a child layer.
this->addChild(pSprite, 0);

cocos2d中图片的添加也是通过添加精灵实现的,由这里我们学会了cocos2d添加精灵的方法。

6、添加显示游戏名字。最简单的方法是将原本HelloWorldScene.cpp里面显示的Hello World文字,直接替换为我们的"Star Fighter",及修改字体的大小。

        //  添加游戏名字 Add a label shows "Star Fighter".
// Create a label and initialize with string "Hello World".
CCLabelTTF* pLabel = CCLabelTTF::create("Star Fighter", "Arial", 36);
CC_BREAK_IF(! pLabel);
// Get window size and place the label upper.
CCSize size = CCDirector::sharedDirector()->getWinSize();
pLabel->setPosition(ccp(size.width / 2, size.height - 50));
// Add the label to HelloWorld layer as a child layer.
this->addChild(pLabel, 1);//第二个数字是渲染的顺序

7、添加玩家player,让玩家位于下方屏幕的中间,在刚刚的HelloWorldScene.cpp文件的init函数里面,(仿照添加背景的代码)添加如下的代码:

         //添加玩家player精灵
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCSprite *player = CCSprite::create("player.png");
player->setPosition(ccp(winSize.width / 2, 50));//设置坐标位置,注意(x,y)的值
this->addChild(player, 2); 

8、把HelloWorldScene.cpp文件的init函数里面,我们不需要用到的以下这段删掉。

// add a "close" icon to exit the progress. it's an autorelease object
    CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
                                        "CloseNormal.png",
                                        "CloseSelected.png",
                                        this,
                                        menu_selector(HelloWorld::menuCloseCallback));
   
 pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
                                origin.y + pCloseItem->getContentSize().height/2));

// create menu, it's an autorelease object
    CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
    pMenu->setPosition(CCPointZero);
    this->addChild(pMenu, 1);

9、运行编译程序,可以看到以下画面。

10.接下来添加敌机,并且让它可以移动。我们在屏幕上方中间创建,建立动作让它们向下移动。

我们在HelloWorldScene.h头文件中添加函数声明void addMonster();

然后在HelloWorldScene.cpp中增加addMonster方法,代码如下:

void HelloWorld::addMonster()
{
CCSprite *monster = CCSprite::create("Monster1.png");
//使敌人敌机从上面出现时,左右显示是完整的,并在屏幕上方随机产生
//如果其他游戏敌人是Y轴出现,可以把以下的X统一改为Y即可
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
int minX = monster->getContentSize().width / 2;
int maxX = winSize.width - monster->getContentSize().width / 2;
int rangeX = maxX - minX;
int actualX = (rand() % rangeX) + minX;//随机位置产生敌人
//设置敌机坐标 并显示出来
monster->setPosition(ccp(actualX,winSize.height + monster->getContentSize().height / 2));
this->addChild(monster);
//使用随机函数控制飞机速度。改下面数字可以调整飞机速度,控制游戏难度,当然敌机、子弹的触碰区域大小等也会影响游戏难度。
int minDuration = 2.0;
int maxDuration = 5.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (rand() % rangeDuration) + minDuration;
//控制敌机的结束坐标,即当整个飞机离开屏幕(注意默认锚点是图片的中心位置)
CCMoveTo *actionMove = CCMoveTo::create(actualDuration, ccp(actualX,-monster->getContentSize().height / 2));
CCCallFuncN *actionMoveDone = CCCallFuncN::create(this, callfuncN_selector(HelloWorld::spriteMoveFinished));
monster->runAction(CCSequence::create(actionMove, actionMoveDone, NULL));
}

在屏幕上方以随机的位置添加敌机精灵,注意计算精灵X轴的位置坐标(因为默认描点在中心,不能让敌机截断只有一部分)。

然后通过随机函数控制的敌机运动总时间,让敌机从上方移动到下方,

移动到离开边界后,调用回调函数spriteMoveFinished,进行删除精灵对象。

这里调用的回调函数,我们尚未对其进行声明和定义。

下面我们先在HelloWorldScene.h头文件中添加函数声明void spriteMoveFinished(CCNode *sender);

然后在HelloWorldScene.cpp中增加函数spriteMoveFinished的定义,代码如下:

1
2
3
4
5
void HelloWorld::spriteMoveFinished(CCNode *sender)  //回调函数spriteMoveFinished,进行删除精灵对象
{
    CCSprite *sprite = (CCSprite*)sender;
     this->removeChild(sprite,  true);
}

接下去就是安装定时器从而定时创建敌机。我们在bool HelloWorld::init()函数的添加玩家player精灵的代码后面,安装定时器,每秒执行一次,代码如下:

1
this->schedule(schedule_selector(HelloWorld::gameLogic),  1. 0);

增加gameLogic方法函数,在HelloWorldScene.h头文件中添加函数声明void gameLogic( float dt );

在HelloWorldScene.cpp中增加代码如下:

1
2
3
4
void HelloWorld::gameLogic(  float dt )
{
     this->addMonster();
}

编译运行,可以看到屏幕上方敌机定时增加,并且以不同的速度向下移动,如下图所示:

11.接着让玩家可以发射子弹。

当用户在屏幕点击时,就让玩家往点击的方向进行发射子弹。

用户的屏幕点击点并不是子弹移动的最终地,借用原文的一张图片来说明:

首先,我们用引擎的函数得到触摸点与子弹初始位置之差我们命名为(offset.x,offset.y)即上图的 (offx,offy)。用户的屏幕点击点并不是子弹移动的最终地,假设如果没有发生碰撞,子弹可以移动到屏幕的尽头直到子弹完全消失,我们将该点命名为(realX,realY)。

当用户点击屏幕后,我们创建子弹精灵,算出触摸点与子弹初始位置之差(offset.x,offset.y)。若触摸点(offset.y>0)在初始位置的上方(即玩家上方),则添加子弹到层上。以等比例原理方法,计算出子弹飞向屏幕上边的最终坐标。然后再用勾股定理计算飞行长度,假定速度为每秒480像素,则计算出飞行总时间。之后就是让子弹执行给定的飞行动作,以及之后的删除自身调用。
要让层可以支持触摸,需要在init方法里面添加如下代码:

1
this->setTouchEnabled( true);

然后重载ccTouchesEnded方法。在HelloWorldScene.h头文件中添加函数声明virtual void ccTouchesEnded(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent);

在HelloWorldScene.cpp中添加代码如下:

void HelloWorld::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
{
CCTouch *touch = (CCTouch*)pTouches->anyObject();
CCPoint location = this->convertTouchToNodeSpace(touch);
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCSprite *projectile = CCSprite::create("zd.png");
projectile->setPosition(ccp(winSize.width / 2, 50));
CCPoint offset = ccpSub(location, projectile->getPosition());
//关于子弹移动轨迹,主要是用了数学的勾股定理,平行线等分线段定理 CE:CB=DE:AB=CD:AC。
//若触摸点(offset.y>0)在初始位置的上方(即玩家上方),则添加子弹到层上.
if (offset.y <= 0)
{
return;
}
this->addChild(projectile);
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("shoot.mp3");
int realY = winSize.height + projectile->getContentSize().height / 2;
//这里是子弹的消失点,也是理解该段的重点,即子弹如果没有碰撞则会在屏幕的尽头消失。
float ratio = (float)offset.x/ (float)offset.y;
//offset.x,offset.y是上面CCPoint offset = ccpSub(location, projectile->getPosition());电脑算出来的。
int realX = (realY - projectile->getPosition().y) * ratio + projectile->getPosition().x;//利用等比例原理算出了realY的位置。
//原文该行(realX - projectile->getPosition().x) 直接写成了realX 错误导致两侧的子弹会跟鼠标稍有偏差,但偏差不大不仔细看不出来。
CCPoint realDest = ccp(realX, realY);//算出了预计子弹的消失点
//通过子弹经过的路径长度,等比例地控制子弹的运行时间
int offRealX = realX - projectile->getPosition().x;
int offRealY = realY - projectile->getPosition().y;
float length = sqrtf(offRealX * offRealX + offRealY * offRealY);
float velocity = 480 / 1;//修改480该数字可以调整子弹运行的快慢
float realMoveDuration = length / velocity;
projectile->runAction(CCSequence::create(CCMoveTo::create(realMoveDuration, realDest),
CCCallFuncN::create(this, callfuncN_selector(HelloWorld::spriteMoveFinished)), NULL));
//如果横板游戏子弹发射点是x轴左侧的,就用该段。
//if (offset.x <= 0)
//{
//    return;
//}
//this->addChild(projectile);
//int realX = winSize.width + projectile->getContentSize().width / 2; //这里是子弹的消失点,也是理解该段的重点,即子弹如果没有碰撞则会在屏幕的尽头消失。
//float ratio = (float)offset.y / (float)offset.x;//offset.x,offset.y是上面CCPoint offset = ccpSub(location, projectile->getPosition());电脑算出来的。
//int realY = (realX - projectile->getPosition().x) * ratio + projectile->getPosition().y;//利用等比例原理算出了realY的位置。
原文该行(realX - projectile->getPosition().x) 直接写成了realX 错误 两侧的子弹会跟鼠标稍有偏差,偏差不大不仔细看不出来。
//CCPoint realDest = ccp(realX, realY);//算出了预计子弹的消失点
通过子弹经过的路径长度,等比例地控制子弹的运行时间
//int offRealX = realX - projectile->getPosition().x;
//int offRealY = realY - projectile->getPosition().y;
//float length = sqrtf(offRealX * offRealX + offRealY * offRealY);
//float velocity = 480 / 1;//修改480该数字可以调整子弹运行的快慢
//float realMoveDuration = length / velocity;
//projectile->runAction(CCSequence::create(CCMoveTo::create(realMoveDuration, realDest),
//CCCallFuncN::create(this, callfuncN_selector(HelloWorld::spriteMoveFinished)), NULL));
} 

编译运行,往屏幕点击,可以看到子弹发射出去。如下图所示。

10.当子弹碰到怪物时,怪物被消灭,子弹消失,实现这些我们需要用碰撞检测。需要在场景中跟踪目标和子弹,在HelloWorldScene.h声明如下:

void update(float dt);

cocos2d::CCArray *_monsters;
cocos2d::CCArray *_projectiles;

HelloWorldScene.cpp构造函数和析构函数,添加如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
HelloWorld::HelloWorld()
{
    _monsters =  NULL;
    _projectiles =  NULL;
}

HelloWorld::~HelloWorld()
{
     if (_monsters)
    {
        _monsters->release();
        _monsters =  NULL;
    }
     if (_projectiles)
    {
        _projectiles->release();
        _projectiles =  NULL;
    }
}

然后在init函数中初始化这两个数组:

1
2
3
4
this->_monsters = CCArray::create();
this->_monsters->retain();
this->_projectiles = CCArray::create();
this->_projectiles->retain();

修改 addMonster函数,为怪物精灵添加标签,并加入到数组,代码如下:

1
2
monster->setTag( 1);
_monsters->addObject(monster);

修改 ccTouchesEnded函数,为子弹精灵添加标签,并加入到数组,代码如下:

1
2
projectile->setTag( 2);
_projectiles->addObject(projectile);

然后修改 spriteMoveFinished函数,增加如下代码:

1
2
3
4
5
6
7
8
if (sprite->getTag() ==  1)
{
    _monsters->removeObject(sprite);
}
else  if (sprite->getTag() ==  2)
{
    _projectiles->removeObject(sprite);
}

添加如下方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
void HelloWorld::update( float dt)
{
    CCArray *projectilesToDelete = CCArray::create();
    
    CCObject *pObject =  NULL;
    CCObject *pObject2 =  NULL; 
    CCARRAY_FOREACH(_projectiles, pObject)
    {
        CCSprite *projectile = (CCSprite*)pObject;
        CCArray *monstersToDelete = CCArray::create();

CCARRAY_FOREACH(_monsters, pObject2)
        {
            CCSprite *monster = (CCSprite*)pObject2;
             if (CCRect::CCRectIntersectsRect(projectile->boundingBox(), monster->boundingBox()))
            {
                monstersToDelete->addObject(monster);
            }           
        }

CCARRAY_FOREACH(monstersToDelete, pObject2)
        {
            CCSprite *monster = (CCSprite*)pObject2;
            _monsters->removeObject(monster);
             this->removeChild(monster,  true);
        }

if (monstersToDelete->count() >  0)
        {
            projectilesToDelete->addObject(projectile);
        }
        
        monstersToDelete->release();
    }

CCARRAY_FOREACH(projectilesToDelete, pObject)
    {
        CCSprite *projectile = (CCSprite*)pObject;
        _projectiles->removeObject(projectile);
         this->removeChild(projectile,  true);
    }
    
    projectilesToDelete->release();
}

遍历子弹数组,计算每一个子弹所可能遇到的怪物,用它们各自的边界框进行交叉检测,检测到交叉,则将怪物对象放入ToDelete(待删除)数组,不能在遍历的时候删除一个对象。若是子弹遇到了怪物,也需要放入ToDelete(待删除)数组。然后从场景和数组中移动掉。同样,也在init函数,安装定时器,代码如下:

1
this->schedule(schedule_selector(HelloWorld::update));

11.编译运行,这时当子弹和怪物碰撞时,它们就会消失;
12.添加音效,在 init函数添加背景音乐,代码如下:

1
CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic( "background-music-aac.wav");

ccTouchesEnded函数,添加子弹音效,代码如下:

1
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect( "shoot.mp3");

13.接下来,创建一个新的场景,来指示"You Win"或者"You Lose"。右键 工程,"Add"→"Class..."→"C++"→"Add","Base class"为CCLayerColor,"Class name"为 GameOverLayer,如下图所示:

GameOverLayer.h文件代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma once
#include  "cocos2d.h"

class GameOverLayer :
     public cocos2d::CCLayerColor
{
public:
    GameOverLayer( void);
    ~GameOverLayer( void);
     bool initWithWon( bool won);

static cocos2d::CCScene* sceneWithWon( bool won);
     static GameOverLayer* createWithWon( bool won);
     void gameOverDone();
};

GameOverLayer.cpp文件代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include  "GameOverLayer.h"
#include  "HelloWorldScene.h"
using  namespace cocos2d;

GameOverLayer::GameOverLayer( void)
{
}

GameOverLayer::~GameOverLayer( void)
{
}

GameOverLayer* GameOverLayer::createWithWon( bool won)
{
    GameOverLayer *pRet =  new GameOverLayer();
     if (pRet && pRet->initWithWon(won))
    {
        pRet->autorelease();
         return pRet;
    }
     else
    {
        CC_SAFE_DELETE(pRet);
         return  NULL;
    }
}

bool GameOverLayer::initWithWon( bool won)
{
     bool bRet =  false;
     do 
    {
        CC_BREAK_IF(! CCLayerColor::initWithColor(ccc4( 255,  255,  255,  255)));//设置屏幕为白色

char *message;
         if (won)
        {
            message =  "You Won!";//显示你赢了
        } 
         else
        {
            message =  "You Lose :[";//显示你输了
        }
        
        CCSize winSize = CCDirector::sharedDirector()->getWinSize();
        CCLabelTTF *label = CCLabelTTF::create(message,  "Arial",  32);//控制字体大小
        label->setColor(ccc3( 0,  0,  0));//控制字体颜色
        label->setPosition(ccp(winSize.width /  2, winSize.height /  2));//设置坐标位置
         this->addChild(label);//添加到屏幕

//场景上的层显示一个文本,在3秒之后调用gameOverDone函数从而返回到HelloWorld场景中
         this->runAction(CCSequence::create(CCDelayTime::create( 3), 
            CCCallFunc::create( this, callfunc_selector(GameOverLayer::gameOverDone)),
             NULL));
        
        bRet =  true;
    }  while ( 0);

return bRet;
}

cocos2d::CCScene* GameOverLayer::sceneWithWon( bool won)
{
    CCScene * scene =  NULL;
     do 
    {
        scene = CCScene::create();
        CC_BREAK_IF(! scene);

GameOverLayer *layer = GameOverLayer::createWithWon(won);
        CC_BREAK_IF(! layer);

scene->addChild(layer);
    }  while ( 0);

return scene;
}

//gameOverDone()函数控制场景,跳转回到HelloWorld游戏场景
void GameOverLayer::gameOverDone()
{
    CCDirector::sharedDirector()->replaceScene(HelloWorld::scene());
}

游戏结束时,切换到以上所建的场景,场景上的层显示一个文本,在3秒之后返回到HelloWorld场景中。

14.最后,为游戏添加一些游戏逻辑。

我们将规则定位:当放走3个敌机后,则游戏结束。而如果游戏结束时,被消灭敌机数量超过30个,则判断为胜利,反之为失败。
记录玩家消灭怪物的数量,进而决定该玩家输赢。在HelloWorldScene.h文件中,添加如下:

1
int _monstersDestroyed;

HelloWorldScene.cpp文件,HelloWorld()构造函数,添加如下代码:

1
_monstersDestroyed =  0;

添加头文件引用:

1
#include  "GameOverLayer.h"

update定时函数中,monstersToDelete循环removeChild(monster, true)的后面添加被消灭怪物的计数,并判断胜利条件,代码如下:

1
2
3
4
5
6
_monstersDestroyed++; //计算消灭的敌机数量
if (_monstersDestroyed >  30)//当放走3个敌机后游戏结束时,如果敌机数量超过30个,则判断为胜利,反之为失败。
{
    CCScene *gameOverScene = GameOverLayer::sceneWithWon( true);
    CCDirector::sharedDirector()->replaceScene(gameOverScene);
}

最后为玩家添加游戏结束条件,规定如果超过3个敌机跑到屏幕下方里,则游戏结束。

HelloWorldScene.h文件中,添加如下:

int _life;

HelloWorldScene.cpp文件中的spriteMoveFinished函数里,sprite->getTag() == 1条件的后面,添加如下:

     //统计放跑敌机的数量,如果超过3个则游戏结束
_life++;
if(_life>=3)
{
CCScene *gameOverScene = GameOverLayer::sceneWithWon(false);
CCDirector::sharedDirector()->replaceScene(gameOverScene);
}    

最后编译并运行,即可看到游戏。到此已完成了一个简单的游戏,包含音效,并带有胜利和失败的结束。

本例子源代码附加资源下载地址:http://download.csdn.net/detail/u013174689/6826063

可以运行压缩文件夹Star Fighter源码\Debug.win32里的exe文件运行查看游戏效果。

如文章存在错误之处,欢迎指出,以便改正。

cocos2d x 入门学习(一)实例制作简单的射击小游戏Star Fighter相关推荐

  1. 利用Python制作第一人称射击小游戏 含源代码

    大家好 我是毕加锁 (锁!) 今天教大家利用Python制作第一人称小游戏 涉及知识点 1.sprites 2.pygame混音器 3.图章    4.python基础语法 .代码 1发射声 from ...

  2. python编辑简单小游戏大全_Python制作简单的滑雪小游戏

    开发工具 Python版本:3.6.4 相关模块: pygame模块: 以及一些Python自带的模块.关注公众号:Python学习指南,回复"滑雪"获取源码 环境搭建 安装Pyt ...

  3. Python制作简单的滑雪小游戏

    开发工具 Python版本:3.6.4 相关模块: pygame模块: 以及一些Python自带的模块. 关注公众号:Python学习指南,回复"滑雪"获取相关文件 环境搭建 安装 ...

  4. C++制作简单的军棋小游戏(控制台窗口)

    一.游戏规则: 这款自己DIY的小游戏有24个棋子.其中司令,军长各1个:师长,旅长,团长,营长,炸弹各2个:连长,排长,工兵,地雷各3个.棋子由小到大的顺序是:司令>军长>师长>旅 ...

  5. 使用construct2制作射击小游戏

    使用construct2制作射击小游戏 简介 本次我们使用construct2制作一个HTML5 射击小游戏. 目的是player方向由鼠标操控,移动由键盘控制,同时拥有计分标志. 背景 建立好新空白 ...

  6. unity课设小游戏_Unity制作20个迷你小游戏实例训练视频教程

    本教程是关于Unity制作20个迷你小游戏实例训练视频教程,时长:20小时,大小:3.8 GB,MP4高清视频格式,教程使用软件:Unity,附源文件,作者:Raja Biswas,共97个章节,语言 ...

  7. 用计算机玩游戏最简单的方法,如何制作电脑简易命令小游戏

    满意答案 sylvia1017 2019.01.20 采纳率:48%    等级:7 已帮助:460人 简单的Dos小游戏 开始学习java,这周只简单的学习了C++的基本语法:输入输出,判断循环,因 ...

  8. 制作一个简单的switch小游戏

    好的,那么,我们可以这样来制作一个简单的 switch 小游戏: 首先,我们需要先引入所需的库,如 stdio.h 和 stdlib.h. 接着,我们可以使用 printf 和 scanf 函数来输出 ...

  9. python +pygame 制作五子连珠小游戏

    python +pygame 制作五子连珠小游戏 学习python半年了,今天分享一个利用pygame制作的五子连珠游戏. 一.代码: 1.球类,ball.py """ ...

最新文章

  1. 视频专辑:Photoshop基础视频教程
  2. 关于Shiro框架权限标识符中*使用的总结
  3. 他用五年研究百位百万富翁生活习惯 结果很震撼
  4. C++中string构造函数的解析
  5. SAP PO相关打印编程
  6. 大批量执行webservice出现“无法连接远程服务器”解决方案
  7. 在ABAP XSLT中调用ABAP类的方法
  8. 深入了解HashMap
  9. 需求、需求工程与需求工程师 — 3. 需求工程的构成
  10. Qt图形测绘窗口部件介绍
  11. 走迷宫问题 算法竞赛入门经典
  12. 第一章 ASP.NET MVC简介(1.1)
  13. 公众号引用js sdk ios兼容问题 报 permission value is offline verifying
  14. AtCoder Beginner Contest 261笔记
  15. Inception(盗梦空间)及代码实现
  16. html后代选择器的语法,[转]CSS子选择器与后代选择器
  17. 微信小程序加入(长按识别)群聊(群二维码)
  18. 「精品」板绘线稿临摹图
  19. 攻防世界 Misc Miscellaneous-200
  20. 小功能⭐️Unity中利用材质自发光实现物体闪烁效果

热门文章

  1. 最受欢迎导师北大演讲:从幸福到更幸福的五个方法
  2. python关键字数据驱动_携程大牛谈自动化测试里的数据驱动和关键字驱动思路的理解...
  3. Linux 下计划任务
  4. 小程序笔记(二)另一种方便获取wxapkg方法
  5. 英语口语智能测试软件,高职高专英语口语智能对话测试系统应用研究
  6. Windows API一日一练(55)FlushFileBuffers和SetFilePointer函数
  7. Java【教程】多线程
  8. python tesseract selenium自动识别验证码登陆
  9. 【STC8G1K08A】芯片---usb串口---直连烧录下载程序
  10. 计算机内存满了怎么清理,最彻底的手机清理软件,电脑内存不足怎么清理-