mirror of https://github.com/axmolengine/axmol.git
some files missiong(eclipse with git is too hard to play)
This commit is contained in:
parent
abc856ac6d
commit
ff5222fff8
|
@ -0,0 +1,117 @@
|
||||||
|
#include "AppDelegate.h"
|
||||||
|
|
||||||
|
#include "cocos2d.h"
|
||||||
|
#include "HelloWorldScene.h"
|
||||||
|
|
||||||
|
#include "CCEGLView.h"
|
||||||
|
|
||||||
|
USING_NS_CC;
|
||||||
|
|
||||||
|
AppDelegate::AppDelegate() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AppDelegate::~AppDelegate() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppDelegate::initInstance() {
|
||||||
|
bool bRet = false;
|
||||||
|
do {
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
||||||
|
|
||||||
|
// Initialize OpenGLView instance, that release by CCDirector when application terminate.
|
||||||
|
// The HelloWorld is designed as HVGA.
|
||||||
|
CCEGLView * pMainWnd = new CCEGLView();
|
||||||
|
CC_BREAK_IF(! pMainWnd
|
||||||
|
|| ! pMainWnd->Create(TEXT("cocos2d: Hello World"), 480, 320));
|
||||||
|
|
||||||
|
#endif // CC_PLATFORM_WIN32
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||||
|
|
||||||
|
// OpenGLView initialized in testsAppDelegate.mm on ios platform, nothing need to do here.
|
||||||
|
|
||||||
|
#endif // CC_PLATFORM_IOS
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||||
|
|
||||||
|
// OpenGLView initialized in HelloWorld/android/jni/helloworld/main.cpp
|
||||||
|
// the default setting is to create a fullscreen view
|
||||||
|
// if you want to use auto-scale, please enable view->create(320,480) in main.cpp
|
||||||
|
// if the resources under '/sdcard" or other writeable path, set it.
|
||||||
|
// warning: the audio source should in assets/
|
||||||
|
// cocos2d::CCFileUtils::setResourcePath("/sdcard");
|
||||||
|
|
||||||
|
#endif // CC_PLATFORM_ANDROID
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WOPHONE)
|
||||||
|
|
||||||
|
// Initialize OpenGLView instance, that release by CCDirector when application terminate.
|
||||||
|
// The HelloWorld is designed as HVGA.
|
||||||
|
CCEGLView* pMainWnd = new CCEGLView(this);
|
||||||
|
CC_BREAK_IF(! pMainWnd || ! pMainWnd->Create(320,480, WM_WINDOW_ROTATE_MODE_CW));
|
||||||
|
|
||||||
|
#ifndef _TRANZDA_VM_
|
||||||
|
// on wophone emulator, we copy resources files to Work7/NEWPLUS/TDA_DATA/Data/ folder instead of zip file
|
||||||
|
cocos2d::CCFileUtils::setResource("HelloWorld.zip");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // CC_PLATFORM_WOPHONE
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_AIRPLAY)
|
||||||
|
// MaxAksenov said it's NOT a very elegant solution. I agree, haha
|
||||||
|
CCDirector::sharedDirector()->setDeviceOrientation(kCCDeviceOrientationLandscapeLeft);
|
||||||
|
#endif
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
|
||||||
|
|
||||||
|
// Initialize OpenGLView instance, that release by CCDirector when application terminate.
|
||||||
|
// The HelloWorld is designed as HVGA.
|
||||||
|
CCEGLView * pMainWnd = new CCEGLView();
|
||||||
|
CC_BREAK_IF(! pMainWnd
|
||||||
|
|| ! pMainWnd->Create("cocos2d: Hello World", 800, 480,480, 320));
|
||||||
|
|
||||||
|
CCFileUtils::setResourcePath("Resource/");
|
||||||
|
|
||||||
|
#endif // CC_PLATFORM_LINUX
|
||||||
|
bRet = true;
|
||||||
|
} while (0);
|
||||||
|
return bRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
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->setDisplayFPS(true);
|
||||||
|
|
||||||
|
// pDirector->setDeviceOrientation(kCCDeviceOrientationLandscapeLeft);
|
||||||
|
|
||||||
|
// 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,43 @@
|
||||||
|
#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 for initialize OpenGL instance, set source path, etc...
|
||||||
|
*/
|
||||||
|
virtual bool initInstance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
@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,82 @@
|
||||||
|
#include "HelloWorldScene.h"
|
||||||
|
|
||||||
|
USING_NS_CC;
|
||||||
|
|
||||||
|
CCScene* HelloWorld::scene()
|
||||||
|
{
|
||||||
|
// 'scene' is an autorelease object
|
||||||
|
CCScene *scene = CCScene::node();
|
||||||
|
|
||||||
|
// 'layer' is an autorelease object
|
||||||
|
HelloWorld *layer = HelloWorld::node();
|
||||||
|
|
||||||
|
// 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::itemFromNormalImage(
|
||||||
|
"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::menuWithItems(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::labelWithString("Hello\nWorld", CCSize(0,0), CCTextAlignmentCenter,"Materhorn.", 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 - 200) );
|
||||||
|
|
||||||
|
// add the label as a child to this layer
|
||||||
|
this->addChild(pLabel, 1);
|
||||||
|
|
||||||
|
// add "HelloWorld" splash screen"
|
||||||
|
CCSprite* pSprite = CCSprite::spriteWithFile("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
|
||||||
|
virtual void menuCloseCallback(CCObject* pSender);
|
||||||
|
|
||||||
|
// implement the "static node()" method manually
|
||||||
|
LAYER_NODE_FUNC(HelloWorld);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __HELLOWORLD_SCENE_H__
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#include "AppDelegate.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
// create the application instance
|
||||||
|
|
||||||
|
|
||||||
|
AppDelegate app;
|
||||||
|
|
||||||
|
return cocos2d::CCApplication::sharedApplication().run();
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef __MAIN_H__
|
||||||
|
#define __MAIN_H__
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||||
|
|
||||||
|
// Windows Header Files:
|
||||||
|
//#include <windows.h>
|
||||||
|
//#include <tchar.h>
|
||||||
|
|
||||||
|
// C RunTime Header Files
|
||||||
|
#include "CCStdC.h"
|
||||||
|
|
||||||
|
#endif // __MAIN_H__
|
|
@ -0,0 +1,5 @@
|
||||||
|
[Trace]
|
||||||
|
GAME <0 or 1> Game Channel
|
||||||
|
|
||||||
|
[Assert]
|
||||||
|
GAME <0 or 1> Game Assert Channel
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="org.cocos2dx.application"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0">
|
||||||
|
<application android:label="@string/app_name" android:debuggable="true" android:icon="@drawable/icon">
|
||||||
|
<activity android:name=".ApplicationDemo"
|
||||||
|
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 in 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,79 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project name="HelloWorld" 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 build.properties file can be created by you and is never touched
|
||||||
|
by the 'android' tool. This is the place to change some of the
|
||||||
|
default property values used by the Ant rules.
|
||||||
|
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'.
|
||||||
|
|
||||||
|
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="build.properties" />
|
||||||
|
|
||||||
|
<!-- The default.properties file is created and updated by the 'android'
|
||||||
|
tool, as well as ADT.
|
||||||
|
This file is an integral part of the build system for your
|
||||||
|
application and should be checked into Version Control Systems. -->
|
||||||
|
<property file="default.properties" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Required pre-setup import -->
|
||||||
|
<import file="${sdk.dir}/tools/ant/pre_setup.xml" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- extension targets. Uncomment the ones where you want to do custom work
|
||||||
|
in between standard targets -->
|
||||||
|
<!--
|
||||||
|
<target name="-pre-build">
|
||||||
|
</target>
|
||||||
|
<target name="-pre-compile">
|
||||||
|
</target>
|
||||||
|
|
||||||
|
[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}]
|
||||||
|
<target name="-post-compile">
|
||||||
|
</target>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Execute the Android Setup task that will setup some properties
|
||||||
|
specific to the target, and import the build rules files.
|
||||||
|
|
||||||
|
The rules file is imported from
|
||||||
|
<SDK>/tools/ant/
|
||||||
|
Depending on the project type it can be either:
|
||||||
|
- main_rules.xml
|
||||||
|
- lib_rules.xml
|
||||||
|
- test_rules.xml
|
||||||
|
|
||||||
|
To customize existing targets, there are two options:
|
||||||
|
- Customize only one target:
|
||||||
|
- copy/paste the target into this file, *before* the
|
||||||
|
<setup> task.
|
||||||
|
- customize it to your needs.
|
||||||
|
- Customize the whole script.
|
||||||
|
- copy/paste the content of the rules files (minus the top node)
|
||||||
|
into this file, *after* the <setup> task
|
||||||
|
- disable the import of the rules by changing the setup task
|
||||||
|
below to <setup import="false" />.
|
||||||
|
- customize to your needs.
|
||||||
|
-->
|
||||||
|
<setup />
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,29 @@
|
||||||
|
# set params
|
||||||
|
ANDROID_NDK_ROOT=/cygdrive/e/android-ndk-r5
|
||||||
|
COCOS2DX_ROOT=/cygdrive/d/Work7/cocos2d-x
|
||||||
|
HELLOWORLD_ROOT=$COCOS2DX_ROOT/HelloWorld/android
|
||||||
|
|
||||||
|
# make sure assets is exist
|
||||||
|
if [ -d $HELLOWORLD_ROOT/assets ]; then
|
||||||
|
rm -rf $HELLOWORLD_ROOT/assets
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir $HELLOWORLD_ROOT/assets
|
||||||
|
|
||||||
|
# copy resources
|
||||||
|
for file in $COCOS2DX_ROOT/HelloWorld/Resource/*
|
||||||
|
do
|
||||||
|
if [ -d $file ]; then
|
||||||
|
cp -rf $file $HELLOWORLD_ROOT/assets
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f $file ]; then
|
||||||
|
cp $file $HELLOWORLD_ROOT/assets
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# build
|
||||||
|
pushd $ANDROID_NDK_ROOT
|
||||||
|
./ndk-build -C $HELLOWORLD_ROOT $*
|
||||||
|
popd
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# 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 use,
|
||||||
|
# "build.properties", and override values to adapt the script to your
|
||||||
|
# project structure.
|
||||||
|
|
||||||
|
# Project target.
|
||||||
|
target=android-7
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||||
|
*
|
||||||
|
* This class was automatically generated by the
|
||||||
|
* aapt tool from the resource data it found. It
|
||||||
|
* should not be modified by hand.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.cocos2dx.application;
|
||||||
|
|
||||||
|
public final class R {
|
||||||
|
public static final class attr {
|
||||||
|
}
|
||||||
|
public static final class drawable {
|
||||||
|
public static final int icon=0x7f020000;
|
||||||
|
}
|
||||||
|
public static final class id {
|
||||||
|
public static final int helloworld_gl_surfaceview=0x7f050001;
|
||||||
|
public static final int textField=0x7f050000;
|
||||||
|
}
|
||||||
|
public static final class layout {
|
||||||
|
public static final int helloworld_demo=0x7f030000;
|
||||||
|
}
|
||||||
|
public static final class string {
|
||||||
|
public static final int app_name=0x7f040000;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include "AppDelegate.h"
|
||||||
|
#include "cocos2d.h"
|
||||||
|
#include <jni.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
|
||||||
|
#define LOG_TAG "main"
|
||||||
|
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
|
||||||
|
|
||||||
|
using namespace cocos2d;
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
|
||||||
|
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)
|
||||||
|
{
|
||||||
|
if (!cocos2d::CCDirector::sharedDirector()->getOpenGLView())
|
||||||
|
{
|
||||||
|
cocos2d::CCEGLView *view = &cocos2d::CCEGLView::sharedOpenGLView();
|
||||||
|
view->setFrameWidthAndHeight(w, h);
|
||||||
|
// if you want to run in WVGA with HVGA resource, set it
|
||||||
|
// view->create(480, 320);
|
||||||
|
cocos2d::CCDirector::sharedDirector()->setOpenGLView(view);
|
||||||
|
|
||||||
|
AppDelegate *pAppDelegate = new AppDelegate();
|
||||||
|
cocos2d::CCApplication::sharedApplication().run();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cocos2d::CCTextureCache::reloadAllTextures();
|
||||||
|
cocos2d::CCDirector::sharedDirector()->setGLDefaultValues();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
# This file is automatically generated by Android Tools.
|
||||||
|
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||||
|
#
|
||||||
|
# This file must *NOT* be checked in Version Control Systems,
|
||||||
|
# as it contains information specific to your local configuration.
|
||||||
|
|
||||||
|
# location of the SDK. This is only used by Ant
|
||||||
|
# For customization when using a Version Control System, please read the
|
||||||
|
# header note.
|
||||||
|
sdk.dir=/home/laschweinski/android/android-sdk-linux_86
|
|
@ -0,0 +1,40 @@
|
||||||
|
-optimizationpasses 5
|
||||||
|
-dontusemixedcaseclassnames
|
||||||
|
-dontskipnonpubliclibraryclasses
|
||||||
|
-dontpreverify
|
||||||
|
-verbose
|
||||||
|
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||||
|
|
||||||
|
-keep public class * extends android.app.Activity
|
||||||
|
-keep public class * extends android.app.Application
|
||||||
|
-keep public class * extends android.app.Service
|
||||||
|
-keep public class * extends android.content.BroadcastReceiver
|
||||||
|
-keep public class * extends android.content.ContentProvider
|
||||||
|
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||||
|
-keep public class * extends android.preference.Preference
|
||||||
|
-keep public class com.android.vending.licensing.ILicensingService
|
||||||
|
|
||||||
|
-keepclasseswithmembernames class * {
|
||||||
|
native <methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclasseswithmembers class * {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclasseswithmembers class * {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclassmembers class * extends android.app.Activity {
|
||||||
|
public void *(android.view.View);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclassmembers enum * {
|
||||||
|
public static **[] values();
|
||||||
|
public static ** valueOf(java.lang.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep class * implements android.os.Parcelable {
|
||||||
|
public static final android.os.Parcelable$Creator *;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical" android:layout_gravity="bottom">
|
||||||
|
<EditText android:id="@+id/textField" android:layout_height="wrap_content" android:layout_weight="0" android:layout_width="fill_parent"></EditText>
|
||||||
|
|
||||||
|
<org.cocos2dx.lib.Cocos2dxGLSurfaceView
|
||||||
|
android:id="@+id/game_gl_surfaceview"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical" android:layout_gravity="bottom">
|
||||||
|
<EditText android:id="@+id/textField" android:layout_height="wrap_content" android:layout_weight="0" android:layout_width="fill_parent"></EditText>
|
||||||
|
|
||||||
|
<org.cocos2dx.lib.Cocos2dxGLSurfaceView
|
||||||
|
android:id="@+id/helloworld_gl_surfaceview"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">helloworld</string>
|
||||||
|
</resources>
|
|
@ -0,0 +1,50 @@
|
||||||
|
package org.cocos2dx.application;
|
||||||
|
import org.cocos2dx.lib.Cocos2dxActivity;
|
||||||
|
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
public class ApplicationDemo extends Cocos2dxActivity{
|
||||||
|
private Cocos2dxGLSurfaceView mGLView;
|
||||||
|
|
||||||
|
protected void onCreate(Bundle savedInstanceState){
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// get the packageName,it's used to set the resource path
|
||||||
|
String packageName = getApplication().getPackageName();
|
||||||
|
super.setPackageName(packageName);
|
||||||
|
|
||||||
|
setContentView(R.layout.helloworld_demo);
|
||||||
|
mGLView = (Cocos2dxGLSurfaceView) findViewById(R.id.helloworld_gl_surfaceview);
|
||||||
|
mGLView.setTextField((EditText)findViewById(R.id.textField));
|
||||||
|
|
||||||
|
// Get the size of the mGLView after the layout happens
|
||||||
|
mGLView.post(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Cocos2dxActivity.screenHeight = mGLView.getHeight();
|
||||||
|
Cocos2dxActivity.screenWidth = mGLView.getWidth();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
mGLView.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
mGLView.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary("cocos2d");
|
||||||
|
System.loadLibrary("cocosdenshion");
|
||||||
|
System.loadLibrary("helloworld");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
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.util.Log;
|
||||||
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
int orientation = mContext.getResources().getConfiguration().orientation;
|
||||||
|
if (orientation == Configuration.ORIENTATION_LANDSCAPE){
|
||||||
|
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,257 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* This is a small port of the "San Angeles Observation" demo
|
||||||
|
* program for OpenGL ES 1.x. For more details, see:
|
||||||
|
*
|
||||||
|
* http://jet.ro/visuals/san-angeles-observation/
|
||||||
|
*
|
||||||
|
* This program demonstrates how to use a GLSurfaceView from Java
|
||||||
|
* along with native OpenGL calls to perform frame rendering.
|
||||||
|
*
|
||||||
|
* Touching the screen will start/stop the animation.
|
||||||
|
*
|
||||||
|
* Note that the demo runs much faster on the emulator than on
|
||||||
|
* real devices, this is mainly due to the following facts:
|
||||||
|
*
|
||||||
|
* - the demo sends bazillions of polygons to OpenGL without
|
||||||
|
* even trying to do culling. Most of them are clearly out
|
||||||
|
* of view.
|
||||||
|
*
|
||||||
|
* - on a real device, the GPU bus is the real bottleneck
|
||||||
|
* that prevent the demo from getting acceptable performance.
|
||||||
|
*
|
||||||
|
* - the software OpenGL engine used in the emulator uses
|
||||||
|
* the system bus instead, and its code rocks :-)
|
||||||
|
*
|
||||||
|
* Fixing the program to send less polygons to the GPU is left
|
||||||
|
* as an exercise to the reader. As always, patches welcomed :-)
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
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.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class Cocos2dxActivity extends Activity{
|
||||||
|
public static int screenWidth;
|
||||||
|
public static int screenHeight;
|
||||||
|
private static Cocos2dxMusic backgroundMusicPlayer;
|
||||||
|
private static Cocos2dxSound soundPlayer;
|
||||||
|
private static Cocos2dxAccelerometer accelerometer;
|
||||||
|
private static boolean accelerometerEnabled = false;
|
||||||
|
private static Handler handler;
|
||||||
|
private final static int HANDLER_SHOW_DIALOG = 1;
|
||||||
|
private static String packageName;
|
||||||
|
|
||||||
|
private static native void nativeSetPaths(String apkPath);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// get frame size
|
||||||
|
DisplayMetrics dm = new DisplayMetrics();
|
||||||
|
getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||||
|
screenWidth = dm.widthPixels;
|
||||||
|
screenHeight = dm.heightPixels;
|
||||||
|
accelerometer = new Cocos2dxAccelerometer(this);
|
||||||
|
|
||||||
|
// init media player and sound player
|
||||||
|
backgroundMusicPlayer = new Cocos2dxMusic(this);
|
||||||
|
soundPlayer = new Cocos2dxSound(this);
|
||||||
|
|
||||||
|
// init bitmap context
|
||||||
|
Cocos2dxBitmap.setContext(this);
|
||||||
|
|
||||||
|
handler = new Handler(){
|
||||||
|
public void handleMessage(Message msg){
|
||||||
|
switch(msg.what){
|
||||||
|
case HANDLER_SHOW_DIALOG:
|
||||||
|
showDialog(((DialogMessage)msg.obj).title, ((DialogMessage)msg.obj).message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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 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 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// resume background music
|
||||||
|
resumeBackgroundMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
if (accelerometerEnabled) {
|
||||||
|
accelerometer.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// pause background music
|
||||||
|
pauseBackgroundMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DialogMessage {
|
||||||
|
public String title;
|
||||||
|
public String message;
|
||||||
|
|
||||||
|
public DialogMessage(String title, String message){
|
||||||
|
this.message = message;
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,354 @@
|
||||||
|
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.Typeface;
|
||||||
|
import android.graphics.Paint.Align;
|
||||||
|
import android.graphics.Paint.FontMetricsInt;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class Cocos2dxBitmap{
|
||||||
|
/*
|
||||||
|
* The values are the same as cocos2dx/platform/CCImage.h.
|
||||||
|
* I think three alignments are OK.
|
||||||
|
*/
|
||||||
|
private static final int ALIGNCENTER = 0x33;
|
||||||
|
private static final int ALIGNLEFT = 0x31;
|
||||||
|
private static final int ALIGNRIGHT = 0x32;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Draw text to bitmap
|
||||||
|
Bitmap bitmap = Bitmap.createBitmap(textProperty.maxWidth,
|
||||||
|
textProperty.totalHeight, Bitmap.Config.ARGB_8888);
|
||||||
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
|
||||||
|
// Draw string
|
||||||
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
|
int x = 0;
|
||||||
|
int y = -fm.ascent;
|
||||||
|
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;
|
||||||
|
|
||||||
|
switch (alignment){
|
||||||
|
case ALIGNCENTER:
|
||||||
|
ret = w / 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ret = 0
|
||||||
|
case ALIGNLEFT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ALIGNRIGHT:
|
||||||
|
ret = w;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default is align left.
|
||||||
|
* Should be same as newPaint().
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.descent - fm.ascent);
|
||||||
|
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.descent - fm.ascent);
|
||||||
|
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){
|
||||||
|
/**
|
||||||
|
* 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (alignment){
|
||||||
|
case ALIGNCENTER:
|
||||||
|
paint.setTextAlign(Align.CENTER);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ALIGNLEFT:
|
||||||
|
paint.setTextAlign(Align.LEFT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ALIGNRIGHT:
|
||||||
|
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);
|
||||||
|
}
|
|
@ -0,0 +1,384 @@
|
||||||
|
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.LinearLayout;
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initView() {
|
||||||
|
mRenderer = new Cocos2dxRenderer();
|
||||||
|
setFocusableInTouchMode(true);
|
||||||
|
setRenderer(mRenderer);
|
||||||
|
|
||||||
|
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 TextView mTextField;
|
||||||
|
|
||||||
|
public TextView getTextField() {
|
||||||
|
return mTextField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextField(TextView view) {
|
||||||
|
mTextField = view;
|
||||||
|
if (null != mTextField && null != textInputWraper) {
|
||||||
|
LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) mTextField.getLayoutParams();
|
||||||
|
linearParams.height = 0;
|
||||||
|
mTextField.setLayoutParams(linearParams);
|
||||||
|
mTextField.setOnEditorActionListener(textInputWraper);
|
||||||
|
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 idPointerDown = event.getAction() >> MotionEvent.ACTION_POINTER_ID_SHIFT;
|
||||||
|
final float xPointerDown = event.getX(idPointerDown);
|
||||||
|
final float yPointerDown = event.getY(idPointerDown);
|
||||||
|
|
||||||
|
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 = event.getX(idDown);
|
||||||
|
final float yDown = event.getY(idDown);
|
||||||
|
|
||||||
|
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 idPointerUp = event.getAction() >> MotionEvent.ACTION_POINTER_ID_SHIFT;
|
||||||
|
final float xPointerUp = event.getX(idPointerUp);
|
||||||
|
final float yPointerUp = event.getY(idPointerUp);
|
||||||
|
|
||||||
|
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 = event.getX(idUp);
|
||||||
|
final float yUp = event.getY(idUp);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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,177 @@
|
||||||
|
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 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){
|
||||||
|
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 = null;
|
||||||
|
|
||||||
|
try{
|
||||||
|
AssetFileDescriptor assetFileDescritor = mContext.getAssets().openFd(path);
|
||||||
|
|
||||||
|
mediaPlayer = new MediaPlayer();
|
||||||
|
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,107 @@
|
||||||
|
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;
|
||||||
|
|
||||||
|
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||||
|
nativeInit(Cocos2dxActivity.screenWidth, Cocos2dxActivity.screenHeight);
|
||||||
|
last = System.nanoTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
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,160 @@
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
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 id and stream id map
|
||||||
|
private HashMap<Integer,Integer> mSoundIdStreamIdMap;
|
||||||
|
// sound path and sound id map
|
||||||
|
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 int INVALID_SOUND_ID = -1;
|
||||||
|
private final int INVALID_STREAM_ID = -1;
|
||||||
|
|
||||||
|
public Cocos2dxSound(Context context){
|
||||||
|
this.mContext = context;
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int preloadEffect(String path){
|
||||||
|
int soundId = INVALID_SOUND_ID;
|
||||||
|
|
||||||
|
// if the sound is preloaded, pass it
|
||||||
|
if (this.mPathSoundIDMap.get(path) != null){
|
||||||
|
soundId = this.mPathSoundIDMap.get(path).intValue();
|
||||||
|
} else {
|
||||||
|
soundId = createSoundIdFromAsset(path);
|
||||||
|
|
||||||
|
if (soundId != INVALID_SOUND_ID){
|
||||||
|
// the sound is loaded but has not been played
|
||||||
|
this.mSoundIdStreamIdMap.put(soundId, INVALID_STREAM_ID);
|
||||||
|
|
||||||
|
// record path and sound id map
|
||||||
|
this.mPathSoundIDMap.put(path, soundId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return soundId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unloadEffect(String path){
|
||||||
|
// get sound id and remove from mPathSoundIDMap
|
||||||
|
Integer soundId = this.mPathSoundIDMap.remove(path);
|
||||||
|
|
||||||
|
if (soundId != null){
|
||||||
|
// unload effect
|
||||||
|
this.mSoundPool.unload(soundId.intValue());
|
||||||
|
|
||||||
|
// remove record from mSoundIdStreamIdMap
|
||||||
|
this.mSoundIdStreamIdMap.remove(soundId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int playEffect(String path, boolean isLoop){
|
||||||
|
Integer soundId = this.mPathSoundIDMap.get(path);
|
||||||
|
|
||||||
|
if (soundId != null){
|
||||||
|
// the sound is preloaded, stop it first
|
||||||
|
|
||||||
|
this.mSoundPool.stop(soundId);
|
||||||
|
|
||||||
|
// play sound
|
||||||
|
int streamId = this.mSoundPool.play(soundId.intValue(), this.mLeftVolume,
|
||||||
|
this.mRightVolume, SOUND_PRIORITY, isLoop ? -1 : 0, SOUND_RATE);
|
||||||
|
|
||||||
|
// record sound id and stream id map
|
||||||
|
this.mSoundIdStreamIdMap.put(soundId, 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 soundId.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopEffect(int soundId){
|
||||||
|
Integer streamId = this.mSoundIdStreamIdMap.get(soundId);
|
||||||
|
|
||||||
|
if (streamId != null && streamId.intValue() != INVALID_STREAM_ID){
|
||||||
|
this.mSoundPool.stop(streamId.intValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getEffectsVolume(){
|
||||||
|
return (this.mLeftVolume + this.mRightVolume) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEffectsVolume(float volume){
|
||||||
|
this.mLeftVolume = this.mRightVolume = volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void end(){
|
||||||
|
this.mSoundPool.release();
|
||||||
|
this.mPathSoundIDMap.clear();
|
||||||
|
this.mSoundIdStreamIdMap.clear();
|
||||||
|
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int createSoundIdFromAsset(String path){
|
||||||
|
int soundId = INVALID_SOUND_ID;
|
||||||
|
|
||||||
|
try {
|
||||||
|
soundId = mSoundPool.load(mContext.getAssets().openFd(path), 0);
|
||||||
|
} catch(Exception e){
|
||||||
|
Log.e(TAG, "error: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return soundId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initData(){
|
||||||
|
this.mSoundIdStreamIdMap = new HashMap<Integer,Integer>();
|
||||||
|
mSoundPool = new SoundPool(MAX_SIMULTANEOUS_STREAMS_DEFAULT, AudioManager.STREAM_MUSIC, SOUND_QUALITY);
|
||||||
|
mPathSoundIDMap = new HashMap<String,Integer>();
|
||||||
|
|
||||||
|
this.mLeftVolume = 0.5f;
|
||||||
|
this.mRightVolume = 0.5f;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
# This file is used to override default values used by the Ant build system.
|
||||||
|
#
|
||||||
|
# This file must be checked in 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,79 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project name="HelloWorld" 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 build.properties file can be created by you and is never touched
|
||||||
|
by the 'android' tool. This is the place to change some of the
|
||||||
|
default property values used by the Ant rules.
|
||||||
|
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'.
|
||||||
|
|
||||||
|
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="build.properties" />
|
||||||
|
|
||||||
|
<!-- The default.properties file is created and updated by the 'android'
|
||||||
|
tool, as well as ADT.
|
||||||
|
This file is an integral part of the build system for your
|
||||||
|
application and should be checked into Version Control Systems. -->
|
||||||
|
<property file="default.properties" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Required pre-setup import -->
|
||||||
|
<import file="${sdk.dir}/tools/ant/pre_setup.xml" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- extension targets. Uncomment the ones where you want to do custom work
|
||||||
|
in between standard targets -->
|
||||||
|
<!--
|
||||||
|
<target name="-pre-build">
|
||||||
|
</target>
|
||||||
|
<target name="-pre-compile">
|
||||||
|
</target>
|
||||||
|
|
||||||
|
[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}]
|
||||||
|
<target name="-post-compile">
|
||||||
|
</target>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Execute the Android Setup task that will setup some properties
|
||||||
|
specific to the target, and import the build rules files.
|
||||||
|
|
||||||
|
The rules file is imported from
|
||||||
|
<SDK>/tools/ant/
|
||||||
|
Depending on the project type it can be either:
|
||||||
|
- main_rules.xml
|
||||||
|
- lib_rules.xml
|
||||||
|
- test_rules.xml
|
||||||
|
|
||||||
|
To customize existing targets, there are two options:
|
||||||
|
- Customize only one target:
|
||||||
|
- copy/paste the target into this file, *before* the
|
||||||
|
<setup> task.
|
||||||
|
- customize it to your needs.
|
||||||
|
- Customize the whole script.
|
||||||
|
- copy/paste the content of the rules files (minus the top node)
|
||||||
|
into this file, *after* the <setup> task
|
||||||
|
- disable the import of the rules by changing the setup task
|
||||||
|
below to <setup import="false" />.
|
||||||
|
- customize to your needs.
|
||||||
|
-->
|
||||||
|
<setup />
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,10 @@
|
||||||
|
# This file is automatically generated by Android Tools.
|
||||||
|
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||||
|
#
|
||||||
|
# This file must *NOT* be checked in Version Control Systems,
|
||||||
|
# as it contains information specific to your local configuration.
|
||||||
|
|
||||||
|
# location of the SDK. This is only used by Ant
|
||||||
|
# For customization when using a Version Control System, please read the
|
||||||
|
# header note.
|
||||||
|
sdk.dir=/home/laschweinski/android/android-sdk-linux_86
|
|
@ -0,0 +1,40 @@
|
||||||
|
-optimizationpasses 5
|
||||||
|
-dontusemixedcaseclassnames
|
||||||
|
-dontskipnonpubliclibraryclasses
|
||||||
|
-dontpreverify
|
||||||
|
-verbose
|
||||||
|
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||||
|
|
||||||
|
-keep public class * extends android.app.Activity
|
||||||
|
-keep public class * extends android.app.Application
|
||||||
|
-keep public class * extends android.app.Service
|
||||||
|
-keep public class * extends android.content.BroadcastReceiver
|
||||||
|
-keep public class * extends android.content.ContentProvider
|
||||||
|
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||||
|
-keep public class * extends android.preference.Preference
|
||||||
|
-keep public class com.android.vending.licensing.ILicensingService
|
||||||
|
|
||||||
|
-keepclasseswithmembernames class * {
|
||||||
|
native <methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclasseswithmembers class * {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclasseswithmembers class * {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclassmembers class * extends android.app.Activity {
|
||||||
|
public void *(android.view.View);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclassmembers enum * {
|
||||||
|
public static **[] values();
|
||||||
|
public static ** valueOf(java.lang.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep class * implements android.os.Parcelable {
|
||||||
|
public static final android.os.Parcelable$Creator *;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical" android:layout_gravity="bottom">
|
||||||
|
<EditText android:id="@+id/textField" android:layout_height="wrap_content" android:layout_weight="0" android:layout_width="fill_parent"></EditText>
|
||||||
|
|
||||||
|
<org.cocos2dx.lib.Cocos2dxGLSurfaceView
|
||||||
|
android:id="@+id/game_gl_surfaceview"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -5,8 +5,8 @@
|
||||||
# Don't modify the script until you know what you do.
|
# Don't modify the script until you know what you do.
|
||||||
|
|
||||||
# set environment paramters
|
# set environment paramters
|
||||||
NDK_ROOT="/workspace/android-dev/android-ndk-r5"
|
NDK_ROOT="/home/laschweinski/android/android-ndk-r5"
|
||||||
ANDROID_SDK_ROOT="/workspace/android-dev/android-sdk-mac_86"
|
ANDROID_SDK_ROOT="/home/laschweinski/android/android-sdk-linux_86"
|
||||||
|
|
||||||
# check if it was called by .bat file
|
# check if it was called by .bat file
|
||||||
if [ $# -eq 5 ];then
|
if [ $# -eq 5 ];then
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# This script should be called by create-android-project.bat
|
||||||
|
# or should be runned in linux shell. It can not be runned under
|
||||||
|
# cygwin.
|
||||||
|
# Don't modify the script until you know what you do.
|
||||||
|
|
||||||
|
# set environment paramters
|
||||||
|
NDK_ROOT="/home/laschweinski/android/android-ndk-r5"
|
||||||
|
ANDROID_SDK_ROOT="/home/laschweinski/android/android-sdk-linux_86"
|
||||||
|
COCOS2DX_ROOT="/home/laschweinski/git/cocos2d-x"
|
||||||
|
|
||||||
|
# check if it was called by .bat file
|
||||||
|
if [ $# -eq 5 ];then
|
||||||
|
if [ $5 = "windows" ];then
|
||||||
|
# called by .bat file
|
||||||
|
sh $1/template/android/copy_files.sh $1 $2 $3 $4
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# the bash file should not be called by cygwin
|
||||||
|
KERNEL_NAME=`uname -s | grep "CYGWIN*"`
|
||||||
|
if [ $KERNEL_NAME"hi" != "hi" ]; then
|
||||||
|
echo "Error!!!"
|
||||||
|
echo "Don't run in cygwin. You should run corresponding bat."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ok, it was run under linux
|
||||||
|
|
||||||
|
# check it was runned in cocos2d-x root
|
||||||
|
#check_path(){
|
||||||
|
# if [ ! -f create-android-project.sh ];then
|
||||||
|
# echo Error!!!
|
||||||
|
# echo Please run in cocos2dx root
|
||||||
|
# exit
|
||||||
|
# fi
|
||||||
|
#}
|
||||||
|
|
||||||
|
create_android_project(){
|
||||||
|
echo "Input package path. For example: org.cocos2dx.example"
|
||||||
|
read PACKAGE_PATH
|
||||||
|
echo "Now cocos2d-x suppurts Android 2.1-update1, 2.2, 2.3 & 3.0"
|
||||||
|
echo "Other versions have not tested."
|
||||||
|
$ANDROID_SDK_ROOT/tools/android list targets
|
||||||
|
echo "input target id:"
|
||||||
|
read TARGET_ID
|
||||||
|
echo "input your project name:"
|
||||||
|
read PROJECT_NAME
|
||||||
|
PROJECT_DIR=`pwd`/$PROJECT_NAME
|
||||||
|
|
||||||
|
$ANDROID_SDK_ROOT/tools/android create project -n $PROJECT_NAME -t $TARGET_ID -k $PACKAGE_PATH -a $PROJECT_NAME -p $PROJECT_DIR
|
||||||
|
}
|
||||||
|
|
||||||
|
#check_path
|
||||||
|
create_android_project
|
||||||
|
|
||||||
|
# invoke template/android/copy_files.sh
|
||||||
|
sh $COCOS2DX_ROOT/template/android/mycopy_files.sh $COCOS2DX_ROOT $PROJECT_NAME $NDK_ROOT $PACKAGE_PATH
|
|
@ -0,0 +1,127 @@
|
||||||
|
# check the args
|
||||||
|
# $1: root of cocos2dx $2: app name $3: ndk root $4:pakcage path
|
||||||
|
|
||||||
|
APP_NAME=$2
|
||||||
|
COCOS2DX_ROOT=$1
|
||||||
|
APP_DIR=`pwd`/$APP_NAME
|
||||||
|
HELLOWORLD_ROOT=$COCOS2DX_ROOT/HelloCocos2dx
|
||||||
|
NDK_ROOT=$3
|
||||||
|
PACKAGE_PATH=$4
|
||||||
|
|
||||||
|
# xxx.yyy.zzz -> xxx/yyy/zzz
|
||||||
|
convert_package_path_to_dir(){
|
||||||
|
PACKAGE_PATH_DIR=`echo $1 | sed -e "s/\./\//g"`
|
||||||
|
}
|
||||||
|
|
||||||
|
# make director andorid and copy all files and directories into it
|
||||||
|
move_files_into_android(){
|
||||||
|
mkdir $APP_DIR/android
|
||||||
|
|
||||||
|
for file in $APP_DIR/*
|
||||||
|
do
|
||||||
|
if [ -d $file ]; then
|
||||||
|
if [ $file != $APP_DIR/android ]; then
|
||||||
|
mv -f $file $APP_DIR/android
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f $file ]; then
|
||||||
|
mv $file $APP_DIR/android
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
#copy linux's
|
||||||
|
move_files_into_linux(){
|
||||||
|
mkdir $APP_DIR/Linux
|
||||||
|
for file in `ls $HELLOWORLD_ROOT/Linux/* | grep -E '.*\.[cpp|h]' `
|
||||||
|
do
|
||||||
|
if [ -f $file ];then
|
||||||
|
cp $file $APP_DIR/Linux
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
#copy eclipse configures
|
||||||
|
move_eclipse_configures_into(){
|
||||||
|
for file in `ls -a $HELLOWORLD_ROOT/ | grep -E '\..*project' `
|
||||||
|
do
|
||||||
|
cp $HELLOWORLD_ROOT/$file $APP_DIR/
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
#copy main sources
|
||||||
|
copy_cpp_h_from_helloworld(){
|
||||||
|
mkdir $APP_DIR/Classes
|
||||||
|
for file in `ls $HELLOWORLD_ROOT/Classes/* | grep -E '.*\.[cpp|h]' `
|
||||||
|
do
|
||||||
|
if [ -f $file ];then
|
||||||
|
cp $file $APP_DIR/Classes
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# copy resources
|
||||||
|
copy_resouces(){
|
||||||
|
mkdir $APP_DIR/Resource
|
||||||
|
|
||||||
|
for file in $HELLOWORLD_ROOT/Resource/*
|
||||||
|
do
|
||||||
|
cp $file $APP_DIR/Resource
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# from HelloWorld copy src and jni to APP_DIR
|
||||||
|
copy_src_and_jni(){
|
||||||
|
cp -rf $HELLOWORLD_ROOT/android/jni $APP_DIR/android
|
||||||
|
cp -rf $HELLOWORLD_ROOT/android/src $APP_DIR/android
|
||||||
|
|
||||||
|
# repalce Android.mk and Application.mk
|
||||||
|
cat $COCOS2DX_ROOT/template/android/AndroidTemplate1.mk > $APP_DIR/android/jni/helloworld/Android.mk
|
||||||
|
cat $COCOS2DX_ROOT/template/android/Application.mk > $APP_DIR/android/jni/Application.mk
|
||||||
|
}
|
||||||
|
|
||||||
|
# copy build_native.sh and replace something
|
||||||
|
copy_build_native(){
|
||||||
|
# here should use # instead of /, why??
|
||||||
|
sed "s#__cocos2dxroot__#$COCOS2DX_ROOT#;s#__ndkroot__#$NDK_ROOT#;s#__projectname__#$APP_NAME#" $COCOS2DX_ROOT/template/android/build_native.sh > $APP_DIR/android/build_native.sh
|
||||||
|
chmod u+x $APP_DIR/android/build_native.sh
|
||||||
|
}
|
||||||
|
|
||||||
|
# replace AndroidManifext.xml and change the activity name
|
||||||
|
# use sed to replace the specified line
|
||||||
|
modify_androidmanifest(){
|
||||||
|
sed "s/ApplicationDemo/$APP_NAME/;s/org\.cocos2dx\.application/$PACKAGE_PATH/" $HELLOWORLD_ROOT/android/AndroidManifest.xml > $APP_DIR/android/AndroidManifest.xml
|
||||||
|
}
|
||||||
|
|
||||||
|
# modify ApplicationDemo.java
|
||||||
|
modify_applicationdemo(){
|
||||||
|
convert_package_path_to_dir $PACKAGE_PATH
|
||||||
|
|
||||||
|
# rename APP_DIR/android/src/org/cocos2dx/application/ApplicationDemo.java to
|
||||||
|
# APP_DIR/android/src/org/cocos2dx/application/$APP_NAME.java, change helloworld to game
|
||||||
|
sed "s/ApplicationDemo/$APP_NAME/;s/helloworld/game/;s/org\.cocos2dx\.application/$PACKAGE_PATH/" $APP_DIR/android/src/org/cocos2dx/application/ApplicationDemo.java > $APP_DIR/android/src/$PACKAGE_PATH_DIR/tempfile.java
|
||||||
|
rm -fr $APP_DIR/android/src/org/cocos2dx/application
|
||||||
|
mv $APP_DIR/android/src/$PACKAGE_PATH_DIR/tempfile.java $APP_DIR/android/src/$PACKAGE_PATH_DIR/$APP_NAME.java
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
modify_layout(){
|
||||||
|
cp $HELLOWORLD_ROOT/android/res/layout/helloworld_demo.xml $APP_DIR/android/res/layout
|
||||||
|
sed "s/helloworld_gl_surfaceview/game_gl_surfaceview/" $APP_DIR/android/res/layout/helloworld_demo.xml > $APP_DIR/android/res/layout/game_demo.xml
|
||||||
|
rm -f $APP_DIR/android/res/layout/main.xml
|
||||||
|
rm -f $APP_DIR/android/res/layout/helloworld_demo.xml
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
move_files_into_android
|
||||||
|
move_files_into_linux
|
||||||
|
move_eclipse_configures_into
|
||||||
|
copy_cpp_h_from_helloworld
|
||||||
|
copy_resouces
|
||||||
|
copy_src_and_jni
|
||||||
|
copy_build_native
|
||||||
|
modify_androidmanifest
|
||||||
|
modify_applicationdemo
|
||||||
|
modify_layout
|
|
@ -0,0 +1 @@
|
||||||
|
c839baf9990fed7ddcaca66167188203ceaf9370
|
|
@ -0,0 +1 @@
|
||||||
|
2aaf84affb08908ea5aa5fd7ce5de973b88109bc
|
|
@ -0,0 +1 @@
|
||||||
|
79a3a895ba8a3568400db39e819a15d110045d6c
|
|
@ -0,0 +1 @@
|
||||||
|
abd4b23cdfdb825428fdd2a1c7381671ce83bbed
|
|
@ -0,0 +1 @@
|
||||||
|
33b72a10558b874067b03ec1fd2a38a53b31d044
|
|
@ -0,0 +1 @@
|
||||||
|
b56dda22b7fe9d89ae31e8dbec799917405ed5e2
|
|
@ -0,0 +1 @@
|
||||||
|
6b9dcb4915a36e3aefef3f153949a96b145fba0d
|
|
@ -0,0 +1 @@
|
||||||
|
0a08f47624fb92eef7de9fed051d92a25e3c6ff8
|
|
@ -0,0 +1 @@
|
||||||
|
365a14b28310b73a048597cc8d87609975705172
|
|
@ -0,0 +1 @@
|
||||||
|
9246a8bc975c764e4aa71f54a50d5f4e4bce7a18
|
|
@ -0,0 +1 @@
|
||||||
|
6869c5352bc6510dba54803f5f4459b0a6a3fcf2
|
|
@ -0,0 +1 @@
|
||||||
|
d13ddb0931c1772127b38010990140adce837bc8
|
|
@ -0,0 +1,282 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>texture</key>
|
||||||
|
<dict>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>512</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>256</integer>
|
||||||
|
</dict>
|
||||||
|
<key>frames</key>
|
||||||
|
<dict>
|
||||||
|
<key>grossini_dance_01.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>347</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>51</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>109</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>0</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-1</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
<key>grossini_dance_02.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>215</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>111</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>63</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>109</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>-6</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-1</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
<key>grossini_dance_03.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>151</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>111</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>63</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>109</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>-6</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-1</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
<key>grossini_dance_04.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>111</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>74</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>109</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>-0.5</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-1</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
<key>grossini_dance_05.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>76</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>111</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>74</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>109</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>-0.5</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-1</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
<key>grossini_dance_06.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>399</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>63</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>109</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>-6</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-1</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
<key>grossini_dance_07.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>105</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>63</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>109</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>-6</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-1</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
<key>grossini_dance_08.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>51</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>109</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>0</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-1</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
<key>grossini_dance_09.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>295</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>51</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>109</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>0</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-1</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
<key>grossini_dance_10.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>232</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>62</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>109</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>5.5</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-1</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
<key>grossini_dance_11.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>169</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>62</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>109</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>5.5</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-1</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
<key>grossini_dance_12.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>279</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>111</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>51</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>106</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>0</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-2.5</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
<key>grossini_dance_13.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>53</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>51</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>109</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>0</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-1</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
<key>grossini_dance_14.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>x</key>
|
||||||
|
<integer>331</integer>
|
||||||
|
<key>y</key>
|
||||||
|
<integer>111</integer>
|
||||||
|
<key>width</key>
|
||||||
|
<integer>51</integer>
|
||||||
|
<key>height</key>
|
||||||
|
<integer>106</integer>
|
||||||
|
<key>offsetX</key>
|
||||||
|
<real>0</real>
|
||||||
|
<key>offsetY</key>
|
||||||
|
<real>-2.5</real>
|
||||||
|
<key>originalWidth</key>
|
||||||
|
<integer>85</integer>
|
||||||
|
<key>originalHeight</key>
|
||||||
|
<integer>-121</integer>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,5 @@
|
||||||
|
[Trace]
|
||||||
|
GAME <0 or 1> Game Channel
|
||||||
|
|
||||||
|
[Assert]
|
||||||
|
GAME <0 or 1> Game Assert Channel
|
|
@ -0,0 +1 @@
|
||||||
|
aec1c0a8c8068377fddca5ddd32084d8c3c3c419
|
|
@ -0,0 +1 @@
|
||||||
|
112328fdb03b8966c8cb7b62a5fc51ce0d4570b1
|
|
@ -0,0 +1 @@
|
||||||
|
9975e4961272d5bda6d5f3bbd61ea0fc02222199
|
|
@ -0,0 +1 @@
|
||||||
|
6a89fbfbe3c98e2d72c84e4d76873375eca87802
|
|
@ -0,0 +1 @@
|
||||||
|
8167faf6c40ffd95a03028f1dcee1abdaa48b222
|
Loading…
Reference in New Issue