Android環境におけるシューティングゲームについて質問です。
プログラミング歴は一年にも満たない初心者です。
現在、大学でAndroidアプリの開発をしており
私自身、四聖龍神禄のようなシューティングゲームを
Androidで開発しようと躍起になっているのですが、
自機の弾の描画が上手くいかなくて苦しんでおります。
私自身は何の入力をしていなくても、自機から前方向(上方向)に
連続的な弾が描画されるプログラムを作成したいのですが、
このプログラムでは、弾が勝手に前方向に進んでしまい、
更に弾が重なって?しまいます。
どのようにすれば等間隔な連続的な弾が描画されるのか
また、なにもしなくても弾が描画されるようになるのか教えて下さい。
一週間くらい悩んでいるのですが、一向に解決の糸口がつかめません。
どうかご教授お願いします!!!
HyperMotion2D.java
package com.hypermotion2d;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import com.roxiga.hypermotion2d.Sprite2D;
import android.content.Context;
import android.media.MediaPlayer;
import android.opengl.GLSurfaceView;
import android.view.SurfaceHolder;
public class HyperMotion2D implements GLSurfaceView.Renderer {
//コンテキスト
private Context _context;
//高さ、幅
public int _width,_height;
//タッチしたのかを識別
public boolean _touch;
//タッチしたかの識別
//弾を発射するかどうか
public boolean _touchEvent = false;
//現在押している座標
private float _xPos,_yPos;
public boolean[] _flagOneBullet = new boolean[20];
//create
private Sprite2D _title = new Sprite2D();
private Sprite2D _earth = new Sprite2D();
//画面制御
//0 タイトル
//1 メイン画面
//2 ゲームオーバー
//3 シナリオ画面
public static final int GS_TITLE = 0;
public static final int GS_MAIN = 1;
public static final int GS_GAMEOVER = 2;
public static final int GS_SCENARIO = 3;
public int _gameState = GS_TITLE;
//キャラクタの高さ
private static final int XY_SIZE = 64;
//キャラクタの移動制御
private float _jitJudgmentX,_jitJudgmentY;
//敵のデータ
private static final int ENEMY_NUM = 8;
private Sprite2D[] _enemy = new Sprite2D[ENEMY_NUM];
private Sprite2D _ship = new Sprite2D();
//長いBGMを再生するときに使うインスタンス
//スタート画面用
private MediaPlayer _mpBGMStart = new MediaPlayer();
//メイン画面用
private MediaPlayer _mpBGMMain = new MediaPlayer();
//自機用の弾幕//最大20
private static final int _oneBulletMax = 20;
private Sprite2D[] _oneBullet = new Sprite2D[_oneBulletMax];
//コンストラクタ
public HyperMotion2D(Context context){
_context = context;
_mpBGMStart = MediaPlayer.create(context,R.raw.startbgm);
_mpBGMMain = MediaPlayer.create(context,R.raw.mainbgm);
}
//フレーム制御
public void onDrawFrame(GL10 gl){
//バッファをクリアにする
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
switch (_gameState){
case GS_TITLE:
//スタート画面に来た時に
_mpBGMStart.start();
_title.draw(gl,getRatio());
break;
case GS_MAIN:
//メインのゲーム画面が来たとき
startBGM();
_earth.draw(gl,getRatio());
enemyDraw01(gl);
charaMove();
for(int i=0;i<_oneBullet.length;i++){
if(_flagOneBullet[i] = true){
_oneBullet[i]._pos._y += 10;
_oneBullet[0].draw(gl);
if(_oneBullet[i]._pos._y < 20){
_flagOneBullet[i] = false;
}
}
}_ship.draw(gl);
break;
case GS_GAMEOVER:
//ゲームオーバになったとき
_earth.draw(gl,getRatio());
enemyDraw01(gl);
enemyMove01();
_ship.draw(gl);
break;
}
}
//メイン画面用のBGM
private void startBGM(){
//BGMを止める
_mpBGMStart.stop();
//メイン画面に来た時にmainbgmを再生
_mpBGMMain.start();
}
//敵の描画
private void enemyDraw01(GL10 gl){
for(int i=0;i<_enemy.length;i++){
_enemy[i].draw(gl);
}
}
//敵の描画
private void enemyMove01(){
for(int i=0;i<_enemy.length;i++){
_enemy[0]._pos._x = (_width-XY_SIZE)/2;
_enemy[0]._pos._y --;
}
}
//画面の比率
private float getRatio(){
return (float)_width/600.0f;
}
//キャラクタの移動制御
private void charaMove(){
//キャラクタの移動制御
if(_ship._pos._x < 0){
_ship._pos._x = 0;
}
else if(_ship._pos._x > _width-XY_SIZE){
_ship._pos._x = _width-XY_SIZE;
}
else if(_ship._pos._y < 0){
_ship._pos._y = 0;
}
else if(_ship._pos._y > _height-XY_SIZE){
_ship._pos._y = _height-XY_SIZE;
}
}
//サーフェス変更
public void onSurfaceChanged(GL10 gl,int width, int height){
}
//サーフェス生成
public void onSurfaceCreated(GL10 gl, EGLConfig config){
//背景色
gl.glClearColor(0.6f,0.8f,1.0f,1.0f);
//ディザを無効か
gl.glDisable(GL10.GL_DITHER);
//深度テストを有効に
gl.glEnable(GL10.GL_DEPTH_TEST);
//テクスチャ機能をON
gl.glEnable(GL10.GL_TEXTURE_2D);
//透明可能
gl.glEnable(GL10.GL_ALPHA_TEST);
//ブレンド可能
gl.glEnable(GL10.GL_BLEND);
//色のブレンド
gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE_MINUS_SRC_ALPHA);
_title.setTexture(gl,_context.getResources(),R.drawable.title);
_title._texWidth = 600;
_title._width = 600;
_earth.setTexture(gl,_context.getResources(),R.drawable.earth);
_earth._texWidth = 600;
_earth._width = 600;
_ship.setTexture(gl,_context.getResources(),R.drawable.ship);
//弾じゃぁぁぁっぁっぁぁぁぁぁぁぁ
for(int i=0;i<_oneBullet.length;i++){
//自機の弾のインスタンスを生成
//インデックスごとにコンストラクタを呼んで生成
_oneBullet[i] = new Sprite2D();
_oneBullet[i].setTexture(gl,_context.getResources(),R.drawable.onebullet);
_oneBullet[i]._pos._x = _xPos;
_oneBullet[i]._pos._y = _yPos;
}
//敵のテクスチャ
for(int i=0;i<_enemy.length;i++){
_enemy[i] = new Sprite2D();
_enemy[i].setTexture(gl,_context.getResources(),R.drawable.enemy);
}
}
//サーフェイス終了時に呼ばれる
public void surfaceDestroyed(SurfaceHolder holder) {
}
//初期状態
public void init(){
for(int i=0;i<_enemy.length;i++){
_enemy[i]._pos._x = (float)Math.random()*(_width-XY_SIZE);
_enemy[i]._pos._y = 500 + i*300+(float)Math.random() * 100;
}
//キャラクタの初期位置
_ship._pos._x = (_width-XY_SIZE)/2;
_ship._pos._y = (_height-XY_SIZE)/4;
}
//onTouchEventより遷移
//タッチした瞬間の行動を制御
public void actionDown(float x,float y){
}
//onTouchEventより遷移
//タッチして、画面を触っている最中の行動を制御
public void actionMove(float x,float y){
_jitJudgmentX = x - _ship._pos._x;
_jitJudgmentY = y - _ship._pos._y;
//当たり判定 /円の当たり判定を作成
float _hitJudgment = _jitJudgmentX * _jitJudgmentX + _jitJudgmentY * _jitJudgmentY;
//当たり判定の距離
float _radius = 100*100;
switch (_gameState){
case GS_MAIN:
if(_hitJudgment <= _radius){
_ship._pos._x = (int)x;
_ship._pos._y = (int)y;
for(int i=0;i<_oneBullet.length;i++){
_oneBullet[i]._pos._x = (int)x;
_oneBullet[i]._pos._y = (int)y;
}
}
break;
}
}
//onTouchEventより遷移
//タッチを離した時の行動を制御
public void actionUp(float x,float y){
switch ( _gameState ){
case GS_TITLE:
init();
_gameState = GS_MAIN;
break;
case GS_MAIN:
break;
case GS_GAMEOVER:
_gameState = GS_TITLE;
break;
}
}
}