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
|
||||
// use 960*640 resources as design resolution size
|
||||
CCFileUtils::sharedFileUtils()->setResourceDirectory("hd");
|
||||
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(960, 640, kResolutionNoBorder);
|
||||
CCFileUtils::sharedFileUtils()->setResourceDirectory("sd");
|
||||
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(480, 320, kResolutionNoBorder);
|
||||
}
|
||||
|
||||
// turn on display FPS
|
||||
|
|
|
@ -77,7 +77,8 @@ bool HelloWorld::init()
|
|||
CC_BREAK_IF(! pCloseItem);
|
||||
|
||||
// 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.
|
||||
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
|
||||
|
@ -90,7 +91,7 @@ bool HelloWorld::init()
|
|||
/////////////////////////////
|
||||
// 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) );
|
||||
player->setPosition( ccp(player->getContentSize().width/2, winSize.height/2) );
|
||||
this->addChild(player);
|
||||
|
@ -126,7 +127,7 @@ void HelloWorld::addTarget()
|
|||
CCSprite *target = CCSprite::create("Target.png", CCRectMake(0,0,27,40) );
|
||||
|
||||
// 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 maxY = winSize.height - target->getContentSize().height/2;
|
||||
int rangeY = (int)(maxY - minY);
|
||||
|
@ -137,7 +138,7 @@ void HelloWorld::addTarget()
|
|||
// and along a random position along the Y axis as calculated
|
||||
target->setPosition(
|
||||
ccp(winSize.width + (target->getContentSize().width/2),
|
||||
actualY) );
|
||||
CCDirector::sharedDirector()->getVisibleOrigin().y + actualY) );
|
||||
this->addChild(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);
|
||||
|
||||
// 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));
|
||||
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