用OGRE1.74搭建游戏框架(一)

新版的OGRE出来了,不知什么原因抛弃了CEGUI。国内的教程好像也更新比较少了,在官网上还是发现不少资料的,现在参考官网上的一些资料来搭建一个游戏的框架。

参考的资料:

http://www.ogre3d.org/tikiwiki/Advanced+Ogre+Framework&structure=Tutorials

首先要先一个能启动OGRE的类(OgreFramework),把OGRE的初始化的相关工作放入其中,大体有如下几个东西:

  • Root
  • RenderWindow
  • Viewport
  • Log
  • Timer
  • InputManager / Keyboard / Mouse
  • SDKTrays Manager

OgreFramework.h

/********************************************************************

created: 2012/02/25

created: 25:2:2012 11:31

filename: E:\Ogre\Project\Ogre_Project\Game_Demo\OgreFramework.h

file path: E:\Ogre\Project\Ogre_Project\Game_Demo

file base: OgreFramework

file ext: h

author: Star purpose: ogre framework

*********************************************************************/ #ifndef _ZH_OGREFRAMEWORK_H_

#define _ZH_OGREFRAMEWORK_H_ #pragma once #include <Ogre.h>

#include <ois/OIS.h>

#include <SdkTrays.h> class OgreFramework: public Ogre::Singleton<OgreFramework>, OIS::KeyListener, OIS::MouseListener

{

public:

OgreFramework();

~OgreFramework(); bool InitOgre(Ogre::String wndTitle, OIS::KeyListener* pKeyListener = , OIS::MouseListener* pMouseListener = );

void UpdateOgre(double timeSinceLastFrame); // for key event

bool keyPressed(const OIS::KeyEvent& evt);

bool keyReleased(const OIS::KeyEvent& evt); // for mouse event

bool mouseMoved(const OIS::MouseEvent& evt);

bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id);

bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id); public:

Ogre::Root* m_pRoot;

Ogre::RenderWindow* m_pRenderWnd;

Ogre::Viewport* m_pViewport;

Ogre::Log* m_pLog;

Ogre::Timer* m_pTimer; OIS::InputManager* m_pInputMgr;

OIS::Keyboard* m_pKeyboard;

OIS::Mouse* m_pMouse; OgreBites::SdkTrayManager* m_pTrayMgr; private:

OgreFramework(const OgreFramework&);

OgreFramework& operator= (const OgreFramework&); }; #endif //_ZH_OGREFRAMEWORK_H_

主要还是要看InitOgre的实现:

bool OgreFramework::InitOgre(Ogre::String wndTitle, OIS::KeyListener* pKeyListener /* = 0 */, OIS::MouseListener* pMouseListener /* = 0 */)

{

Ogre::LogManager* logMgr = new Ogre::LogManager(); m_pLog = Ogre::LogManager::getSingleton().createLog("OgreLogfile.log", true, true, flase);

m_pLog->setDebugOutputEnabled(true); m_pRoot = new Ogre::Root(); if (!m_pRoot->showConfigDialog())

return false; m_pRenderWnd = m_pRoot->initialise(true, wndTitle); m_pViewport = m_pRenderWnd->addViewport();

m_pViewport->setBackgroundColour(ColourValue(0.5f, 0.5f, 0.5f, 1.0f)); m_pViewport->setCamera(); size_t hWnd = ;

OIS::ParamList paramList;

m_pRenderWnd->getCustomAttribute("WINDOW", &hWnd); paramList.insert(OIS::ParamList::value_type("WINDOW", Ogre::StringConverter::toSgring(hWnd))); m_pInputMgr = OIS::InputManager::createInputSystem(paramList); m_pKeyboard = static_cast<OIS::Keyboard*>(m_pInputMgr->createInputObject(OIS::OISKeyboard, true));

m_pMouse = static_cast<OIS::Mouse*>(m_pInputMgr->createInputObject(OIS::OISMouse, true)); m_pMouse->getMouseState().height = m_pRenderWnd->getHeight();

m_pMouse->getMouseState().width = m_pRenderWnd->getWidth(); if (pKeyListener == NULL)

m_pKeyboard->setEventCallback(this);

else

m_pKeyboard->setEventCallback(pKeyListener); if (pMouseListener == NULL)

m_pMouse->setEventCallback(this);

else

m_pMouse->setEventCallback(pMouseListener); // load resources

Ogre::String secName, typeName, archName;

Ogre::ConfigFile cf;

cf.load("resources.cfg"); Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();

while (seci.hasMoreElements)

{

secName = seci.peekNextKey();

Ogre::ConfigFile::SettingsMultiMap* settings = seci.getNext();

Ogre::ConfigFile::SettingsMultiMap::iterator i;

for (i = settings->begin(); i != settings->end(); ++i)

{

typeName = i->first;

archName = i->second;

Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName);

}

}

Ogre::TextureManager::getSingleton().setDefaultNumMipmaps();

Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); m_pTrayMgr = new OgreBites::SdkTrayManager("OFTrayMgr", m_pRenderWnd, m_pMouse, ); m_pTimer = new Ogre::Timer();

m_pTimer->reset(); m_pRenderWnd->setActive(true); return true;

}

里边主要做了以下几个工作:

1.创建日志管理

2.创建OGRE的Root

3.创建渲染窗口(RenderWindow)和视口(Viewport)

4.启动OIS

5.设置鼠标和键盘的监听

6.载入资源

7.设置Timer

8.初始化SDKTrayManager

9.创建并显示debug overlay

注意,这里边没有像机和场景管理器,这个要到后面的状态类中才用到。

void OgreFramework::UpdateOgre(double timeSinceLastFrame)

{ }

这个函数用于在每一帧中更新和OGRE相关的一些东西,自己写的东西是要在每个状态中自己更新。

其实游戏的框架,普遍还是用的State这个设计模式。这样就可以在开始菜单,游戏画面,结束画面中自由的切换。看Android的libgdx引擎也是这样做的,分成不同的Screen来相互切换。

用OGRE1.74搭建游戏框架(二)--添加菜单

在上一节中,已经把OGRE的一个框架搭出来了,而且用的是一个单例模式,这样就意味着我们在后面的状态模式中可以很容易的就使用OGRE来帮我们进行图形绘制。

首先,写一个所有游戏状态的基类,因为我们大体可以抽象出所有游戏状态都应该有:

1.进入这个状态时应该做一些准备工作

2.退出这个状态时应该删除某些东西

3.暂停和继续时的一些动作。

4.更新

而一个游戏里有很多状态的切换,而我们又不想让一个状态知道另一个状态的存在,于是我们就要有一个统一管理这些状态的一个类,这样就能让这些状态之间解耦。(如果不这样做,比如说我想从菜单状态切换到游戏开始状态,那么我得在开始菜单中保存一个指向游戏开始状态的指针,而游戏开始状态想切到其它的状态也得这么做。)

因此我们写一个状态管理类,它实现一个状态监听接口。

状态管理用一个栈来存储所有的状态,当从当前状态切换到另一个状态时,就把栈顶的状态取出,并调用它的Exit()函数,并Pop出去,然后再初始化新的状态,并调用新状态的Enter()函数。

void CGameStateManager::ChangeGameState(CGameState* state)
{
if (!m_ActiveStateStack.empty())
{
m_ActiveStateStack.back()->Exit();
m_ActiveStateStack.pop_back();
} m_ActiveStateStack.push_back(state);
Init(state);
m_ActiveStateStack.back()->Enter();
}

GameState.h文件如下:

/********************************************************************
created: 2012/02/25
created: 25:2:2012 15:05
filename: E:\Ogre\Project\Ogre_Project\Game_Demo\GameState.h
file path: E:\Ogre\Project\Ogre_Project\Game_Demo
file base: GameState
file ext: h
author: Star purpose: the parent of all the game state
*********************************************************************/ #ifndef _ZH_GAMESTATE_H_
#define _ZH_GAMESTATE_H_ #pragma once #include "OgreFramework.h" class CGameState; class CGameStateListener
{
public:
CGameStateListener(){};
virtual ~CGameStateListener(){}; virtual void ManageGameState(Ogre::String stateName, CGameState* state) = ; virtual CGameState* FindByName(Ogre::String stateName) = ;
virtual void ChangeGameState(CGameState* state) = ;
virtual bool PushGameState(CGameState* state) = ;
virtual void PopGameState() = ;
virtual void PauseCurGameState() = ;
virtual void Shutdown() = ;
virtual void PopAllAndPushGameState(CGameState* state) = ;
}; class CGameState : public OIS::KeyListener,public OIS::MouseListener, public OgreBites::SdkTrayListener
{
public:
static void Create(CGameStateListener* parent, const Ogre::String name) {}; void destroy() { delete this; } virtual void Enter() = ;
virtual void Exit() = ;
virtual bool Pause() { return true;}
virtual void Resume() {};
virtual void Update(double timeSinceLastFrame) = ; protected:
CGameState(){}; CGameState* FindByName(Ogre::String stateName) {return m_pListener->FindByName(stateName); }
void ChangeGameState(CGameState* state) { m_pListener->ChangeGameState(state); }
bool PushGameState(CGameState* state) { return m_pListener->PushGameState(state);}
void PopGameState() {m_pListener->PopGameState(); }
void Shutdown() { m_pListener->Shutdown(); }
void PopAllAndPushGameState(CGameState* state) { m_pListener->PopAllAndPushGameState(state); } CGameStateListener* m_pListener; Ogre::Camera* m_pCamera;
Ogre::SceneManager* m_pSceneMgr;
Ogre::FrameEvent m_FrameEvent;
}; // macro define
#define DECLARE_GAMESTATE_CLASS(T) \
static void Create(CGameStateListener* pListener, const Ogre::String name) \
{ \
T* newState = new T(); \
newState->m_pListener = pListener; \
pListener->ManageGameState(name, newState); \
} \ #endif //_ZH_GAMESTATE_H_

上面代码中最后有一个宏定义,它的做用就是定义每个状态,并把它自己注册进状态管理类里。这是为了让你少写一些代码,不然你每定义一个状态类就得写一遍这个函数,有这个宏就方便多了。

可以看一下类图:

GameStateManager.h

/********************************************************************
created: 2012/02/25
created: 25:2:2012 16:05
filename: E:\Ogre\Project\Ogre_Project\Game_Demo\GameStateManager.h
file path: E:\Ogre\Project\Ogre_Project\Game_Demo
file base: GameStateManager
file ext: h
author: Star purpose: Manage all the game states
*********************************************************************/ #ifndef _ZH_GAMESTATEMANAGER_H_
#define _ZH_GAMESTATEMANAGER_H_ #pragma once
#include "GameState.h" class CGameStateManager : public CGameStateListener
{
public:
typedef struct
{
Ogre::String name;
CGameState* state;
} SState_info; CGameStateManager();
~CGameStateManager(); void ManageGameState(Ogre::String stateName, CGameState* state); CGameState* FindByName(Ogre::String stateName); void Start(CGameState* state);
void ChangeGameState(CGameState* state);
bool PushGameState(CGameState* state);
void PopGameState();
void PauseCurGameState();
void Shutdown();
void PopAllAndPushGameState(CGameState* state); protected:
void Init(CGameState* state); std::vector<CGameState*> m_ActiveStateStack;
std::vector<SState_info> m_States;
bool m_bShutdown;
}; #endif //_ZH_GAMESTATEMANAGER_H_

这个就是状态管理类,这里边的Start函数,就是程序消息循环的位置了。状态的切换也都在这里边发生。

这些函数的实现我就不复制,粘贴了,到时最后会发一个代码链接。

有了这些状态定义,我们现在就来试一下,先做一个MenuState。

MenuState.h

/********************************************************************
created: 2012/02/27
created: 27:2:2012 11:40
filename: E:\Ogre\Project\Ogre_Project\Game_Demo\MenuState.h
file path: E:\Ogre\Project\Ogre_Project\Game_Demo
file base: MenuState
file ext: h
author: Star purpose: the menu of the game
*********************************************************************/ #ifndef _ZH_MENUSTATE_H_
#define _ZH_MENUSTATE_H_ #pragma once #include "GameState.h" class CMenuState : public CGameState
{
public:
CMenuState(); DECLARE_GAMESTATE_CLASS(CMenuState) void Enter();
void CreateScene();
void Exit(); bool keyPressed(const OIS::KeyEvent &evt);
bool keyReleased(const OIS::KeyEvent &evt); bool mouseMoved( const OIS::MouseEvent &evt);
bool mousePressed( const OIS::MouseEvent &evt, OIS::MouseButtonID id );
bool mouseReleased( const OIS::MouseEvent &evt, OIS::MouseButtonID id ); void buttonHit(OgreBites::Button* button); void Update(double timeSinceLastFrame); private:
bool m_bQuit; }; #endif //_ZH_MENUSTATE_H_

主要讲一下Enter函数,这里边就要创建一下菜单界面了,还有Camera和SceneManager的创建,用的是OGRE现在带的SDKTray。然后也可以创建场景,这样就会有比较动感的开始菜单界面了等。

void CMenuState::Enter()
{
Ogre::FontManager::getSingleton().getByName("SdkTrays/Caption")->load();
COgreFramework::getSingletonPtr()->m_pLog->logMessage("Entering MenuState.h."); m_pSceneMgr = COgreFramework::getSingletonPtr()->m_pRoot->createSceneManager(ST_GENERIC, "MenuSceneMgr");
m_pSceneMgr->setAmbientLight(Ogre::ColourValue(0.7f, 0.7f, 0.7f)); m_pCamera = m_pSceneMgr->createCamera("MenuCam");
m_pCamera->setPosition(Vector3(, , -));
m_pCamera->lookAt(Vector3(, , ));
m_pCamera->setNearClipDistance(); m_pCamera->setAspectRatio(Real(COgreFramework::getSingletonPtr()->m_pViewport->getActualWidth())/
Real(COgreFramework::getSingletonPtr()->m_pViewport->getActualHeight())); COgreFramework::getSingletonPtr()->m_pViewport->setCamera(m_pCamera); COgreFramework::getSingletonPtr()->m_pTrayMgr->destroyAllWidgets();
COgreFramework::getSingletonPtr()->m_pTrayMgr->showFrameStats(OgreBites::TL_BOTTOMLEFT);
COgreFramework::getSingletonPtr()->m_pTrayMgr->showLogo(OgreBites::TL_BOTTOMRIGHT);
COgreFramework::getSingletonPtr()->m_pTrayMgr->showCursor();
COgreFramework::getSingletonPtr()->m_pTrayMgr->createButton(OgreBites::TL_CENTER, "EnterBtn", "Enter GameState", );
COgreFramework::getSingletonPtr()->m_pTrayMgr->createButton(OgreBites::TL_CENTER, "ExitBtn", "Exit OgreFramework", );
COgreFramework::getSingletonPtr()->m_pTrayMgr->createLabel(OgreBites::TL_TOP, "MenuLbl","Menu mode", ); CreateScene();
}

这边有一个注意项:

如果没有这句的话

 Ogre::FontManager::getSingleton().getByName("SdkTrays/Caption")->load();

我这边顶上的那个Label里是不显示文字的,在他的论坛里找到这么一个解决方案。

最后的效果截图:

通过这样的框架就可以搭建自己的游戏了,只要继承GameState,实现自己的场景绘制和UI,就好了。期待你的游戏的产生。

资源下载:

http://download.csdn.net/detail/sunstar1989/4094433

用OGRE1.74搭建游戏框架(三)--加入人物控制和场景

有了前面的状态机,我们就可以很方便的扩展出自己的游戏场景状态的类。

现在我们要写一个RunState的类,这个就是游戏的主场景所在的地方,从MenuState可以跳转过来。

一、加入第三人称控制器

对于人物的控制,新版的OGRE已经给出了一个示例,就是那个Sample_Charater。

里边是对一个OGRE新模型的控制,操作起来感觉不错,就是向前跑动的时候没法看身后的东西,得停下来,Camera才会回到自由模式。

这个地方主要用到两个类:

SdkCameraMan:封装了OGRE的像机,可以比较自由的控制像机。

SinbadCharacterController:对于Sinbad的角色的控制以及动画的播放。

只要声明并定义好这两个类就能快速的实现第三人称的控制。

CRunState.h

class CRunState : public CGameState
{
public:
CRunState(); DECLARE_GAMESTATE_CLASS(CRunState) void Enter();
void CreateScene();
void Exit();
bool Pause();
void Resume(); bool keyPressed(const OIS::KeyEvent &evt);
bool keyReleased(const OIS::KeyEvent &evt); bool mouseMoved( const OIS::MouseEvent &evt);
bool mousePressed( const OIS::MouseEvent &evt, OIS::MouseButtonID id );
bool mouseReleased( const OIS::MouseEvent &evt, OIS::MouseButtonID id ); void Update(double timeSinceLastFrame); protected:
OgreBites::SdkCameraMan* m_pCameraMan; bool m_bIsQuit; SinbadCharacterController* m_pChara;
};

在Enter函数中初始化:

void CRunState::Enter()
{
COgreFramework::getSingletonPtr()->m_pLog->logMessage("Entering RunState.h."); m_pSceneMgr = COgreFramework::getSingletonPtr()->m_pRoot->createSceneManager(ST_GENERIC, "RunSceneMgr");
m_pSceneMgr->setAmbientLight(Ogre::ColourValue(0.3f, 0.3f, 0.3f)); m_pCamera = m_pSceneMgr->createCamera("MainCam");
m_pCamera->setNearClipDistance(5); m_pCamera->setAspectRatio(Real(COgreFramework::getSingletonPtr()->m_pViewport->getActualWidth())/
Real(COgreFramework::getSingletonPtr()->m_pViewport->getActualHeight())); COgreFramework::getSingletonPtr()->m_pViewport->setCamera(m_pCamera); m_pCameraMan = new OgreBites::SdkCameraMan(m_pCamera);
m_pCameraMan->setStyle(OgreBites::CS_MANUAL); m_pChara = new SinbadCharacterController(m_pCamera); COgreFramework::getSingletonPtr()->m_pTrayMgr->destroyAllWidgets();
COgreFramework::getSingletonPtr()->m_pTrayMgr->hideCursor(); CreateScene(); }

在那些键盘和鼠标消息中响应人物和摄像机的事件。最后要在Update中更新动画。

void CRunState::Update(double timeSinceLastFrame)
{
if (m_bIsQuit)
{
Shutdown();
return;
} if (m_pChara)
m_pChara->addTime(timeSinceLastFrame/1000); // from miliseconds to seconds }

这边注意,因为我们前面用的是毫秒,这边动画更新需要的是秒为单位,所以要除,否则画面不会动。

二、载入.Scene场景文件

如果要用代码加入物体,不仅麻烦(得算坐标),而且不易修改(修改后得重新编译)。于是就有了场景文件的出现,而且也有了开源的场景编辑器(Ogitor)。

Ogitor是一个基于QT的OGRE场景的编辑器,可以到官网上下载:

http://www.ogitor.org/HomePage

在我们的工程中要用到的就是三个文件(在Ogitor的安装目录的/SampleApp_Source/下):

DotSceneLoader.h

DotSceneLoader.cpp

rapidxml.h

把他们拷进我们的工程里,我们将要使用他们来载入场景。

这时,会发现程序有错,DotSceneLoader.cpp里要引用到PagedGeometry的一些东西,这是一个用来植树造林的工具,我们也可以去下载。

http://www.ogre3d.org/tikiwiki/PagedGeometry+Engine

官方没有提供已经编译好的,所以需要自己编译,要配置OGRE的头文件和库的路径。

新的OGRE中的material的一个方法改了,所以编译会有错误:

需要将:

bestTechnique = material->getBestTechnique(material->getLodIndexSquaredDepth(parent->minDistanceSquared));

转换为:

bestTechnique = getLodIndex(parent->minDistanceSquared)

这样就可以编译出LIB库了。

回到我们的工程:

在CreateScene函数中载入场景:

void CRunState::CreateScene()
{
DotSceneLoader* pDotSceneLoader = new DotSceneLoader();
pDotSceneLoader->parseDotScene("CubeScene.xml", "General", m_pSceneMgr, m_pSceneMgr->getRootSceneNode());
delete pDotSceneLoader; // add a bright light above the scene
Light* light = m_pSceneMgr->createLight();
light->setType(Light::LT_POINT);
light->setPosition(-10, 40, 20);
light->setSpecularColour(ColourValue::White); // create a floor mesh resource
MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Plane(Vector3::UNIT_Y, 0), 100, 100, 10, 10, true, 1, 10, 10, Vector3::UNIT_Z); // create a floor entity, give it a material, and place it at the origin
Entity* floor = m_pSceneMgr->createEntity("Floor", "floor");
floor->setMaterialName("Examples/Rockwall");
floor->setCastShadows(false);
m_pSceneMgr->getRootSceneNode()->attachObject(floor);
}

这边要注意在资源文件(resource.cfg)中加入CubeScene.xml和Cube模型的资源路径,否则OGRE不会载入他们,就找不到这些资源。

最后就可以看到结果了:

尝试着载入了Ogitor自带的Sample文件,SampleScene3.scene。注意要把资源路径配好。

人缩小一倍还比房子大。。。有点像绿巨人,人物的位置要根据地形高低来设置好。

 
 
 
 

用用OGRE1.74搭建游戏框架(转载)的更多相关文章

  1. 使用Html5+C#+微信 开发移动端游戏详细教程 :(三)使用html5引擎搭建游戏框架

    教程里的案例我们是通过H5游戏引擎开发,目前H5的游戏引擎比较好用的是白鹭,不过对于新手来说白鹭的开发环境和工具使用过于复杂,这里推荐一个国内大神编写的游戏引擎:lufylegend. 直接在页面引入 ...

  2. Unity 游戏框架搭建 (六) 关于框架的一些好文和一些思考

      在进行项目架构阶段,游戏框架可以解决一部分问题.剩下的架构问题还需要根据不同的项目解决.总之游戏框架是游戏架构的一部分. 关于锤子和钉子:   最近又拿起了<代码大全>和<暗时间 ...

  3. Unity 游戏框架搭建 2018 (一) 架构、框架与 QFramework 简介

    约定 还记得上版本的第二十四篇的约定嘛?现在出来履行啦~ 为什么要重制? 之前写的专栏都是按照心情写的,在最初的时候笔者什么都不懂,而且文章的发布是按照很随性的一个顺序.结果就是说,大家都看完了,都还 ...

  4. Unity 游戏框架搭建 (十七) 静态扩展GameObject实现链式编程

    本篇本来是作为原来 优雅的QChain的第一篇的内容,但是QChain流产了,所以收录到了游戏框架搭建系列.本篇介绍如何实现GameObject的链式编程. 链式编程的实现技术之一是C#的静态扩展.静 ...

  5. Unity 游戏框架搭建 (十六) v0.0.1 架构调整

    背景: 前段时间用Xamarin.OSX开发一些工具,遇到了两个问题. QFramework的大部分的类耦合了Unity的API,这样导致不能在其他CLR平台使用QFramework. QFramew ...

  6. Unity 游戏框架搭建 (十三) 无需继承的单例的模板

    之前的文章中介绍的Unity 游戏框架搭建 (二) 单例的模板和Unity 游戏框架搭建 (三) MonoBehaviour单例的模板有一些问题. 存在的问题: 只要继承了单例的模板就无法再继承其他的 ...

  7. Unity 游戏框架搭建 (十) QFramework v0.0.2小结

    从框架搭建系列的第一篇文章开始到现在有四个多月时间了,这段时间对自己来说有很多的收获,好多小伙伴和前辈不管是在评论区还是私下里给出的建议非常有参考性,在此先谢过各位. 说到是一篇小节,先列出框架的概要 ...

  8. 凉鞋:我所理解的框架 【Unity 游戏框架搭建】

    前言 架构和框架这些概念听起来很遥远,让很多初学者不明觉厉.会产生"等自己技术牛逼了再去做架构或者搭建框架"这样的想法.在这里笔者可以很肯定地告诉大家,初学者是完全可以去做这些事情 ...

  9. [Android游戏开发]游戏框架的搭建

    通常情况下,游戏开发的基本框架中,一般包括以下模块: 窗口管理(Window management):该模块负责在Android平台上创建.运行.暂停.恢复游戏界面等功能. 输入模块(Input):该 ...

随机推荐

  1. 解决Windows平台通过cURL上传APP到蒲公英pgyer平台时无法使用中文升级描述的问题

    解决Windows平台通过cURL上传APP到蒲公英pgyer平台时无法使用中文升级描述的问题 官方上传命令 curl -F file=@"315.apk" -F uKey=XXX ...

  2. Atitit.rust语言特性 attilax 总结

    Atitit.rust语言特性 attilax 总结 1. 创建这个新语言的目的是为了解决一个顽疾:软件的演进速度大大低于硬件的演进,软件在语言级别上无法真正利用多核计算带来的性能提升.1 2. 不会 ...

  3. swift中代理的使用

    1.首先定义一份协议. protocol HttpToolProrocol{ //1.代理方法,将server返回的字典传递给调用者 func didRecieveResults(result:NSD ...

  4. oracle中直方图的使用

    本文从不绑定变量和绑定变量两种情况讨论直方图的作用 一.不绑定变量 SQL> create table test(name varchar2(10));表已创建.SQL> insert i ...

  5. u-boot-2014_04在TQ2440上的移植

    本文详细介绍了新版本的u-boot-2014_04在tq2440平台上的移植过程,期间参考了网上的其他移植文档,还有韦东山的移植uboot视频,讲的很好.下面是共享链接,欢迎下载,一同学习.其中有移植 ...

  6. cvm母机宕机重启后数据库修复

    下午正在开周会,然后收到短信,说是X.X.X.X的机器ping不通了,一轮测试过后,发现是某台数据库服务器挂了,先不急着重启,问下tencent客服... 乖乖的好家伙,母机的主板坏了....一个小时 ...

  7. springmvc demo

    [说明]今天上午稍稍偏了一下方向,看了看servlet的相关知识,下午做maven+spring+springMVC的整合,晚上成功实现了一个小demo(可以在jsp动态页面上获得通过地址栏输入的参数 ...

  8. 小米4s经常断网

    https://zhidao.baidu.com/question/1387985910554061020.html

  9. A norm is a function. 范数是函数。

    [范数]范数是函数.A norm is a function.范数(norm),是具有“长度”概念的函数.在线性代数.泛函分析及相关的数学领域,是一个函数,其为向量空间内的所有向量赋予非零的正长度或大 ...

  10. 从 零开始 无差错 装好nginx+PHP

    由于这两天 一直有人追问 nginx为何报错,为何php没装好啥的,大多原因是 : 1.编译与yum混合安装,导致很多包的路径不对,进而报错 2.yum源比较旧,导致 与新版本的php不匹配 3.安装 ...