some files missiong(eclipse with git is too hard to play)

This commit is contained in:
laschweinski 2011-08-21 19:00:26 +08:00
parent abc856ac6d
commit ff5222fff8
54 changed files with 2806 additions and 3 deletions

View File

@ -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();
}

View File

@ -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_

View File

@ -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
}

View File

@ -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__

View File

@ -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();
}

View File

@ -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__

View File

@ -0,0 +1,5 @@
[Trace]
GAME <0 or 1> Game Channel
[Assert]
GAME <0 or 1> Game Assert Channel

View File

@ -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>

View File

@ -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.

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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

View File

@ -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 *;
}

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">helloworld</string>
</resources>

View File

@ -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");
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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.

View File

@ -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>

View File

@ -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

View File

@ -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 *;
}

View File

@ -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>

View File

@ -5,8 +5,8 @@
# Don't modify the script until you know what you do.
# set environment paramters
NDK_ROOT="/workspace/android-dev/android-ndk-r5"
ANDROID_SDK_ROOT="/workspace/android-dev/android-sdk-mac_86"
NDK_ROOT="/home/laschweinski/android/android-ndk-r5"
ANDROID_SDK_ROOT="/home/laschweinski/android/android-sdk-linux_86"
# check if it was called by .bat file
if [ $# -eq 5 ];then

60
mycreate-android-project.sh Executable file
View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
c839baf9990fed7ddcaca66167188203ceaf9370

View File

@ -0,0 +1 @@
2aaf84affb08908ea5aa5fd7ce5de973b88109bc

View File

@ -0,0 +1 @@
79a3a895ba8a3568400db39e819a15d110045d6c

View File

@ -0,0 +1 @@
abd4b23cdfdb825428fdd2a1c7381671ce83bbed

View File

@ -0,0 +1 @@
33b72a10558b874067b03ec1fd2a38a53b31d044

View File

@ -0,0 +1 @@
b56dda22b7fe9d89ae31e8dbec799917405ed5e2

View File

@ -0,0 +1 @@
6b9dcb4915a36e3aefef3f153949a96b145fba0d

View File

@ -0,0 +1 @@
0a08f47624fb92eef7de9fed051d92a25e3c6ff8

View File

@ -0,0 +1 @@
365a14b28310b73a048597cc8d87609975705172

View File

@ -0,0 +1 @@
9246a8bc975c764e4aa71f54a50d5f4e4bce7a18

View File

@ -0,0 +1 @@
6869c5352bc6510dba54803f5f4459b0a6a3fcf2

View File

@ -0,0 +1 @@
d13ddb0931c1772127b38010990140adce837bc8

View File

@ -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>

View File

@ -0,0 +1,5 @@
[Trace]
GAME <0 or 1> Game Channel
[Assert]
GAME <0 or 1> Game Assert Channel

View File

@ -0,0 +1 @@
aec1c0a8c8068377fddca5ddd32084d8c3c3c419

View File

@ -0,0 +1 @@
112328fdb03b8966c8cb7b62a5fc51ce0d4570b1

View File

@ -0,0 +1 @@
9975e4961272d5bda6d5f3bbd61ea0fc02222199

View File

@ -0,0 +1 @@
6a89fbfbe3c98e2d72c84e4d76873375eca87802

View File

@ -0,0 +1 @@
8167faf6c40ffd95a03028f1dcee1abdaa48b222