素人のウィルコム用Javaアプリ制作の記録です
このブログの目次

ソースコード

呼び出し部分。Y!mobileのサンプルを参考に。

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class Teruteru extends MIDlet {
	static MIDlet midlet;

    //コンストラクタ
    public Teruteru() {
		midlet=this;
        TeruteruCanvas sc = new TeruteruCanvas();
        Display.getDisplay(this).setCurrent(sc);
        Thread thread=new Thread(sc);
        thread.start();
    }

    //アプリの開始
    public void startApp() {
    }

    //アプリの一時停止
    public void pauseApp() {
    }

    //アプリの終了
    public void destroyApp(boolean flag) {
    }
}

メインの部分。

import java.util.Random;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.game.*;

import javax.microedition.media.*;
import javax.microedition.media.control.*;
import java.io.*;

public class TeruteruCanvas extends GameCanvas implements Runnable,CommandListener{
	//画像
	Image im_title;
	Image im_Player;
	Image im_ame;
	Image im_bg;
	Image im_gover;
	//BGM
	Player sndBGM;
	Player goverBGM;
	Player damageSE;
	Player scoreSE;
	
	String BGMname;
	String SEname;
	
	//ディスプレイサイズ取得
	int display_width = getWidth();
	int display_height = getHeight();
	
	//ランダム生成
	Random random = new Random();
	//ソフトキー
	Command exit;
	Command inst;
	
	String keyCommand = ""; //コマンド保存
	
	boolean inst_flag = false;
	boolean flag;
	
	//コンストラクタ
	TeruteruCanvas(){
		//キーイベントの抑制
		super(false);
		
		//画像の読み込み
		try{
			im_title = Image.createImage("/teruri-1.png");
			im_Player = Image.createImage("/player_sp.png");
			im_ame = Image.createImage("/ame.png");
			im_bg = Image.createImage("/bg.png");
			im_gover = Image.createImage("/gameover.png");
			
		}catch(Exception e){
			System.out.println(e.getClass().getName());
		}
		//BGMの読み込み
		try {
			InputStream in_bgm = getClass().getResourceAsStream("/teruteru_pops.mid");
			InputStream in_gover = getClass().getResourceAsStream("/teruteru_Healing_Harp.mid");
			InputStream in_damage = getClass().getResourceAsStream("/se_damage.wav");
			InputStream in_score = getClass().getResourceAsStream("/se_score.wav");
			
			sndBGM = Manager.createPlayer(in_bgm, "audio/midi");
			goverBGM = Manager.createPlayer(in_gover, "audio/midi");
			damageSE = Manager.createPlayer(in_damage, "audio/x-wav");
			scoreSE = Manager.createPlayer(in_score, "audio/x-wav");
			sndBGM.setLoopCount(-1);
		}catch (Exception e) {
			e.printStackTrace();
		}
		
		//ソフトキーの設定
		exit = new Command("終了", Command.EXIT, 0);
		addCommand(exit);
		inst = new Command("操作説明", Command.SCREEN, 1);
		addCommand(inst);
		setCommandListener(this);
	}
	
	//雨粒オブジェクトクラス
	class Object_Ame {
		//雨粒初期位置
		private int x;
		private int y;
		//雨粒画像サイズ 現状は直入力
		private int ame_width;
		private int ame_height;
		//雨粒移動距離
		private int dy;
		//画面内生存判定
		private boolean suv;
		
		private int rnd;
		
		//コンストラクタ
		Object_Ame(){
			Set();
			this.ame_width = 32;
			this.ame_height = 5;
			this.dy = 5;
			this.suv = true;
		}
		
		int getX(){return x;}
		int getY(){return y;}
		int getWidth(){return ame_width;}
		int getHeight(){return ame_height;}
		boolean getState(){return suv;}
		
		//xy軸決定
		void Set(){
			setX(randX());
			setY(randY());
		}
		void setX(int setx){
			x = setx;
		}
		void setY(int sety){
			y = sety;
		}
		
		//ランダム
		int randX(){
			int field_width = display_width/10;
			rnd = random.nextInt(display_width) - field_width - ame_width*2;
			if(rnd < 0) randX();
			return rnd;
		}
		int randY(){
			int field_height = display_height;
			rnd = (random.nextInt(display_height) - field_height) + 50;
			//if(rnd < 0) randY();
			return rnd;
		}
		
		//dy方向移動
		void MoveAme(){
			y += dy;
		}
		
		//死亡判定
		void deadState(){
			suv = false;
		}
	}
	
	class Object_Player {
		private int life;
		private int p_width; //プレイヤースプライトサイズ
		//プレイヤー初期位置
		private int x;
		private int y;
		//移動速度
		private int dir; //移動方向
		private int dx; //通常移動速度
		//無敵時間
		private int inv; //無敵時間
		private int inv_f; //無敵経過時間
		//接近フラグ
		private boolean close;
		//点滅管理用
		private int visflag;
		
		Object_Player(){
			this.life = 4;
			this.p_width = 40;
			this.x = 0;
			this.y = display_height * 4/ 5;
			this.dir = 0; //移動方向
			this.dx = 4; //通常移動速度
			this.inv = 25; //無敵時間
			this.inv_f = 0; //無敵経過時間
			this.visflag = 0;
			this.close = false;
		}
		int getX(){return x;}
		int getY(){return y;}
		int getdir(){return dir;}
		int getinv(){return inv;}
		int getinv_f(){return inv_f;}
		int getlife(){return life;}
		int getvisflag(){return visflag;}
		boolean getclose(){return close;}
		
		void PlayerControl(int key){
			//ボタン進行判定
			if (key != 0){
				setdir(1);
			}else if(getX() > 0){
				setdir(-1);
			}else{
				setdir(0);
			}
			PlayerMove();
		}
		
		void PlayerMove(){
			x += dx * dir;
		}
		
		void setdir(int setDir){
			dir = setDir;
		}
		void setinv_f(int sett){
			inv_f = sett;
		}
		
		void inv_check(){
			if(inv_f >= inv){
				setinv_f(0);
			}else if(isinv()){
				inv_f++;
			}
		}
		boolean isinv(){
			if(inv_f >= 1 & inv_f < inv){
				return true;
			}
			return false;
		}
		
		void lifedown(){
			life--;
		}
		
		int switchvisflag(){
			if(visflag == 0){
				visflag = 1;
			}else if(visflag == 1){
				visflag = 0;
			}
			return visflag;
		}
		
		void setclose(boolean st){
			close = st;
		}
		
		void spacehit(){
			int field_width = display_width/10;
			if(x < 0) x = 0;
			if(x > display_width - p_width - field_width) x = display_width - p_width - field_width;
		}
	}
	
	class Stage {
		private int stagesize; //ステージ長さ
		private int progress; //進行状況
		private int score; //スコア
		//画面内の雨粒数
		private int ame_st;
		private int ame_max;
		private int framecount; //フレームカウント
		
		Stage(){
			this.stagesize = 1000; //ステージ長さ
			this.progress = 0; //進行状況
			this.score = 0; //スコア
			//画面内の雨粒数
			this.ame_st = 7;
			this.ame_max = 7;
			this.framecount = 0;
		}
		int getProgress(){return progress;}
		int getStage(){return stagesize;}
		int getScore(){return score;}
		int getAmest(){return ame_st;}
		int getAmemax(){return ame_max;}
		int getFramecount(){return framecount;}
		
		void incProgress(){
			progress++;
		}
		
		void incScore(){
			score++;
		}
		
		boolean StageEnd(){
			if(progress > stagesize){
				return true;
			}
			return false;
		}
		
		void count_up(){
			framecount++;
		}
	}
	
	class Sqer {
		private int x;
		private int y;
		private int w;
		private int h;
		
		Sqer(int sq_x, int sq_y, int sq_w, int sq_h){
			this.x = sq_x;
			this.y = sq_y;
			this.w = sq_w;
			this.h = sq_h;
		}
		
		int getX(){return x;}
		int getY(){return y;}
		int getW(){return w;}
		int getH(){return h;}
		int getCX(){
			return (x+w)/2;
		}
		int getCY(){
			return (y+h)/2;
		}
	}
	
	public void run(){
		Graphics g = getGraphics();
		int scene = 1; //シーン情報
		
		//ゲームグラフィック
		Sprite title = new Sprite(im_title, 250, 250);
		Sprite p = new Sprite(im_Player, 50, 50);
		Sqer p_cl = new Sqer(16, 4, 18, 19);
		p.defineCollisionRectangle(p_cl.getX(), p_cl.getY(), p_cl.getW(), p_cl.getH());
		Sprite bg = new Sprite(im_bg);
		Sprite gover = new Sprite(im_gover);
		//ステージ生成
		Stage s = new Stage();
		//配列変数
		Object_Ame[] ame = new Object_Ame[s.getAmemax()];
		Sprite[] am = new Sprite[s.getAmemax()];
		Sqer am_cl = new Sqer(2,11,12,12);
		for(int i = 0; i < s.getAmemax(); i++){
			am[i] = new Sprite(im_ame);
			am[i].defineCollisionRectangle(am_cl.getX(), am_cl.getY(), am_cl.getW(), am_cl.getH());
		}
		//プレイヤー生成
		Object_Player player = new Object_Player();
		//ゲージ用変数設定
		Sqer g1 = new Sqer(display_width - display_width/10, display_height/10, display_width/25, (display_width * 3)/5);
		
		//Font
		Font largefont;
		Font font;
		largefont = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN,Font.SIZE_LARGE);
		font = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN,Font.SIZE_MEDIUM);
		
		int clear = 0; //クリア回数
		int high_score = 0; //ハイスコア
		
		int keyState = 0; //キー情報
		flag = true;
		
		while(flag){
			//画面の初期化
			g.setColor(255,255,255);
			g.fillRect(0,0,display_width,display_height);
			
			//ボタン操作取得
			keyState = getKeyStates();
			
			switch(scene){
			case 0: //init
				player = new Object_Player();
				s = new Stage();
				//配列初期化
				ame = new Object_Ame[s.getAmemax()];
				//コマンド初期化
				keyCommand = "";
				
				scene = 1;
				break;
			case 1: //タイトル画面
				//スタートキーが押された
				if((FIRE_PRESSED &keyState) != 0){
					scene = 2;
					//BGMスタート
					try{
						sndBGM.start();
						sndBGM.setMediaTime(0); //最初から再生します
					}catch (Exception e) {
						e.printStackTrace();
					}
				}
				
				//操作説明キーが押された
				if(inst_flag == true){
					scene = 5;
				}
				
				drawTitle(g, font, largefont, title, high_score, clear);
				
				break;
			case 2: //ゲームループ
				
				//ボタン進行判定
				player.PlayerControl(FIRE_PRESSED &keyState);
				//移動制限
				player.spacehit();
				//当たり判定
				GameisHit(ame, am, player, p, s, am_cl, p_cl, s.getAmest());
				//無敵継続処理
				player.inv_check();
				//進行増加
				s.incProgress();
				s.count_up();
				
				//終了判定
				if(s.StageEnd()){
					scene = 4;
					try{  
						sndBGM.stop();
					}catch (Exception e) {
						e.printStackTrace();
					}
				}else if(player.getlife() <= 0){
					scene = 3;
					try{  
						sndBGM.stop();
					}catch (Exception e) {
						e.printStackTrace();
					}
				}
				
				//隠しコマンド
				if(keyCommand.equals("6109")){
					player.setinv_f(1);
				}else if(keyCommand.equals("37564")){
					player.lifedown();
				}
				
				//描画
				drawGameBackground(g, bg);
				drawGamePlayer(g, player, p, s.getFramecount());
				drawGameMoveObj(g, ame, am, s.getAmest());
				drawGameUI(g, font, largefont, s.getScore(), player.getlife(), player.getclose(), s, g1);
				
				break;
			case 3: //ゲームオーバー画面
				//BGM
				try{
					goverBGM.start();
				}catch (Exception e) {
					e.printStackTrace();
				}
				
				//スコアを更新
				if(s.getScore() > high_score){
					high_score = s.getScore();
				}
				
				//描画
				drawGameOver(g, font, gover, s.getScore());
				
				try {
				Thread.sleep(500);
				} catch (Exception e){
				}
				
				if((FIRE_PRESSED &keyState) != 0){
					scene = 0;
					try{
						goverBGM.stop();
						goverBGM.setMediaTime(0);
					}catch (Exception e) {
						e.printStackTrace();
					}
				}
				
				break;
			case 4: //クリア画面
				//スコアを更新
				if(s.getScore() > high_score){
					high_score = s.getScore();
				}
				//描画
				drawClearStage(g, font, s.getScore(), player.getlife(), bg);
				
				try {
				Thread.sleep(1000);
				} catch (Exception e){
				}
				
				if((FIRE_PRESSED &keyState) != 0){
					scene = 0;
					clear++;
				}
				
				break;
			case 5: //操作説明
				if(inst_flag == false){
					scene = 1;
				}
				//描画
				Instraction(g, font);
				
				break;
			}
			//画面に反映
			flushGraphics();
			
			//スリープ
			try {
				Thread.sleep(100);
			} catch (Exception e){
			}
		}
		
		//アプリ終了通知
		Teruteru.midlet.notifyDestroyed();
	}
	
	public void keyPressed(int keyCode) {
		if (keyCode==0){
			return;
		}
		
		switch(keyCode) {
			//数字キー・記号キー
			case KEY_NUM0: keyCommand+="0";break;
			case KEY_NUM1: keyCommand+="1";break;
			case KEY_NUM2: keyCommand+="2";break;
			case KEY_NUM3: keyCommand+="3";break;
			case KEY_NUM4: keyCommand+="4";break;
			case KEY_NUM5: keyCommand+="5";break;
			case KEY_NUM6: keyCommand+="6";break;
			case KEY_NUM7: keyCommand+="7";break;
			case KEY_NUM8: keyCommand+="8";break;
			case KEY_NUM9: keyCommand+="9";break;
			case KEY_STAR: keyCommand ="";break;
		}
	}
	public void GameisHit(Object_Ame[] ame, Sprite[] am, Object_Player player, Sprite p, Stage s, Sqer am_cl, Sqer p_cl, int ame_st){
		//接近変数
		int px2=0;
		int px1=0;
		int py2=0;
		int py1=0;
		int r = 40;
		int close_count = 0;
		//オブジェクト処理
		for(int i = 0; i < ame_st; i++){
			//オブジェクト生成
			if(ame[i] == null || ame[i].getState() == false){
				ame[i] = new Object_Ame();
			}else{
				//オブジェクト移動
				ame[i].MoveAme();
			}
			//範囲外に出たときの処置
			if(ame[i].getY() > display_height){
				ame[i].deadState();
			}
			//衝突判定
			if(player.getinv_f() == 0){ //無敵でないとき
				if(ame[i].getState() & p.collidesWith(am[i], true)){ //AmeがDeadでない&衝突している
					//SE再生
					try{
						damageSE.start();
						damageSE.setMediaTime(0); //最初から再生します
					}catch (Exception e) {
						e.printStackTrace();
					}
					player.lifedown();
					ame[i].deadState();
					player.setinv_f(1);
					break;
				}
				//かすり判定
				px2 = am[i].getX() + am_cl.getCX() -r/2;
				py2 = am[i].getY() + am_cl.getCY() -r/2;
				px1 = player.getX() + p_cl.getCX() -r/3;
				py1 = player.getY() + p_cl.getCY() -r/2;
				
				if(Math.abs(px2 - px1) * Math.abs(px2 - px1) + Math.abs(py2 - py1) * Math.abs(py2 - py1) < r*r){
					//接近スコア加算
					try{
						scoreSE.start();
					}catch (Exception e) {
						e.printStackTrace();
					}
					close_count++; //接近カウント
					s.incScore();
				}
			}
		}
		
		//1つ以上と接近でフラグON
		if(close_count > 0){
			player.setclose(true);
		}else{
			player.setclose(false);
		}
	}
	
	public void drawGameBackground(Graphics g, Sprite bg){
		//背景
		bg.setFrame(0);
		bg.setPosition(0, 0);
		bg.paint(g);
	}
	public void drawGamePlayer(Graphics g, Object_Player player, Sprite p, int framecount){
		//プレイヤーキャラ
		if(player.getdir() == 1){
			p.setTransform(2);
			p.setFrame(1);
		}else if(player.getdir() == -1){
			p.setTransform(0);
			p.setFrame(1);
		}else{
			p.setFrame(0);
		}
		
		//点滅演出
		if(player.isinv()){
			if(player.switchvisflag()==0){
				p.setVisible(false);
			}else{
				p.setVisible(true);
			}
		}else{
			p.setVisible(true);
		}
		
		//プレイヤー描画
		int p_x = player.getX();
		int p_y = player.getY();
		p.setPosition(p_x, p_y);
		p.paint(g);
	}
	public void drawGameMoveObj(Graphics g, Object_Ame[] ame, Sprite[] am, int ame_st){
		//障害物オブジェクト
		for(int i = 0; i < ame_st; i++){
			int am_x = ame[i].getX();
			int am_y = ame[i].getY();
			am[i].setPosition(am_x, am_y);
			am[i].paint(g);
		}
	}
	
	public void drawGameUI(Graphics g, Font font, Font largefont, int score, int life, boolean close, Stage s, Sqer g1){
		//進行ゲージ描画
		int x1 = g1.getX();
		int y1 = g1.getY();
		int w1 = g1.getW();
		int h1 = g1.getH();
		int progress = s.getProgress();
		int stage = s.getStage();
		g.setColor(0,0,0); //影
		g.drawRect(x1, y1, w1, h1);
		g.setColor(255,0,0); //実ゲージ
		g.fillRect(x1, y1, w1, h1);
		int gh_f = (int)((double)(1-((double) progress / stage)) * 100 * ((double)h1 / 100));
		g.setColor(0,128,128); //減る部分
		g.fillRect(x1 + 1, y1 + 1, w1 - 2, gh_f - 2);
		
		//スコア表示描画
		g.setColor(0,0,0);
		g.setFont(largefont);
		g.drawString("ENERGY:" + score, 0, 0, g.LEFT | g.TOP);
		
		//接近演出
		if(close){
			g.setColor(255,0,0);
			g.drawString("+ENERGY", 70, (s.getFramecount() % 3), g.LEFT | g.TOP);
		}
		
		//ライフ表示描画
		g.setColor(255,0,0);
		g.setFont(font);
		for(int i = 0; i < life; i++){
			g.drawString("●", 0 + (i * 14), 25, g.LEFT | g.TOP);
		}
	}
	
	public void drawTitle(Graphics g, Font font, Font largefont, Sprite title, int high_score, int clear){
		//描画
		title.setFrame(0);
		title.setPosition(0, 0);
		title.paint(g);
		
		title.setPosition(0, 0);
		if(clear >= 3){
			title.setFrame(3);
			title.paint(g);
		}else if(clear >= 2){
			title.setFrame(1);
			title.paint(g);
			title.setFrame(2);
			title.paint(g);
		}else if(clear >= 1){
			title.setFrame(1);
			title.paint(g);
		}
		
		g.setColor(0,0,0);
		g.setFont(largefont);
		g.drawString("HI SCORE:" + high_score, 0, 0, g.LEFT | g.TOP);
		g.drawString("PRESS START", display_width/3, display_height*4/5, g.LEFT | g.BOTTOM);
		g.setFont(font);
		g.drawString("★"+keyCommand, 0, display_height - 35, g.LEFT | g.TOP);
		g.drawString("(c) sui-kiki", 0, display_height, g.LEFT | g.BOTTOM);
	}
	
	public void drawGameOver(Graphics g, Font font, Sprite gover, int score){
		//描画
		g.setColor(0,0,0);
		g.fillRect(0,0,display_width,display_height);
		gover.setFrame(0);
		gover.setPosition(0, 0);
		gover.paint(g);
		
		g.setColor(255,255,255);
		g.setFont(font);
		g.drawString("Game Over", display_width/5, display_height*3/5+5, g.LEFT | g.TOP);
		g.drawString("Stage Score(ENERGY):" + score, display_width/5, display_height*3/5 + 20, g.LEFT | g.TOP);
		g.drawString("Restart PRESS BUTTON", display_width/3, display_height, g.LEFT | g.BOTTOM);
	}
	
	public void drawClearStage(Graphics g, Font font, int score, int life, Sprite bg){
		drawGameBackground(g, bg);
		g.setColor(255,0,0);
		g.setFont(font);
		g.drawString("Game Clear!!", display_width/4, display_height/2 - 10, g.LEFT | g.TOP);
		g.setColor(0,0,0);
		g.drawString("Stage Score(ENERGY):" + score, display_width/4, display_height/2 + 15, g.LEFT | g.TOP);
		g.drawString("Life Bonus(Life*50):" + life * 50, display_width/4, display_height/2 + 30, g.LEFT | g.TOP);
		g.drawString("Final Score:" + score + (life * 50), display_width/4, display_height/2 + 45, g.LEFT | g.TOP);
		g.drawString("Restart PRESS BUTTON", display_width/4, display_height*4/5, g.LEFT | g.TOP);
	}
	
	public void Instraction(Graphics g, Font font){
		//操作説明
		g.setFont(font);
		g.setColor(200,200,0);
		g.drawString("★操作方法★", 0, 0, g.LEFT | g.TOP);
		g.setColor(0,0,0);
		g.drawString("中央キーで右方向に移動し、", 0, 15, g.LEFT | g.TOP);
		g.drawString("離すと元の位置に戻っていきます。", 0, 30, g.LEFT | g.TOP);
		g.setColor(200,200,0);
		g.drawString("★得点の増やし方★", 0, display_height/5, g.LEFT | g.TOP);
		g.setColor(0,0,0);
		g.drawString("雨粒に近づくとエネルギーを吸収し、", 0, display_height/5+15, g.LEFT | g.TOP);
		g.drawString("スコアが増加します。", 0, display_height/5+30, g.LEFT | g.TOP);
		g.setColor(200,200,0);
		g.drawString("★隠しコマンド★", 0, display_height*2/5, g.LEFT | g.TOP);
		g.setColor(0,0,0);
		g.drawString("いろいろためそう", 0, display_height*2/5+15, g.LEFT | g.TOP);
		g.setColor(200,200,0);
		g.drawString("★クリア回数によって", 0, display_height*3/5, g.LEFT | g.TOP);
		g.drawString(" タイトルイラストが変化します★", 0, display_height*3/5+15, g.LEFT | g.TOP);
		g.setColor(200,200,0);
		g.drawString("★使用した素材★", 0, display_height*4/5 , g.LEFT | g.TOP);
		g.setColor(0,0,0);
		g.drawString("BGM:音楽研究所", 0, display_height*4/5+15 , g.LEFT | g.TOP);
		g.drawString("SE:TAM Music Factory", 0, display_height*4/5+30 , g.LEFT | g.TOP);
	}
	
	//キーリリースイベント
	public void keyReleased(int keyCode) {}
	
	public void commandAction(Command c, Displayable d) {
		if (c == exit) {
			flag=false;
		}else if(c == inst){
			//ボタン情報を送信
			inst_flag = !inst_flag;
		}
	}
}