cocos2d-x官方自带的输入框,简直惨不忍睹,在ios还好,在安卓简直了。。用过的都知道。。。

所以为了用户体验,我们自己搞一个吧。输入框这种东西比较特殊,不像按钮、列表框之类的很容易实现,因为涉及到复制粘贴、操作虚拟键盘等,所以当然是用安卓原生的输入框最好了。

非常感谢我们的主程陈剑大哥,思路是陈剑大哥想的,我只负责记录一下。

本来代码50天前就写好了,但是绑定到js一直失败,恶心了好几天放弃了。前几天在用lua写点东西,把之前的代码拷过来试着绑定到lua,结果一次就成功了,完全没有踩坑,不知道说什么好了。。而且前几天官方发布了cocos2d-x 3.8版本,已经自带了,所以现在再发出来感觉毫无竞争力了呢。。。

使用原生控件的优点不用多说了,缺点当然也是有的。例如排版、布局、屏幕适配等,都要适应cocos2d的规则,而且由于是系统控件,渲染层级不受cocos2d的zorder的影响。当然这些努力一下也是可以解决的。

要注意的有:

1、c++通过jni控制java创建安卓控件。

2、c++持有java对象的引用,防止垃圾回收。

3、java回调c语言,c语言调用c++,所以需要处理好java对象与c++对象的对应关系。

我的做法是:

1、创建一个输入框工厂类,负责根据不同平台生成输入框,当然我只会安卓的。

2、工厂类维护一个map,保存c++对象和java对象的对应关系。

3、根据cocos2d的世界坐标系,更新安卓原生控件。

防止恶意转载还改名的恶心行为。本博客地址:http://www.cnblogs.com/wolfred7464/

上代码吧:

 #ifndef __CocosAndroidStudio__EditText__
#define __CocosAndroidStudio__EditText__ #include <string>
#include "cocos2d.h" class EditText : public cocos2d::Node {
public:
virtual ~EditText() {};
virtual void setString(const std::string& str) = ;
virtual std::string getString() = ; protected: }; #endif /* defined(__CocosAndroidStudio__EditText__) */

EditText.h

 #ifndef __CocosAndroidStudio__EditTextAndroid__
#define __CocosAndroidStudio__EditTextAndroid__ #include "EditText.h"
#include "platform/android/jni/JniHelper.h"
#include "EditTextFactory.h" class EditTextAndroid : public EditText {
public:
~EditTextAndroid(); virtual void setString(const std::string& str) override;
virtual std::string getString() override; virtual void setPosition(const cocos2d::Vec2& pos) override;
virtual void setContentSize(const cocos2d::Size& size) override; virtual void onEnter() override; friend class EditTextFactory; private:
EditTextAndroid();
static EditTextAndroid* create(); cocos2d::JniMethodInfo getJavaMethod(const char* name, const char* param);
void setPositionAndroid();
void setContentSizeAndroid(); jobject _object;
}; #endif /* defined(__CocosAndroidStudio__EditTextAndroid__) */

EditTextAndroid.h

 #include "EditTextAndroid.h"
#include "cocos2d.h"
#include <unistd.h>
#include <string> USING_NS_CC;
using namespace std; EditTextAndroid* EditTextAndroid::create() {
auto ret = new EditTextAndroid();
ret->autorelease();
return ret;
} EditTextAndroid::EditTextAndroid() {
auto env = cocos2d::JniHelper::getEnv(); jclass cls = env->FindClass("org/red/tools/RedEditText");
assert(cls != NULL); jmethodID ctor = env->GetMethodID(cls, "<init>", "()V");
assert(ctor != NULL); this->_object = env->NewObject(cls, ctor);
env->NewGlobalRef(this->_object);
} EditTextAndroid::~EditTextAndroid() {
auto env = cocos2d::JniHelper::getEnv();
env->DeleteGlobalRef(this->_object);
} JniMethodInfo EditTextAndroid::getJavaMethod(const char* name, const char* param) {
JniMethodInfo info;
bool isHave = JniHelper::getMethodInfo(info, "org/red/tools/RedEditText", name, param);
assert(isHave);
return info;
} void EditTextAndroid::setString(const std::string& str) {
auto info = getJavaMethod("setString", "(Ljava/lang/String;)V");
jstring jstr = info.env->NewStringUTF(str.c_str());
info.env->CallVoidMethod(this->_object, info.methodID, jstr);
} std::string EditTextAndroid::getString() {
auto info = getJavaMethod("getString", "()Ljava/lang/String;");
auto jstr = (jstring)info.env->CallObjectMethod(this->_object, info.methodID); jboolean isCopy;
auto chars = info.env->GetStringUTFChars(jstr, &isCopy);
std::string str(chars);
if(isCopy == JNI_TRUE) {
info.env->ReleaseStringUTFChars(jstr, chars);
}
info.env->DeleteLocalRef(jstr);
return str;
} void EditTextAndroid::setPosition(const Vec2& pos) {
EditText::setPosition(pos);
setPositionAndroid();
} void EditTextAndroid::setContentSize(const Size& size) {
EditText::setContentSize(size);
setContentSizeAndroid();
} void EditTextAndroid::setPositionAndroid() {
if(isRunning()) {
auto pos = convertToWorldSpace(Vec2(, getContentSize().height));
auto info = getJavaMethod("setPosition", "(II)V");
auto visHeight = Director::getInstance()->getVisibleSize().height;
info.env->CallVoidMethod(this->_object, info.methodID, jint(pos.x), jint(visHeight - pos.y));
}
} void EditTextAndroid::setContentSizeAndroid() {
if(isRunning()) {
auto realSize = SizeApplyAffineTransform(getContentSize(), getNodeToWorldAffineTransform());
auto info = getJavaMethod("setContentSize", "(II)V");
info.env->CallVoidMethod(this->_object, info.methodID, jint(realSize.width), jint(realSize.height));
}
} void EditTextAndroid::onEnter() {
EditText::onEnter();
setPositionAndroid();
setContentSizeAndroid();
} extern "C" {
JNIEXPORT void JNICALL Java_org_red_tools_RedEditText_nativeOnTextChanged(JNIEnv *env, jobject javaThis, jstring jstr) {
jboolean isCopy;
auto chars = env->GetStringUTFChars(jstr, &isCopy);
std::string str(chars);
if(isCopy == JNI_TRUE) {
env->ReleaseStringUTFChars(jstr, chars);
}
log("[Red] textChanged: %s", str.c_str());
}
}

EditTextAndroid.cpp

 #ifndef __CocosAndroidStudio__EditTextFactory__
#define __CocosAndroidStudio__EditTextFactory__ #include "EditText.h"
#include <map>
#include "platform/android/jni/JniHelper.h" class EditTextFactory {
public:
static EditTextFactory* getInstance(); EditText* createEditText();
EditText* getEditTextByJobject(jobject obj); private:
EditTextFactory(); std::map<jobject, EditText*> _map;
}; #endif /* defined(__CocosAndroidStudio__EditTextFactory__) */

EditTextFactory.h

 #include "EditTextFactory.h"
#include "EditTextAndroid.h"
#include <string>
#include "cocos2d.h" EditTextFactory::EditTextFactory() {} EditTextFactory* EditTextFactory::getInstance() {
static EditTextFactory instance;
return &instance;
} EditText* EditTextFactory::createEditText() {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
auto edit = EditTextAndroid::create();
auto jobj = edit->_object;
_map.insert(std::pair<jobject, EditText*>(jobj, edit));
return edit;
#endif return nullptr;
} EditText* EditTextFactory::getEditTextByJobject(jobject obj) {
return _map[obj];
}

EditTextFactory.cpp

 package org.red.tools;

 import org.cocos2dx.lib.Cocos2dxActivity;

 import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.FrameLayout; public class RedEditText { private EditText _edit; public RedEditText() {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
RedEditText.this._edit = new EditText(Cocos2dxActivity.getContext());
EditText edit = RedEditText.this._edit;
//edit.setBackgroundDrawable(null);
edit.setTextColor(Color.rgb(255, 255, 255));
edit.setMaxLines(1);
edit.setSingleLine();
edit.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
Cocos2dxActivity activity = (Cocos2dxActivity)(Cocos2dxActivity.getContext());
FrameLayout root = (FrameLayout)activity.findViewById(android.R.id.content).getRootView();
root.addView(edit); edit.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
nativeOnTextChanged(s.toString());
} @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void afterTextChanged(Editable s) {}
});
}
});
} public void setString(final String str) {
Log.e("red", str);
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
_edit.setText(str);
}
});
} public String getString() {
return _edit.getText().toString();
} public void setContentSize(final int w, final int h) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)_edit.getLayoutParams();
params.width = w;
params.height = h;
_edit.setLayoutParams(params);
}
});
} public void setPosition(final int x, final int y) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)_edit.getLayoutParams();
params.leftMargin = x;
params.topMargin = y;
_edit.setLayoutParams(params);
}
});
} private native void nativeOnTextChanged(String s); }

RedEditText.java

最后是luabinding,吐血推荐教程:http://www.cocos.com/doc/tutorial/show?id=1295

这是我绑定之后的代码,可以直接用:

 #include "base/ccConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#ifndef __RedBindings_h__
#define __RedBindings_h__ #ifdef __cplusplus
extern "C" {
#endif
#include "tolua++.h"
#ifdef __cplusplus
}
#endif int register_all_RedBindings(lua_State* tolua_S); #endif // __RedBindings_h__
#endif //#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32

lua_RedBindings_auto.hpp

 #include "lua_RedBindings_auto.hpp"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#include "RedBindings.h"
#include "tolua_fix.h"
#include "LuaBasicConversions.h" int lua_RedBindings_EditText_setString(lua_State* tolua_S)
{
int argc = ;
EditText* cobj = nullptr;
bool ok = true; #if COCOS2D_DEBUG >= 1
tolua_Error tolua_err;
#endif #if COCOS2D_DEBUG >= 1
if (!tolua_isusertype(tolua_S,,"EditText",,&tolua_err)) goto tolua_lerror;
#endif cobj = (EditText*)tolua_tousertype(tolua_S,,); #if COCOS2D_DEBUG >= 1
if (!cobj)
{
tolua_error(tolua_S,"invalid 'cobj' in function 'lua_RedBindings_EditText_setString'", nullptr);
return ;
}
#endif argc = lua_gettop(tolua_S)-;
if (argc == )
{
std::string arg0; ok &= luaval_to_std_string(tolua_S, ,&arg0, "EditText:setString");
if(!ok)
{
tolua_error(tolua_S,"invalid arguments in function 'lua_RedBindings_EditText_setString'", nullptr);
return ;
}
cobj->setString(arg0);
lua_settop(tolua_S, );
return ;
}
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "EditText:setString",argc, );
return ; #if COCOS2D_DEBUG >= 1
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'lua_RedBindings_EditText_setString'.",&tolua_err);
#endif return ;
}
int lua_RedBindings_EditText_getString(lua_State* tolua_S)
{
int argc = ;
EditText* cobj = nullptr;
bool ok = true; #if COCOS2D_DEBUG >= 1
tolua_Error tolua_err;
#endif #if COCOS2D_DEBUG >= 1
if (!tolua_isusertype(tolua_S,,"EditText",,&tolua_err)) goto tolua_lerror;
#endif cobj = (EditText*)tolua_tousertype(tolua_S,,); #if COCOS2D_DEBUG >= 1
if (!cobj)
{
tolua_error(tolua_S,"invalid 'cobj' in function 'lua_RedBindings_EditText_getString'", nullptr);
return ;
}
#endif argc = lua_gettop(tolua_S)-;
if (argc == )
{
if(!ok)
{
tolua_error(tolua_S,"invalid arguments in function 'lua_RedBindings_EditText_getString'", nullptr);
return ;
}
std::string ret = cobj->getString();
tolua_pushcppstring(tolua_S,ret);
return ;
}
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "EditText:getString",argc, );
return ; #if COCOS2D_DEBUG >= 1
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'lua_RedBindings_EditText_getString'.",&tolua_err);
#endif return ;
}
static int lua_RedBindings_EditText_finalize(lua_State* tolua_S)
{
printf("luabindings: finalizing LUA object (EditText)");
return ;
} int lua_register_RedBindings_EditText(lua_State* tolua_S)
{
tolua_usertype(tolua_S,"EditText");
tolua_cclass(tolua_S,"EditText","EditText","cc.Node",nullptr); tolua_beginmodule(tolua_S,"EditText");
tolua_function(tolua_S,"setString",lua_RedBindings_EditText_setString);
tolua_function(tolua_S,"getString",lua_RedBindings_EditText_getString);
tolua_endmodule(tolua_S);
std::string typeName = typeid(EditText).name();
g_luaType[typeName] = "EditText";
g_typeCast["EditText"] = "EditText";
return ;
} int lua_RedBindings_EditTextFactory_getEditTextByJobject(lua_State* tolua_S)
{
int argc = ;
EditTextFactory* cobj = nullptr;
bool ok = true; #if COCOS2D_DEBUG >= 1
tolua_Error tolua_err;
#endif #if COCOS2D_DEBUG >= 1
if (!tolua_isusertype(tolua_S,,"EditTextFactory",,&tolua_err)) goto tolua_lerror;
#endif cobj = (EditTextFactory*)tolua_tousertype(tolua_S,,); #if COCOS2D_DEBUG >= 1
if (!cobj)
{
tolua_error(tolua_S,"invalid 'cobj' in function 'lua_RedBindings_EditTextFactory_getEditTextByJobject'", nullptr);
return ;
}
#endif argc = lua_gettop(tolua_S)-;
if (argc == )
{
_jobject* arg0; ok &= luaval_to_object<_jobject>(tolua_S, , "_jobject",&arg0, "EditTextFactory:getEditTextByJobject");
if(!ok)
{
tolua_error(tolua_S,"invalid arguments in function 'lua_RedBindings_EditTextFactory_getEditTextByJobject'", nullptr);
return ;
}
EditText* ret = cobj->getEditTextByJobject(arg0);
object_to_luaval<EditText>(tolua_S, "EditText",(EditText*)ret);
return ;
}
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "EditTextFactory:getEditTextByJobject",argc, );
return ; #if COCOS2D_DEBUG >= 1
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'lua_RedBindings_EditTextFactory_getEditTextByJobject'.",&tolua_err);
#endif return ;
}
int lua_RedBindings_EditTextFactory_createEditText(lua_State* tolua_S)
{
int argc = ;
EditTextFactory* cobj = nullptr;
bool ok = true; #if COCOS2D_DEBUG >= 1
tolua_Error tolua_err;
#endif #if COCOS2D_DEBUG >= 1
if (!tolua_isusertype(tolua_S,,"EditTextFactory",,&tolua_err)) goto tolua_lerror;
#endif cobj = (EditTextFactory*)tolua_tousertype(tolua_S,,); #if COCOS2D_DEBUG >= 1
if (!cobj)
{
tolua_error(tolua_S,"invalid 'cobj' in function 'lua_RedBindings_EditTextFactory_createEditText'", nullptr);
return ;
}
#endif argc = lua_gettop(tolua_S)-;
if (argc == )
{
if(!ok)
{
tolua_error(tolua_S,"invalid arguments in function 'lua_RedBindings_EditTextFactory_createEditText'", nullptr);
return ;
}
EditText* ret = cobj->createEditText();
object_to_luaval<EditText>(tolua_S, "EditText",(EditText*)ret);
return ;
}
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "EditTextFactory:createEditText",argc, );
return ; #if COCOS2D_DEBUG >= 1
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'lua_RedBindings_EditTextFactory_createEditText'.",&tolua_err);
#endif return ;
}
int lua_RedBindings_EditTextFactory_getInstance(lua_State* tolua_S)
{
int argc = ;
bool ok = true; #if COCOS2D_DEBUG >= 1
tolua_Error tolua_err;
#endif #if COCOS2D_DEBUG >= 1
if (!tolua_isusertable(tolua_S,,"EditTextFactory",,&tolua_err)) goto tolua_lerror;
#endif argc = lua_gettop(tolua_S) - ; if (argc == )
{
if(!ok)
{
tolua_error(tolua_S,"invalid arguments in function 'lua_RedBindings_EditTextFactory_getInstance'", nullptr);
return ;
}
EditTextFactory* ret = EditTextFactory::getInstance();
object_to_luaval<EditTextFactory>(tolua_S, "EditTextFactory",(EditTextFactory*)ret);
return ;
}
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d\n ", "EditTextFactory:getInstance",argc, );
return ;
#if COCOS2D_DEBUG >= 1
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'lua_RedBindings_EditTextFactory_getInstance'.",&tolua_err);
#endif
return ;
}
static int lua_RedBindings_EditTextFactory_finalize(lua_State* tolua_S)
{
printf("luabindings: finalizing LUA object (EditTextFactory)");
return ;
} int lua_register_RedBindings_EditTextFactory(lua_State* tolua_S)
{
tolua_usertype(tolua_S,"EditTextFactory");
tolua_cclass(tolua_S,"EditTextFactory","EditTextFactory","",nullptr); tolua_beginmodule(tolua_S,"EditTextFactory");
tolua_function(tolua_S,"getEditTextByJobject",lua_RedBindings_EditTextFactory_getEditTextByJobject);
tolua_function(tolua_S,"createEditText",lua_RedBindings_EditTextFactory_createEditText);
tolua_function(tolua_S,"getInstance", lua_RedBindings_EditTextFactory_getInstance);
tolua_endmodule(tolua_S);
std::string typeName = typeid(EditTextFactory).name();
g_luaType[typeName] = "EditTextFactory";
g_typeCast["EditTextFactory"] = "EditTextFactory";
return ;
} static int lua_RedBindings_EditTextAndroid_finalize(lua_State* tolua_S)
{
printf("luabindings: finalizing LUA object (EditTextAndroid)");
return ;
} int lua_register_RedBindings_EditTextAndroid(lua_State* tolua_S)
{
tolua_usertype(tolua_S,"EditTextAndroid");
tolua_cclass(tolua_S,"EditTextAndroid","EditTextAndroid","EditText",nullptr); tolua_beginmodule(tolua_S,"EditTextAndroid");
tolua_endmodule(tolua_S);
std::string typeName = typeid(EditTextAndroid).name();
g_luaType[typeName] = "EditTextAndroid";
g_typeCast["EditTextAndroid"] = "EditTextAndroid";
return ;
}
TOLUA_API int register_all_RedBindings(lua_State* tolua_S)
{
tolua_open(tolua_S); tolua_module(tolua_S,"red",);
tolua_beginmodule(tolua_S,"red"); lua_register_RedBindings_EditText(tolua_S);
lua_register_RedBindings_EditTextFactory(tolua_S);
lua_register_RedBindings_EditTextAndroid(tolua_S); tolua_endmodule(tolua_S);
return ;
} #endif

lua_RedBindings_auto.cpp

为cocos2d-x实现安卓输入框。非全屏,无dialog,绑定到lua的更多相关文章

  1. 微信非全屏播放设置(仅Iphone)

    由于微信X5内核强制视频全屏,用X5自带内核播放,一般内嵌视频打开播放就会被全屏. ihpone里面可以通过设置 x-webkit-airplay="true" webkit-pl ...

  2. IOS(苹果手机)使用video播放HLS流,实现在内部播放及全屏播放(即非全屏和全屏播放)。

    需求: 实现PC及移动端播放HLS流,并且可以自动播放,在页面内部播放及全屏播放功能. 初步:PC及安卓机使用hls.js实现hls流自动播放及全屏非全屏播放 首先使用了hls.js插件,可以实现在P ...

  3. OSG 初始化为非全屏窗口

    OSG默认的窗口时全屏的,调试的时候不方便. 在网上看到一段代码,可以非全屏显示 int _tmain(int argc, _TCHAR* argv[]){ osgViewer::Viewer vie ...

  4. android ActionBarActivity设置全屏无标题

    新建的Activity继承自ActionBarActivity,设置全屏无标题本来很简单的事,但是没想到app竟然无缘无故的挂,要么就是白屏一片,要么就是黑屏.坑了我一个多小时!!! 原因是Actio ...

  5. Android TV 全屏无标题

    想要全部窗口全屏无标题,修改 res\values\styles.xml 可设置主题和样式 <resources> <!-- Base application theme, depe ...

  6. ActionBarActivity设置全屏无标题

    新建的Activity继承自ActionBarActivity,设置全屏无标题本来非常easy的事,可是没想到app居然无缘无故的挂,要么就是白屏一片,要么就是黑屏.坑了我一个多小时.!! 原因是Ac ...

  7. 微信内置浏览器在使用video标签时(安卓)默认全屏的原因及解决办法

    根据X5论坛得到的答案是:设计如此. 腾讯真是越来越嚣张了,一家独大后用户体验都不注重了(不给程序员留活路). 听说有个申请加入vdeo白名单的,域名验证后就可以解决默认全屏(反正我是没见过申请入口, ...

  8. 自定义控件:抽屉SlidingDrawer——wrap_content非全屏

    android:allowSingleTap   指示抽屉是否可以打开/通过手柄上的一个水龙头关闭. android:animateOnClick  表示所述抽屉是否应该打开/与当用户点击手柄动画关闭 ...

  9. Java Swing JFrame实现全屏--无标题,无边框

    实现方式一: import java.awt.Dimension; import java.awt.Toolkit; import javax.swing.JFrame; public class T ...

随机推荐

  1. Android Studio 复制粘贴图片到drawable文件夹没有效果 - 解决方法

    我想放一些图片到drawable文件夹里面,但是简单的复制文件,粘贴文件,或者拖拽文件,都不起作用.不知道为什么,之前是可以的,突然就不行了. 解决方案 在drawable文件夹的目录上右键,选择Re ...

  2. 使用openoffice将word文件转换为pdf格式遇到问题:The type com.sun.star.lang.XEventListener cannot be resolved. It is indirectly referenced from required

    The type com.sun.star.lang.XEventListener cannot be resolved. It is indirectly referenced from requi ...

  3. 模板引擎逻辑语句处理之对单层for循环的处理

    先上代码 private function moldforExt(){//模板单层For循环处理 $SQL=$this->sql_obj; $URL=$this->url_obj; req ...

  4. CSS3动画与过渡

    transform:在使用2D或3D转换前需用transform-style申明转换的类型,preserve-3d或者preserve-2d 属性 translate(): 通过 translate( ...

  5. ORACLE之PACKAGE

    刚学pl/sql编程,写了两个package.pkg_temp_fn和pkg_temp_fn2.内容涉及pl/sql基本语法,游标,存储过程(in,out),函数(有返回值). pkg_temp_fn ...

  6. JMS - Message

    一条 JMS 消息包含三个部分:消息头.消息属性和消息体. 消息头 消息头提供了和消息有关的元数据,它描述了消息有谁创建.何时创建.数据的有效长度等信息.消息头还包含了描述消息目的地(主题或队列)的路 ...

  7. DayDream, 移动VR 2.0里程碑: 概述(上篇)

    VR设备, 断断续续使用了很多个; 尤其是最近半年,主要是PC VR方面项目. 以前对移动VR不感冒,这几天试用了一下DayDream, 眼前突然一亮, 就如同年初首次使用HTC Vive眼前一亮的感 ...

  8. Cocos2d-x中停止播放背景音乐

    停止背景音乐播放代码放置到什么地方比较适合呢?例如:在HelloWorld场景中,主要代码如下: bool HelloWorld::init() { return true; } void Hello ...

  9. PHP学习笔记 - 进阶篇(11)

    PHP学习笔记 - 进阶篇(11) 数据库操作 PHP支持哪些数据库 PHP通过安装相应的扩展来实现数据库操作,现代应用程序的设计离不开数据库的应用,当前主流的数据库有MsSQL,MySQL,Syba ...

  10. C#学习笔记之线程 - 通知Signal

    通知事件等待句柄 Signal With EventWaitHandle 事件等待句柄常用于通知.当一个线程等待直到接收到另外一个线程发出的信号.事件等待句柄是最简单的信号结构,它与C#事件无关.有三 ...