프로세싱에서 안드로이드를 지원한다. 쉽게 말해서 프로세싱을 가지고 안드로이드용 앱을 만들 수 있다는 것이다. 그만큼 쉽게 비쥬얼한 앱을 만들 수 있다는 것이다. 그런데 초보자에겐 쉽지 않은듯 ... 프로세싱만 가지고 만드는게 아니라 다른 툴들과 마찬가지로 자바도 필요하고 SDK도 필요하고 ... 프로세싱에서 작업한 코드를 결국에는 SDK을 이용해서 앱으로 만드는것 같다. 간단한 예제를 적용해 보는것으로 어떤 식으로 만들 수 있는지 알아 보자.
PED에는 몇가지 개발모드를 사용할 수 있도록 되어 있다. 기본모드인 자바, 이 예제에서 추가할 Android 그리고 파이썬모드도 추가 가능하다.
오른쪽 상단 귀퉁이의 버튼을 클릭해서 보면 [모드 추가]라는 메뉴가 있다. 선택한다. 예제 전에 이미 추가해 놓았기 때문에 Android 메뉴가 떠 있지만 설치 전이라면 보이지 않는다.
[Mode]탭에서 Android Mode를 선택하고 인스톨한다. 안정버전은 3.0.1이다. 베타 버전을 설치해 본것이다. 뭐가 다른지는 모른다. ㅎ설치하는 중에 나오는지 실행하면 나오는지 기억이 가물가물한데 분명한것은 SDK가 어디에 설치 되어 있는지 설치 되어 있지 않다면 같이 이 모드를 설치하면서 반드시 설치해야 한다. 이미 설치 되어 있어서 위치만 지정해 주었다. 이제 Android Mode를 사용할 수 있게 되었다.
예제는 프로세싱 사이트에 있는 튜토리얼을 그대로 적용해 보았다. 아래 링크에서 확인 할 수 있다.
http://android.processing.org/tutorials/index.html
첫번재 예제는 화면의 좌/우를 터치하면 흰색/검정으로 반전되는 간단한 앱이다. 두번째 좀 더 심화된 예제를 해 보자. 마찬가지로 튜토리얼 두번째 Using Sensors 에 코드가 있다. 스마트폰의 가속도 정보를 추출해서 화면에 보여 주는 코드이다. 이것만 하면 심심하니 앞에서 해본 SuperFormula 소스를 같이 적용해 보았다. 폰의 accelerometer값중에 az를 기존 숫자 대신에 대입해 주었다. 폰의 움직임에 따라 그 값이 변화니 그래프도 마찬가지로 변하게 된다.
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
Context context;
SensorManager manager;
Sensor sensor;
AccelerometerListener listener;
float ax, ay, az;
float t;
void setup() {
fullScreen();
context = surface.getActivity();
manager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
sensor = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
listener = new AccelerometerListener();
manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_GAME);
noFill();
stroke(255);
strokeWeight(2);
textFont(createFont("Arial", 60));
}
void draw() {
background(0);
text("X: " + ax, 10, 60);
text("Y: " + ay, 10, 120);
text("Z: " + az, 10, 180);
translate(width/2, height/2);
beginShape();
for (float theta = 0; theta <= 2 * PI; theta += 0.01) {
float rad = r(theta,
3,
2,
int(az),
1,
sin(t) * 1.2 + 1.2,
cos(t) * 1.2 + 1.2
);
float x = rad * cos(theta) * 50;
float y = rad * sin(theta) * 50;
vertex(x,y);
}
endShape();
t += 0.1;
}
float r(float theta, float a, float b, float m, float n1, float n2, float n3) {
return pow(pow(abs(cos(m * theta / 4.0) / a), n2) +
pow(abs(sin(m * theta / 4.0) / b), n3), -1.0 / n1);
}
class AccelerometerListener implements SensorEventListener {
public void onSensorChanged(SensorEvent event) {
ax = event.values[0];
ay = event.values[1];
az = event.values[2];
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
public void onResume() {
super.onResume();
if (manager != null) {
manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_GAME);
}
}
public void onPause() {
super.onPause();
if (manager != null) {
manager.unregisterListener(listener);
}
}