忍者ブログ
AndroidSDK
[1] [2] [3]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

 DoJaなんかだとCanvasとかIApplicationをRunnableにしてメインループをそこにおいて描画なんてのをやるんだけど、IApplication=Activity Canvas=Viewで同じことやろうとすると上のメッセージがでる。どうもこういうことらしい

http://code.google.com/android/reference/android/view/View.html

The basic cycle of a view is as follows:
An event comes in and is dispatched to the appropriate view. The view handles the event and notifies any listeners.
If in the course of processing the event, the view's bounds may need to be changed, the view will call requestLayout().
Similarly, if in the course of processing the event the view's appearance may need to be changed, the view will call invalidate().
If either requestLayout() or invalidate() were called, the framework will take care of measuring, laying out, and drawing the tree as appropriate.
Note: The entire view tree is single threaded. You must always be on the UI thread when calling any method on any view. If you are doing work on other threads and want to update the state of a view from that thread, you should use a Handler.

こちらも同様のアドヴァイスが。いちはやくDoJaから(?)の移植をしておられる。
http://castor.s26.xrea.com/blog/2007/11/17
PR
無数のボールが跳ね回るアプレットのソースが公開されているので、そちらの移植を乱暴にやりつつ、泥縄式におぼえていきたい。
http://homepage.mac.com/catincat/java/physics/mass/
http://homepage.mac.com/catincat/java/physics/mass/MassiveBall.java

まず
Applet = View
Color = 存在しないので新しく作る
Graphics = Canvas
Image = Bitmap
という感じで置き換えて乱暴にコードを削った。
マウス処理はちょっと後回しにしておいて
repaint() = invalidate()
Graphics.setcolor() = Paint.setARGB()
とかやった
もとのアプレットはメイン処理をデーモンスレッドで走らせててそこでrepaintしていたが、同じ様にやると
Only the original thread that created a view hierarchy can touch its views
といって怒られた。とりあえず早い所結果が見たいので
http://code.google.com/android/samples/ApiDemos/src/com/google/android/samples/graphics/GLView1.html
ここのメッセージハンドラの処理を見て、スレッドじゃなくタイマー処理で再描画を呼び出すことにした。

ものすごーくラフで、いろいろ整理してないけどとりあえずボールが沢山出て動く、ってところまでいけたのがこれ。

androidsample

sample source

package com.andor.ball;

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

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;

public class AndroBall extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(new MassiveBall(this));
}

}


class MassiveBall extends SimulationApplet {
static final double _r_max=16,_r_mid=12,_r_min=6;
Ball[] _largeBalls=new Ball[20];
Ball[] _smallBalls=new Ball[30];
Ball[] _allBalls=new Ball[_largeBalls.length+_smallBalls.length];
Grid _grid;
Ball _seizedBall;
public void run(){

}

public MassiveBall(Context context) {
super(context);
int i=0;
int j;
int c;
c= _largeBalls.length;
for (j=0;j _allBalls[i]=_largeBalls[j]=createBall(_r_max,_r_mid);

c= _smallBalls.length;
for (j=0;j _allBalls[i]=_smallBalls[j]=createBall(_r_mid,_r_min);

_grid=new Grid(_width,_height,_r_mid,10);

}

protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w,h,oldw,oldh);
}


private Ball createBall(double in_r_max,double in_r_min) {
float d1,d2,d3;
d1 = (float)Math.random();
d2 = (float)Math.random();
d3 = (float)Math.random();
int i1,i2,i3;
i1 = (int)(Math.random()*255);
i2 = (int)(Math.random()*255);
i3 = (int)(Math.random()*255);
double r=d1*(in_r_max-in_r_min)+in_r_min;
double d = r*2;
double x=d2*(_width-d)+r;
double y=d3*(_height-d)+r;
Color color=new Color(i1,i2,i3);
return new Ball(x,y,r,color);
}

protected synchronized void run(double in_dt) {
if (_smallBalls == null){
return;
}
if (_largeBalls == null){
return;
}
if (_grid == null){
return;
}

_grid.clear();
int i;
int c;

c = _smallBalls.length;
for (i=0;i _grid.add(_smallBalls[i],_smallBalls[i].x,_smallBalls[i].y);

_grid.apply(new Grid.Operator() {
public void matchObjects(Object a,Object b) {
if (((Ball)a).id<((Ball)b).id)
((Ball)a).collide((Ball)b);
}
});


c = _largeBalls.length;
for (i=0;i for (int j=0;j _largeBalls[i].collide(_largeBalls[j]);
for (int j=0;j<_smallBalls.length;j++)
_largeBalls[i].collide(_smallBalls[j]);
}

c = _allBalls.length;
for (i=0;i _allBalls[i].fall(in_dt);
_allBalls[i].bound(_width,_height);
_allBalls[i].move(in_dt);
}
if (_seizedBall!=null) {
_seizedBall.u+=in_dt*2*((_mouse_x-_seizedBall.x)/_ft-_seizedBall.u)/_ft;
_seizedBall.v+=in_dt*2*((_mouse_y-_seizedBall.y)/_ft-_seizedBall.v)/_ft;
}
}

public void mousePressed(int x,int y) {
for (int i=0;i<_allBalls.length;i++) {
Ball b=_allBalls[i];
double dx=b.x-x;
double dy=b.y-y;
if (dx*dx+dy*dy }
}

public void mouseReleased(int x,int y) {
_seizedBall=null;
}

protected void paintOffscreen(Canvas g) {
int i;
int c;
int x,y,w,h;
Color color;
if (_allBalls == null){
return;
}
c =_allBalls.length;
Paint paint = new Paint();
for (i=0;i Ball b=_allBalls[i];
x = (int)(b.x-b.r);
y = (int)(b.y-b.r);
w = (int)b.r;
color=b.color;
paint.setARGB(255, color.r, color.g, color.b);
g.drawCircle(x, y, w, paint);
}
}
}

class Color{
public int r,g,b;
public Color(int in_r,int in_g,int in_b){
r = in_r;
g = in_g;
b = in_b;
}
}

abstract class SimulationApplet extends View implements Runnable,MouseListener {
public static final double _ft=0.1;
private static final double _dt=0.01;

private Bitmap _image;
protected int _width = 320;
protected int _height = 240;
protected int _mouse_x,_mouse_y;
protected boolean _mouse_down;

Canvas _canvas;
private Rect _rect = new Rect();
private Paint _paint;
AndroBall _parent;

private long _nextTime;
private boolean is_animate;

public SimulationApplet(Context c) {
super(c);
is_animate = false;
_paint = new Paint();
_paint.setAntiAlias(true);
_paint.setARGB(255, 255, 255, 255);
}

protected void onAttachedToWindow() {
is_animate = true;
Message msg = mHandler.obtainMessage(INVALIDATE);
_nextTime = SystemClock.uptimeMillis();
mHandler.sendMessageAtTime(msg, _nextTime);
super.onAttachedToWindow();
}

protected void onDetachedFromWindow() {
is_animate = false;
super.onDetachedFromWindow();
}

private static final int INVALIDATE = 1;
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (is_animate && msg.what == INVALIDATE) {
run(_dt);
invalidate();
msg = obtainMessage(INVALIDATE);
long current = SystemClock.uptimeMillis();
if (_nextTime < current) {
_nextTime = current + 5;
}
sendMessageAtTime(msg, _nextTime);
_nextTime += 5;
}
}
};

protected void onSizeChanged(int w, int h, int oldw, int oldh) {
int curW = _image != null ? _image.width() : 0;
int curH = _image != null ? _image.height() : 0;
if (curW >= w && curH >= h) {
return;
}
if (curW < w) curW = w;
if (curH < h) curH = h;
_width=curW;
_height=curH;
Bitmap newBitmap = Bitmap.createBitmap(curW, curH, false);
Canvas newCanvas = new Canvas();
newCanvas.setDevice(newBitmap);
if (_image != null) {
newCanvas.drawBitmap(_image, 0, 0, null);
}
_image = newBitmap;
_canvas = newCanvas;
}

protected abstract void run(double dt);

public boolean onMotionEvent(MotionEvent event) {
int action = event.getAction();
_mouse_x = (int)event.getX();
_mouse_y = (int)event.getY();

if ((action == MotionEvent.ACTION_DOWN) || (action == MotionEvent.ACTION_MOVE)){
_mouse_down=true;
mousePressed(_mouse_x,_mouse_y);
}else{
_mouse_down=false;
mouseReleased(_mouse_x,_mouse_y);
}
return true;
}
protected void onDraw(Canvas canvas) {
if ((_rect != null) && (_paint != null)){
_rect.set(0, 0,
_width,_height);
_canvas.drawRect(_rect, _paint);
paintOffscreen(_canvas);
}
if (_image != null) {
canvas.drawBitmap(_image, 0, 0, null);
}
}
protected abstract void paintOffscreen(Canvas canvas);
}
class Ball {
private static final double _elasticity=0.8;
private static final double _gravity=200;
private static final double _bounce=0.7;
private static int _number=0;

public double x,y;
public double u,v;
public double r,m;
public final double d;
public int id;
public Color color;

public Ball(double x,double y,double r,Color color) {
this.x=x;
this.y=y;
this.r=r;
this.d = r*2;
this.color=color;
m=Math.PI*r*r;
id=_number++;
}

public void fall(double dt) {
v+=dt*_gravity;
}

public void move(double dt) {
x+=dt*u;
y+=dt*v;
}

public void collide(Ball b) {
double dx=b.x-x;
double dy=b.y-y;
double dr=Math.sqrt(dx*dx+dy*dy);
if (dr dx/=dr;
dy/=dr;
double dw=(b.u-u)*dx+(b.v-v)*dy;
if (dw<0) {
double fw=dw*(1+_elasticity)/(b.m+m);
u+=fw*dx*b.m;
v+=fw*dy*b.m;
b.u+=-fw*dx*m;
b.v+=-fw*dy*m;
}
double fr=_bounce*(dr-b.r-r)/(b.m+m);
x+=fr*dx*b.m;
y+=fr*dy*b.m;
b.x+=-fr*dx*m;
b.y+=-fr*dy*m;
}
}

public void bound(double width,double height) {
if (x if (u<0) u*=-_elasticity;
x+=_bounce*(r-x);
}
if (x>width-r) {
if (u>0) u*=-_elasticity;
x+=_bounce*(width-r-x);
}
if (y if (v<0) v*=-_elasticity;
y+=_bounce*(r-y);
}
if (y>height-r) {
if (v>0) v*=-_elasticity;
y+=_bounce*(height-r-y);
}
}
}

class Grid {
private double _width,_height,_delta;
private int _cols,_rows,_capacity;
private Object[][][] _cells;
private int[][] _counts;

public Grid(double width,double height,double delta,int capacity) {
this._width=width;
this._height=height;
this._delta=delta;
this._capacity=capacity;
_cols=(int)Math.ceil(width/delta);
_rows=(int)Math.ceil(height/delta);
_cells=new Object[_cols][_rows][capacity];
_counts=new int[_cols][_rows];
}

public void clear() {
int c,c2;
int i,j;
c = _cols;
c2 = _rows;
for (i=0;i for (j=0;j _counts[i][j]=0;
}

public void add(Object obj,double x,double y) {
int i=(int)(x/_delta);
int j=(int)(y/_delta);
if (i<0) i=0;
if (i>=_cols) i=_cols-1;
if (j<0) j=0;
if (j>=_rows) j=_rows-1;
if (_counts[i][j]<_capacity)
_cells[i][j][_counts[i][j]++]=obj;
}

public void apply(Operator op) {
for (int i=0;i<_cols;i++) {
int i2min=Math.max(0,i-1);
int i2max=Math.min(i+1,_cols-1);
for (int j=0;j<_rows;j++) {
int j2min=Math.max(0,j-1);
int j2max=Math.min(j+1,_rows-1);
for (int k=0;k<_counts[i][j];k++)
for (int i2=i2min;i2<=i2max;i2++)
for (int j2=j2min;j2<=j2max;j2++)
for (int k2=0;k2<_counts[i2][j2];k2++)
op.matchObjects(
_cells[i][j][k],
_cells[i2][j2][k2]);
}
}
}

public interface Operator {
void matchObjects(Object a,Object b);
}


}

interface MouseListener {
void mousePressed(int _mouse_x,int _mouse_y);
void mouseReleased(int x,int y);
}



 The Canvas class holds the "draw" calls. To draw something, you need 4 basic
components: A Bitmap to hold the pixels, a Canvas to host the draw calls
(writing into the bitmap), a drawing primitive (e.g. Rect, Path, text,
Bitmap), and a paint (to describe the colors and styles for the drawing).

http://code.google.com/android/reference/android/graphics/Canvas.html

WindowsAPIの描画の感じににてるのかな。

The Paint class holds the style and color information about how to draw
geometries, text and bitmaps.
次に試してみたのがカラーキューブ

http://code.google.com/android/samples/ApiDemos/src/com/google/android/samples/graphics/GLView1.html

OpenGLが使える模様。

アニメーションのためのタイマー処理はは以下のハンドラがやってくれている。

private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (mAnimate && msg.what == INVALIDATE) {
invalidate();
msg = obtainMessage(INVALIDATE);
long current = SystemClock.uptimeMillis();
if (mNextTime < current) {
mNextTime = current + 20;
}
sendMessageAtTime(msg, mNextTime);
mNextTime += 20;
}
}
};

protected void onAttachedToWindow() {
mAnimate = true;
Message msg = mHandler.obtainMessage(INVALIDATE);
mNextTime = SystemClock.uptimeMillis();
mHandler.sendMessageAtTime(msg, mNextTime);
super.onAttachedToWindow();
}
 なんかこのての処理既視感があるな。COCOAってこんなんじゃなかったっけ。それ以前にJavaのなにがしかでもこういうのあんのかな。まあいいや慣れだ慣れ。
役にたつかもしれないからメッセージとハンドラにリンクはっとこう
http://code.google.com/android/reference/android/os/Message.html
http://code.google.com/android/reference/android/os/Handler.html


Windowsのエミュレータが動かないのは原因が分からん。Linuxも検証まだ。明日はデバッガまわりをいじる予定。

お絵描きソフト
http://code.google.com/android/samples/ApiDemos/src/com/google/android/samples/graphics/TouchPaint.html

これによると、押す強さと押した範囲がとれるようだ。(実装依存というやつだが)。
残念ながらエミュレータではとれないみたいだけど、ソースはこんな感じになってる
public boolean onMotionEvent(MotionEvent event) {
int action = event.getAction();
mCurDown = action == MotionEvent.ACTION_DOWN
|| action == MotionEvent.ACTION_MOVE;
mCurX = (int)event.getX();
mCurY = (int)event.getY();
mCurPressure = event.getPressure();
mCurSize = event.getSize();
mCurWidth = (int)(mCurSize*(getWidth()/3));
if (mCurWidth < 1) mCurWidth = 1;
if (mCurDown && mBitmap != null) {
int pressureLevel = (int)(mCurPressure*255);
mPaint.setARGB(pressureLevel, 255, 255, 255);
mCanvas.drawCircle(mCurX, mCurY, mCurWidth, mPaint);
mRect.set(mCurX-mCurWidth-2, mCurY-mCurWidth-2,
mCurX+mCurWidth+2, mCurY+mCurWidth+2);
invalidate(mRect);
}
return true;
}

リファレンス見てもとれそうな感じで書いてある。
http://code.google.com/android/reference/android/view/MotionEvent.html#getPressure()
押したサイズもとれるようにはなっている
http://code.google.com/android/reference/android/view/MotionEvent.html#getSize()

ここらへんは実際の端末で対応するかどうかだから、別途public final long getDownTime()とかで書く必要もあるんだろうな

さあリンク集だ


キーパッドからの入力に応じて画面上のボールが動く
http://rio1218.blog26.fc2.com/blog-entry-33.html
http://rio1218.blog26.fc2.com/blog-entry-34.html
任意のビューをアラートダイアログに表示
http://www.javadrive.jp/android/alertdialog/index5.html
メインループとキー情報がとれて三角形が動く
http://castor.s26.xrea.com/blog/tech/android
http://castor.s26.xrea.com/blog/2007/11/17
ボタンクリック時の処理を設定したアラートダイアログを表示
http://www.javadrive.jp/android/alertdialog/index3.html
ImageButton?を作る
http://d.hatena.ne.jp/s_welt/20071114
地図アプリ
http://www.atmarkit.co.jp/fjava/column/koyama/koyama09_5.html
AndroidのOpenGL ESでのマウスピッキング
http://chephes.cocolog-nifty.com/blog/android/index.html
ContentProvider? を使って コンタクトリストのデータを取得する
http://www.plants-web.jp/flashmind/blog/2007/11/android_contentprovider.html
Android SDKとOpenGL Message/Handlerさわり
http://androidsdk.blog.shinobi.jp/Entry/3/
Androidアプリでクロック機能を実装するためのヒント
http://kousei-inc.com/portal/index.php?%E5%8B%9D%E6%89%8B%E3%81%ABAndroid%E3%83%96%E3%83%AD%E3%82%B0
チャット形式で様々な事にトライ 必見
http://www.lingr.com/room/Androider-ja/archives/2007/11/23
AndroidでTwitterクライアント
http://www.adamrocker.com/blog/173/android_twitter_client.html
AndroidでWebページサムネイル
http://chephes.cocolog-nifty.com/blog/2007/11/androidweb_476f.html
Bug LabsのモジュラーなデバイスでGoogleのAndroidが走るらしい
http://blog.browncat.org/2007/11/bug_labsgoogleandroid.html
動画ファイル再生
http://kazhik.net/tech/2007/12/android-1.html
ダイヤラ
http://sadko.mobi/callfreq/index.html
RSSリーダ
http://code.google.com/p/android-feed-reader/
ブロック崩し
http://chephes.cocolog-nifty.com/blog/2007/11/android_07e5.html


リンク紹介系
http://androidsdk.blog.shinobi.jp/Entry/2/
http://nozaki.com/2007/11/29/1655/
http://www.blogmura.com/profile/196683.html
http://www.kanshin.com/keyword/1271169
http://nozaki.com/2007/11/29/1655/?view=tra


RSS系
http://buzzurl.jp/user/tsupo/keyword/Java?mode=rss
http://www.namaan.net/rss/WebView/
http://www41.atwiki.jp/tako2lab/rss


手取り足取り教える系
http://www.edita.jp/web2/one/web26533397.html
http://www.edita.jp/bestation/one/bestation6007187.html
http://blog.goo.ne.jp/xmldtp/e/53d99581f0294d4f37cb9dfe56bd6b3d
http://www.atmarkit.co.jp/fjava/column/koyama/koyama09_3.html
http://codezine.jp/a/article/aid/1925.aspx
http://www.saturn.dti.ne.jp/~npaka/android/
http://blog.makotokw.com/2007/11/25/eclipseandroidapidemo/
http://tokyo-ltd.at.webry.info/
http://blog.flup.jp/2007/11/29/android_intro_2/


日本語翻訳系
http://tsudoe.com/pukiwiki/?%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB
http://www.android-ja.net/modules/xpwiki/?tutorial
http://www.muo.jp/android/toolbox/apis/opengl.html
http://www.muo.jp/android/devel/data/databases.html
http://tsudoe.com/pukiwiki/index.php?FrontPage
http://www.android-ja.net/modules/xpwiki/?tutorial-exercise2


素人悩みながら始めてる系
http://memo333.cocolog-nifty.com/blog/android_4/index.html
http://memo333.cocolog-nifty.com/blog/2007/11/index.html


日記とか
http://adinnovator.typepad.com/ad_innovator/2007/11/googletvandroid.html
http://saekiyoshiyasu.org/pyb/pyblosxom.cgi/hardware/mobile/
http://kiyonari.vox.com/library/post/android%E6%90%BA%E5%B8%AF%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB.html
http://b.hatena.ne.jp/keyword/%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%BD%E3%83%BC%E3%82%B9?sort=eid
http://blog.livedoor.jp/arabian_tower/index.rdf
http://uiengineda.blogs.com/uiengine_/2007/11/googleandroid-s.html
http://wassr.jp/user/haoyayoi/statuses/IvRbqtNkBw
http://www29.atwiki.jp/android/ref/11.html
http://mute0.cocolog-nifty.com/blog/2007/11/google_android.html
http://journal.mycom.co.jp/news/2007/11/13/005/index.html
http://www29.atwiki.jp/android/ref/11.html?sort=deserial
http://blog.so-net.ne.jp/studio-dejavu/archive/c30365919
http://www.in-vitro.jp/blog/index.cgi/2007/11/
http://taggy.jp/user/news/detail/15636451
http://www.nkozawa.com/blog/archives/category/programing/
http://builder.japan.zdnet.com/news/story/0,3800079086,20363554,00.htm
http://blog.livedoor.jp/vine_user/archives/51183134.html
http://k-tai.impress.co.jp/cda/article/news_toppage/37176.html
http://blog.lab4frog.com/blog/2007/11/android.html
http://www.901am.jp/archives/2007/google-announces-10-million-android-developer-challenge.html
http://v.japan.cnet.com/blog/story/0,2000071498,000269c-0000021009o,00.htm
http://www.sprasia.com/blog/gon/20071113114739.html?SprasiaSession=atbdp0r1b5rnum60tlcda3sns6
http://gihyo.jp/dev/clip/01/orangenews/vol42/0001
http://ameblo.jp/satopy/entry-10055333262.html
http://internet.watch.impress.co.jp/cda/news/2007/11/13/17495.html
http://it.nikkei.co.jp/rd/rd.aspr?s=IT&g=fa&n=RS2036036906112007
http://androidzaurus.seesaa.net/



忍者ブログ [PR]
カレンダー
04 2024/05 06
S M T W T F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
カテゴリー
フリーエリア
最新トラックバック
プロフィール
HN:
No Name Ninja
性別:
非公開
バーコード
ブログ内検索