Facebook Twitter LinkedIn E-mail
magnify
Home Archive for category "手机平台"

引路蜂游戏编程指南

Raindrop

Guidebee Android Game Engine – RainDrop Demo To use guidebee android game engine in your project in your build.gradle

add the following

dependencies {
    ...
    compile 'com.guidebee:game-engine:0.9.8'
}

Mario collect coins

Download

Guidebee Android Game Engine Tutorials

  1. Android Gradle Project
  2. Basics
  3. Packages
  4. Game Logic
  5. Basic Graphics
  6. Texture & TextureRegion
  7. TextureAtlas
  8. Handling Input and On Screen Game Pad
  9. Sound and Music
  10. Scenery and TiledMap
  11. SVG Image and Unmanaged Assets
  12. Collision Detection
  13. Microedition Game API
  14. Bring Physics to your Game World
  15. UI Components and HUD Components
  16. Camera and Viewport basics

Box2D

To use guidebee android game engine in your project in your build.gradle

add the following

dependencies {
    ...
    compile 'com.guidebee:game-engine:0.9.9'
}

Mario collect coins

Download

Guidebee Android Game Engine Box2D Tutorials

  1. Introduction
  2. Basic Concepts
  3. Control Player
  4. Body Types
  5. Shape Types
  6. Apply Forces and Impulses to Bodies
  7. Collision Detection and Collision Filter
  8. Sensors
  9. Ray Casts
  10. Joints
  11. More on Bodies
  12. The world
 

本博客支持android,iphone,iPad 显示

借助于WPTouch ,本博客在移动设备上有更美观的显示,有兴趣的朋友可以使用您的手机或平板电脑登录本博客:-)

 

如何使Android应用开机时自动启动

如果需要在Android开机时自动启动应用程序,可以通过响应android.intent.action.BOOT_COMPLETED广播消息来实现, Android系统启动结束时,会发出 android.intent.action.BOOT_COMPLETED 消息。 具体步骤如下:

1. 定义一个Broadcast Receiver ,比如:BootupReceiver

public class BootupReceiver extends BroadcastReceiver{

 @Override
 public void onReceive(Context context, Intent intent) {

 //better delay some time.
 try {
 Thread.sleep(2000);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 Intent i = new Intent(context, BootupDemoActivity.class);
 i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 context.startActivity(i);

 }

}

用于响应android.intent.action.BOOT_COMPLETED。

2. 在Manifest文件中定义该Broadcast Receiver

<receiver android:name=”.BootupReceiver” android:enabled=”true”
android:permission=”android.permission.RECEIVE_BOOT_COMPLETED”>
<intent-filter>
<action android:name=”android.intent.action.BOOT_COMPLETED”></action>
<category android:name=”android.intent.category.DEFAULT” />
</intent-filter>

</receiver>

3. 加上所需权限

<uses-permission android:name=”android.permission.RECEIVE_BOOT_COMPLETED” />

这些,但手机重启示会自动运行你的应用。 不过此时你的应用可能会被屏幕锁定挡住。解除屏幕锁定后可以看到你运行的应用。

如果想用户一开机就看到你的应用,可以使用代码就屏幕锁去除,方法如下:

1. 在Activity的onCreate事件处理中添加下面代码

 KeyguardManager keyguardManager
 = (KeyguardManager)getSystemService(KEYGUARD_SERVICE);
 KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);

 lock.disableKeyguard();

2. 在Manifest文件中添加所需权限

<uses-permission android:name=”android.permission.DISABLE_KEYGUARD” />

本例代码下载

 

在Android手机上安装完整版Ubuntu

目前市场的Android手机性能越来越高,完全可以安装Ubuntu桌面操作系统。在Android手机安装Ubuntu有两种方法,

对上述两种方法进行实测之后,发现目前都有局限性,第一种方法,目前对触摸屏缺乏支持,因此在Nexus S手机上安装之后,基本无法操作,只启动显示Ubuntu桌面,后面无法响应按键(触摸屏)事件。

第二种方法,可以安装Ubuntu9.x 到Nexus S手机上,同时也保留原先的Android系统,但操作系统比较老,使用apt-get update 有问题,很多链接出现404 问题,需要修改/etc/apt/sources.list 指向旧的ubuntu 版本,勉强可以更新,但致命的一个问题是原文提供的ubuntu.img 只有2G,ubuntu操作系统基本占据的2G的空间,留给用户使用的空余空间不到100M,无法安装一些常用软件如apache,mysql 等,实用性不高。

这里给出一个综合的方法,首先根据第一种中提供的rootfs.ext2 ,使用dd ,mkfs.ext2 创建一个新的my4gimage.ext2 文件(4G 左右,SD卡能支持的单个文件最大为4G)。这个文件映像文件包含了Ubuntu 10.0 版本和ssh server. 文件下载(900M ,tar.gz格式

基本步骤可以参考上面第二种方法的步骤,概述如下:

1.  对于需要安装Ubuntu系统的手机,首先需要获得root 权限,简单的方法是使用fastboot 重新刷机,如CyanogenMod 提供的ROM。

2. 将ubuntu.tar.gz 解压到手机sd卡的ubuntu 目录下。

3. 使用数据线把手机连接到PC,使用adb shell ,或者直接运行手机上terminal Emulator

然后,输入su ,进入超级用户模式,然后 键入

  • cd /sdcard
  • cd ubuntu
  • sh ubuntu.sh (只需运行一次)
  • bootubuntu

下面就可以使用apt-get update 进行升级,可以升级到最新的Ubuntu 11.x 。

升级可以使用SSH 客户端,或是使用vnc 客户端,

  • 如果使用ssh ,需要先启动 ssh 服务,  /etc/init.d/ssh start

  • 如果使用vnc ,需先安装vnc server ,   apt-get install tightvncserver

下面就可以使用do-release-upgrade 升级Ubuntu 或是安装apache2 ,php, mysql 。

注:mysql 安装中可能或出现/com/ubuntu/upstart 无法连接的错误,从而无法使用service mysql start 来启动mysql ,可以直接在命令行执行mysqld & 绕过。

这样安装好的Ubuntu和桌面系统一样使用,性能相当不错,作为一般的Web 服务器用于开发,或是作为Web 服务器临时替代(手机本身可以作为Access Point)都是一个不错的选择。

 

Android简明开发教程三:第一个应用Hello World

在安装后Android开发环境和创建好Android模拟器之后,就可以开始写第一个Android应用“Hello,World”。后面的例子均采用Eclipse IDE。
安装ADT plugin之后,创建的新项目种类就会增加一个Android Project类型:

选择Android Project项目类型,出现下面对话框:

Project Name : Hello World
Build Target: 这里选择 Android 1.6 ,如果你的Build Target 列表为空,则表示你忘记设置Android SDK安装目录了。可以通过Windows -> Preferences -> Android 来设置SDK路径。
Application Name: Hello World
Package name: com.pstreets.android.example, 如果您开发过Java或是.Net Framework 应用,包名称并不陌生。
Create Activity: HelloWorld。 Activity 是Android平台中特有的一个新概念。以Java ME或是Windows Mobile CE应用作参考,它类似于Java ME和Windows Mobile中 UI类的Form类。
Min SDK Version: 可以为空。 Android平台的 版本比较多,从1.5到目前的3.0。Android平台支持向下兼容。Min SDK Version指出了您开发应用支持的最第版本。4对应于Android 1.5。

点击“Finish”则在Eclipse 的Workspace中创建了“Hello World”项目:

ADT Plug自动创建了几个目录:

src  应用源码目录
gen  Android应用自动生成的代码,主要是根据Android资源目录res下的资源来生成的,这样可以根据资源ID来访问应用中的资源。一般不建议手工改动,即使改动,下次编译时也会被重新覆盖。
Android 1.6 表示当前选择的Android版本是Android1.6,你可以使用Android1.6中提供的API。可以通过项目的属性来修改Android版本。
assets  静态文件目录。Hello world 中为空。
res 为应用中的资源目录,res中含有多个子目录,为多种资源。如果你曾经使用Silverlight, Polish Java ME或是 WPF等使用XML来描述UI的应用,则您会觉得res 目录下的各种资源文件似曾相识。Android也是采用XML来描述UI的。
AndroidManifest.xml 应用程序描述文件,类同于Java ME的 JAD文件。它定义了应用的构成,组件,权限等信息。
default.properties 和proguard.cfg 一般不需要改动。proguard.cfg主要用来扰码(混淆器)来保护应用防止反编译。开发过Java 或是.Net 应用的应该对这比较熟悉。

这样就有了第一个应用“Hello World”,可以直接运行。Run As -> Android Application ,将启动模拟器,如果你有Android设备,则也可以选择使用Android设备运行。

到目前为止我们还没有写一行代码。还不能说了解开发Android应用的基本概念。所以需要具体了解一下这个应用的几个重要的组成部分:

主Activity ,打开类 com.pstreets.android.example.HelloWorld

package com.pstreets.android.example;  

import android.app.Activity;
import android.os.Bundle;  

public class HelloWorld extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

 前面提到Activity是Android中类似Windows Mobile 中的Form类的基本UI类。如果您开发过Java ME应用,Activity更像MIDlet,当Android应用可以有多个Activity,而每个Java ME应用中只能有一个MIDlet派生类。如果熟悉MVC ,MVP模型 ,Activity类似于 MVC或是 MVP模型中的 Controller或是Presenter。Activity 有多个生命周期事件可以实现,onCreate是其中一个,它类似于Java ME MIDlet的 startApp 或是 From 的 From_Load事件。Activity将在后面在详细介绍。 setContentView(R.layout.main); 设置Activity主用户UI。

Layout资源文件  res->layout->main.xml
<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android
    android:orientation=”vertical”
    android:layout_width=”fill_parent”
    android:layout_height=”fill_parent”
    >
<TextView 
    android:layout_width=”fill_parent”
    android:layout_height=”wrap_content”
    android:text=”@string/hello”
    />
</LinearLayout>

Android 是通过XML来描述 UI 的,UI 一般通过res 下Layout资源来描述 main.xml 中定义了HelloWorld主界面。可以看到LinearLayout和TextView两个元素。这表示主界面采用LinearLayout布局(类似Swing 中Layout),下面是一个TextView(文本框),文本框显示的内容是@string/hello, @string/hello为一个string 资源,@表示资源引用。string资源定义在res->values->strings.xml 中,其值为<string name=”hello”>Hello World, HelloWorld!</string>。

View 在Android中表示一个可视化组件,刚接触Android开发时,可能会有些困惑,因为在其它平台在View一般指用户界面(Windows),如果拿Java ME或是Windows Mobile做类比的话,Android中的View相当于Windows Mobile中的Control 或是Component, ViewGroup相当于 Container或是Swing中的Layout。  R.layout.main 定义在 gen->R.Java 中,为自动为资源生成的资源ID。

AndroidManifest.xml  应用程序清单
<?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android
      package=”com.pstreets.android.example”
      android:versionCode=”1″
      android:versionName=”1.0″>
    <application android:icon=”@drawable/icon” android:label=”@string/app_name”>
        <activity android:name=”.HelloWorld”
                  android:label=”@string/app_name”>
            <intent-filter>
                <action android:name=”android.intent.action.MAIN” />
                <category android:name=”android.intent.category.LAUNCHER” />
            </intent-filter>
        </activity>

    </application>
    <uses-sdk android:minSdkVersion=”4″ />

</manifest>

和Java ME的JAD文件类似,AndroidManifest.xml定义了Android应用中所有的Activity ,应用的图标,权限等属性。
<intent-filter>
 <action android:name=”android.intent.action.MAIN” />
 <category android:name=”android.intent.category.LAUNCHER” />
</intent-filter> 表示这个Activity 是可以通过Android应用菜单来启动,具体含义在介绍Activity时再说明。

此外,Android 除了使用XML来描述UI外,如果你不怕麻烦的话,也可以通过代码来创建UI,方法类似Swing UI。

 

Android自定义地图示例:QQ地图

再来一个简单一些的自定义地图类型示例:QQ地图,QQ地图URL规则比较简单。1-17级都是有一层组成,选用GENERIC_MAPTYPE_5作为QQ地图类型,直接在CustomMap修改代码如下:

package com.pstreets.gisengine.demo;
import com.mapdigit.gis.raster.ICustomMapType;
import com.mapdigit.gis.raster.MapType;
import com.mapdigit.gis.geometry.GeoLatLng;
import com.pstreets.gisengine.R;
import com.pstreets.gisengine.SharedMapInstance;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

public class CustomMap extends Activity {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	}

	@Override
	public void onStart() {
		super.onStart();
		MapType.setCustomMapTileUrl(new TiandiMapType());
		GeoLatLng center = new GeoLatLng(32.0616667, 118.7777778);
		SharedMapInstance.map.setCenter(center, 13, MapType.GENERIC_MAPTYPE_5);

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.mapzoom_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle item selection
		switch (item.getItemId()) {
		case R.id.zoomin:
			SharedMapInstance.map.zoomIn();

			return true;
		case R.id.zoomout:
			SharedMapInstance.map.zoomOut();
			return true;

		default:
			return super.onOptionsItemSelected(item);
		}

	}

}

class TiandiMapType implements ICustomMapType {

    private static int serverIndex=1;

    public String getTileURL(int mtype, int x, int y, int zoomLevel) {
        String returnURL="";
        serverIndex+=1;
        serverIndex%=3;
        int maxTiles=(int)Math.pow(2, zoomLevel);
        switch(mtype){
            case MapType.GENERIC_MAPTYPE_5:
            	 returnURL= "http://p" 
            		 + serverIndex+".map.qq.com/maptiles/" ;
                 y=maxTiles-y-1;
                 returnURL+=+zoomLevel
				   +"/"+(int)(x/16)+"/"+(int)(y/16)+"/"+x+"_"+y+".gif";
                break;
            case MapType.GENERIC_MAPTYPE_6:

                if(zoomLevel<11){
                   returnURL= "http://tile" 
                	   + serverIndex+".tianditu.com/DataServer?T=A0512_EMap";
                   returnURL+="&X="+x+"&Y="+y+"&L="+zoomLevel;

                }else if(zoomLevel<13){
                   returnURL= "http://tile" 
                	   + serverIndex+".tianditu.com/DataServer?T=B0627_EMap1112";
                   returnURL+="&X="+x+"&Y="+y+"&L="+zoomLevel;
                }else{
                   returnURL= "http://tile" 
                	   + serverIndex+".tianditu.com/DataServer?T=siwei0608";
                   returnURL+="&X="+x+"&Y="+y+"&L="+zoomLevel;
                }
                 
                break;
            case MapType.GENERIC_MAPTYPE_7:
                if(zoomLevel<11){
                   returnURL= "http://tile" 
                	   + serverIndex+".tianditu.com/DataServer?T=AB0512_Anno";
                   returnURL+="&X="+x+"&Y="+y+"&L="+zoomLevel;
                }else{
                   returnURL=MapType.EMPTY_TILE_URL;
                }
                 
                break;

        }
        return returnURL;
    }

}
 

QQ地图的分片方法和Google中国地图分片方法一致,经纬度坐标无需调整。