mirror of https://github.com/axmolengine/axmol.git
add proj.android to samples/SimpleGame, use getVisibleSize & getVisibleOrigin instead of getWinSize
This commit is contained in:
parent
7e4615cd7b
commit
11b5ae5cef
|
@ -0,0 +1,57 @@
|
||||||
|
#include "AppDelegate.h"
|
||||||
|
|
||||||
|
#include "cocos2d.h"
|
||||||
|
#include "HelloWorldScene.h"
|
||||||
|
|
||||||
|
USING_NS_CC;
|
||||||
|
|
||||||
|
AppDelegate::AppDelegate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AppDelegate::~AppDelegate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppDelegate::applicationDidFinishLaunching()
|
||||||
|
{
|
||||||
|
// initialize director
|
||||||
|
CCDirector *pDirector = CCDirector::sharedDirector();
|
||||||
|
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
|
||||||
|
|
||||||
|
// enable High Resource Mode(2x, such as iphone4) and maintains low resource on other devices.
|
||||||
|
// pDirector->enableRetinaDisplay(true);
|
||||||
|
|
||||||
|
// turn on display FPS
|
||||||
|
pDirector->setDisplayStats(true);
|
||||||
|
|
||||||
|
// set FPS. the default value is 1.0/60 if you don't call this
|
||||||
|
pDirector->setAnimationInterval(1.0 / 60);
|
||||||
|
|
||||||
|
// create a scene. it's an autorelease object
|
||||||
|
CCScene *pScene = HelloWorld::scene();
|
||||||
|
|
||||||
|
// run
|
||||||
|
pDirector->runWithScene(pScene);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
|
||||||
|
void AppDelegate::applicationDidEnterBackground()
|
||||||
|
{
|
||||||
|
CCDirector::sharedDirector()->pause();
|
||||||
|
|
||||||
|
// if you use SimpleAudioEngine, it must be pause
|
||||||
|
// SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
// this function will be called when the app is active again
|
||||||
|
void AppDelegate::applicationWillEnterForeground()
|
||||||
|
{
|
||||||
|
CCDirector::sharedDirector()->resume();
|
||||||
|
|
||||||
|
// if you use SimpleAudioEngine, it must resume here
|
||||||
|
// SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef _APP_DELEGATE_H_
|
||||||
|
#define _APP_DELEGATE_H_
|
||||||
|
|
||||||
|
#include "CCApplication.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief The cocos2d Application.
|
||||||
|
|
||||||
|
The reason for implement as private inheritance is to hide some interface call by CCDirector.
|
||||||
|
*/
|
||||||
|
class AppDelegate : private cocos2d::CCApplication
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AppDelegate();
|
||||||
|
virtual ~AppDelegate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Implement CCDirector and CCScene init code here.
|
||||||
|
@return true Initialize success, app continue.
|
||||||
|
@return false Initialize failed, app terminate.
|
||||||
|
*/
|
||||||
|
virtual bool applicationDidFinishLaunching();
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief The function be called when the application enter background
|
||||||
|
@param the pointer of the application
|
||||||
|
*/
|
||||||
|
virtual void applicationDidEnterBackground();
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief The function be called when the application enter foreground
|
||||||
|
@param the pointer of the application
|
||||||
|
*/
|
||||||
|
virtual void applicationWillEnterForeground();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _APP_DELEGATE_H_
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
#include "HelloWorldScene.h"
|
||||||
|
#include "SimpleAudioEngine.h"
|
||||||
|
|
||||||
|
using namespace cocos2d;
|
||||||
|
using namespace CocosDenshion;
|
||||||
|
|
||||||
|
CCScene* HelloWorld::scene()
|
||||||
|
{
|
||||||
|
// 'scene' is an autorelease object
|
||||||
|
CCScene *scene = CCScene::create();
|
||||||
|
|
||||||
|
// 'layer' is an autorelease object
|
||||||
|
HelloWorld *layer = HelloWorld::create();
|
||||||
|
|
||||||
|
// add layer as a child to scene
|
||||||
|
scene->addChild(layer);
|
||||||
|
|
||||||
|
// return the scene
|
||||||
|
return scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
// on "init" you need to initialize your instance
|
||||||
|
bool HelloWorld::init()
|
||||||
|
{
|
||||||
|
//////////////////////////////
|
||||||
|
// 1. super init first
|
||||||
|
if ( !CCLayer::init() )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// 2. add a menu item with "X" image, which is clicked to quit the program
|
||||||
|
// you may modify it.
|
||||||
|
|
||||||
|
// 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(CCDirector::sharedDirector()->getWinSize().width - 20, 20) );
|
||||||
|
|
||||||
|
// create menu, it's an autorelease object
|
||||||
|
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
|
||||||
|
pMenu->setPosition( CCPointZero );
|
||||||
|
this->addChild(pMenu, 1);
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// 3. add your codes below...
|
||||||
|
|
||||||
|
// add a label shows "Hello World"
|
||||||
|
// create and initialize a label
|
||||||
|
CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Thonburi", 34);
|
||||||
|
|
||||||
|
// ask director the window size
|
||||||
|
CCSize size = CCDirector::sharedDirector()->getWinSize();
|
||||||
|
|
||||||
|
// position the label on the center of the screen
|
||||||
|
pLabel->setPosition( ccp(size.width / 2, size.height - 20) );
|
||||||
|
|
||||||
|
// add the label as a child to this layer
|
||||||
|
this->addChild(pLabel, 1);
|
||||||
|
|
||||||
|
// add "HelloWorld" splash screen"
|
||||||
|
CCSprite* pSprite = CCSprite::create("HelloWorld.png");
|
||||||
|
|
||||||
|
// position the sprite on the center of the screen
|
||||||
|
pSprite->setPosition( ccp(size.width/2, size.height/2) );
|
||||||
|
|
||||||
|
// add the sprite as a child to this layer
|
||||||
|
this->addChild(pSprite, 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HelloWorld::menuCloseCallback(CCObject* pSender)
|
||||||
|
{
|
||||||
|
CCDirector::sharedDirector()->end();
|
||||||
|
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||||
|
exit(0);
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef __HELLOWORLD_SCENE_H__
|
||||||
|
#define __HELLOWORLD_SCENE_H__
|
||||||
|
|
||||||
|
#include "cocos2d.h"
|
||||||
|
|
||||||
|
class HelloWorld : public cocos2d::CCLayer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
|
||||||
|
virtual bool init();
|
||||||
|
|
||||||
|
// there's no 'id' in cpp, so we recommand to return the exactly class pointer
|
||||||
|
static cocos2d::CCScene* scene();
|
||||||
|
|
||||||
|
// a selector callback
|
||||||
|
void menuCloseCallback(CCObject* pSender);
|
||||||
|
|
||||||
|
// implement the "static node()" method manually
|
||||||
|
CREATE_FUNC(HelloWorld);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __HELLOWORLD_SCENE_H__
|
|
@ -0,0 +1 @@
|
||||||
|
5fe89fb5bd58cedf13b0363f97b20e3ea7ff255d
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="src" path="gen"/>
|
||||||
|
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||||
|
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||||
|
<classpathentry kind="output" path="bin/classes"/>
|
||||||
|
</classpath>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>SimpleGame</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="org.cocos2dx.simplegame"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0">
|
||||||
|
|
||||||
|
<uses-sdk android:minSdkVersion="8"/>
|
||||||
|
|
||||||
|
<application android:label="@string/app_name"
|
||||||
|
android:debuggable="true"
|
||||||
|
android:icon="@drawable/icon">
|
||||||
|
|
||||||
|
<activity android:name=".SimpleGame"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:screenOrientation="landscape"
|
||||||
|
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||||
|
android:configChanges="orientation">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
<supports-screens android:largeScreens="true"
|
||||||
|
android:smallScreens="true"
|
||||||
|
android:anyDensity="true"
|
||||||
|
android:normalScreens="true"/>
|
||||||
|
</manifest>
|
|
@ -0,0 +1,17 @@
|
||||||
|
# This file is used to override default values used by the Ant build system.
|
||||||
|
#
|
||||||
|
# This file must be checked into Version Control Systems, as it is
|
||||||
|
# integral to the build system of your project.
|
||||||
|
|
||||||
|
# This file is only used by the Ant script.
|
||||||
|
|
||||||
|
# You can use this to override default values such as
|
||||||
|
# 'source.dir' for the location of your java source folder and
|
||||||
|
# 'out.dir' for the location of your output folder.
|
||||||
|
|
||||||
|
# You can also use it define how the release builds are signed by declaring
|
||||||
|
# the following properties:
|
||||||
|
# 'key.store' for the location of your keystore and
|
||||||
|
# 'key.alias' for the name of the key to use.
|
||||||
|
# The password will be asked during the build when you use the 'release' target.
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project name="SimpleGame" default="help">
|
||||||
|
|
||||||
|
<!-- The local.properties file is created and updated by the 'android' tool.
|
||||||
|
It contains the path to the SDK. It should *NOT* be checked into
|
||||||
|
Version Control Systems. -->
|
||||||
|
<property file="local.properties" />
|
||||||
|
|
||||||
|
<!-- The ant.properties file can be created by you. It is only edited by the
|
||||||
|
'android' tool to add properties to it.
|
||||||
|
This is the place to change some Ant specific build properties.
|
||||||
|
Here are some properties you may want to change/update:
|
||||||
|
|
||||||
|
source.dir
|
||||||
|
The name of the source directory. Default is 'src'.
|
||||||
|
out.dir
|
||||||
|
The name of the output directory. Default is 'bin'.
|
||||||
|
|
||||||
|
For other overridable properties, look at the beginning of the rules
|
||||||
|
files in the SDK, at tools/ant/build.xml
|
||||||
|
|
||||||
|
Properties related to the SDK location or the project target should
|
||||||
|
be updated using the 'android' tool with the 'update' action.
|
||||||
|
|
||||||
|
This file is an integral part of the build system for your
|
||||||
|
application and should be checked into Version Control Systems.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<property file="ant.properties" />
|
||||||
|
|
||||||
|
<!-- if sdk.dir was not set from one of the property file, then
|
||||||
|
get it from the ANDROID_HOME env var.
|
||||||
|
This must be done before we load project.properties since
|
||||||
|
the proguard config can use sdk.dir -->
|
||||||
|
<property environment="env" />
|
||||||
|
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
|
||||||
|
<isset property="env.ANDROID_HOME" />
|
||||||
|
</condition>
|
||||||
|
|
||||||
|
<!-- The project.properties file is created and updated by the 'android'
|
||||||
|
tool, as well as ADT.
|
||||||
|
|
||||||
|
This contains project specific properties such as project target, and library
|
||||||
|
dependencies. Lower level build properties are stored in ant.properties
|
||||||
|
(or in .classpath for Eclipse projects).
|
||||||
|
|
||||||
|
This file is an integral part of the build system for your
|
||||||
|
application and should be checked into Version Control Systems. -->
|
||||||
|
<loadproperties srcFile="project.properties" />
|
||||||
|
|
||||||
|
<!-- quick check on sdk.dir -->
|
||||||
|
<fail
|
||||||
|
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
|
||||||
|
unless="sdk.dir"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Import per project custom build rules if present at the root of the project.
|
||||||
|
This is the place to put custom intermediary targets such as:
|
||||||
|
-pre-build
|
||||||
|
-pre-compile
|
||||||
|
-post-compile (This is typically used for code obfuscation.
|
||||||
|
Compiled code location: ${out.classes.absolute.dir}
|
||||||
|
If this is not done in place, override ${out.dex.input.absolute.dir})
|
||||||
|
-post-package
|
||||||
|
-post-build
|
||||||
|
-pre-clean
|
||||||
|
-->
|
||||||
|
<import file="custom_rules.xml" optional="true" />
|
||||||
|
|
||||||
|
<!-- Import the actual build file.
|
||||||
|
|
||||||
|
To customize existing targets, there are two options:
|
||||||
|
- Customize only one target:
|
||||||
|
- copy/paste the target into this file, *before* the
|
||||||
|
<import> task.
|
||||||
|
- customize it to your needs.
|
||||||
|
- Customize the whole content of build.xml
|
||||||
|
- copy/paste the content of the rules files (minus the top node)
|
||||||
|
into this file, replacing the <import> task.
|
||||||
|
- customize to your needs.
|
||||||
|
|
||||||
|
***********************
|
||||||
|
****** IMPORTANT ******
|
||||||
|
***********************
|
||||||
|
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
|
||||||
|
in order to avoid having your file be overridden by tools such as "android update project"
|
||||||
|
-->
|
||||||
|
<!-- version-tag: 1 -->
|
||||||
|
<import file="${sdk.dir}/tools/ant/build.xml" />
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,91 @@
|
||||||
|
APPNAME="SimpleGame"
|
||||||
|
|
||||||
|
# options
|
||||||
|
|
||||||
|
buildexternalsfromsource=
|
||||||
|
|
||||||
|
usage(){
|
||||||
|
cat << EOF
|
||||||
|
usage: $0 [options]
|
||||||
|
|
||||||
|
Build C/C++ code for $APPNAME using Android NDK
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
-s Build externals from source
|
||||||
|
-h this help
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
while getopts "sh" OPTION; do
|
||||||
|
case "$OPTION" in
|
||||||
|
s)
|
||||||
|
buildexternalsfromsource=1
|
||||||
|
;;
|
||||||
|
h)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# paths
|
||||||
|
|
||||||
|
if [ -z "${NDK_ROOT+aaa}" ];then
|
||||||
|
echo "please define NDK_ROOT"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
# ... use paths relative to current directory
|
||||||
|
COCOS2DX_ROOT="$DIR/../.."
|
||||||
|
APP_ROOT="$DIR/.."
|
||||||
|
APP_ANDROID_ROOT="$DIR"
|
||||||
|
|
||||||
|
echo "NDK_ROOT = $NDK_ROOT"
|
||||||
|
echo "COCOS2DX_ROOT = $COCOS2DX_ROOT"
|
||||||
|
echo "APP_ROOT = $APP_ROOT"
|
||||||
|
echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT"
|
||||||
|
|
||||||
|
# make sure assets is exist
|
||||||
|
if [ -d "$APP_ANDROID_ROOT"/assets ]; then
|
||||||
|
rm -rf "$APP_ANDROID_ROOT"/assets
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir "$APP_ANDROID_ROOT"/assets
|
||||||
|
|
||||||
|
# copy resources
|
||||||
|
for file in "$APP_ROOT"/Resources/*
|
||||||
|
do
|
||||||
|
if [ -d "$file" ]; then
|
||||||
|
cp -rf "$file" "$APP_ANDROID_ROOT"/assets
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
cp "$file" "$APP_ANDROID_ROOT"/assets
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# copy icons (if they exist)
|
||||||
|
file="$APP_ANDROID_ROOT"/assets/Icon-72.png
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
cp "$file" "$APP_ANDROID_ROOT"/res/drawable-hdpi/icon.png
|
||||||
|
fi
|
||||||
|
file="$APP_ANDROID_ROOT"/assets/Icon-48.png
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
cp "$file" "$APP_ANDROID_ROOT"/res/drawable-mdpi/icon.png
|
||||||
|
fi
|
||||||
|
file="$APP_ANDROID_ROOT"/assets/Icon-32.png
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
cp "$file" "$APP_ANDROID_ROOT"/res/drawable-ldpi/icon.png
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [[ "$buildexternalsfromsource" ]]; then
|
||||||
|
echo "Building external dependencies from source"
|
||||||
|
"$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
|
||||||
|
"NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/source"
|
||||||
|
else
|
||||||
|
echo "Using prebuilt externals"
|
||||||
|
"$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
|
||||||
|
"NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/prebuilt"
|
||||||
|
fi
|
|
@ -0,0 +1,21 @@
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := game_shared
|
||||||
|
|
||||||
|
LOCAL_MODULE_FILENAME := libgame
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := hellocpp/main.cpp \
|
||||||
|
../../Classes/AppDelegate.cpp \
|
||||||
|
../../Classes/HelloWorldScene.cpp
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes
|
||||||
|
|
||||||
|
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static cocosdenshion_static cocos_extension_static
|
||||||
|
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
$(call import-module,CocosDenshion/android) \
|
||||||
|
$(call import-module,cocos2dx) \
|
||||||
|
$(call import-module,extensions)
|
|
@ -0,0 +1,2 @@
|
||||||
|
APP_STL := gnustl_static
|
||||||
|
APP_CPPFLAGS := -frtti
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include "AppDelegate.h"
|
||||||
|
#include "platform/android/jni/JniHelper.h"
|
||||||
|
#include <jni.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
|
||||||
|
#include "HelloWorldScene.h"
|
||||||
|
|
||||||
|
#define LOG_TAG "main"
|
||||||
|
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
|
||||||
|
|
||||||
|
using namespace cocos2d;
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
|
||||||
|
jint JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||||
|
{
|
||||||
|
JniHelper::setJavaVM(vm);
|
||||||
|
|
||||||
|
return JNI_VERSION_1_4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)
|
||||||
|
{
|
||||||
|
if (!CCDirector::sharedDirector()->getOpenGLView())
|
||||||
|
{
|
||||||
|
CCEGLView *view = CCEGLView::sharedOpenGLView();
|
||||||
|
view->setFrameSize(w, h);
|
||||||
|
|
||||||
|
AppDelegate *pAppDelegate = new AppDelegate();
|
||||||
|
CCApplication::sharedApplication()->run();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ccDrawInit();
|
||||||
|
ccGLInvalidateStateCache();
|
||||||
|
|
||||||
|
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
|
||||||
|
CCTextureCache::reloadAllTextures();
|
||||||
|
CCNotificationCenter::sharedNotificationCenter()->postNotification(EVNET_COME_TO_FOREGROUND, NULL);
|
||||||
|
CCDirector::sharedDirector()->setGLDefaultValues();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
append_str=' \'
|
||||||
|
|
||||||
|
list_alldir()
|
||||||
|
{
|
||||||
|
for file in $1/*
|
||||||
|
do
|
||||||
|
if [ -f $file ]; then
|
||||||
|
echo $file$append_str | grep .cpp
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d $file ]; then
|
||||||
|
list_alldir $file
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
list_alldir "$1"
|
||||||
|
else
|
||||||
|
list_alldir "."
|
||||||
|
fi
|
|
@ -0,0 +1,20 @@
|
||||||
|
# To enable ProGuard in your project, edit project.properties
|
||||||
|
# to define the proguard.config property as described in that file.
|
||||||
|
#
|
||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the ProGuard
|
||||||
|
# include property in project.properties.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
|
@ -0,0 +1,14 @@
|
||||||
|
# This file is automatically generated by Android Tools.
|
||||||
|
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||||
|
#
|
||||||
|
# This file must be checked in Version Control Systems.
|
||||||
|
#
|
||||||
|
# To customize properties used by the Ant build system edit
|
||||||
|
# "ant.properties", and override values to adapt the script to your
|
||||||
|
# project structure.
|
||||||
|
#
|
||||||
|
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||||
|
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||||
|
|
||||||
|
# Project target.
|
||||||
|
target=android-8
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">SimpleGame</string>
|
||||||
|
</resources>
|
|
@ -0,0 +1,107 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.hardware.Sensor;
|
||||||
|
import android.hardware.SensorEvent;
|
||||||
|
import android.hardware.SensorEventListener;
|
||||||
|
import android.hardware.SensorManager;
|
||||||
|
import android.view.Display;
|
||||||
|
import android.view.Surface;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This class is used for controlling the Accelerometer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Cocos2dxAccelerometer implements SensorEventListener {
|
||||||
|
|
||||||
|
private static final String TAG = "Cocos2dxAccelerometer";
|
||||||
|
private Context mContext;
|
||||||
|
private SensorManager mSensorManager;
|
||||||
|
private Sensor mAccelerometer;
|
||||||
|
private int mNaturalOrientation;
|
||||||
|
|
||||||
|
public Cocos2dxAccelerometer(Context context){
|
||||||
|
mContext = context;
|
||||||
|
|
||||||
|
//Get an instance of the SensorManager
|
||||||
|
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
|
||||||
|
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||||
|
|
||||||
|
Display display = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||||
|
mNaturalOrientation = display.getOrientation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enable() {
|
||||||
|
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disable () {
|
||||||
|
mSensorManager.unregisterListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSensorChanged(SensorEvent event) {
|
||||||
|
|
||||||
|
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float x = event.values[0];
|
||||||
|
float y = event.values[1];
|
||||||
|
float z = event.values[2];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Because the axes are not swapped when the device's screen orientation changes.
|
||||||
|
* So we should swap it here.
|
||||||
|
* In tablets such as Motorola Xoom, the default orientation is landscape, so should
|
||||||
|
* consider this.
|
||||||
|
*/
|
||||||
|
int orientation = mContext.getResources().getConfiguration().orientation;
|
||||||
|
if ((orientation == Configuration.ORIENTATION_LANDSCAPE) && (mNaturalOrientation != Surface.ROTATION_0)){
|
||||||
|
float tmp = x;
|
||||||
|
x = -y;
|
||||||
|
y = tmp;
|
||||||
|
}
|
||||||
|
else if ((orientation == Configuration.ORIENTATION_PORTRAIT) && (mNaturalOrientation != Surface.ROTATION_0))
|
||||||
|
{
|
||||||
|
float tmp = x;
|
||||||
|
x = y;
|
||||||
|
y = -tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSensorChanged(x, y, z, event.timestamp);
|
||||||
|
// Log.d(TAG, "x = " + event.values[0] + " y = " + event.values[1] + " z = " + event.values[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void onSensorChanged(float x, float y, float z, long timeStamp);
|
||||||
|
}
|
|
@ -0,0 +1,346 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2012 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class Cocos2dxActivity extends Activity{
|
||||||
|
|
||||||
|
protected Cocos2dxGLSurfaceView mGLView;
|
||||||
|
private static Cocos2dxMusic backgroundMusicPlayer;
|
||||||
|
private static Cocos2dxSound soundPlayer;
|
||||||
|
private static Cocos2dxAccelerometer accelerometer;
|
||||||
|
private static AssetManager assetManager;
|
||||||
|
private static boolean accelerometerEnabled = false;
|
||||||
|
private static Handler handler;
|
||||||
|
private final static int HANDLER_SHOW_DIALOG = 1;
|
||||||
|
private final static int HANDLER_SHOW_EDITBOX_DIALOG = 2;
|
||||||
|
|
||||||
|
private static String packageName;
|
||||||
|
|
||||||
|
private static native void nativeSetPaths(String apkPath);
|
||||||
|
private static native void nativeSetEditboxText(byte[] text);
|
||||||
|
|
||||||
|
|
||||||
|
static class ShowDialogHandler extends Handler {
|
||||||
|
WeakReference<Cocos2dxActivity> mActivity;
|
||||||
|
|
||||||
|
ShowDialogHandler(Cocos2dxActivity activity) {
|
||||||
|
mActivity = new WeakReference<Cocos2dxActivity>(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
Cocos2dxActivity theActivity = mActivity.get();
|
||||||
|
switch(msg.what) {
|
||||||
|
case HANDLER_SHOW_DIALOG:
|
||||||
|
theActivity.showDialog(((DialogMessage)msg.obj).title, ((DialogMessage)msg.obj).message);
|
||||||
|
break;
|
||||||
|
case HANDLER_SHOW_EDITBOX_DIALOG:
|
||||||
|
theActivity.onShowEditBoxDialog((EditBoxMessage)msg.obj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public Cocos2dxGLSurfaceView getGLView() {
|
||||||
|
return mGLView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// get frame size
|
||||||
|
DisplayMetrics dm = new DisplayMetrics();
|
||||||
|
getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||||
|
accelerometer = new Cocos2dxAccelerometer(this);
|
||||||
|
|
||||||
|
// init media player and sound player
|
||||||
|
backgroundMusicPlayer = new Cocos2dxMusic(this);
|
||||||
|
soundPlayer = new Cocos2dxSound(this);
|
||||||
|
|
||||||
|
// init asset manager for jni call
|
||||||
|
assetManager = getAssets();
|
||||||
|
|
||||||
|
// init bitmap context
|
||||||
|
Cocos2dxBitmap.setContext(this);
|
||||||
|
|
||||||
|
handler = new ShowDialogHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDeviceModel(){
|
||||||
|
return Build.MODEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AssetManager getAssetManager() {
|
||||||
|
return assetManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCurrentLanguage() {
|
||||||
|
String languageName = java.util.Locale.getDefault().getLanguage();
|
||||||
|
return languageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showMessageBox(String title, String message){
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = HANDLER_SHOW_DIALOG;
|
||||||
|
msg.obj = new DialogMessage(title, message);
|
||||||
|
|
||||||
|
handler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void enableAccelerometer() {
|
||||||
|
accelerometerEnabled = true;
|
||||||
|
accelerometer.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void disableAccelerometer() {
|
||||||
|
accelerometerEnabled = false;
|
||||||
|
accelerometer.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void preloadBackgroundMusic(String path){
|
||||||
|
backgroundMusicPlayer.preloadBackgroundMusic(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void playBackgroundMusic(String path, boolean isLoop){
|
||||||
|
backgroundMusicPlayer.playBackgroundMusic(path, isLoop);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stopBackgroundMusic(){
|
||||||
|
backgroundMusicPlayer.stopBackgroundMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void pauseBackgroundMusic(){
|
||||||
|
backgroundMusicPlayer.pauseBackgroundMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resumeBackgroundMusic(){
|
||||||
|
backgroundMusicPlayer.resumeBackgroundMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void rewindBackgroundMusic(){
|
||||||
|
backgroundMusicPlayer.rewindBackgroundMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBackgroundMusicPlaying(){
|
||||||
|
return backgroundMusicPlayer.isBackgroundMusicPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getBackgroundMusicVolume(){
|
||||||
|
return backgroundMusicPlayer.getBackgroundVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setBackgroundMusicVolume(float volume){
|
||||||
|
backgroundMusicPlayer.setBackgroundVolume(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int playEffect(String path, boolean isLoop){
|
||||||
|
return soundPlayer.playEffect(path, isLoop);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stopEffect(int soundId){
|
||||||
|
soundPlayer.stopEffect(soundId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void pauseEffect(int soundId){
|
||||||
|
soundPlayer.pauseEffect(soundId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resumeEffect(int soundId){
|
||||||
|
soundPlayer.resumeEffect(soundId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getEffectsVolume(){
|
||||||
|
return soundPlayer.getEffectsVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setEffectsVolume(float volume){
|
||||||
|
soundPlayer.setEffectsVolume(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void preloadEffect(String path){
|
||||||
|
soundPlayer.preloadEffect(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unloadEffect(String path){
|
||||||
|
soundPlayer.unloadEffect(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stopAllEffects(){
|
||||||
|
soundPlayer.stopAllEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void pauseAllEffects(){
|
||||||
|
soundPlayer.pauseAllEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resumeAllEffects(){
|
||||||
|
soundPlayer.resumeAllEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void end(){
|
||||||
|
backgroundMusicPlayer.end();
|
||||||
|
soundPlayer.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCocos2dxPackageName(){
|
||||||
|
return packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void terminateProcess(){
|
||||||
|
android.os.Process.killProcess(android.os.Process.myPid());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
if (accelerometerEnabled) {
|
||||||
|
accelerometer.enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
if (accelerometerEnabled) {
|
||||||
|
accelerometer.disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setPackageName(String packageName) {
|
||||||
|
Cocos2dxActivity.packageName = packageName;
|
||||||
|
|
||||||
|
String apkFilePath = "";
|
||||||
|
ApplicationInfo appInfo = null;
|
||||||
|
PackageManager packMgmr = getApplication().getPackageManager();
|
||||||
|
try {
|
||||||
|
appInfo = packMgmr.getApplicationInfo(packageName, 0);
|
||||||
|
} catch (NameNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException("Unable to locate assets, aborting...");
|
||||||
|
}
|
||||||
|
apkFilePath = appInfo.sourceDir;
|
||||||
|
Log.w("apk path", apkFilePath);
|
||||||
|
|
||||||
|
// add this link at the renderer class
|
||||||
|
nativeSetPaths(apkFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDialog(String title, String message){
|
||||||
|
Dialog dialog = new AlertDialog.Builder(this)
|
||||||
|
.setTitle(title)
|
||||||
|
.setMessage(message)
|
||||||
|
.setPositiveButton("Ok",
|
||||||
|
new DialogInterface.OnClickListener()
|
||||||
|
{
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton){
|
||||||
|
|
||||||
|
}
|
||||||
|
}).create();
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void showEditBoxDialog(String title, String content, int inputMode, int inputFlag, int returnType, int maxLength)
|
||||||
|
{
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = HANDLER_SHOW_EDITBOX_DIALOG;
|
||||||
|
msg.obj = new EditBoxMessage(title, content, inputMode, inputFlag, returnType, maxLength);
|
||||||
|
handler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onShowEditBoxDialog(EditBoxMessage msg)
|
||||||
|
{
|
||||||
|
Dialog dialog = new Cocos2dxEditBoxDialog(this, msg);
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEditBoxResult(String editResult)
|
||||||
|
{
|
||||||
|
Log.i("editbox_content", editResult);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
final byte[] bytesUTF8 = editResult.getBytes("UTF8");
|
||||||
|
// pass utf8 string from editbox activity to native.
|
||||||
|
// Should invoke native method in GL thread.
|
||||||
|
mGLView.queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
nativeSetEditboxText(bytesUTF8);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (java.io.UnsupportedEncodingException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DialogMessage {
|
||||||
|
public String title;
|
||||||
|
public String message;
|
||||||
|
|
||||||
|
public DialogMessage(String title, String message){
|
||||||
|
this.message = message;
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditBoxMessage {
|
||||||
|
public String title;
|
||||||
|
public String content;
|
||||||
|
public int inputMode;
|
||||||
|
public int inputFlag;
|
||||||
|
public int returnType;
|
||||||
|
public int maxLength;
|
||||||
|
|
||||||
|
public EditBoxMessage(String title, String content, int inputMode, int inputFlag, int returnType, int maxLength){
|
||||||
|
this.content = content;
|
||||||
|
this.title = title;
|
||||||
|
this.inputMode = inputMode;
|
||||||
|
this.inputFlag = inputFlag;
|
||||||
|
this.returnType = returnType;
|
||||||
|
this.maxLength = maxLength;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,455 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.graphics.Paint.Align;
|
||||||
|
import android.graphics.Paint.FontMetricsInt;
|
||||||
|
import android.text.TextPaint;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class Cocos2dxBitmap{
|
||||||
|
/*
|
||||||
|
* The values are the same as cocos2dx/platform/CCImage.h.
|
||||||
|
*/
|
||||||
|
private static final int HALIGNCENTER = 3;
|
||||||
|
private static final int HALIGNLEFT = 1;
|
||||||
|
private static final int HALIGNRIGHT = 2;
|
||||||
|
// vertical alignment
|
||||||
|
private static final int VALIGNTOP = 1;
|
||||||
|
private static final int VALIGNBOTTOM = 2;
|
||||||
|
private static final int VALIGNCENTER = 3;
|
||||||
|
|
||||||
|
private static Context context;
|
||||||
|
|
||||||
|
public static void setContext(Context context){
|
||||||
|
Cocos2dxBitmap.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @width: the width to draw, it can be 0
|
||||||
|
* @height: the height to draw, it can be 0
|
||||||
|
*/
|
||||||
|
public static void createTextBitmap(String content, String fontName,
|
||||||
|
int fontSize, int alignment, int width, int height){
|
||||||
|
|
||||||
|
content = refactorString(content);
|
||||||
|
Paint paint = newPaint(fontName, fontSize, alignment);
|
||||||
|
|
||||||
|
TextProperty textProperty = computeTextProperty(content, paint, width, height);
|
||||||
|
|
||||||
|
int bitmapTotalHeight = (height == 0 ? textProperty.totalHeight:height);
|
||||||
|
|
||||||
|
// Draw text to bitmap
|
||||||
|
Bitmap bitmap = Bitmap.createBitmap(textProperty.maxWidth,
|
||||||
|
bitmapTotalHeight, Bitmap.Config.ARGB_8888);
|
||||||
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
|
||||||
|
// Draw string
|
||||||
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
|
int x = 0;
|
||||||
|
int y = computeY(fm, height, textProperty.totalHeight, alignment);
|
||||||
|
String[] lines = textProperty.lines;
|
||||||
|
for (String line : lines){
|
||||||
|
x = computeX(paint, line, textProperty.maxWidth, alignment);
|
||||||
|
canvas.drawText(line, x, y, paint);
|
||||||
|
y += textProperty.heightPerLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
initNativeObject(bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int computeX(Paint paint, String content, int w, int alignment){
|
||||||
|
int ret = 0;
|
||||||
|
int hAlignment = alignment & 0x0F;
|
||||||
|
|
||||||
|
switch (hAlignment){
|
||||||
|
case HALIGNCENTER:
|
||||||
|
ret = w / 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ret = 0
|
||||||
|
case HALIGNLEFT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HALIGNRIGHT:
|
||||||
|
ret = w;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default is align left.
|
||||||
|
* Should be same as newPaint().
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int computeY(FontMetricsInt fm, int constrainHeight, int totalHeight, int alignment) {
|
||||||
|
int y = -fm.top;
|
||||||
|
|
||||||
|
if (constrainHeight > totalHeight) {
|
||||||
|
int vAlignment = (alignment >> 4) & 0x0F;
|
||||||
|
|
||||||
|
switch (vAlignment) {
|
||||||
|
case VALIGNTOP:
|
||||||
|
y = -fm.top;
|
||||||
|
break;
|
||||||
|
case VALIGNCENTER:
|
||||||
|
y = -fm.top + (constrainHeight - totalHeight)/2;
|
||||||
|
break;
|
||||||
|
case VALIGNBOTTOM:
|
||||||
|
y = -fm.top + (constrainHeight - totalHeight);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TextProperty{
|
||||||
|
// The max width of lines
|
||||||
|
int maxWidth;
|
||||||
|
// The height of all lines
|
||||||
|
int totalHeight;
|
||||||
|
int heightPerLine;
|
||||||
|
String[] lines;
|
||||||
|
|
||||||
|
TextProperty(int w, int h, String[] lines){
|
||||||
|
this.maxWidth = w;
|
||||||
|
this.heightPerLine = h;
|
||||||
|
this.totalHeight = h * lines.length;
|
||||||
|
this.lines = lines;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextProperty computeTextProperty(String content, Paint paint,
|
||||||
|
int maxWidth, int maxHeight){
|
||||||
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
|
int h = (int)Math.ceil(fm.bottom - fm.top);
|
||||||
|
int maxContentWidth = 0;
|
||||||
|
|
||||||
|
String[] lines = splitString(content, maxHeight, maxWidth, paint);
|
||||||
|
|
||||||
|
if (maxWidth != 0){
|
||||||
|
maxContentWidth = maxWidth;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
* Compute the max width
|
||||||
|
*/
|
||||||
|
int temp = 0;
|
||||||
|
for (String line : lines){
|
||||||
|
temp = (int)Math.ceil(paint.measureText(line, 0, line.length()));
|
||||||
|
if (temp > maxContentWidth){
|
||||||
|
maxContentWidth = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TextProperty(maxContentWidth, h, lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If maxWidth or maxHeight is not 0,
|
||||||
|
* split the string to fix the maxWidth and maxHeight.
|
||||||
|
*/
|
||||||
|
private static String[] splitString(String content, int maxHeight, int maxWidth,
|
||||||
|
Paint paint){
|
||||||
|
String[] lines = content.split("\\n");
|
||||||
|
String[] ret = null;
|
||||||
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
|
int heightPerLine = (int)Math.ceil(fm.bottom - fm.top);
|
||||||
|
int maxLines = maxHeight / heightPerLine;
|
||||||
|
|
||||||
|
if (maxWidth != 0){
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
for (String line : lines){
|
||||||
|
/*
|
||||||
|
* The width of line is exceed maxWidth, should divide it into
|
||||||
|
* two or more lines.
|
||||||
|
*/
|
||||||
|
int lineWidth = (int)Math.ceil(paint.measureText(line));
|
||||||
|
if (lineWidth > maxWidth){
|
||||||
|
strList.addAll(divideStringWithMaxWidth(paint, line, maxWidth));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
strList.add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should not exceed the max height;
|
||||||
|
*/
|
||||||
|
if (maxLines > 0 && strList.size() >= maxLines){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove exceeding lines
|
||||||
|
*/
|
||||||
|
if (maxLines > 0 && strList.size() > maxLines){
|
||||||
|
while (strList.size() > maxLines){
|
||||||
|
strList.removeLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = new String[strList.size()];
|
||||||
|
strList.toArray(ret);
|
||||||
|
} else
|
||||||
|
if (maxHeight != 0 && lines.length > maxLines) {
|
||||||
|
/*
|
||||||
|
* Remove exceeding lines
|
||||||
|
*/
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
for (int i = 0; i < maxLines; i++){
|
||||||
|
strList.add(lines[i]);
|
||||||
|
}
|
||||||
|
ret = new String[strList.size()];
|
||||||
|
strList.toArray(ret);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LinkedList<String> divideStringWithMaxWidth(Paint paint, String content,
|
||||||
|
int width){
|
||||||
|
int charLength = content.length();
|
||||||
|
int start = 0;
|
||||||
|
int tempWidth = 0;
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Break a String into String[] by the width & should wrap the word
|
||||||
|
*/
|
||||||
|
for (int i = 1; i <= charLength; ++i){
|
||||||
|
tempWidth = (int)Math.ceil(paint.measureText(content, start, i));
|
||||||
|
if (tempWidth >= width){
|
||||||
|
int lastIndexOfSpace = content.substring(0, i).lastIndexOf(" ");
|
||||||
|
|
||||||
|
if (lastIndexOfSpace != -1 && lastIndexOfSpace > start){
|
||||||
|
/**
|
||||||
|
* Should wrap the word
|
||||||
|
*/
|
||||||
|
strList.add(content.substring(start, lastIndexOfSpace));
|
||||||
|
i = lastIndexOfSpace;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
* Should not exceed the width
|
||||||
|
*/
|
||||||
|
if (tempWidth > width){
|
||||||
|
strList.add(content.substring(start, i - 1));
|
||||||
|
/*
|
||||||
|
* compute from previous char
|
||||||
|
*/
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strList.add(content.substring(start, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove spaces at the beginning of a new line
|
||||||
|
while(content.indexOf(i++) == ' ') {
|
||||||
|
}
|
||||||
|
|
||||||
|
start = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the last chars
|
||||||
|
*/
|
||||||
|
if (start < charLength){
|
||||||
|
strList.add(content.substring(start));
|
||||||
|
}
|
||||||
|
|
||||||
|
return strList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Paint newPaint(String fontName, int fontSize, int alignment){
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setColor(Color.WHITE);
|
||||||
|
paint.setTextSize(fontSize);
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set type face for paint, now it support .ttf file.
|
||||||
|
*/
|
||||||
|
if (fontName.endsWith(".ttf")){
|
||||||
|
try {
|
||||||
|
//Typeface typeFace = Typeface.createFromAsset(context.getAssets(), fontName);
|
||||||
|
Typeface typeFace = Cocos2dxTypefaces.get(context, fontName);
|
||||||
|
paint.setTypeface(typeFace);
|
||||||
|
} catch (Exception e){
|
||||||
|
Log.e("Cocos2dxBitmap",
|
||||||
|
"error to create ttf type face: " + fontName);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The file may not find, use system font
|
||||||
|
*/
|
||||||
|
paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL));
|
||||||
|
}
|
||||||
|
|
||||||
|
int hAlignment = alignment & 0x0F;
|
||||||
|
switch (hAlignment){
|
||||||
|
case HALIGNCENTER:
|
||||||
|
paint.setTextAlign(Align.CENTER);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HALIGNLEFT:
|
||||||
|
paint.setTextAlign(Align.LEFT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HALIGNRIGHT:
|
||||||
|
paint.setTextAlign(Align.RIGHT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
paint.setTextAlign(Align.LEFT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return paint;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String refactorString(String str){
|
||||||
|
// Avoid error when content is ""
|
||||||
|
if (str.compareTo("") == 0){
|
||||||
|
return " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the font of "\n" is "" or "\n", insert " " in front of it.
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
* "\nabc" -> " \nabc"
|
||||||
|
* "\nabc\n\n" -> " \nabc\n \n"
|
||||||
|
*/
|
||||||
|
StringBuilder strBuilder = new StringBuilder(str);
|
||||||
|
int start = 0;
|
||||||
|
int index = strBuilder.indexOf("\n");
|
||||||
|
while (index != -1){
|
||||||
|
if (index == 0 || strBuilder.charAt(index -1) == '\n'){
|
||||||
|
strBuilder.insert(start, " ");
|
||||||
|
start = index + 2;
|
||||||
|
} else {
|
||||||
|
start = index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start > strBuilder.length() || index == strBuilder.length()){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = strBuilder.indexOf("\n", start);
|
||||||
|
}
|
||||||
|
|
||||||
|
return strBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void initNativeObject(Bitmap bitmap){
|
||||||
|
byte[] pixels = getPixels(bitmap);
|
||||||
|
if (pixels == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nativeInitBitmapDC(bitmap.getWidth(), bitmap.getHeight(), pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] getPixels(Bitmap bitmap){
|
||||||
|
if (bitmap != null){
|
||||||
|
byte[] pixels = new byte[bitmap.getWidth() * bitmap.getHeight() * 4];
|
||||||
|
ByteBuffer buf = ByteBuffer.wrap(pixels);
|
||||||
|
buf.order(ByteOrder.nativeOrder());
|
||||||
|
bitmap.copyPixelsToBuffer(buf);
|
||||||
|
return pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void nativeInitBitmapDC(int width, int height, byte[] pixels);
|
||||||
|
|
||||||
|
private static int getFontSizeAccordingHeight(int height)
|
||||||
|
{
|
||||||
|
Paint paint = new Paint();
|
||||||
|
Rect bounds = new Rect();
|
||||||
|
|
||||||
|
paint.setTypeface(Typeface.DEFAULT);
|
||||||
|
int incr_text_size = 1;
|
||||||
|
boolean found_desired_size = false;
|
||||||
|
|
||||||
|
while (!found_desired_size) {
|
||||||
|
|
||||||
|
paint.setTextSize(incr_text_size);
|
||||||
|
String text = "SghMNy";
|
||||||
|
paint.getTextBounds(text, 0, text.length(), bounds);
|
||||||
|
|
||||||
|
incr_text_size++;
|
||||||
|
|
||||||
|
if (height - bounds.height() <= 2) {
|
||||||
|
found_desired_size = true;
|
||||||
|
}
|
||||||
|
Log.d("font size", "incr size:" + incr_text_size);
|
||||||
|
}
|
||||||
|
return incr_text_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getStringWithEllipsis(String originalText, float width, float fontSize){
|
||||||
|
if(TextUtils.isEmpty(originalText)){
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
TextPaint paint = new TextPaint();
|
||||||
|
paint.setTypeface(Typeface.DEFAULT);
|
||||||
|
paint.setTextSize(fontSize);
|
||||||
|
|
||||||
|
return TextUtils.ellipsize(originalText, paint, width,
|
||||||
|
TextUtils.TruncateAt.valueOf("END")).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,338 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2012 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.drawable.ColorDrawable;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.text.InputFilter;
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.TextView.OnEditorActionListener;
|
||||||
|
|
||||||
|
public class Cocos2dxEditBoxDialog extends Dialog {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter any text, including line breaks.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModeAny = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter an e-mail address.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModeEmailAddr = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter an integer value.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModeNumeric = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter a phone number.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModePhoneNumber = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter a URL.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModeUrl = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter a real number value.
|
||||||
|
* This extends kEditBoxInputModeNumeric by allowing a decimal point.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModeDecimal = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter any text, except for line breaks.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModeSingleLine = 6;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the text entered is confidential data that should be
|
||||||
|
* obscured whenever possible. This implies EDIT_BOX_INPUT_FLAG_SENSITIVE.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputFlagPassword = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the text entered is sensitive data that the
|
||||||
|
* implementation must never store into a dictionary or table for use
|
||||||
|
* in predictive, auto-completing, or other accelerated input schemes.
|
||||||
|
* A credit card number is an example of sensitive data.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputFlagSensitive = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This flag is a hint to the implementation that during text editing,
|
||||||
|
* the initial letter of each word should be capitalized.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputFlagInitialCapsWord = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This flag is a hint to the implementation that during text editing,
|
||||||
|
* the initial letter of each sentence should be capitalized.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputFlagInitialCapsSentence = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Capitalize all characters automatically.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputFlagInitialCapsAllCharacters = 4;
|
||||||
|
|
||||||
|
private final int kKeyboardReturnTypeDefault = 0;
|
||||||
|
private final int kKeyboardReturnTypeDone = 1;
|
||||||
|
private final int kKeyboardReturnTypeSend = 2;
|
||||||
|
private final int kKeyboardReturnTypeSearch = 3;
|
||||||
|
private final int kKeyboardReturnTypeGo = 4;
|
||||||
|
|
||||||
|
//
|
||||||
|
private EditText mInputEditText = null;
|
||||||
|
private TextView mTextViewTitle = null;
|
||||||
|
private int mInputMode = 0;
|
||||||
|
private int mInputFlag = 0;
|
||||||
|
private int mReturnType = 0;
|
||||||
|
private int mMaxLength = -1;
|
||||||
|
|
||||||
|
private int mInputFlagConstraints = 0x00000;
|
||||||
|
private int mInputModeContraints = 0x00000;
|
||||||
|
private boolean mIsMultiline = false;
|
||||||
|
private Cocos2dxActivity mParentActivity = null;
|
||||||
|
private EditBoxMessage mMsg = null;
|
||||||
|
|
||||||
|
public Cocos2dxEditBoxDialog(Context context, EditBoxMessage msg) {
|
||||||
|
//super(context, R.style.Theme_Translucent);
|
||||||
|
super(context, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
mParentActivity = (Cocos2dxActivity)context;
|
||||||
|
mMsg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converting dips to pixels
|
||||||
|
private int convertDipsToPixels(float dips)
|
||||||
|
{
|
||||||
|
float scale = getContext().getResources().getDisplayMetrics().density;
|
||||||
|
return Math.round(dips * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
getWindow().setBackgroundDrawable(new ColorDrawable(0x80000000));
|
||||||
|
|
||||||
|
LinearLayout layout = new LinearLayout(mParentActivity);
|
||||||
|
layout.setOrientation(LinearLayout.VERTICAL);
|
||||||
|
|
||||||
|
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.
|
||||||
|
LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.FILL_PARENT);
|
||||||
|
|
||||||
|
mTextViewTitle = new TextView(mParentActivity);
|
||||||
|
LinearLayout.LayoutParams textviewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
textviewParams.leftMargin = textviewParams.rightMargin = convertDipsToPixels(10);
|
||||||
|
mTextViewTitle.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
|
||||||
|
layout.addView(mTextViewTitle, textviewParams);
|
||||||
|
|
||||||
|
mInputEditText = new EditText(mParentActivity);
|
||||||
|
LinearLayout.LayoutParams editTextParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
editTextParams.leftMargin = editTextParams.rightMargin = convertDipsToPixels(10);
|
||||||
|
|
||||||
|
layout.addView(mInputEditText, editTextParams);
|
||||||
|
|
||||||
|
setContentView(layout, layoutParams);
|
||||||
|
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
|
||||||
|
mInputMode = mMsg.inputMode;
|
||||||
|
mInputFlag = mMsg.inputFlag;
|
||||||
|
mReturnType = mMsg.returnType;
|
||||||
|
mMaxLength = mMsg.maxLength;
|
||||||
|
|
||||||
|
mTextViewTitle.setText(mMsg.title);
|
||||||
|
mInputEditText.setText(mMsg.content);
|
||||||
|
|
||||||
|
int oldImeOptions = mInputEditText.getImeOptions();
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
||||||
|
oldImeOptions = mInputEditText.getImeOptions();
|
||||||
|
|
||||||
|
switch (mInputMode)
|
||||||
|
{
|
||||||
|
case kEditBoxInputModeAny:
|
||||||
|
mInputModeContraints =
|
||||||
|
InputType.TYPE_CLASS_TEXT |
|
||||||
|
InputType.TYPE_TEXT_FLAG_MULTI_LINE;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputModeEmailAddr:
|
||||||
|
mInputModeContraints =
|
||||||
|
InputType.TYPE_CLASS_TEXT |
|
||||||
|
InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputModeNumeric:
|
||||||
|
mInputModeContraints =
|
||||||
|
InputType.TYPE_CLASS_NUMBER |
|
||||||
|
InputType.TYPE_NUMBER_FLAG_SIGNED;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputModePhoneNumber:
|
||||||
|
mInputModeContraints = InputType.TYPE_CLASS_PHONE;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputModeUrl:
|
||||||
|
mInputModeContraints =
|
||||||
|
InputType.TYPE_CLASS_TEXT |
|
||||||
|
InputType.TYPE_TEXT_VARIATION_URI;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputModeDecimal:
|
||||||
|
mInputModeContraints =
|
||||||
|
InputType.TYPE_CLASS_NUMBER |
|
||||||
|
InputType.TYPE_NUMBER_FLAG_DECIMAL |
|
||||||
|
InputType.TYPE_NUMBER_FLAG_SIGNED;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputModeSingleLine:
|
||||||
|
mInputModeContraints = InputType.TYPE_CLASS_TEXT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mIsMultiline ) {
|
||||||
|
mInputModeContraints |= InputType.TYPE_TEXT_FLAG_MULTI_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mInputEditText.setInputType(mInputModeContraints | mInputFlagConstraints);
|
||||||
|
|
||||||
|
switch (mInputFlag)
|
||||||
|
{
|
||||||
|
case kEditBoxInputFlagPassword:
|
||||||
|
mInputFlagConstraints = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputFlagSensitive:
|
||||||
|
mInputFlagConstraints = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputFlagInitialCapsWord:
|
||||||
|
mInputFlagConstraints = InputType.TYPE_TEXT_FLAG_CAP_WORDS;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputFlagInitialCapsSentence:
|
||||||
|
mInputFlagConstraints = InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputFlagInitialCapsAllCharacters:
|
||||||
|
mInputFlagConstraints = InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mInputEditText.setInputType(mInputFlagConstraints | mInputModeContraints);
|
||||||
|
|
||||||
|
switch (mReturnType) {
|
||||||
|
case kKeyboardReturnTypeDefault:
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_ACTION_NONE);
|
||||||
|
break;
|
||||||
|
case kKeyboardReturnTypeDone:
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_ACTION_DONE);
|
||||||
|
break;
|
||||||
|
case kKeyboardReturnTypeSend:
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_ACTION_SEND);
|
||||||
|
break;
|
||||||
|
case kKeyboardReturnTypeSearch:
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_ACTION_SEARCH);
|
||||||
|
break;
|
||||||
|
case kKeyboardReturnTypeGo:
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_ACTION_GO);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_ACTION_NONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mMaxLength > 0) {
|
||||||
|
mInputEditText.setFilters(
|
||||||
|
new InputFilter[] {
|
||||||
|
new InputFilter.LengthFilter(mMaxLength)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handler initHandler = new Handler();
|
||||||
|
initHandler.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
mInputEditText.requestFocus();
|
||||||
|
mInputEditText.setSelection(mInputEditText.length());
|
||||||
|
openKeyboard();
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
mInputEditText.setOnEditorActionListener(new OnEditorActionListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
|
// if user didn't set keyboard type,
|
||||||
|
// this callback will be invoked twice with 'KeyEvent.ACTION_DOWN' and 'KeyEvent.ACTION_UP'
|
||||||
|
if (actionId != EditorInfo.IME_NULL
|
||||||
|
|| (actionId == EditorInfo.IME_NULL
|
||||||
|
&& event != null
|
||||||
|
&& event.getAction() == KeyEvent.ACTION_DOWN))
|
||||||
|
{
|
||||||
|
//Log.d("EditBox", "actionId: "+actionId +",event: "+event);
|
||||||
|
mParentActivity.setEditBoxResult(mInputEditText.getText().toString());
|
||||||
|
closeKeyboard();
|
||||||
|
dismiss();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openKeyboard() {
|
||||||
|
InputMethodManager imm = (InputMethodManager) mParentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.showSoftInput(mInputEditText, 0);
|
||||||
|
Log.d("Cocos2dxEditBox", "openKeyboard");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeKeyboard() {
|
||||||
|
InputMethodManager imm = (InputMethodManager) mParentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(mInputEditText.getWindowToken(), 0);
|
||||||
|
Log.d("Cocos2dxEditBox", "closeKeyboard");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
super.onStop();
|
||||||
|
Log.d("EditBox", "onStop...");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2012 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
public class Cocos2dxEditText extends EditText {
|
||||||
|
|
||||||
|
private Cocos2dxGLSurfaceView mView;
|
||||||
|
|
||||||
|
public Cocos2dxEditText(Context context) {
|
||||||
|
super(context);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cocos2dxEditText(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cocos2dxEditText(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMainView(Cocos2dxGLSurfaceView glSurfaceView) {
|
||||||
|
mView = glSurfaceView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Let GlSurfaceView get focus if back key is input
|
||||||
|
*/
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
|
super.onKeyDown(keyCode, event);
|
||||||
|
|
||||||
|
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||||
|
mView.requestFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,417 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.opengl.GLSurfaceView;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.TextView.OnEditorActionListener;
|
||||||
|
|
||||||
|
class TextInputWraper implements TextWatcher, OnEditorActionListener {
|
||||||
|
|
||||||
|
private static final Boolean debug = false;
|
||||||
|
private void LogD(String msg) {
|
||||||
|
if (debug) Log.d("TextInputFilter", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Cocos2dxGLSurfaceView mMainView;
|
||||||
|
private String mText;
|
||||||
|
private String mOriginText;
|
||||||
|
|
||||||
|
private Boolean isFullScreenEdit() {
|
||||||
|
InputMethodManager imm = (InputMethodManager)mMainView.getTextField().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
return imm.isFullscreenMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextInputWraper(Cocos2dxGLSurfaceView view) {
|
||||||
|
mMainView = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOriginText(String text) {
|
||||||
|
mOriginText = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
if (isFullScreenEdit()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogD("afterTextChanged: " + s);
|
||||||
|
int nModified = s.length() - mText.length();
|
||||||
|
if (nModified > 0) {
|
||||||
|
final String insertText = s.subSequence(mText.length(), s.length()).toString();
|
||||||
|
mMainView.insertText(insertText);
|
||||||
|
LogD("insertText(" + insertText + ")");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (; nModified < 0; ++nModified) {
|
||||||
|
mMainView.deleteBackward();
|
||||||
|
LogD("deleteBackward");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mText = s.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count,
|
||||||
|
int after) {
|
||||||
|
LogD("beforeTextChanged(" + s + ")start: " + start + ",count: " + count + ",after: " + after);
|
||||||
|
mText = s.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
|
if (mMainView.getTextField() == v && isFullScreenEdit()) {
|
||||||
|
// user press the action button, delete all old text and insert new text
|
||||||
|
for (int i = mOriginText.length(); i > 0; --i) {
|
||||||
|
mMainView.deleteBackward();
|
||||||
|
LogD("deleteBackward");
|
||||||
|
}
|
||||||
|
String text = v.getText().toString();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If user input nothing, translate "\n" to engine.
|
||||||
|
*/
|
||||||
|
if (text.compareTo("") == 0){
|
||||||
|
text = "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('\n' != text.charAt(text.length() - 1)) {
|
||||||
|
text += '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
final String insertText = text;
|
||||||
|
mMainView.insertText(insertText);
|
||||||
|
LogD("insertText(" + insertText + ")");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Cocos2dxGLSurfaceView extends GLSurfaceView {
|
||||||
|
|
||||||
|
static private Cocos2dxGLSurfaceView mainView;
|
||||||
|
|
||||||
|
private static final String TAG = Cocos2dxGLSurfaceView.class.getCanonicalName();
|
||||||
|
private Cocos2dxRenderer mRenderer;
|
||||||
|
|
||||||
|
private static final boolean debug = false;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// for initialize
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
public Cocos2dxGLSurfaceView(Context context) {
|
||||||
|
super(context);
|
||||||
|
initView();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cocos2dxGLSurfaceView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
initView();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCocos2dxRenderer(Cocos2dxRenderer renderer){
|
||||||
|
mRenderer = renderer;
|
||||||
|
setRenderer(mRenderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initView() {
|
||||||
|
setFocusableInTouchMode(true);
|
||||||
|
|
||||||
|
textInputWraper = new TextInputWraper(this);
|
||||||
|
|
||||||
|
handler = new Handler(){
|
||||||
|
public void handleMessage(Message msg){
|
||||||
|
switch(msg.what){
|
||||||
|
case HANDLER_OPEN_IME_KEYBOARD:
|
||||||
|
if (null != mTextField && mTextField.requestFocus()) {
|
||||||
|
mTextField.removeTextChangedListener(textInputWraper);
|
||||||
|
mTextField.setText("");
|
||||||
|
String text = (String)msg.obj;
|
||||||
|
mTextField.append(text);
|
||||||
|
textInputWraper.setOriginText(text);
|
||||||
|
mTextField.addTextChangedListener(textInputWraper);
|
||||||
|
InputMethodManager imm = (InputMethodManager)mainView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.showSoftInput(mTextField, 0);
|
||||||
|
Log.d("GLSurfaceView", "showSoftInput");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HANDLER_CLOSE_IME_KEYBOARD:
|
||||||
|
if (null != mTextField) {
|
||||||
|
mTextField.removeTextChangedListener(textInputWraper);
|
||||||
|
InputMethodManager imm = (InputMethodManager)mainView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(mTextField.getWindowToken(), 0);
|
||||||
|
Log.d("GLSurfaceView", "HideSoftInput");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mainView = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPause(){
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleOnPause();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResume(){
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleOnResume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// for text input
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
private final static int HANDLER_OPEN_IME_KEYBOARD = 2;
|
||||||
|
private final static int HANDLER_CLOSE_IME_KEYBOARD = 3;
|
||||||
|
private static Handler handler;
|
||||||
|
private static TextInputWraper textInputWraper;
|
||||||
|
private Cocos2dxEditText mTextField;
|
||||||
|
|
||||||
|
public TextView getTextField() {
|
||||||
|
return mTextField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextField(Cocos2dxEditText view) {
|
||||||
|
mTextField = view;
|
||||||
|
if (null != mTextField && null != textInputWraper) {
|
||||||
|
mTextField.setOnEditorActionListener(textInputWraper);
|
||||||
|
mTextField.setMainView(this);
|
||||||
|
this.requestFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void openIMEKeyboard() {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = HANDLER_OPEN_IME_KEYBOARD;
|
||||||
|
msg.obj = mainView.getContentText();
|
||||||
|
handler.sendMessage(msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getContentText() {
|
||||||
|
return mRenderer.getContentText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void closeIMEKeyboard() {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = HANDLER_CLOSE_IME_KEYBOARD;
|
||||||
|
handler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertText(final String text) {
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleInsertText(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteBackward() {
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleDeleteBackward();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// for touch event
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public boolean onTouchEvent(final MotionEvent event) {
|
||||||
|
// these data are used in ACTION_MOVE and ACTION_CANCEL
|
||||||
|
final int pointerNumber = event.getPointerCount();
|
||||||
|
final int[] ids = new int[pointerNumber];
|
||||||
|
final float[] xs = new float[pointerNumber];
|
||||||
|
final float[] ys = new float[pointerNumber];
|
||||||
|
|
||||||
|
for (int i = 0; i < pointerNumber; i++) {
|
||||||
|
ids[i] = event.getPointerId(i);
|
||||||
|
xs[i] = event.getX(i);
|
||||||
|
ys[i] = event.getY(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event.getAction() & MotionEvent.ACTION_MASK) {
|
||||||
|
case MotionEvent.ACTION_POINTER_DOWN:
|
||||||
|
final int indexPointerDown = event.getAction() >> MotionEvent.ACTION_POINTER_ID_SHIFT;
|
||||||
|
final int idPointerDown = event.getPointerId(indexPointerDown);
|
||||||
|
final float xPointerDown = event.getX(indexPointerDown);
|
||||||
|
final float yPointerDown = event.getY(indexPointerDown);
|
||||||
|
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleActionDown(idPointerDown, xPointerDown, yPointerDown);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
// there are only one finger on the screen
|
||||||
|
final int idDown = event.getPointerId(0);
|
||||||
|
final float xDown = xs[0];
|
||||||
|
final float yDown = ys[0];
|
||||||
|
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleActionDown(idDown, xDown, yDown);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleActionMove(ids, xs, ys);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
|
final int indexPointUp = event.getAction() >> MotionEvent.ACTION_POINTER_ID_SHIFT;
|
||||||
|
final int idPointerUp = event.getPointerId(indexPointUp);
|
||||||
|
final float xPointerUp = event.getX(indexPointUp);
|
||||||
|
final float yPointerUp = event.getY(indexPointUp);
|
||||||
|
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleActionUp(idPointerUp, xPointerUp, yPointerUp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
// there are only one finger on the screen
|
||||||
|
final int idUp = event.getPointerId(0);
|
||||||
|
final float xUp = xs[0];
|
||||||
|
final float yUp = ys[0];
|
||||||
|
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleActionUp(idUp, xUp, yUp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleActionCancel(ids, xs, ys);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug){
|
||||||
|
dumpEvent(event);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is called before Cocos2dxRenderer.nativeInit(), so the width and height is correct.
|
||||||
|
*/
|
||||||
|
protected void onSizeChanged(int w, int h, int oldw, int oldh){
|
||||||
|
this.mRenderer.setScreenWidthAndHeight(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
|
final int kc = keyCode;
|
||||||
|
if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) {
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleKeyDown(kc);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onKeyDown(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show an event in the LogCat view, for debugging
|
||||||
|
private void dumpEvent(MotionEvent event) {
|
||||||
|
String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" ,
|
||||||
|
"POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" };
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int action = event.getAction();
|
||||||
|
int actionCode = action & MotionEvent.ACTION_MASK;
|
||||||
|
sb.append("event ACTION_" ).append(names[actionCode]);
|
||||||
|
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|
||||||
|
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
|
||||||
|
sb.append("(pid " ).append(
|
||||||
|
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
|
||||||
|
sb.append(")" );
|
||||||
|
}
|
||||||
|
sb.append("[" );
|
||||||
|
for (int i = 0; i < event.getPointerCount(); i++) {
|
||||||
|
sb.append("#" ).append(i);
|
||||||
|
sb.append("(pid " ).append(event.getPointerId(i));
|
||||||
|
sb.append(")=" ).append((int) event.getX(i));
|
||||||
|
sb.append("," ).append((int) event.getY(i));
|
||||||
|
if (i + 1 < event.getPointerCount())
|
||||||
|
sb.append(";" );
|
||||||
|
}
|
||||||
|
sb.append("]" );
|
||||||
|
Log.d(TAG, sb.toString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,228 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.AssetFileDescriptor;
|
||||||
|
import android.media.MediaPlayer;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This class is used for controlling background music
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Cocos2dxMusic {
|
||||||
|
|
||||||
|
private static final String TAG = "Cocos2dxMusic";
|
||||||
|
private float mLeftVolume;
|
||||||
|
private float mRightVolume;
|
||||||
|
private Context mContext;
|
||||||
|
private MediaPlayer mBackgroundMediaPlayer;
|
||||||
|
private boolean mIsPaused;
|
||||||
|
private String mCurrentPath;
|
||||||
|
|
||||||
|
public Cocos2dxMusic(Context context){
|
||||||
|
this.mContext = context;
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void preloadBackgroundMusic(String path){
|
||||||
|
if ((mCurrentPath == null) || (! mCurrentPath.equals(path))){
|
||||||
|
// preload new background music
|
||||||
|
|
||||||
|
// release old resource and create a new one
|
||||||
|
if (mBackgroundMediaPlayer != null){
|
||||||
|
mBackgroundMediaPlayer.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
mBackgroundMediaPlayer = createMediaplayerFromAssets(path);
|
||||||
|
|
||||||
|
// record the path
|
||||||
|
mCurrentPath = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playBackgroundMusic(String path, boolean isLoop){
|
||||||
|
if (mCurrentPath == null){
|
||||||
|
// it is the first time to play background music
|
||||||
|
// or end() was called
|
||||||
|
mBackgroundMediaPlayer = createMediaplayerFromAssets(path);
|
||||||
|
mCurrentPath = path;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (! mCurrentPath.equals(path)){
|
||||||
|
// play new background music
|
||||||
|
|
||||||
|
// release old resource and create a new one
|
||||||
|
if (mBackgroundMediaPlayer != null){
|
||||||
|
mBackgroundMediaPlayer.release();
|
||||||
|
}
|
||||||
|
mBackgroundMediaPlayer = createMediaplayerFromAssets(path);
|
||||||
|
|
||||||
|
// record the path
|
||||||
|
mCurrentPath = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mBackgroundMediaPlayer == null){
|
||||||
|
Log.e(TAG, "playBackgroundMusic: background media player is null");
|
||||||
|
} else {
|
||||||
|
// if the music is playing or paused, stop it
|
||||||
|
mBackgroundMediaPlayer.stop();
|
||||||
|
|
||||||
|
mBackgroundMediaPlayer.setLooping(isLoop);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mBackgroundMediaPlayer.prepare();
|
||||||
|
mBackgroundMediaPlayer.seekTo(0);
|
||||||
|
mBackgroundMediaPlayer.start();
|
||||||
|
|
||||||
|
this.mIsPaused = false;
|
||||||
|
} catch (Exception e){
|
||||||
|
Log.e(TAG, "playBackgroundMusic: error state");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopBackgroundMusic(){
|
||||||
|
if (mBackgroundMediaPlayer != null){
|
||||||
|
mBackgroundMediaPlayer.stop();
|
||||||
|
|
||||||
|
// should set the state, if not , the following sequence will be error
|
||||||
|
// play -> pause -> stop -> resume
|
||||||
|
this.mIsPaused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseBackgroundMusic(){
|
||||||
|
if (mBackgroundMediaPlayer != null && mBackgroundMediaPlayer.isPlaying()){
|
||||||
|
mBackgroundMediaPlayer.pause();
|
||||||
|
this.mIsPaused = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resumeBackgroundMusic(){
|
||||||
|
if (mBackgroundMediaPlayer != null && this.mIsPaused){
|
||||||
|
mBackgroundMediaPlayer.start();
|
||||||
|
this.mIsPaused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rewindBackgroundMusic(){
|
||||||
|
if (mBackgroundMediaPlayer != null){
|
||||||
|
mBackgroundMediaPlayer.stop();
|
||||||
|
|
||||||
|
try {
|
||||||
|
mBackgroundMediaPlayer.prepare();
|
||||||
|
mBackgroundMediaPlayer.seekTo(0);
|
||||||
|
mBackgroundMediaPlayer.start();
|
||||||
|
|
||||||
|
this.mIsPaused = false;
|
||||||
|
} catch (Exception e){
|
||||||
|
Log.e(TAG, "rewindBackgroundMusic: error state");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBackgroundMusicPlaying(){
|
||||||
|
boolean ret = false;
|
||||||
|
|
||||||
|
if (mBackgroundMediaPlayer == null){
|
||||||
|
ret = false;
|
||||||
|
} else {
|
||||||
|
ret = mBackgroundMediaPlayer.isPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void end(){
|
||||||
|
if (mBackgroundMediaPlayer != null){
|
||||||
|
mBackgroundMediaPlayer.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBackgroundVolume(){
|
||||||
|
if (this.mBackgroundMediaPlayer != null){
|
||||||
|
return (this.mLeftVolume + this.mRightVolume) / 2;
|
||||||
|
} else {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackgroundVolume(float volume){
|
||||||
|
if (volume < 0.0f){
|
||||||
|
volume = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volume > 1.0f){
|
||||||
|
volume = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mLeftVolume = this.mRightVolume = volume;
|
||||||
|
if (this.mBackgroundMediaPlayer != null){
|
||||||
|
this.mBackgroundMediaPlayer.setVolume(this.mLeftVolume, this.mRightVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initData(){
|
||||||
|
mLeftVolume =0.5f;
|
||||||
|
mRightVolume = 0.5f;
|
||||||
|
mBackgroundMediaPlayer = null;
|
||||||
|
mIsPaused = false;
|
||||||
|
mCurrentPath = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create mediaplayer for music
|
||||||
|
* @param path the path relative to assets
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private MediaPlayer createMediaplayerFromAssets(String path){
|
||||||
|
MediaPlayer mediaPlayer = new MediaPlayer();
|
||||||
|
|
||||||
|
try{
|
||||||
|
if (path.startsWith("/")) {
|
||||||
|
mediaPlayer.setDataSource(path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AssetFileDescriptor assetFileDescritor = mContext.getAssets().openFd(path);
|
||||||
|
mediaPlayer.setDataSource(assetFileDescritor.getFileDescriptor(),
|
||||||
|
assetFileDescritor.getStartOffset(), assetFileDescritor.getLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaPlayer.prepare();
|
||||||
|
|
||||||
|
mediaPlayer.setVolume(mLeftVolume, mRightVolume);
|
||||||
|
}catch (Exception e) {
|
||||||
|
mediaPlayer = null;
|
||||||
|
Log.e(TAG, "error: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mediaPlayer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
|
import javax.microedition.khronos.opengles.GL10;
|
||||||
|
|
||||||
|
import android.opengl.GLSurfaceView;
|
||||||
|
|
||||||
|
public class Cocos2dxRenderer implements GLSurfaceView.Renderer {
|
||||||
|
private final static long NANOSECONDSPERSECOND = 1000000000L;
|
||||||
|
private final static long NANOSECONDSPERMINISECOND = 1000000;
|
||||||
|
private static long animationInterval = (long)(1.0 / 60 * NANOSECONDSPERSECOND);
|
||||||
|
private long last;
|
||||||
|
private int screenWidth;
|
||||||
|
private int screenHeight;
|
||||||
|
|
||||||
|
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||||
|
nativeInit(screenWidth, screenHeight);
|
||||||
|
last = System.nanoTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScreenWidthAndHeight(int w, int h){
|
||||||
|
this.screenWidth = w;
|
||||||
|
this.screenHeight = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSurfaceChanged(GL10 gl, int w, int h) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDrawFrame(GL10 gl) {
|
||||||
|
|
||||||
|
long now = System.nanoTime();
|
||||||
|
long interval = now - last;
|
||||||
|
|
||||||
|
// should render a frame when onDrawFrame() is called
|
||||||
|
// or there is a "ghost"
|
||||||
|
nativeRender();
|
||||||
|
|
||||||
|
// fps controlling
|
||||||
|
if (interval < animationInterval){
|
||||||
|
try {
|
||||||
|
// because we render it before, so we should sleep twice time interval
|
||||||
|
Thread.sleep((animationInterval - interval) * 2 / NANOSECONDSPERMINISECOND);
|
||||||
|
} catch (Exception e){}
|
||||||
|
}
|
||||||
|
|
||||||
|
last = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleActionDown(int id, float x, float y)
|
||||||
|
{
|
||||||
|
nativeTouchesBegin(id, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleActionUp(int id, float x, float y)
|
||||||
|
{
|
||||||
|
nativeTouchesEnd(id, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleActionCancel(int[] id, float[] x, float[] y)
|
||||||
|
{
|
||||||
|
nativeTouchesCancel(id, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleActionMove(int[] id, float[] x, float[] y)
|
||||||
|
{
|
||||||
|
nativeTouchesMove(id, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleKeyDown(int keyCode)
|
||||||
|
{
|
||||||
|
nativeKeyDown(keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleOnPause(){
|
||||||
|
nativeOnPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleOnResume(){
|
||||||
|
nativeOnResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setAnimationInterval(double interval){
|
||||||
|
animationInterval = (long)(interval * NANOSECONDSPERSECOND);
|
||||||
|
}
|
||||||
|
private static native void nativeTouchesBegin(int id, float x, float y);
|
||||||
|
private static native void nativeTouchesEnd(int id, float x, float y);
|
||||||
|
private static native void nativeTouchesMove(int[] id, float[] x, float[] y);
|
||||||
|
private static native void nativeTouchesCancel(int[] id, float[] x, float[] y);
|
||||||
|
private static native boolean nativeKeyDown(int keyCode);
|
||||||
|
private static native void nativeRender();
|
||||||
|
private static native void nativeInit(int w, int h);
|
||||||
|
private static native void nativeOnPause();
|
||||||
|
private static native void nativeOnResume();
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// handle input method edit message
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public void handleInsertText(final String text) {
|
||||||
|
nativeInsertText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleDeleteBackward() {
|
||||||
|
nativeDeleteBackward();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContentText() {
|
||||||
|
return nativeGetContentText();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void nativeInsertText(String text);
|
||||||
|
private static native void nativeDeleteBackward();
|
||||||
|
private static native String nativeGetContentText();
|
||||||
|
}
|
|
@ -0,0 +1,245 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.media.SoundPool;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This class is used for controlling effect
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Cocos2dxSound {
|
||||||
|
private Context mContext;
|
||||||
|
private SoundPool mSoundPool;
|
||||||
|
private float mLeftVolume;
|
||||||
|
private float mRightVolume;
|
||||||
|
|
||||||
|
// sound path and stream ids map
|
||||||
|
// a file may be played many times at the same time
|
||||||
|
// so there is an array map to a file path
|
||||||
|
private HashMap<String,ArrayList<Integer>> mPathStreamIDsMap;
|
||||||
|
|
||||||
|
private HashMap<String, Integer> mPathSoundIdMap;
|
||||||
|
|
||||||
|
private static final String TAG = "Cocos2dxSound";
|
||||||
|
private static final int MAX_SIMULTANEOUS_STREAMS_DEFAULT = 5;
|
||||||
|
private static final float SOUND_RATE = 1.0f;
|
||||||
|
private static final int SOUND_PRIORITY = 1;
|
||||||
|
private static final int SOUND_QUALITY = 5;
|
||||||
|
|
||||||
|
private final static int INVALID_SOUND_ID = -1;
|
||||||
|
private final static int INVALID_STREAM_ID = -1;
|
||||||
|
|
||||||
|
public Cocos2dxSound(Context context){
|
||||||
|
this.mContext = context;
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int preloadEffect(String path){
|
||||||
|
Integer soundID = this.mPathSoundIdMap.get(path);
|
||||||
|
|
||||||
|
if (soundID == null) {
|
||||||
|
soundID = createSoundIdFromAsset(path);
|
||||||
|
this.mPathSoundIdMap.put(path, soundID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return soundID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unloadEffect(String path){
|
||||||
|
// stop effects
|
||||||
|
ArrayList<Integer> streamIDs = this.mPathStreamIDsMap.get(path);
|
||||||
|
if (streamIDs != null) {
|
||||||
|
for (Integer streamID : streamIDs) {
|
||||||
|
this.mSoundPool.stop(streamID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.mPathStreamIDsMap.remove(path);
|
||||||
|
|
||||||
|
// unload effect
|
||||||
|
Integer soundID = this.mPathSoundIdMap.get(path);
|
||||||
|
this.mSoundPool.unload(soundID);
|
||||||
|
this.mPathSoundIdMap.remove(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int playEffect(String path, boolean isLoop){
|
||||||
|
Integer soundId = this.mPathSoundIdMap.get(path);
|
||||||
|
int streamId = INVALID_STREAM_ID;
|
||||||
|
|
||||||
|
if (soundId != null){
|
||||||
|
// play sound
|
||||||
|
streamId = this.mSoundPool.play(soundId.intValue(), this.mLeftVolume,
|
||||||
|
this.mRightVolume, SOUND_PRIORITY, isLoop ? -1 : 0, SOUND_RATE);
|
||||||
|
|
||||||
|
// record stream id
|
||||||
|
ArrayList<Integer> streamIds = this.mPathStreamIDsMap.get(path);
|
||||||
|
if (streamIds == null) {
|
||||||
|
streamIds = new ArrayList<Integer>();
|
||||||
|
this.mPathStreamIDsMap.put(path, streamIds);
|
||||||
|
}
|
||||||
|
streamIds.add(streamId);
|
||||||
|
} else {
|
||||||
|
// the effect is not prepared
|
||||||
|
soundId = preloadEffect(path);
|
||||||
|
if (soundId == INVALID_SOUND_ID){
|
||||||
|
// can not preload effect
|
||||||
|
return INVALID_SOUND_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Someone reports that, it can not play effect for the
|
||||||
|
* first time. If you are lucky to meet it. There are two
|
||||||
|
* ways to resolve it.
|
||||||
|
* 1. Add some delay here. I don't know how long it is, so
|
||||||
|
* I don't add it here.
|
||||||
|
* 2. If you use 2.2(API level 8), you can call
|
||||||
|
* SoundPool.setOnLoadCompleteListener() to play the effect.
|
||||||
|
* Because the method is supported from 2.2, so I can't use
|
||||||
|
* it here.
|
||||||
|
*/
|
||||||
|
playEffect(path, isLoop);
|
||||||
|
}
|
||||||
|
|
||||||
|
return streamId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopEffect(int streamID){
|
||||||
|
this.mSoundPool.stop(streamID);
|
||||||
|
|
||||||
|
// remove record
|
||||||
|
for (String path : this.mPathStreamIDsMap.keySet()) {
|
||||||
|
if (this.mPathStreamIDsMap.get(path).contains(streamID)) {
|
||||||
|
this.mPathStreamIDsMap.get(path).remove(this.mPathStreamIDsMap.get(path).indexOf(streamID));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseEffect(int streamID){
|
||||||
|
this.mSoundPool.pause(streamID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resumeEffect(int streamID){
|
||||||
|
this.mSoundPool.resume(streamID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseAllEffects(){
|
||||||
|
this.mSoundPool.autoPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resumeAllEffects(){
|
||||||
|
// autoPause() is available since level 8
|
||||||
|
this.mSoundPool.autoResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void stopAllEffects(){
|
||||||
|
// stop effects
|
||||||
|
if (! this.mPathStreamIDsMap.isEmpty()) {
|
||||||
|
Iterator<?> iter = this.mPathStreamIDsMap.entrySet().iterator();
|
||||||
|
while (iter.hasNext()){
|
||||||
|
Map.Entry<String, ArrayList<Integer>> entry = (Map.Entry<String, ArrayList<Integer>>)iter.next();
|
||||||
|
for (int streamID : entry.getValue()) {
|
||||||
|
this.mSoundPool.stop(streamID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove records
|
||||||
|
this.mPathStreamIDsMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getEffectsVolume(){
|
||||||
|
return (this.mLeftVolume + this.mRightVolume) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void setEffectsVolume(float volume){
|
||||||
|
// volume should be in [0, 1.0]
|
||||||
|
if (volume < 0){
|
||||||
|
volume = 0;
|
||||||
|
}
|
||||||
|
if (volume > 1){
|
||||||
|
volume = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mLeftVolume = this.mRightVolume = volume;
|
||||||
|
|
||||||
|
// change the volume of playing sounds
|
||||||
|
if (! this.mPathStreamIDsMap.isEmpty()) {
|
||||||
|
Iterator<?> iter = this.mPathStreamIDsMap.entrySet().iterator();
|
||||||
|
while (iter.hasNext()){
|
||||||
|
Map.Entry<String, ArrayList<Integer>> entry = (Map.Entry<String, ArrayList<Integer>>)iter.next();
|
||||||
|
for (int streamID : entry.getValue()) {
|
||||||
|
this.mSoundPool.setVolume(streamID, mLeftVolume, mRightVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void end(){
|
||||||
|
this.mSoundPool.release();
|
||||||
|
this.mPathStreamIDsMap.clear();
|
||||||
|
this.mPathSoundIdMap.clear();
|
||||||
|
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int createSoundIdFromAsset(String path){
|
||||||
|
int soundId = INVALID_SOUND_ID;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (path.startsWith("/")){
|
||||||
|
soundId = mSoundPool.load(path, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
soundId = mSoundPool.load(mContext.getAssets().openFd(path), 0);
|
||||||
|
}
|
||||||
|
} catch(Exception e){
|
||||||
|
soundId = INVALID_SOUND_ID;
|
||||||
|
Log.e(TAG, "error: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return soundId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initData(){
|
||||||
|
this.mPathStreamIDsMap = new HashMap<String,ArrayList<Integer>>();
|
||||||
|
this.mPathSoundIdMap = new HashMap<String, Integer>();
|
||||||
|
mSoundPool = new SoundPool(MAX_SIMULTANEOUS_STREAMS_DEFAULT, AudioManager.STREAM_MUSIC, SOUND_QUALITY);
|
||||||
|
|
||||||
|
this.mLeftVolume = 0.5f;
|
||||||
|
this.mRightVolume = 0.5f;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import java.util.Hashtable;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
|
||||||
|
public class Cocos2dxTypefaces {
|
||||||
|
private static final Hashtable<String, Typeface> cache = new Hashtable<String, Typeface>();
|
||||||
|
|
||||||
|
public static Typeface get(Context context, String name){
|
||||||
|
synchronized(cache){
|
||||||
|
if (! cache.containsKey(name)){
|
||||||
|
Typeface t = Typeface.createFromAsset(context.getAssets(), name);
|
||||||
|
cache.put(name, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache.get(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2012 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.simplegame;
|
||||||
|
|
||||||
|
import org.cocos2dx.lib.Cocos2dxActivity;
|
||||||
|
import org.cocos2dx.lib.Cocos2dxEditText;
|
||||||
|
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
|
||||||
|
import org.cocos2dx.lib.Cocos2dxRenderer;
|
||||||
|
|
||||||
|
import android.app.ActivityManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.ConfigurationInfo;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
public class SimpleGame extends Cocos2dxActivity{
|
||||||
|
|
||||||
|
protected void onCreate(Bundle savedInstanceState){
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
if (detectOpenGLES20()) {
|
||||||
|
// get the packageName,it's used to set the resource path
|
||||||
|
String packageName = getApplication().getPackageName();
|
||||||
|
super.setPackageName(packageName);
|
||||||
|
|
||||||
|
// FrameLayout
|
||||||
|
ViewGroup.LayoutParams framelayout_params =
|
||||||
|
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
|
||||||
|
ViewGroup.LayoutParams.FILL_PARENT);
|
||||||
|
FrameLayout framelayout = new FrameLayout(this);
|
||||||
|
framelayout.setLayoutParams(framelayout_params);
|
||||||
|
|
||||||
|
// Cocos2dxEditText layout
|
||||||
|
ViewGroup.LayoutParams edittext_layout_params =
|
||||||
|
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
Cocos2dxEditText edittext = new Cocos2dxEditText(this);
|
||||||
|
edittext.setLayoutParams(edittext_layout_params);
|
||||||
|
|
||||||
|
// ...add to FrameLayout
|
||||||
|
framelayout.addView(edittext);
|
||||||
|
|
||||||
|
// Cocos2dxGLSurfaceView
|
||||||
|
mGLView = new Cocos2dxGLSurfaceView(this);
|
||||||
|
|
||||||
|
// ...add to FrameLayout
|
||||||
|
framelayout.addView(mGLView);
|
||||||
|
|
||||||
|
mGLView.setEGLContextClientVersion(2);
|
||||||
|
mGLView.setCocos2dxRenderer(new Cocos2dxRenderer());
|
||||||
|
mGLView.setTextField(edittext);
|
||||||
|
|
||||||
|
// Set framelayout as the content view
|
||||||
|
setContentView(framelayout);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log.d("activity", "don't support gles2.0");
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
mGLView.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
mGLView.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean detectOpenGLES20()
|
||||||
|
{
|
||||||
|
ActivityManager am =
|
||||||
|
(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
|
ConfigurationInfo info = am.getDeviceConfigurationInfo();
|
||||||
|
return (info.reqGlEsVersion >= 0x20000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary("game");
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,8 +45,8 @@ bool AppDelegate::applicationDidFinishLaunching() {
|
||||||
{
|
{
|
||||||
// android, windows, blackberry, linux or mac
|
// android, windows, blackberry, linux or mac
|
||||||
// use 960*640 resources as design resolution size
|
// use 960*640 resources as design resolution size
|
||||||
CCFileUtils::sharedFileUtils()->setResourceDirectory("hd");
|
CCFileUtils::sharedFileUtils()->setResourceDirectory("sd");
|
||||||
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(960, 640, kResolutionNoBorder);
|
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(480, 320, kResolutionNoBorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// turn on display FPS
|
// turn on display FPS
|
||||||
|
|
|
@ -77,7 +77,8 @@ bool HelloWorld::init()
|
||||||
CC_BREAK_IF(! pCloseItem);
|
CC_BREAK_IF(! pCloseItem);
|
||||||
|
|
||||||
// Place the menu item bottom-right conner.
|
// Place the menu item bottom-right conner.
|
||||||
pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));
|
pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getVisibleSize().width - 20,
|
||||||
|
CCDirector::sharedDirector()->getVisibleOrigin().y + 20));
|
||||||
|
|
||||||
// Create a menu with the "close" menu item, it's an auto release object.
|
// Create a menu with the "close" menu item, it's an auto release object.
|
||||||
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
|
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
|
||||||
|
@ -90,7 +91,7 @@ bool HelloWorld::init()
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
// 2. add your codes below...
|
// 2. add your codes below...
|
||||||
|
|
||||||
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
|
CCSize winSize = CCDirector::sharedDirector()->getVisibleSize();
|
||||||
CCSprite *player = CCSprite::create("Player.png", CCRectMake(0, 0, 27, 40) );
|
CCSprite *player = CCSprite::create("Player.png", CCRectMake(0, 0, 27, 40) );
|
||||||
player->setPosition( ccp(player->getContentSize().width/2, winSize.height/2) );
|
player->setPosition( ccp(player->getContentSize().width/2, winSize.height/2) );
|
||||||
this->addChild(player);
|
this->addChild(player);
|
||||||
|
@ -126,7 +127,7 @@ void HelloWorld::addTarget()
|
||||||
CCSprite *target = CCSprite::create("Target.png", CCRectMake(0,0,27,40) );
|
CCSprite *target = CCSprite::create("Target.png", CCRectMake(0,0,27,40) );
|
||||||
|
|
||||||
// Determine where to spawn the target along the Y axis
|
// Determine where to spawn the target along the Y axis
|
||||||
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
|
CCSize winSize = CCDirector::sharedDirector()->getVisibleSize();
|
||||||
float minY = target->getContentSize().height/2;
|
float minY = target->getContentSize().height/2;
|
||||||
float maxY = winSize.height - target->getContentSize().height/2;
|
float maxY = winSize.height - target->getContentSize().height/2;
|
||||||
int rangeY = (int)(maxY - minY);
|
int rangeY = (int)(maxY - minY);
|
||||||
|
@ -137,7 +138,7 @@ void HelloWorld::addTarget()
|
||||||
// and along a random position along the Y axis as calculated
|
// and along a random position along the Y axis as calculated
|
||||||
target->setPosition(
|
target->setPosition(
|
||||||
ccp(winSize.width + (target->getContentSize().width/2),
|
ccp(winSize.width + (target->getContentSize().width/2),
|
||||||
actualY) );
|
CCDirector::sharedDirector()->getVisibleOrigin().y + actualY) );
|
||||||
this->addChild(target);
|
this->addChild(target);
|
||||||
|
|
||||||
// Determine speed of the target
|
// Determine speed of the target
|
||||||
|
@ -194,7 +195,7 @@ void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event)
|
||||||
CCLog("++++++++after x:%f, y:%f", location.x, location.y);
|
CCLog("++++++++after x:%f, y:%f", location.x, location.y);
|
||||||
|
|
||||||
// Set up initial location of projectile
|
// Set up initial location of projectile
|
||||||
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
|
CCSize winSize = CCDirector::sharedDirector()->getVisibleSize();
|
||||||
CCSprite *projectile = CCSprite::create("Projectile.png", CCRectMake(0, 0, 20, 20));
|
CCSprite *projectile = CCSprite::create("Projectile.png", CCRectMake(0, 0, 20, 20));
|
||||||
projectile->setPosition( ccp(20, winSize.height/2) );
|
projectile->setPosition( ccp(20, winSize.height/2) );
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="src" path="gen"/>
|
||||||
|
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||||
|
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||||
|
<classpathentry kind="output" path="bin/classes"/>
|
||||||
|
</classpath>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>SimpleGame</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="org.cocos2dx.simplegame"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0">
|
||||||
|
|
||||||
|
<uses-sdk android:minSdkVersion="8"/>
|
||||||
|
|
||||||
|
<application android:label="@string/app_name"
|
||||||
|
android:debuggable="true"
|
||||||
|
android:icon="@drawable/icon">
|
||||||
|
|
||||||
|
<activity android:name=".SimpleGame"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:screenOrientation="landscape"
|
||||||
|
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||||
|
android:configChanges="orientation">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
<supports-screens android:largeScreens="true"
|
||||||
|
android:smallScreens="true"
|
||||||
|
android:anyDensity="true"
|
||||||
|
android:normalScreens="true"/>
|
||||||
|
</manifest>
|
|
@ -0,0 +1,17 @@
|
||||||
|
# This file is used to override default values used by the Ant build system.
|
||||||
|
#
|
||||||
|
# This file must be checked into Version Control Systems, as it is
|
||||||
|
# integral to the build system of your project.
|
||||||
|
|
||||||
|
# This file is only used by the Ant script.
|
||||||
|
|
||||||
|
# You can use this to override default values such as
|
||||||
|
# 'source.dir' for the location of your java source folder and
|
||||||
|
# 'out.dir' for the location of your output folder.
|
||||||
|
|
||||||
|
# You can also use it define how the release builds are signed by declaring
|
||||||
|
# the following properties:
|
||||||
|
# 'key.store' for the location of your keystore and
|
||||||
|
# 'key.alias' for the name of the key to use.
|
||||||
|
# The password will be asked during the build when you use the 'release' target.
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project name="SimpleGame" default="help">
|
||||||
|
|
||||||
|
<!-- The local.properties file is created and updated by the 'android' tool.
|
||||||
|
It contains the path to the SDK. It should *NOT* be checked into
|
||||||
|
Version Control Systems. -->
|
||||||
|
<property file="local.properties" />
|
||||||
|
|
||||||
|
<!-- The ant.properties file can be created by you. It is only edited by the
|
||||||
|
'android' tool to add properties to it.
|
||||||
|
This is the place to change some Ant specific build properties.
|
||||||
|
Here are some properties you may want to change/update:
|
||||||
|
|
||||||
|
source.dir
|
||||||
|
The name of the source directory. Default is 'src'.
|
||||||
|
out.dir
|
||||||
|
The name of the output directory. Default is 'bin'.
|
||||||
|
|
||||||
|
For other overridable properties, look at the beginning of the rules
|
||||||
|
files in the SDK, at tools/ant/build.xml
|
||||||
|
|
||||||
|
Properties related to the SDK location or the project target should
|
||||||
|
be updated using the 'android' tool with the 'update' action.
|
||||||
|
|
||||||
|
This file is an integral part of the build system for your
|
||||||
|
application and should be checked into Version Control Systems.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<property file="ant.properties" />
|
||||||
|
|
||||||
|
<!-- if sdk.dir was not set from one of the property file, then
|
||||||
|
get it from the ANDROID_HOME env var.
|
||||||
|
This must be done before we load project.properties since
|
||||||
|
the proguard config can use sdk.dir -->
|
||||||
|
<property environment="env" />
|
||||||
|
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
|
||||||
|
<isset property="env.ANDROID_HOME" />
|
||||||
|
</condition>
|
||||||
|
|
||||||
|
<!-- The project.properties file is created and updated by the 'android'
|
||||||
|
tool, as well as ADT.
|
||||||
|
|
||||||
|
This contains project specific properties such as project target, and library
|
||||||
|
dependencies. Lower level build properties are stored in ant.properties
|
||||||
|
(or in .classpath for Eclipse projects).
|
||||||
|
|
||||||
|
This file is an integral part of the build system for your
|
||||||
|
application and should be checked into Version Control Systems. -->
|
||||||
|
<loadproperties srcFile="project.properties" />
|
||||||
|
|
||||||
|
<!-- quick check on sdk.dir -->
|
||||||
|
<fail
|
||||||
|
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
|
||||||
|
unless="sdk.dir"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Import per project custom build rules if present at the root of the project.
|
||||||
|
This is the place to put custom intermediary targets such as:
|
||||||
|
-pre-build
|
||||||
|
-pre-compile
|
||||||
|
-post-compile (This is typically used for code obfuscation.
|
||||||
|
Compiled code location: ${out.classes.absolute.dir}
|
||||||
|
If this is not done in place, override ${out.dex.input.absolute.dir})
|
||||||
|
-post-package
|
||||||
|
-post-build
|
||||||
|
-pre-clean
|
||||||
|
-->
|
||||||
|
<import file="custom_rules.xml" optional="true" />
|
||||||
|
|
||||||
|
<!-- Import the actual build file.
|
||||||
|
|
||||||
|
To customize existing targets, there are two options:
|
||||||
|
- Customize only one target:
|
||||||
|
- copy/paste the target into this file, *before* the
|
||||||
|
<import> task.
|
||||||
|
- customize it to your needs.
|
||||||
|
- Customize the whole content of build.xml
|
||||||
|
- copy/paste the content of the rules files (minus the top node)
|
||||||
|
into this file, replacing the <import> task.
|
||||||
|
- customize to your needs.
|
||||||
|
|
||||||
|
***********************
|
||||||
|
****** IMPORTANT ******
|
||||||
|
***********************
|
||||||
|
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
|
||||||
|
in order to avoid having your file be overridden by tools such as "android update project"
|
||||||
|
-->
|
||||||
|
<!-- version-tag: 1 -->
|
||||||
|
<import file="${sdk.dir}/tools/ant/build.xml" />
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,91 @@
|
||||||
|
APPNAME="SimpleGame"
|
||||||
|
|
||||||
|
# options
|
||||||
|
|
||||||
|
buildexternalsfromsource=
|
||||||
|
|
||||||
|
usage(){
|
||||||
|
cat << EOF
|
||||||
|
usage: $0 [options]
|
||||||
|
|
||||||
|
Build C/C++ code for $APPNAME using Android NDK
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
-s Build externals from source
|
||||||
|
-h this help
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
while getopts "sh" OPTION; do
|
||||||
|
case "$OPTION" in
|
||||||
|
s)
|
||||||
|
buildexternalsfromsource=1
|
||||||
|
;;
|
||||||
|
h)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# paths
|
||||||
|
|
||||||
|
if [ -z "${NDK_ROOT+aaa}" ];then
|
||||||
|
echo "please define NDK_ROOT"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
# ... use paths relative to current directory
|
||||||
|
COCOS2DX_ROOT="$DIR/../../../"
|
||||||
|
APP_ROOT="$DIR/.."
|
||||||
|
APP_ANDROID_ROOT="$DIR"
|
||||||
|
|
||||||
|
echo "NDK_ROOT = $NDK_ROOT"
|
||||||
|
echo "COCOS2DX_ROOT = $COCOS2DX_ROOT"
|
||||||
|
echo "APP_ROOT = $APP_ROOT"
|
||||||
|
echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT"
|
||||||
|
|
||||||
|
# make sure assets is exist
|
||||||
|
if [ -d "$APP_ANDROID_ROOT"/assets ]; then
|
||||||
|
rm -rf "$APP_ANDROID_ROOT"/assets
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir "$APP_ANDROID_ROOT"/assets
|
||||||
|
|
||||||
|
# copy resources
|
||||||
|
for file in "$APP_ROOT"/Resources/*
|
||||||
|
do
|
||||||
|
if [ -d "$file" ]; then
|
||||||
|
cp -rf "$file" "$APP_ANDROID_ROOT"/assets
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
cp "$file" "$APP_ANDROID_ROOT"/assets
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# copy icons (if they exist)
|
||||||
|
file="$APP_ANDROID_ROOT"/assets/Icon-72.png
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
cp "$file" "$APP_ANDROID_ROOT"/res/drawable-hdpi/icon.png
|
||||||
|
fi
|
||||||
|
file="$APP_ANDROID_ROOT"/assets/Icon-48.png
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
cp "$file" "$APP_ANDROID_ROOT"/res/drawable-mdpi/icon.png
|
||||||
|
fi
|
||||||
|
file="$APP_ANDROID_ROOT"/assets/Icon-32.png
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
cp "$file" "$APP_ANDROID_ROOT"/res/drawable-ldpi/icon.png
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [[ "$buildexternalsfromsource" ]]; then
|
||||||
|
echo "Building external dependencies from source"
|
||||||
|
"$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
|
||||||
|
"NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/source"
|
||||||
|
else
|
||||||
|
echo "Using prebuilt externals"
|
||||||
|
"$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
|
||||||
|
"NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/prebuilt"
|
||||||
|
fi
|
|
@ -0,0 +1,22 @@
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := game_shared
|
||||||
|
|
||||||
|
LOCAL_MODULE_FILENAME := libgame
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := hellocpp/main.cpp \
|
||||||
|
../../Classes/AppDelegate.cpp \
|
||||||
|
../../Classes/HelloWorldScene.cpp \
|
||||||
|
../../Classes/GameOverScene.cpp
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes
|
||||||
|
|
||||||
|
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static cocosdenshion_static cocos_extension_static
|
||||||
|
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
$(call import-module,CocosDenshion/android) \
|
||||||
|
$(call import-module,cocos2dx) \
|
||||||
|
$(call import-module,extensions)
|
|
@ -0,0 +1,2 @@
|
||||||
|
APP_STL := gnustl_static
|
||||||
|
APP_CPPFLAGS := -frtti
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include "AppDelegate.h"
|
||||||
|
#include "platform/android/jni/JniHelper.h"
|
||||||
|
#include <jni.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
|
||||||
|
#include "HelloWorldScene.h"
|
||||||
|
|
||||||
|
#define LOG_TAG "main"
|
||||||
|
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
|
||||||
|
|
||||||
|
using namespace cocos2d;
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
|
||||||
|
jint JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||||
|
{
|
||||||
|
JniHelper::setJavaVM(vm);
|
||||||
|
|
||||||
|
return JNI_VERSION_1_4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)
|
||||||
|
{
|
||||||
|
if (!CCDirector::sharedDirector()->getOpenGLView())
|
||||||
|
{
|
||||||
|
CCEGLView *view = CCEGLView::sharedOpenGLView();
|
||||||
|
view->setFrameSize(w, h);
|
||||||
|
|
||||||
|
AppDelegate *pAppDelegate = new AppDelegate();
|
||||||
|
CCApplication::sharedApplication()->run();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ccDrawInit();
|
||||||
|
ccGLInvalidateStateCache();
|
||||||
|
|
||||||
|
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
|
||||||
|
CCTextureCache::reloadAllTextures();
|
||||||
|
CCNotificationCenter::sharedNotificationCenter()->postNotification(EVNET_COME_TO_FOREGROUND, NULL);
|
||||||
|
CCDirector::sharedDirector()->setGLDefaultValues();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
append_str=' \'
|
||||||
|
|
||||||
|
list_alldir()
|
||||||
|
{
|
||||||
|
for file in $1/*
|
||||||
|
do
|
||||||
|
if [ -f $file ]; then
|
||||||
|
echo $file$append_str | grep .cpp
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d $file ]; then
|
||||||
|
list_alldir $file
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
list_alldir "$1"
|
||||||
|
else
|
||||||
|
list_alldir "."
|
||||||
|
fi
|
|
@ -0,0 +1,20 @@
|
||||||
|
# To enable ProGuard in your project, edit project.properties
|
||||||
|
# to define the proguard.config property as described in that file.
|
||||||
|
#
|
||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the ProGuard
|
||||||
|
# include property in project.properties.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
|
@ -0,0 +1,14 @@
|
||||||
|
# This file is automatically generated by Android Tools.
|
||||||
|
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||||
|
#
|
||||||
|
# This file must be checked in Version Control Systems.
|
||||||
|
#
|
||||||
|
# To customize properties used by the Ant build system edit
|
||||||
|
# "ant.properties", and override values to adapt the script to your
|
||||||
|
# project structure.
|
||||||
|
#
|
||||||
|
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||||
|
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||||
|
|
||||||
|
# Project target.
|
||||||
|
target=android-8
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">SimpleGame</string>
|
||||||
|
</resources>
|
|
@ -0,0 +1,107 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.hardware.Sensor;
|
||||||
|
import android.hardware.SensorEvent;
|
||||||
|
import android.hardware.SensorEventListener;
|
||||||
|
import android.hardware.SensorManager;
|
||||||
|
import android.view.Display;
|
||||||
|
import android.view.Surface;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This class is used for controlling the Accelerometer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Cocos2dxAccelerometer implements SensorEventListener {
|
||||||
|
|
||||||
|
private static final String TAG = "Cocos2dxAccelerometer";
|
||||||
|
private Context mContext;
|
||||||
|
private SensorManager mSensorManager;
|
||||||
|
private Sensor mAccelerometer;
|
||||||
|
private int mNaturalOrientation;
|
||||||
|
|
||||||
|
public Cocos2dxAccelerometer(Context context){
|
||||||
|
mContext = context;
|
||||||
|
|
||||||
|
//Get an instance of the SensorManager
|
||||||
|
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
|
||||||
|
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||||
|
|
||||||
|
Display display = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||||
|
mNaturalOrientation = display.getOrientation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enable() {
|
||||||
|
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disable () {
|
||||||
|
mSensorManager.unregisterListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSensorChanged(SensorEvent event) {
|
||||||
|
|
||||||
|
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float x = event.values[0];
|
||||||
|
float y = event.values[1];
|
||||||
|
float z = event.values[2];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Because the axes are not swapped when the device's screen orientation changes.
|
||||||
|
* So we should swap it here.
|
||||||
|
* In tablets such as Motorola Xoom, the default orientation is landscape, so should
|
||||||
|
* consider this.
|
||||||
|
*/
|
||||||
|
int orientation = mContext.getResources().getConfiguration().orientation;
|
||||||
|
if ((orientation == Configuration.ORIENTATION_LANDSCAPE) && (mNaturalOrientation != Surface.ROTATION_0)){
|
||||||
|
float tmp = x;
|
||||||
|
x = -y;
|
||||||
|
y = tmp;
|
||||||
|
}
|
||||||
|
else if ((orientation == Configuration.ORIENTATION_PORTRAIT) && (mNaturalOrientation != Surface.ROTATION_0))
|
||||||
|
{
|
||||||
|
float tmp = x;
|
||||||
|
x = y;
|
||||||
|
y = -tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSensorChanged(x, y, z, event.timestamp);
|
||||||
|
// Log.d(TAG, "x = " + event.values[0] + " y = " + event.values[1] + " z = " + event.values[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void onSensorChanged(float x, float y, float z, long timeStamp);
|
||||||
|
}
|
|
@ -0,0 +1,346 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2012 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class Cocos2dxActivity extends Activity{
|
||||||
|
|
||||||
|
protected Cocos2dxGLSurfaceView mGLView;
|
||||||
|
private static Cocos2dxMusic backgroundMusicPlayer;
|
||||||
|
private static Cocos2dxSound soundPlayer;
|
||||||
|
private static Cocos2dxAccelerometer accelerometer;
|
||||||
|
private static AssetManager assetManager;
|
||||||
|
private static boolean accelerometerEnabled = false;
|
||||||
|
private static Handler handler;
|
||||||
|
private final static int HANDLER_SHOW_DIALOG = 1;
|
||||||
|
private final static int HANDLER_SHOW_EDITBOX_DIALOG = 2;
|
||||||
|
|
||||||
|
private static String packageName;
|
||||||
|
|
||||||
|
private static native void nativeSetPaths(String apkPath);
|
||||||
|
private static native void nativeSetEditboxText(byte[] text);
|
||||||
|
|
||||||
|
|
||||||
|
static class ShowDialogHandler extends Handler {
|
||||||
|
WeakReference<Cocos2dxActivity> mActivity;
|
||||||
|
|
||||||
|
ShowDialogHandler(Cocos2dxActivity activity) {
|
||||||
|
mActivity = new WeakReference<Cocos2dxActivity>(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
Cocos2dxActivity theActivity = mActivity.get();
|
||||||
|
switch(msg.what) {
|
||||||
|
case HANDLER_SHOW_DIALOG:
|
||||||
|
theActivity.showDialog(((DialogMessage)msg.obj).title, ((DialogMessage)msg.obj).message);
|
||||||
|
break;
|
||||||
|
case HANDLER_SHOW_EDITBOX_DIALOG:
|
||||||
|
theActivity.onShowEditBoxDialog((EditBoxMessage)msg.obj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public Cocos2dxGLSurfaceView getGLView() {
|
||||||
|
return mGLView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// get frame size
|
||||||
|
DisplayMetrics dm = new DisplayMetrics();
|
||||||
|
getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||||
|
accelerometer = new Cocos2dxAccelerometer(this);
|
||||||
|
|
||||||
|
// init media player and sound player
|
||||||
|
backgroundMusicPlayer = new Cocos2dxMusic(this);
|
||||||
|
soundPlayer = new Cocos2dxSound(this);
|
||||||
|
|
||||||
|
// init asset manager for jni call
|
||||||
|
assetManager = getAssets();
|
||||||
|
|
||||||
|
// init bitmap context
|
||||||
|
Cocos2dxBitmap.setContext(this);
|
||||||
|
|
||||||
|
handler = new ShowDialogHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDeviceModel(){
|
||||||
|
return Build.MODEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AssetManager getAssetManager() {
|
||||||
|
return assetManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCurrentLanguage() {
|
||||||
|
String languageName = java.util.Locale.getDefault().getLanguage();
|
||||||
|
return languageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showMessageBox(String title, String message){
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = HANDLER_SHOW_DIALOG;
|
||||||
|
msg.obj = new DialogMessage(title, message);
|
||||||
|
|
||||||
|
handler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void enableAccelerometer() {
|
||||||
|
accelerometerEnabled = true;
|
||||||
|
accelerometer.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void disableAccelerometer() {
|
||||||
|
accelerometerEnabled = false;
|
||||||
|
accelerometer.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void preloadBackgroundMusic(String path){
|
||||||
|
backgroundMusicPlayer.preloadBackgroundMusic(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void playBackgroundMusic(String path, boolean isLoop){
|
||||||
|
backgroundMusicPlayer.playBackgroundMusic(path, isLoop);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stopBackgroundMusic(){
|
||||||
|
backgroundMusicPlayer.stopBackgroundMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void pauseBackgroundMusic(){
|
||||||
|
backgroundMusicPlayer.pauseBackgroundMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resumeBackgroundMusic(){
|
||||||
|
backgroundMusicPlayer.resumeBackgroundMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void rewindBackgroundMusic(){
|
||||||
|
backgroundMusicPlayer.rewindBackgroundMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBackgroundMusicPlaying(){
|
||||||
|
return backgroundMusicPlayer.isBackgroundMusicPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getBackgroundMusicVolume(){
|
||||||
|
return backgroundMusicPlayer.getBackgroundVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setBackgroundMusicVolume(float volume){
|
||||||
|
backgroundMusicPlayer.setBackgroundVolume(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int playEffect(String path, boolean isLoop){
|
||||||
|
return soundPlayer.playEffect(path, isLoop);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stopEffect(int soundId){
|
||||||
|
soundPlayer.stopEffect(soundId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void pauseEffect(int soundId){
|
||||||
|
soundPlayer.pauseEffect(soundId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resumeEffect(int soundId){
|
||||||
|
soundPlayer.resumeEffect(soundId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getEffectsVolume(){
|
||||||
|
return soundPlayer.getEffectsVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setEffectsVolume(float volume){
|
||||||
|
soundPlayer.setEffectsVolume(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void preloadEffect(String path){
|
||||||
|
soundPlayer.preloadEffect(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unloadEffect(String path){
|
||||||
|
soundPlayer.unloadEffect(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stopAllEffects(){
|
||||||
|
soundPlayer.stopAllEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void pauseAllEffects(){
|
||||||
|
soundPlayer.pauseAllEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resumeAllEffects(){
|
||||||
|
soundPlayer.resumeAllEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void end(){
|
||||||
|
backgroundMusicPlayer.end();
|
||||||
|
soundPlayer.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCocos2dxPackageName(){
|
||||||
|
return packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void terminateProcess(){
|
||||||
|
android.os.Process.killProcess(android.os.Process.myPid());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
if (accelerometerEnabled) {
|
||||||
|
accelerometer.enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
if (accelerometerEnabled) {
|
||||||
|
accelerometer.disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setPackageName(String packageName) {
|
||||||
|
Cocos2dxActivity.packageName = packageName;
|
||||||
|
|
||||||
|
String apkFilePath = "";
|
||||||
|
ApplicationInfo appInfo = null;
|
||||||
|
PackageManager packMgmr = getApplication().getPackageManager();
|
||||||
|
try {
|
||||||
|
appInfo = packMgmr.getApplicationInfo(packageName, 0);
|
||||||
|
} catch (NameNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException("Unable to locate assets, aborting...");
|
||||||
|
}
|
||||||
|
apkFilePath = appInfo.sourceDir;
|
||||||
|
Log.w("apk path", apkFilePath);
|
||||||
|
|
||||||
|
// add this link at the renderer class
|
||||||
|
nativeSetPaths(apkFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDialog(String title, String message){
|
||||||
|
Dialog dialog = new AlertDialog.Builder(this)
|
||||||
|
.setTitle(title)
|
||||||
|
.setMessage(message)
|
||||||
|
.setPositiveButton("Ok",
|
||||||
|
new DialogInterface.OnClickListener()
|
||||||
|
{
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton){
|
||||||
|
|
||||||
|
}
|
||||||
|
}).create();
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void showEditBoxDialog(String title, String content, int inputMode, int inputFlag, int returnType, int maxLength)
|
||||||
|
{
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = HANDLER_SHOW_EDITBOX_DIALOG;
|
||||||
|
msg.obj = new EditBoxMessage(title, content, inputMode, inputFlag, returnType, maxLength);
|
||||||
|
handler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onShowEditBoxDialog(EditBoxMessage msg)
|
||||||
|
{
|
||||||
|
Dialog dialog = new Cocos2dxEditBoxDialog(this, msg);
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEditBoxResult(String editResult)
|
||||||
|
{
|
||||||
|
Log.i("editbox_content", editResult);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
final byte[] bytesUTF8 = editResult.getBytes("UTF8");
|
||||||
|
// pass utf8 string from editbox activity to native.
|
||||||
|
// Should invoke native method in GL thread.
|
||||||
|
mGLView.queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
nativeSetEditboxText(bytesUTF8);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (java.io.UnsupportedEncodingException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DialogMessage {
|
||||||
|
public String title;
|
||||||
|
public String message;
|
||||||
|
|
||||||
|
public DialogMessage(String title, String message){
|
||||||
|
this.message = message;
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditBoxMessage {
|
||||||
|
public String title;
|
||||||
|
public String content;
|
||||||
|
public int inputMode;
|
||||||
|
public int inputFlag;
|
||||||
|
public int returnType;
|
||||||
|
public int maxLength;
|
||||||
|
|
||||||
|
public EditBoxMessage(String title, String content, int inputMode, int inputFlag, int returnType, int maxLength){
|
||||||
|
this.content = content;
|
||||||
|
this.title = title;
|
||||||
|
this.inputMode = inputMode;
|
||||||
|
this.inputFlag = inputFlag;
|
||||||
|
this.returnType = returnType;
|
||||||
|
this.maxLength = maxLength;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,455 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.graphics.Paint.Align;
|
||||||
|
import android.graphics.Paint.FontMetricsInt;
|
||||||
|
import android.text.TextPaint;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class Cocos2dxBitmap{
|
||||||
|
/*
|
||||||
|
* The values are the same as cocos2dx/platform/CCImage.h.
|
||||||
|
*/
|
||||||
|
private static final int HALIGNCENTER = 3;
|
||||||
|
private static final int HALIGNLEFT = 1;
|
||||||
|
private static final int HALIGNRIGHT = 2;
|
||||||
|
// vertical alignment
|
||||||
|
private static final int VALIGNTOP = 1;
|
||||||
|
private static final int VALIGNBOTTOM = 2;
|
||||||
|
private static final int VALIGNCENTER = 3;
|
||||||
|
|
||||||
|
private static Context context;
|
||||||
|
|
||||||
|
public static void setContext(Context context){
|
||||||
|
Cocos2dxBitmap.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @width: the width to draw, it can be 0
|
||||||
|
* @height: the height to draw, it can be 0
|
||||||
|
*/
|
||||||
|
public static void createTextBitmap(String content, String fontName,
|
||||||
|
int fontSize, int alignment, int width, int height){
|
||||||
|
|
||||||
|
content = refactorString(content);
|
||||||
|
Paint paint = newPaint(fontName, fontSize, alignment);
|
||||||
|
|
||||||
|
TextProperty textProperty = computeTextProperty(content, paint, width, height);
|
||||||
|
|
||||||
|
int bitmapTotalHeight = (height == 0 ? textProperty.totalHeight:height);
|
||||||
|
|
||||||
|
// Draw text to bitmap
|
||||||
|
Bitmap bitmap = Bitmap.createBitmap(textProperty.maxWidth,
|
||||||
|
bitmapTotalHeight, Bitmap.Config.ARGB_8888);
|
||||||
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
|
||||||
|
// Draw string
|
||||||
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
|
int x = 0;
|
||||||
|
int y = computeY(fm, height, textProperty.totalHeight, alignment);
|
||||||
|
String[] lines = textProperty.lines;
|
||||||
|
for (String line : lines){
|
||||||
|
x = computeX(paint, line, textProperty.maxWidth, alignment);
|
||||||
|
canvas.drawText(line, x, y, paint);
|
||||||
|
y += textProperty.heightPerLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
initNativeObject(bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int computeX(Paint paint, String content, int w, int alignment){
|
||||||
|
int ret = 0;
|
||||||
|
int hAlignment = alignment & 0x0F;
|
||||||
|
|
||||||
|
switch (hAlignment){
|
||||||
|
case HALIGNCENTER:
|
||||||
|
ret = w / 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ret = 0
|
||||||
|
case HALIGNLEFT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HALIGNRIGHT:
|
||||||
|
ret = w;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default is align left.
|
||||||
|
* Should be same as newPaint().
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int computeY(FontMetricsInt fm, int constrainHeight, int totalHeight, int alignment) {
|
||||||
|
int y = -fm.top;
|
||||||
|
|
||||||
|
if (constrainHeight > totalHeight) {
|
||||||
|
int vAlignment = (alignment >> 4) & 0x0F;
|
||||||
|
|
||||||
|
switch (vAlignment) {
|
||||||
|
case VALIGNTOP:
|
||||||
|
y = -fm.top;
|
||||||
|
break;
|
||||||
|
case VALIGNCENTER:
|
||||||
|
y = -fm.top + (constrainHeight - totalHeight)/2;
|
||||||
|
break;
|
||||||
|
case VALIGNBOTTOM:
|
||||||
|
y = -fm.top + (constrainHeight - totalHeight);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TextProperty{
|
||||||
|
// The max width of lines
|
||||||
|
int maxWidth;
|
||||||
|
// The height of all lines
|
||||||
|
int totalHeight;
|
||||||
|
int heightPerLine;
|
||||||
|
String[] lines;
|
||||||
|
|
||||||
|
TextProperty(int w, int h, String[] lines){
|
||||||
|
this.maxWidth = w;
|
||||||
|
this.heightPerLine = h;
|
||||||
|
this.totalHeight = h * lines.length;
|
||||||
|
this.lines = lines;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextProperty computeTextProperty(String content, Paint paint,
|
||||||
|
int maxWidth, int maxHeight){
|
||||||
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
|
int h = (int)Math.ceil(fm.bottom - fm.top);
|
||||||
|
int maxContentWidth = 0;
|
||||||
|
|
||||||
|
String[] lines = splitString(content, maxHeight, maxWidth, paint);
|
||||||
|
|
||||||
|
if (maxWidth != 0){
|
||||||
|
maxContentWidth = maxWidth;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
* Compute the max width
|
||||||
|
*/
|
||||||
|
int temp = 0;
|
||||||
|
for (String line : lines){
|
||||||
|
temp = (int)Math.ceil(paint.measureText(line, 0, line.length()));
|
||||||
|
if (temp > maxContentWidth){
|
||||||
|
maxContentWidth = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TextProperty(maxContentWidth, h, lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If maxWidth or maxHeight is not 0,
|
||||||
|
* split the string to fix the maxWidth and maxHeight.
|
||||||
|
*/
|
||||||
|
private static String[] splitString(String content, int maxHeight, int maxWidth,
|
||||||
|
Paint paint){
|
||||||
|
String[] lines = content.split("\\n");
|
||||||
|
String[] ret = null;
|
||||||
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
|
int heightPerLine = (int)Math.ceil(fm.bottom - fm.top);
|
||||||
|
int maxLines = maxHeight / heightPerLine;
|
||||||
|
|
||||||
|
if (maxWidth != 0){
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
for (String line : lines){
|
||||||
|
/*
|
||||||
|
* The width of line is exceed maxWidth, should divide it into
|
||||||
|
* two or more lines.
|
||||||
|
*/
|
||||||
|
int lineWidth = (int)Math.ceil(paint.measureText(line));
|
||||||
|
if (lineWidth > maxWidth){
|
||||||
|
strList.addAll(divideStringWithMaxWidth(paint, line, maxWidth));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
strList.add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should not exceed the max height;
|
||||||
|
*/
|
||||||
|
if (maxLines > 0 && strList.size() >= maxLines){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove exceeding lines
|
||||||
|
*/
|
||||||
|
if (maxLines > 0 && strList.size() > maxLines){
|
||||||
|
while (strList.size() > maxLines){
|
||||||
|
strList.removeLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = new String[strList.size()];
|
||||||
|
strList.toArray(ret);
|
||||||
|
} else
|
||||||
|
if (maxHeight != 0 && lines.length > maxLines) {
|
||||||
|
/*
|
||||||
|
* Remove exceeding lines
|
||||||
|
*/
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
for (int i = 0; i < maxLines; i++){
|
||||||
|
strList.add(lines[i]);
|
||||||
|
}
|
||||||
|
ret = new String[strList.size()];
|
||||||
|
strList.toArray(ret);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LinkedList<String> divideStringWithMaxWidth(Paint paint, String content,
|
||||||
|
int width){
|
||||||
|
int charLength = content.length();
|
||||||
|
int start = 0;
|
||||||
|
int tempWidth = 0;
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Break a String into String[] by the width & should wrap the word
|
||||||
|
*/
|
||||||
|
for (int i = 1; i <= charLength; ++i){
|
||||||
|
tempWidth = (int)Math.ceil(paint.measureText(content, start, i));
|
||||||
|
if (tempWidth >= width){
|
||||||
|
int lastIndexOfSpace = content.substring(0, i).lastIndexOf(" ");
|
||||||
|
|
||||||
|
if (lastIndexOfSpace != -1 && lastIndexOfSpace > start){
|
||||||
|
/**
|
||||||
|
* Should wrap the word
|
||||||
|
*/
|
||||||
|
strList.add(content.substring(start, lastIndexOfSpace));
|
||||||
|
i = lastIndexOfSpace;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
* Should not exceed the width
|
||||||
|
*/
|
||||||
|
if (tempWidth > width){
|
||||||
|
strList.add(content.substring(start, i - 1));
|
||||||
|
/*
|
||||||
|
* compute from previous char
|
||||||
|
*/
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strList.add(content.substring(start, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove spaces at the beginning of a new line
|
||||||
|
while(content.indexOf(i++) == ' ') {
|
||||||
|
}
|
||||||
|
|
||||||
|
start = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the last chars
|
||||||
|
*/
|
||||||
|
if (start < charLength){
|
||||||
|
strList.add(content.substring(start));
|
||||||
|
}
|
||||||
|
|
||||||
|
return strList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Paint newPaint(String fontName, int fontSize, int alignment){
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setColor(Color.WHITE);
|
||||||
|
paint.setTextSize(fontSize);
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set type face for paint, now it support .ttf file.
|
||||||
|
*/
|
||||||
|
if (fontName.endsWith(".ttf")){
|
||||||
|
try {
|
||||||
|
//Typeface typeFace = Typeface.createFromAsset(context.getAssets(), fontName);
|
||||||
|
Typeface typeFace = Cocos2dxTypefaces.get(context, fontName);
|
||||||
|
paint.setTypeface(typeFace);
|
||||||
|
} catch (Exception e){
|
||||||
|
Log.e("Cocos2dxBitmap",
|
||||||
|
"error to create ttf type face: " + fontName);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The file may not find, use system font
|
||||||
|
*/
|
||||||
|
paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL));
|
||||||
|
}
|
||||||
|
|
||||||
|
int hAlignment = alignment & 0x0F;
|
||||||
|
switch (hAlignment){
|
||||||
|
case HALIGNCENTER:
|
||||||
|
paint.setTextAlign(Align.CENTER);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HALIGNLEFT:
|
||||||
|
paint.setTextAlign(Align.LEFT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HALIGNRIGHT:
|
||||||
|
paint.setTextAlign(Align.RIGHT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
paint.setTextAlign(Align.LEFT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return paint;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String refactorString(String str){
|
||||||
|
// Avoid error when content is ""
|
||||||
|
if (str.compareTo("") == 0){
|
||||||
|
return " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the font of "\n" is "" or "\n", insert " " in front of it.
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
* "\nabc" -> " \nabc"
|
||||||
|
* "\nabc\n\n" -> " \nabc\n \n"
|
||||||
|
*/
|
||||||
|
StringBuilder strBuilder = new StringBuilder(str);
|
||||||
|
int start = 0;
|
||||||
|
int index = strBuilder.indexOf("\n");
|
||||||
|
while (index != -1){
|
||||||
|
if (index == 0 || strBuilder.charAt(index -1) == '\n'){
|
||||||
|
strBuilder.insert(start, " ");
|
||||||
|
start = index + 2;
|
||||||
|
} else {
|
||||||
|
start = index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start > strBuilder.length() || index == strBuilder.length()){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = strBuilder.indexOf("\n", start);
|
||||||
|
}
|
||||||
|
|
||||||
|
return strBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void initNativeObject(Bitmap bitmap){
|
||||||
|
byte[] pixels = getPixels(bitmap);
|
||||||
|
if (pixels == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nativeInitBitmapDC(bitmap.getWidth(), bitmap.getHeight(), pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] getPixels(Bitmap bitmap){
|
||||||
|
if (bitmap != null){
|
||||||
|
byte[] pixels = new byte[bitmap.getWidth() * bitmap.getHeight() * 4];
|
||||||
|
ByteBuffer buf = ByteBuffer.wrap(pixels);
|
||||||
|
buf.order(ByteOrder.nativeOrder());
|
||||||
|
bitmap.copyPixelsToBuffer(buf);
|
||||||
|
return pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void nativeInitBitmapDC(int width, int height, byte[] pixels);
|
||||||
|
|
||||||
|
private static int getFontSizeAccordingHeight(int height)
|
||||||
|
{
|
||||||
|
Paint paint = new Paint();
|
||||||
|
Rect bounds = new Rect();
|
||||||
|
|
||||||
|
paint.setTypeface(Typeface.DEFAULT);
|
||||||
|
int incr_text_size = 1;
|
||||||
|
boolean found_desired_size = false;
|
||||||
|
|
||||||
|
while (!found_desired_size) {
|
||||||
|
|
||||||
|
paint.setTextSize(incr_text_size);
|
||||||
|
String text = "SghMNy";
|
||||||
|
paint.getTextBounds(text, 0, text.length(), bounds);
|
||||||
|
|
||||||
|
incr_text_size++;
|
||||||
|
|
||||||
|
if (height - bounds.height() <= 2) {
|
||||||
|
found_desired_size = true;
|
||||||
|
}
|
||||||
|
Log.d("font size", "incr size:" + incr_text_size);
|
||||||
|
}
|
||||||
|
return incr_text_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getStringWithEllipsis(String originalText, float width, float fontSize){
|
||||||
|
if(TextUtils.isEmpty(originalText)){
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
TextPaint paint = new TextPaint();
|
||||||
|
paint.setTypeface(Typeface.DEFAULT);
|
||||||
|
paint.setTextSize(fontSize);
|
||||||
|
|
||||||
|
return TextUtils.ellipsize(originalText, paint, width,
|
||||||
|
TextUtils.TruncateAt.valueOf("END")).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,338 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2012 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.drawable.ColorDrawable;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.text.InputFilter;
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.TextView.OnEditorActionListener;
|
||||||
|
|
||||||
|
public class Cocos2dxEditBoxDialog extends Dialog {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter any text, including line breaks.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModeAny = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter an e-mail address.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModeEmailAddr = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter an integer value.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModeNumeric = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter a phone number.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModePhoneNumber = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter a URL.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModeUrl = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter a real number value.
|
||||||
|
* This extends kEditBoxInputModeNumeric by allowing a decimal point.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModeDecimal = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is allowed to enter any text, except for line breaks.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputModeSingleLine = 6;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the text entered is confidential data that should be
|
||||||
|
* obscured whenever possible. This implies EDIT_BOX_INPUT_FLAG_SENSITIVE.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputFlagPassword = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the text entered is sensitive data that the
|
||||||
|
* implementation must never store into a dictionary or table for use
|
||||||
|
* in predictive, auto-completing, or other accelerated input schemes.
|
||||||
|
* A credit card number is an example of sensitive data.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputFlagSensitive = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This flag is a hint to the implementation that during text editing,
|
||||||
|
* the initial letter of each word should be capitalized.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputFlagInitialCapsWord = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This flag is a hint to the implementation that during text editing,
|
||||||
|
* the initial letter of each sentence should be capitalized.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputFlagInitialCapsSentence = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Capitalize all characters automatically.
|
||||||
|
*/
|
||||||
|
private final int kEditBoxInputFlagInitialCapsAllCharacters = 4;
|
||||||
|
|
||||||
|
private final int kKeyboardReturnTypeDefault = 0;
|
||||||
|
private final int kKeyboardReturnTypeDone = 1;
|
||||||
|
private final int kKeyboardReturnTypeSend = 2;
|
||||||
|
private final int kKeyboardReturnTypeSearch = 3;
|
||||||
|
private final int kKeyboardReturnTypeGo = 4;
|
||||||
|
|
||||||
|
//
|
||||||
|
private EditText mInputEditText = null;
|
||||||
|
private TextView mTextViewTitle = null;
|
||||||
|
private int mInputMode = 0;
|
||||||
|
private int mInputFlag = 0;
|
||||||
|
private int mReturnType = 0;
|
||||||
|
private int mMaxLength = -1;
|
||||||
|
|
||||||
|
private int mInputFlagConstraints = 0x00000;
|
||||||
|
private int mInputModeContraints = 0x00000;
|
||||||
|
private boolean mIsMultiline = false;
|
||||||
|
private Cocos2dxActivity mParentActivity = null;
|
||||||
|
private EditBoxMessage mMsg = null;
|
||||||
|
|
||||||
|
public Cocos2dxEditBoxDialog(Context context, EditBoxMessage msg) {
|
||||||
|
//super(context, R.style.Theme_Translucent);
|
||||||
|
super(context, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
mParentActivity = (Cocos2dxActivity)context;
|
||||||
|
mMsg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converting dips to pixels
|
||||||
|
private int convertDipsToPixels(float dips)
|
||||||
|
{
|
||||||
|
float scale = getContext().getResources().getDisplayMetrics().density;
|
||||||
|
return Math.round(dips * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
getWindow().setBackgroundDrawable(new ColorDrawable(0x80000000));
|
||||||
|
|
||||||
|
LinearLayout layout = new LinearLayout(mParentActivity);
|
||||||
|
layout.setOrientation(LinearLayout.VERTICAL);
|
||||||
|
|
||||||
|
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.
|
||||||
|
LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.FILL_PARENT);
|
||||||
|
|
||||||
|
mTextViewTitle = new TextView(mParentActivity);
|
||||||
|
LinearLayout.LayoutParams textviewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
textviewParams.leftMargin = textviewParams.rightMargin = convertDipsToPixels(10);
|
||||||
|
mTextViewTitle.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
|
||||||
|
layout.addView(mTextViewTitle, textviewParams);
|
||||||
|
|
||||||
|
mInputEditText = new EditText(mParentActivity);
|
||||||
|
LinearLayout.LayoutParams editTextParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
editTextParams.leftMargin = editTextParams.rightMargin = convertDipsToPixels(10);
|
||||||
|
|
||||||
|
layout.addView(mInputEditText, editTextParams);
|
||||||
|
|
||||||
|
setContentView(layout, layoutParams);
|
||||||
|
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
|
||||||
|
mInputMode = mMsg.inputMode;
|
||||||
|
mInputFlag = mMsg.inputFlag;
|
||||||
|
mReturnType = mMsg.returnType;
|
||||||
|
mMaxLength = mMsg.maxLength;
|
||||||
|
|
||||||
|
mTextViewTitle.setText(mMsg.title);
|
||||||
|
mInputEditText.setText(mMsg.content);
|
||||||
|
|
||||||
|
int oldImeOptions = mInputEditText.getImeOptions();
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
||||||
|
oldImeOptions = mInputEditText.getImeOptions();
|
||||||
|
|
||||||
|
switch (mInputMode)
|
||||||
|
{
|
||||||
|
case kEditBoxInputModeAny:
|
||||||
|
mInputModeContraints =
|
||||||
|
InputType.TYPE_CLASS_TEXT |
|
||||||
|
InputType.TYPE_TEXT_FLAG_MULTI_LINE;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputModeEmailAddr:
|
||||||
|
mInputModeContraints =
|
||||||
|
InputType.TYPE_CLASS_TEXT |
|
||||||
|
InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputModeNumeric:
|
||||||
|
mInputModeContraints =
|
||||||
|
InputType.TYPE_CLASS_NUMBER |
|
||||||
|
InputType.TYPE_NUMBER_FLAG_SIGNED;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputModePhoneNumber:
|
||||||
|
mInputModeContraints = InputType.TYPE_CLASS_PHONE;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputModeUrl:
|
||||||
|
mInputModeContraints =
|
||||||
|
InputType.TYPE_CLASS_TEXT |
|
||||||
|
InputType.TYPE_TEXT_VARIATION_URI;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputModeDecimal:
|
||||||
|
mInputModeContraints =
|
||||||
|
InputType.TYPE_CLASS_NUMBER |
|
||||||
|
InputType.TYPE_NUMBER_FLAG_DECIMAL |
|
||||||
|
InputType.TYPE_NUMBER_FLAG_SIGNED;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputModeSingleLine:
|
||||||
|
mInputModeContraints = InputType.TYPE_CLASS_TEXT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mIsMultiline ) {
|
||||||
|
mInputModeContraints |= InputType.TYPE_TEXT_FLAG_MULTI_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mInputEditText.setInputType(mInputModeContraints | mInputFlagConstraints);
|
||||||
|
|
||||||
|
switch (mInputFlag)
|
||||||
|
{
|
||||||
|
case kEditBoxInputFlagPassword:
|
||||||
|
mInputFlagConstraints = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputFlagSensitive:
|
||||||
|
mInputFlagConstraints = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputFlagInitialCapsWord:
|
||||||
|
mInputFlagConstraints = InputType.TYPE_TEXT_FLAG_CAP_WORDS;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputFlagInitialCapsSentence:
|
||||||
|
mInputFlagConstraints = InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
|
||||||
|
break;
|
||||||
|
case kEditBoxInputFlagInitialCapsAllCharacters:
|
||||||
|
mInputFlagConstraints = InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mInputEditText.setInputType(mInputFlagConstraints | mInputModeContraints);
|
||||||
|
|
||||||
|
switch (mReturnType) {
|
||||||
|
case kKeyboardReturnTypeDefault:
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_ACTION_NONE);
|
||||||
|
break;
|
||||||
|
case kKeyboardReturnTypeDone:
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_ACTION_DONE);
|
||||||
|
break;
|
||||||
|
case kKeyboardReturnTypeSend:
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_ACTION_SEND);
|
||||||
|
break;
|
||||||
|
case kKeyboardReturnTypeSearch:
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_ACTION_SEARCH);
|
||||||
|
break;
|
||||||
|
case kKeyboardReturnTypeGo:
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_ACTION_GO);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mInputEditText.setImeOptions(oldImeOptions | EditorInfo.IME_ACTION_NONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mMaxLength > 0) {
|
||||||
|
mInputEditText.setFilters(
|
||||||
|
new InputFilter[] {
|
||||||
|
new InputFilter.LengthFilter(mMaxLength)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handler initHandler = new Handler();
|
||||||
|
initHandler.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
mInputEditText.requestFocus();
|
||||||
|
mInputEditText.setSelection(mInputEditText.length());
|
||||||
|
openKeyboard();
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
mInputEditText.setOnEditorActionListener(new OnEditorActionListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
|
// if user didn't set keyboard type,
|
||||||
|
// this callback will be invoked twice with 'KeyEvent.ACTION_DOWN' and 'KeyEvent.ACTION_UP'
|
||||||
|
if (actionId != EditorInfo.IME_NULL
|
||||||
|
|| (actionId == EditorInfo.IME_NULL
|
||||||
|
&& event != null
|
||||||
|
&& event.getAction() == KeyEvent.ACTION_DOWN))
|
||||||
|
{
|
||||||
|
//Log.d("EditBox", "actionId: "+actionId +",event: "+event);
|
||||||
|
mParentActivity.setEditBoxResult(mInputEditText.getText().toString());
|
||||||
|
closeKeyboard();
|
||||||
|
dismiss();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openKeyboard() {
|
||||||
|
InputMethodManager imm = (InputMethodManager) mParentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.showSoftInput(mInputEditText, 0);
|
||||||
|
Log.d("Cocos2dxEditBox", "openKeyboard");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeKeyboard() {
|
||||||
|
InputMethodManager imm = (InputMethodManager) mParentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(mInputEditText.getWindowToken(), 0);
|
||||||
|
Log.d("Cocos2dxEditBox", "closeKeyboard");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
super.onStop();
|
||||||
|
Log.d("EditBox", "onStop...");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2012 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
public class Cocos2dxEditText extends EditText {
|
||||||
|
|
||||||
|
private Cocos2dxGLSurfaceView mView;
|
||||||
|
|
||||||
|
public Cocos2dxEditText(Context context) {
|
||||||
|
super(context);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cocos2dxEditText(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cocos2dxEditText(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMainView(Cocos2dxGLSurfaceView glSurfaceView) {
|
||||||
|
mView = glSurfaceView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Let GlSurfaceView get focus if back key is input
|
||||||
|
*/
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
|
super.onKeyDown(keyCode, event);
|
||||||
|
|
||||||
|
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||||
|
mView.requestFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,417 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.opengl.GLSurfaceView;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.TextView.OnEditorActionListener;
|
||||||
|
|
||||||
|
class TextInputWraper implements TextWatcher, OnEditorActionListener {
|
||||||
|
|
||||||
|
private static final Boolean debug = false;
|
||||||
|
private void LogD(String msg) {
|
||||||
|
if (debug) Log.d("TextInputFilter", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Cocos2dxGLSurfaceView mMainView;
|
||||||
|
private String mText;
|
||||||
|
private String mOriginText;
|
||||||
|
|
||||||
|
private Boolean isFullScreenEdit() {
|
||||||
|
InputMethodManager imm = (InputMethodManager)mMainView.getTextField().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
return imm.isFullscreenMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextInputWraper(Cocos2dxGLSurfaceView view) {
|
||||||
|
mMainView = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOriginText(String text) {
|
||||||
|
mOriginText = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
if (isFullScreenEdit()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogD("afterTextChanged: " + s);
|
||||||
|
int nModified = s.length() - mText.length();
|
||||||
|
if (nModified > 0) {
|
||||||
|
final String insertText = s.subSequence(mText.length(), s.length()).toString();
|
||||||
|
mMainView.insertText(insertText);
|
||||||
|
LogD("insertText(" + insertText + ")");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (; nModified < 0; ++nModified) {
|
||||||
|
mMainView.deleteBackward();
|
||||||
|
LogD("deleteBackward");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mText = s.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count,
|
||||||
|
int after) {
|
||||||
|
LogD("beforeTextChanged(" + s + ")start: " + start + ",count: " + count + ",after: " + after);
|
||||||
|
mText = s.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
|
if (mMainView.getTextField() == v && isFullScreenEdit()) {
|
||||||
|
// user press the action button, delete all old text and insert new text
|
||||||
|
for (int i = mOriginText.length(); i > 0; --i) {
|
||||||
|
mMainView.deleteBackward();
|
||||||
|
LogD("deleteBackward");
|
||||||
|
}
|
||||||
|
String text = v.getText().toString();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If user input nothing, translate "\n" to engine.
|
||||||
|
*/
|
||||||
|
if (text.compareTo("") == 0){
|
||||||
|
text = "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('\n' != text.charAt(text.length() - 1)) {
|
||||||
|
text += '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
final String insertText = text;
|
||||||
|
mMainView.insertText(insertText);
|
||||||
|
LogD("insertText(" + insertText + ")");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Cocos2dxGLSurfaceView extends GLSurfaceView {
|
||||||
|
|
||||||
|
static private Cocos2dxGLSurfaceView mainView;
|
||||||
|
|
||||||
|
private static final String TAG = Cocos2dxGLSurfaceView.class.getCanonicalName();
|
||||||
|
private Cocos2dxRenderer mRenderer;
|
||||||
|
|
||||||
|
private static final boolean debug = false;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// for initialize
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
public Cocos2dxGLSurfaceView(Context context) {
|
||||||
|
super(context);
|
||||||
|
initView();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cocos2dxGLSurfaceView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
initView();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCocos2dxRenderer(Cocos2dxRenderer renderer){
|
||||||
|
mRenderer = renderer;
|
||||||
|
setRenderer(mRenderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initView() {
|
||||||
|
setFocusableInTouchMode(true);
|
||||||
|
|
||||||
|
textInputWraper = new TextInputWraper(this);
|
||||||
|
|
||||||
|
handler = new Handler(){
|
||||||
|
public void handleMessage(Message msg){
|
||||||
|
switch(msg.what){
|
||||||
|
case HANDLER_OPEN_IME_KEYBOARD:
|
||||||
|
if (null != mTextField && mTextField.requestFocus()) {
|
||||||
|
mTextField.removeTextChangedListener(textInputWraper);
|
||||||
|
mTextField.setText("");
|
||||||
|
String text = (String)msg.obj;
|
||||||
|
mTextField.append(text);
|
||||||
|
textInputWraper.setOriginText(text);
|
||||||
|
mTextField.addTextChangedListener(textInputWraper);
|
||||||
|
InputMethodManager imm = (InputMethodManager)mainView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.showSoftInput(mTextField, 0);
|
||||||
|
Log.d("GLSurfaceView", "showSoftInput");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HANDLER_CLOSE_IME_KEYBOARD:
|
||||||
|
if (null != mTextField) {
|
||||||
|
mTextField.removeTextChangedListener(textInputWraper);
|
||||||
|
InputMethodManager imm = (InputMethodManager)mainView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(mTextField.getWindowToken(), 0);
|
||||||
|
Log.d("GLSurfaceView", "HideSoftInput");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mainView = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPause(){
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleOnPause();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResume(){
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleOnResume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// for text input
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
private final static int HANDLER_OPEN_IME_KEYBOARD = 2;
|
||||||
|
private final static int HANDLER_CLOSE_IME_KEYBOARD = 3;
|
||||||
|
private static Handler handler;
|
||||||
|
private static TextInputWraper textInputWraper;
|
||||||
|
private Cocos2dxEditText mTextField;
|
||||||
|
|
||||||
|
public TextView getTextField() {
|
||||||
|
return mTextField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextField(Cocos2dxEditText view) {
|
||||||
|
mTextField = view;
|
||||||
|
if (null != mTextField && null != textInputWraper) {
|
||||||
|
mTextField.setOnEditorActionListener(textInputWraper);
|
||||||
|
mTextField.setMainView(this);
|
||||||
|
this.requestFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void openIMEKeyboard() {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = HANDLER_OPEN_IME_KEYBOARD;
|
||||||
|
msg.obj = mainView.getContentText();
|
||||||
|
handler.sendMessage(msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getContentText() {
|
||||||
|
return mRenderer.getContentText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void closeIMEKeyboard() {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = HANDLER_CLOSE_IME_KEYBOARD;
|
||||||
|
handler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertText(final String text) {
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleInsertText(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteBackward() {
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleDeleteBackward();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// for touch event
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public boolean onTouchEvent(final MotionEvent event) {
|
||||||
|
// these data are used in ACTION_MOVE and ACTION_CANCEL
|
||||||
|
final int pointerNumber = event.getPointerCount();
|
||||||
|
final int[] ids = new int[pointerNumber];
|
||||||
|
final float[] xs = new float[pointerNumber];
|
||||||
|
final float[] ys = new float[pointerNumber];
|
||||||
|
|
||||||
|
for (int i = 0; i < pointerNumber; i++) {
|
||||||
|
ids[i] = event.getPointerId(i);
|
||||||
|
xs[i] = event.getX(i);
|
||||||
|
ys[i] = event.getY(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event.getAction() & MotionEvent.ACTION_MASK) {
|
||||||
|
case MotionEvent.ACTION_POINTER_DOWN:
|
||||||
|
final int indexPointerDown = event.getAction() >> MotionEvent.ACTION_POINTER_ID_SHIFT;
|
||||||
|
final int idPointerDown = event.getPointerId(indexPointerDown);
|
||||||
|
final float xPointerDown = event.getX(indexPointerDown);
|
||||||
|
final float yPointerDown = event.getY(indexPointerDown);
|
||||||
|
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleActionDown(idPointerDown, xPointerDown, yPointerDown);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
// there are only one finger on the screen
|
||||||
|
final int idDown = event.getPointerId(0);
|
||||||
|
final float xDown = xs[0];
|
||||||
|
final float yDown = ys[0];
|
||||||
|
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleActionDown(idDown, xDown, yDown);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleActionMove(ids, xs, ys);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
|
final int indexPointUp = event.getAction() >> MotionEvent.ACTION_POINTER_ID_SHIFT;
|
||||||
|
final int idPointerUp = event.getPointerId(indexPointUp);
|
||||||
|
final float xPointerUp = event.getX(indexPointUp);
|
||||||
|
final float yPointerUp = event.getY(indexPointUp);
|
||||||
|
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleActionUp(idPointerUp, xPointerUp, yPointerUp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
// there are only one finger on the screen
|
||||||
|
final int idUp = event.getPointerId(0);
|
||||||
|
final float xUp = xs[0];
|
||||||
|
final float yUp = ys[0];
|
||||||
|
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleActionUp(idUp, xUp, yUp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleActionCancel(ids, xs, ys);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug){
|
||||||
|
dumpEvent(event);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is called before Cocos2dxRenderer.nativeInit(), so the width and height is correct.
|
||||||
|
*/
|
||||||
|
protected void onSizeChanged(int w, int h, int oldw, int oldh){
|
||||||
|
this.mRenderer.setScreenWidthAndHeight(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
|
final int kc = keyCode;
|
||||||
|
if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) {
|
||||||
|
queueEvent(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mRenderer.handleKeyDown(kc);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onKeyDown(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show an event in the LogCat view, for debugging
|
||||||
|
private void dumpEvent(MotionEvent event) {
|
||||||
|
String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" ,
|
||||||
|
"POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" };
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int action = event.getAction();
|
||||||
|
int actionCode = action & MotionEvent.ACTION_MASK;
|
||||||
|
sb.append("event ACTION_" ).append(names[actionCode]);
|
||||||
|
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|
||||||
|
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
|
||||||
|
sb.append("(pid " ).append(
|
||||||
|
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
|
||||||
|
sb.append(")" );
|
||||||
|
}
|
||||||
|
sb.append("[" );
|
||||||
|
for (int i = 0; i < event.getPointerCount(); i++) {
|
||||||
|
sb.append("#" ).append(i);
|
||||||
|
sb.append("(pid " ).append(event.getPointerId(i));
|
||||||
|
sb.append(")=" ).append((int) event.getX(i));
|
||||||
|
sb.append("," ).append((int) event.getY(i));
|
||||||
|
if (i + 1 < event.getPointerCount())
|
||||||
|
sb.append(";" );
|
||||||
|
}
|
||||||
|
sb.append("]" );
|
||||||
|
Log.d(TAG, sb.toString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,228 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.AssetFileDescriptor;
|
||||||
|
import android.media.MediaPlayer;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This class is used for controlling background music
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Cocos2dxMusic {
|
||||||
|
|
||||||
|
private static final String TAG = "Cocos2dxMusic";
|
||||||
|
private float mLeftVolume;
|
||||||
|
private float mRightVolume;
|
||||||
|
private Context mContext;
|
||||||
|
private MediaPlayer mBackgroundMediaPlayer;
|
||||||
|
private boolean mIsPaused;
|
||||||
|
private String mCurrentPath;
|
||||||
|
|
||||||
|
public Cocos2dxMusic(Context context){
|
||||||
|
this.mContext = context;
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void preloadBackgroundMusic(String path){
|
||||||
|
if ((mCurrentPath == null) || (! mCurrentPath.equals(path))){
|
||||||
|
// preload new background music
|
||||||
|
|
||||||
|
// release old resource and create a new one
|
||||||
|
if (mBackgroundMediaPlayer != null){
|
||||||
|
mBackgroundMediaPlayer.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
mBackgroundMediaPlayer = createMediaplayerFromAssets(path);
|
||||||
|
|
||||||
|
// record the path
|
||||||
|
mCurrentPath = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playBackgroundMusic(String path, boolean isLoop){
|
||||||
|
if (mCurrentPath == null){
|
||||||
|
// it is the first time to play background music
|
||||||
|
// or end() was called
|
||||||
|
mBackgroundMediaPlayer = createMediaplayerFromAssets(path);
|
||||||
|
mCurrentPath = path;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (! mCurrentPath.equals(path)){
|
||||||
|
// play new background music
|
||||||
|
|
||||||
|
// release old resource and create a new one
|
||||||
|
if (mBackgroundMediaPlayer != null){
|
||||||
|
mBackgroundMediaPlayer.release();
|
||||||
|
}
|
||||||
|
mBackgroundMediaPlayer = createMediaplayerFromAssets(path);
|
||||||
|
|
||||||
|
// record the path
|
||||||
|
mCurrentPath = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mBackgroundMediaPlayer == null){
|
||||||
|
Log.e(TAG, "playBackgroundMusic: background media player is null");
|
||||||
|
} else {
|
||||||
|
// if the music is playing or paused, stop it
|
||||||
|
mBackgroundMediaPlayer.stop();
|
||||||
|
|
||||||
|
mBackgroundMediaPlayer.setLooping(isLoop);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mBackgroundMediaPlayer.prepare();
|
||||||
|
mBackgroundMediaPlayer.seekTo(0);
|
||||||
|
mBackgroundMediaPlayer.start();
|
||||||
|
|
||||||
|
this.mIsPaused = false;
|
||||||
|
} catch (Exception e){
|
||||||
|
Log.e(TAG, "playBackgroundMusic: error state");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopBackgroundMusic(){
|
||||||
|
if (mBackgroundMediaPlayer != null){
|
||||||
|
mBackgroundMediaPlayer.stop();
|
||||||
|
|
||||||
|
// should set the state, if not , the following sequence will be error
|
||||||
|
// play -> pause -> stop -> resume
|
||||||
|
this.mIsPaused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseBackgroundMusic(){
|
||||||
|
if (mBackgroundMediaPlayer != null && mBackgroundMediaPlayer.isPlaying()){
|
||||||
|
mBackgroundMediaPlayer.pause();
|
||||||
|
this.mIsPaused = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resumeBackgroundMusic(){
|
||||||
|
if (mBackgroundMediaPlayer != null && this.mIsPaused){
|
||||||
|
mBackgroundMediaPlayer.start();
|
||||||
|
this.mIsPaused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rewindBackgroundMusic(){
|
||||||
|
if (mBackgroundMediaPlayer != null){
|
||||||
|
mBackgroundMediaPlayer.stop();
|
||||||
|
|
||||||
|
try {
|
||||||
|
mBackgroundMediaPlayer.prepare();
|
||||||
|
mBackgroundMediaPlayer.seekTo(0);
|
||||||
|
mBackgroundMediaPlayer.start();
|
||||||
|
|
||||||
|
this.mIsPaused = false;
|
||||||
|
} catch (Exception e){
|
||||||
|
Log.e(TAG, "rewindBackgroundMusic: error state");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBackgroundMusicPlaying(){
|
||||||
|
boolean ret = false;
|
||||||
|
|
||||||
|
if (mBackgroundMediaPlayer == null){
|
||||||
|
ret = false;
|
||||||
|
} else {
|
||||||
|
ret = mBackgroundMediaPlayer.isPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void end(){
|
||||||
|
if (mBackgroundMediaPlayer != null){
|
||||||
|
mBackgroundMediaPlayer.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBackgroundVolume(){
|
||||||
|
if (this.mBackgroundMediaPlayer != null){
|
||||||
|
return (this.mLeftVolume + this.mRightVolume) / 2;
|
||||||
|
} else {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackgroundVolume(float volume){
|
||||||
|
if (volume < 0.0f){
|
||||||
|
volume = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volume > 1.0f){
|
||||||
|
volume = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mLeftVolume = this.mRightVolume = volume;
|
||||||
|
if (this.mBackgroundMediaPlayer != null){
|
||||||
|
this.mBackgroundMediaPlayer.setVolume(this.mLeftVolume, this.mRightVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initData(){
|
||||||
|
mLeftVolume =0.5f;
|
||||||
|
mRightVolume = 0.5f;
|
||||||
|
mBackgroundMediaPlayer = null;
|
||||||
|
mIsPaused = false;
|
||||||
|
mCurrentPath = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create mediaplayer for music
|
||||||
|
* @param path the path relative to assets
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private MediaPlayer createMediaplayerFromAssets(String path){
|
||||||
|
MediaPlayer mediaPlayer = new MediaPlayer();
|
||||||
|
|
||||||
|
try{
|
||||||
|
if (path.startsWith("/")) {
|
||||||
|
mediaPlayer.setDataSource(path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AssetFileDescriptor assetFileDescritor = mContext.getAssets().openFd(path);
|
||||||
|
mediaPlayer.setDataSource(assetFileDescritor.getFileDescriptor(),
|
||||||
|
assetFileDescritor.getStartOffset(), assetFileDescritor.getLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaPlayer.prepare();
|
||||||
|
|
||||||
|
mediaPlayer.setVolume(mLeftVolume, mRightVolume);
|
||||||
|
}catch (Exception e) {
|
||||||
|
mediaPlayer = null;
|
||||||
|
Log.e(TAG, "error: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mediaPlayer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
|
import javax.microedition.khronos.opengles.GL10;
|
||||||
|
|
||||||
|
import android.opengl.GLSurfaceView;
|
||||||
|
|
||||||
|
public class Cocos2dxRenderer implements GLSurfaceView.Renderer {
|
||||||
|
private final static long NANOSECONDSPERSECOND = 1000000000L;
|
||||||
|
private final static long NANOSECONDSPERMINISECOND = 1000000;
|
||||||
|
private static long animationInterval = (long)(1.0 / 60 * NANOSECONDSPERSECOND);
|
||||||
|
private long last;
|
||||||
|
private int screenWidth;
|
||||||
|
private int screenHeight;
|
||||||
|
|
||||||
|
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||||
|
nativeInit(screenWidth, screenHeight);
|
||||||
|
last = System.nanoTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScreenWidthAndHeight(int w, int h){
|
||||||
|
this.screenWidth = w;
|
||||||
|
this.screenHeight = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSurfaceChanged(GL10 gl, int w, int h) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDrawFrame(GL10 gl) {
|
||||||
|
|
||||||
|
long now = System.nanoTime();
|
||||||
|
long interval = now - last;
|
||||||
|
|
||||||
|
// should render a frame when onDrawFrame() is called
|
||||||
|
// or there is a "ghost"
|
||||||
|
nativeRender();
|
||||||
|
|
||||||
|
// fps controlling
|
||||||
|
if (interval < animationInterval){
|
||||||
|
try {
|
||||||
|
// because we render it before, so we should sleep twice time interval
|
||||||
|
Thread.sleep((animationInterval - interval) * 2 / NANOSECONDSPERMINISECOND);
|
||||||
|
} catch (Exception e){}
|
||||||
|
}
|
||||||
|
|
||||||
|
last = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleActionDown(int id, float x, float y)
|
||||||
|
{
|
||||||
|
nativeTouchesBegin(id, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleActionUp(int id, float x, float y)
|
||||||
|
{
|
||||||
|
nativeTouchesEnd(id, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleActionCancel(int[] id, float[] x, float[] y)
|
||||||
|
{
|
||||||
|
nativeTouchesCancel(id, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleActionMove(int[] id, float[] x, float[] y)
|
||||||
|
{
|
||||||
|
nativeTouchesMove(id, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleKeyDown(int keyCode)
|
||||||
|
{
|
||||||
|
nativeKeyDown(keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleOnPause(){
|
||||||
|
nativeOnPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleOnResume(){
|
||||||
|
nativeOnResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setAnimationInterval(double interval){
|
||||||
|
animationInterval = (long)(interval * NANOSECONDSPERSECOND);
|
||||||
|
}
|
||||||
|
private static native void nativeTouchesBegin(int id, float x, float y);
|
||||||
|
private static native void nativeTouchesEnd(int id, float x, float y);
|
||||||
|
private static native void nativeTouchesMove(int[] id, float[] x, float[] y);
|
||||||
|
private static native void nativeTouchesCancel(int[] id, float[] x, float[] y);
|
||||||
|
private static native boolean nativeKeyDown(int keyCode);
|
||||||
|
private static native void nativeRender();
|
||||||
|
private static native void nativeInit(int w, int h);
|
||||||
|
private static native void nativeOnPause();
|
||||||
|
private static native void nativeOnResume();
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// handle input method edit message
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public void handleInsertText(final String text) {
|
||||||
|
nativeInsertText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleDeleteBackward() {
|
||||||
|
nativeDeleteBackward();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContentText() {
|
||||||
|
return nativeGetContentText();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void nativeInsertText(String text);
|
||||||
|
private static native void nativeDeleteBackward();
|
||||||
|
private static native String nativeGetContentText();
|
||||||
|
}
|
|
@ -0,0 +1,245 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.media.SoundPool;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This class is used for controlling effect
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Cocos2dxSound {
|
||||||
|
private Context mContext;
|
||||||
|
private SoundPool mSoundPool;
|
||||||
|
private float mLeftVolume;
|
||||||
|
private float mRightVolume;
|
||||||
|
|
||||||
|
// sound path and stream ids map
|
||||||
|
// a file may be played many times at the same time
|
||||||
|
// so there is an array map to a file path
|
||||||
|
private HashMap<String,ArrayList<Integer>> mPathStreamIDsMap;
|
||||||
|
|
||||||
|
private HashMap<String, Integer> mPathSoundIdMap;
|
||||||
|
|
||||||
|
private static final String TAG = "Cocos2dxSound";
|
||||||
|
private static final int MAX_SIMULTANEOUS_STREAMS_DEFAULT = 5;
|
||||||
|
private static final float SOUND_RATE = 1.0f;
|
||||||
|
private static final int SOUND_PRIORITY = 1;
|
||||||
|
private static final int SOUND_QUALITY = 5;
|
||||||
|
|
||||||
|
private final static int INVALID_SOUND_ID = -1;
|
||||||
|
private final static int INVALID_STREAM_ID = -1;
|
||||||
|
|
||||||
|
public Cocos2dxSound(Context context){
|
||||||
|
this.mContext = context;
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int preloadEffect(String path){
|
||||||
|
Integer soundID = this.mPathSoundIdMap.get(path);
|
||||||
|
|
||||||
|
if (soundID == null) {
|
||||||
|
soundID = createSoundIdFromAsset(path);
|
||||||
|
this.mPathSoundIdMap.put(path, soundID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return soundID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unloadEffect(String path){
|
||||||
|
// stop effects
|
||||||
|
ArrayList<Integer> streamIDs = this.mPathStreamIDsMap.get(path);
|
||||||
|
if (streamIDs != null) {
|
||||||
|
for (Integer streamID : streamIDs) {
|
||||||
|
this.mSoundPool.stop(streamID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.mPathStreamIDsMap.remove(path);
|
||||||
|
|
||||||
|
// unload effect
|
||||||
|
Integer soundID = this.mPathSoundIdMap.get(path);
|
||||||
|
this.mSoundPool.unload(soundID);
|
||||||
|
this.mPathSoundIdMap.remove(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int playEffect(String path, boolean isLoop){
|
||||||
|
Integer soundId = this.mPathSoundIdMap.get(path);
|
||||||
|
int streamId = INVALID_STREAM_ID;
|
||||||
|
|
||||||
|
if (soundId != null){
|
||||||
|
// play sound
|
||||||
|
streamId = this.mSoundPool.play(soundId.intValue(), this.mLeftVolume,
|
||||||
|
this.mRightVolume, SOUND_PRIORITY, isLoop ? -1 : 0, SOUND_RATE);
|
||||||
|
|
||||||
|
// record stream id
|
||||||
|
ArrayList<Integer> streamIds = this.mPathStreamIDsMap.get(path);
|
||||||
|
if (streamIds == null) {
|
||||||
|
streamIds = new ArrayList<Integer>();
|
||||||
|
this.mPathStreamIDsMap.put(path, streamIds);
|
||||||
|
}
|
||||||
|
streamIds.add(streamId);
|
||||||
|
} else {
|
||||||
|
// the effect is not prepared
|
||||||
|
soundId = preloadEffect(path);
|
||||||
|
if (soundId == INVALID_SOUND_ID){
|
||||||
|
// can not preload effect
|
||||||
|
return INVALID_SOUND_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Someone reports that, it can not play effect for the
|
||||||
|
* first time. If you are lucky to meet it. There are two
|
||||||
|
* ways to resolve it.
|
||||||
|
* 1. Add some delay here. I don't know how long it is, so
|
||||||
|
* I don't add it here.
|
||||||
|
* 2. If you use 2.2(API level 8), you can call
|
||||||
|
* SoundPool.setOnLoadCompleteListener() to play the effect.
|
||||||
|
* Because the method is supported from 2.2, so I can't use
|
||||||
|
* it here.
|
||||||
|
*/
|
||||||
|
playEffect(path, isLoop);
|
||||||
|
}
|
||||||
|
|
||||||
|
return streamId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopEffect(int streamID){
|
||||||
|
this.mSoundPool.stop(streamID);
|
||||||
|
|
||||||
|
// remove record
|
||||||
|
for (String path : this.mPathStreamIDsMap.keySet()) {
|
||||||
|
if (this.mPathStreamIDsMap.get(path).contains(streamID)) {
|
||||||
|
this.mPathStreamIDsMap.get(path).remove(this.mPathStreamIDsMap.get(path).indexOf(streamID));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseEffect(int streamID){
|
||||||
|
this.mSoundPool.pause(streamID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resumeEffect(int streamID){
|
||||||
|
this.mSoundPool.resume(streamID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseAllEffects(){
|
||||||
|
this.mSoundPool.autoPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resumeAllEffects(){
|
||||||
|
// autoPause() is available since level 8
|
||||||
|
this.mSoundPool.autoResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void stopAllEffects(){
|
||||||
|
// stop effects
|
||||||
|
if (! this.mPathStreamIDsMap.isEmpty()) {
|
||||||
|
Iterator<?> iter = this.mPathStreamIDsMap.entrySet().iterator();
|
||||||
|
while (iter.hasNext()){
|
||||||
|
Map.Entry<String, ArrayList<Integer>> entry = (Map.Entry<String, ArrayList<Integer>>)iter.next();
|
||||||
|
for (int streamID : entry.getValue()) {
|
||||||
|
this.mSoundPool.stop(streamID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove records
|
||||||
|
this.mPathStreamIDsMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getEffectsVolume(){
|
||||||
|
return (this.mLeftVolume + this.mRightVolume) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void setEffectsVolume(float volume){
|
||||||
|
// volume should be in [0, 1.0]
|
||||||
|
if (volume < 0){
|
||||||
|
volume = 0;
|
||||||
|
}
|
||||||
|
if (volume > 1){
|
||||||
|
volume = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mLeftVolume = this.mRightVolume = volume;
|
||||||
|
|
||||||
|
// change the volume of playing sounds
|
||||||
|
if (! this.mPathStreamIDsMap.isEmpty()) {
|
||||||
|
Iterator<?> iter = this.mPathStreamIDsMap.entrySet().iterator();
|
||||||
|
while (iter.hasNext()){
|
||||||
|
Map.Entry<String, ArrayList<Integer>> entry = (Map.Entry<String, ArrayList<Integer>>)iter.next();
|
||||||
|
for (int streamID : entry.getValue()) {
|
||||||
|
this.mSoundPool.setVolume(streamID, mLeftVolume, mRightVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void end(){
|
||||||
|
this.mSoundPool.release();
|
||||||
|
this.mPathStreamIDsMap.clear();
|
||||||
|
this.mPathSoundIdMap.clear();
|
||||||
|
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int createSoundIdFromAsset(String path){
|
||||||
|
int soundId = INVALID_SOUND_ID;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (path.startsWith("/")){
|
||||||
|
soundId = mSoundPool.load(path, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
soundId = mSoundPool.load(mContext.getAssets().openFd(path), 0);
|
||||||
|
}
|
||||||
|
} catch(Exception e){
|
||||||
|
soundId = INVALID_SOUND_ID;
|
||||||
|
Log.e(TAG, "error: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return soundId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initData(){
|
||||||
|
this.mPathStreamIDsMap = new HashMap<String,ArrayList<Integer>>();
|
||||||
|
this.mPathSoundIdMap = new HashMap<String, Integer>();
|
||||||
|
mSoundPool = new SoundPool(MAX_SIMULTANEOUS_STREAMS_DEFAULT, AudioManager.STREAM_MUSIC, SOUND_QUALITY);
|
||||||
|
|
||||||
|
this.mLeftVolume = 0.5f;
|
||||||
|
this.mRightVolume = 0.5f;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import java.util.Hashtable;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
|
||||||
|
public class Cocos2dxTypefaces {
|
||||||
|
private static final Hashtable<String, Typeface> cache = new Hashtable<String, Typeface>();
|
||||||
|
|
||||||
|
public static Typeface get(Context context, String name){
|
||||||
|
synchronized(cache){
|
||||||
|
if (! cache.containsKey(name)){
|
||||||
|
Typeface t = Typeface.createFromAsset(context.getAssets(), name);
|
||||||
|
cache.put(name, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache.get(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2012 cocos2d-x.org
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package org.cocos2dx.simplegame;
|
||||||
|
|
||||||
|
import org.cocos2dx.lib.Cocos2dxActivity;
|
||||||
|
import org.cocos2dx.lib.Cocos2dxEditText;
|
||||||
|
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
|
||||||
|
import org.cocos2dx.lib.Cocos2dxRenderer;
|
||||||
|
|
||||||
|
import android.app.ActivityManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.ConfigurationInfo;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
public class SimpleGame extends Cocos2dxActivity{
|
||||||
|
|
||||||
|
protected void onCreate(Bundle savedInstanceState){
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
if (detectOpenGLES20()) {
|
||||||
|
// get the packageName,it's used to set the resource path
|
||||||
|
String packageName = getApplication().getPackageName();
|
||||||
|
super.setPackageName(packageName);
|
||||||
|
|
||||||
|
// FrameLayout
|
||||||
|
ViewGroup.LayoutParams framelayout_params =
|
||||||
|
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
|
||||||
|
ViewGroup.LayoutParams.FILL_PARENT);
|
||||||
|
FrameLayout framelayout = new FrameLayout(this);
|
||||||
|
framelayout.setLayoutParams(framelayout_params);
|
||||||
|
|
||||||
|
// Cocos2dxEditText layout
|
||||||
|
ViewGroup.LayoutParams edittext_layout_params =
|
||||||
|
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
Cocos2dxEditText edittext = new Cocos2dxEditText(this);
|
||||||
|
edittext.setLayoutParams(edittext_layout_params);
|
||||||
|
|
||||||
|
// ...add to FrameLayout
|
||||||
|
framelayout.addView(edittext);
|
||||||
|
|
||||||
|
// Cocos2dxGLSurfaceView
|
||||||
|
mGLView = new Cocos2dxGLSurfaceView(this);
|
||||||
|
|
||||||
|
// ...add to FrameLayout
|
||||||
|
framelayout.addView(mGLView);
|
||||||
|
|
||||||
|
mGLView.setEGLContextClientVersion(2);
|
||||||
|
mGLView.setCocos2dxRenderer(new Cocos2dxRenderer());
|
||||||
|
mGLView.setTextField(edittext);
|
||||||
|
|
||||||
|
// Set framelayout as the content view
|
||||||
|
setContentView(framelayout);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log.d("activity", "don't support gles2.0");
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
mGLView.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
mGLView.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean detectOpenGLES20()
|
||||||
|
{
|
||||||
|
ActivityManager am =
|
||||||
|
(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
|
ConfigurationInfo info = am.getDeviceConfigurationInfo();
|
||||||
|
return (info.reqGlEsVersion >= 0x20000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary("game");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue