Androidプログラミング日記 (仮)  

シューティング作るぞ!> 第一回 骨組みと画像表示

あなたは

人目のプログラマーだよ。

Androidプログラミング日記 (仮).

 

 

 

 

まずは

最初は自機を表示させるだけのコードを書いてみます。とはいっても、ある程度先を見越したコードを書いていきます。

ちょっとだけポリモーフィズム的なことも入っています。まだ全然実装はされていませんがそのへんも踏まえてのコードです。

私自身いつもこのままコードコピペしているようなものなのでこれをコピペすれば一歩踏み出せるようなコードにしています。

 

 

 

 

画像を表示させるだけなのですがちょっとファイル数が多いです。とはいっても最終的なファイル数はあまり変わらない数にする予定です。(これに表示させたいオブジェクトのクラスファイルをプラスさせる程度)

Activityファイル、MainLoopファイル、Mesodファイルはほぼいつもこのまま使用しています。

将来を見越してObjectクラスをabstractクラスとしています。なぜそうするかはあとあとわかってくると思います。

 

画面を縦固定にするためにandroid:screenOrientation="portrait"

をAndroidManifest.xmlに追記

ファイル名「AndroidManifest.xml」


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="and.roid.shooting2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="4" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".Shooting2Activity"
            android:label="@string/app_name"
			
            android:screenOrientation="portrait">
			
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
						

ファイル名「Shooting2Activity.java」

/*
 * プロジェクトを作成するとまずこれが作成されますねのクラス
 * ”元から作成されてるやつ”と書いてあるやつ以外を書くと
 * フルスクリーン仕様になり、画面の大きさを変数に収めています
 */
package and.roid.shooting2;

import android.app.Activity;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.view.Display;
import android.view.Window;
import android.view.WindowManager;

public class Shooting2Activity extends Activity {
	public float disp_w,disp_h;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);//元から作成されてるやつ
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        Window window = getWindow();
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        WindowManager manager = window.getWindowManager();
        Display disp = manager.getDefaultDisplay();
        disp_w = disp.getWidth();
        disp_h = disp.getHeight();

        setContentView(new MainLoop(this));
        //setContentView(R.layout.main);//元から作成されてるやつ

    }
}
						

ファイル名「MainLoop.java」

/*
 * SurfaceViewをextendsさせたクラス
 * メインループなどはここにあります
 * 基本的にSurfaceViewを使用した時には決まった変数の使用
 * などがあるので、そういう変数やメソッドの末尾に
 * ”お決まり”と書いておきます
 */
package and.roid.shooting2;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MainLoop extends SurfaceView implements SurfaceHolder.Callback,Runnable{
	private SurfaceHolder holder;//お決まり
	private Thread thread;//お決まり

	//どのActivityを使用しているかのための変数
	private Shooting2Activity s2a;
	private float disp_w,disp_h;
	private Drawable jikiimg,tamaimg;


	/*
	 * Objectクラスを使用する準備
	 * 今回だけではこれの意味はあまりありません
	 */
	private Object jiki;

	//コンストラクタが二つあるけど気にしないように
	//こちらのコンストラクタは、自前でViewを実装するときに
	//呼ばれるコンストラクタっぽい
	public MainLoop(Context context) {
		super(context);
		init(context);
	}
	//こちらはxml方式でViewを呼び出すときに呼ばれるぽい
	public MainLoop(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public void init(Context context){
		holder = getHolder();//お決まり
		holder.addCallback(this);//お決まり
		holder.setFixedSize(getWidth(), getHeight());//お決まり
		/*
		 * s2a = (Shooting2Activity)context;
		 * よくわからないけども、私的には使用している(今現在
		 * 画面に表示させている)アプリの何か色々なものをcontext
		 * として受け取り、それがいまどのActivityのやつかとか
		 * そんな感じの雰囲気と思います。(キニシテナイ)
		 */
		s2a = (Shooting2Activity)context;
		disp_w = s2a.disp_w;
		disp_h = s2a.disp_h;

		Resources resources = context.getResources();//画像登録準備
		//ビットマップ方式で画像取り込み
		//ビットマップで取り込む理由として、使用したい大きさなどに変換できるので
		Bitmap img= BitmapFactory.decodeResource(resources,and.roid.shooting2.R.drawable.jiki);
		//ここで画像分割
		//わざわざ画像の大きさをgetWidthgetHeightを使用するのは
		//確実に大きさを図って分割するため
		Bitmap jikibit = Bitmap.createBitmap(img,0,0,img.getWidth()/2,img.getHeight());
		Bitmap tamabit = Bitmap.createBitmap(img,img.getWidth()/2,0,img.getWidth()/2,img.getHeight());

		/*
		 * Onjectクラスではインスタンス(実装)できないので
		 * ObjectクラスをextendsさせたJikiクラスを実装
		 */
		jiki = new Jiki(disp_w,disp_h);
		jiki.Oint(jikibit, 240, 800, 10, 10, jikibit.getWidth(), jikibit.getHeight());

	}

	//implements Runnableを実装するとこのメソッドが自動追加
	//ここがメインループとなります
	public void run() {//お決まり
		Canvas c;
		Paint p = new Paint();
		p.setAntiAlias(true);

		while(thread != null){
			c = holder.lockCanvas();//お決まり

			c.drawColor(Color.BLACK);
			jiki.ODraw(c);


			holder.unlockCanvasAndPost(c);//お決まり

			try {
				Thread.sleep(50);//お決まり
			} catch (Exception e){}
		}
	}

	public boolean onTouchEvent(MotionEvent event){
		int action = event.getAction();
		int x = (int)event.getX();
		int y = (int)event.getY();
		switch(action){
		case MotionEvent.ACTION_DOWN:
			break;
		case MotionEvent.ACTION_UP:
			break;
		}
		return true;
	}


	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {}//お決まり

	public void surfaceCreated(SurfaceHolder arg0) {thread = new Thread(this);thread.start();}//お決まり

	public void surfaceDestroyed(SurfaceHolder arg0) {thread = null;}//お決まり

}

						

ファイル名「Mesod.java」


/*
 * 無理やり作った汎用メソッド群
 * なんども使用するようなメソッドをかためて置いて
 * おきたかったので無理やりつくったクラス
 */

package and.roid.shooting2;

import android.graphics.Rect;

public class Mesod {
	/*
	 * わたくしの環境がXPERIAでその画面幅でアプリを作成
	 * しているのでそれから各アプリの画面幅に合うように調整
	 * させるための変数
	 */

	static public final float XPERIA_W = 480f;
	static public final float XPERIA_H = 854f;
	//せっかくなので0も固定値に
	static public final float ZERO = 0f;


	/*
	 * 受け取ったxy座標と調べたい短形範囲が重なっているかいないか
	 */
	public boolean RectTap(int x,int y,Rect gazou){
		return gazou.left < x && gazou.top < y && gazou.right > x && gazou.bottom > y;
	}
	/*
	 * この2行で各座標を実装機種の画面比に合わせます
	 */
	public int setSizeX(float disp_w,float zahyou){return (int) (zahyou * (disp_w / XPERIA_W));}
	public int setSizeY(float disp_h,float zahyou){return (int) (zahyou * (disp_h / XPERIA_H));}
}


						

ファイル名「Object.java」


package and.roid.shooting2;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

public abstract class Object {
	private Mesod ms = new Mesod();
	private float disp_w,disp_h;
	//オブジェクトの画像
	private Drawable img;
	//オブジェクトの中心座標
	private float cx,cy;
	//向かおうとしている座標
	private float vx,vy;
	//オブジェクトの移動スピード
	private float spx,spy;
	//オブジェクトの大きさ
	private int imgw,imgh;

	public Object(){}
	public Object(float dw,float dh){
		disp_w = dw;
		disp_h = dh;
	}
	public void Oint(Bitmap imgb,float x,float y, float sx,float sy,int w,int h){
		img = new BitmapDrawable(imgb);
		cx = ms.setSizeX(disp_w, x);
		cy = ms.setSizeY(disp_h, y);
		spx = sx;
		spy = sy;
		imgw = w;
		imgh = h;
	}
	public void ODraw(Canvas c){
		img.setBounds((int)(cx-imgw/2),(int)(cy-imgh/2),(int)(cx+imgw/2),(int)(cy+imgh/2));
		img.draw(c);
	}
}

						

ファイル名「Jiki.java」


package and.roid.shooting2;

public class Jiki extends Object{
	public Jiki(){}
	public Jiki(float dw,float dh){
		super(dw,dh);
	}
}

						
 

無事成功しました!

 

一応他のエミュレータで試しましたが無事真ん中下らへんに表示させましたし、たぶんこれで大丈夫ですキット・・・

今回コードを書くにあたって、なるべく細かくコードのほうに説明をつけました。

しかしいつも思うのですが、自分にもっと画力があれば・・・と思います;;

ゲームって8割くらい見た目が大事ですよね;;中身はわからなくてもパッケージでかっちゃう時もありますしね・・中身はワカラナクテモ・・・・

でも海外のゲームなどはグラは日本の細かい綺麗な見た目ほどではなくても、世界観と革新的なシステムで大ヒットしてるゲームが多いですし、FalloutとかオブリとかスカイリムとかボダランとかBFとか

自分はアメリカンなんだと言い聞かせれば、まだまだ戦ってイケルはずですね;;

 

<戻る   次へ>

 

 

 

Androidプログラミング日記 (仮) | サイトマップ | 個人情報保護方針 | 応援メールテヘペロ | ©2012 Japan  相互リンク大募集中です