겔러그 형태의 간단한 슈팅 게임입니다~
아군기가 적기를 공격하면 아이템이 나오는데요~
아이템은 크게 두종류 입니다~
아군기가 먹으면 득이 되는 아이템(Bonus.java) 과 아군기가 먹으면 아군기가 파괴되는 아이템(Conuss.java)입니다~
일단 허접한 실력으로 제가 소스는 구현해 봤는데요~~
지금 빌드해서 실행시키면 실행은 되는데요~
적기를 맞추어서 아이템이 나오자마자 게임에서 튕겨 버립니다ㅜㅠ
고수님들 조언좀 부탁드려요ㅠㅜ
Bonus.java, Conuss.java 는 아이템 클래스구요~
Colliusion.java는 충돌 클래스 입니다~
MyGameView.java 가 화면 쏘는 클래스구요~
아래 Colliusion.java 소스에서 랜덤으로 아이템 생성되는 코드가 틀린것 같은데요~(붉은 색으로 표시 했습니다~)
제가 잘 몰라서요...ㅠㅜ 한가지 아이템 일때는 랜덤 사용해서 구현이 되는데요~
두가지 아이템을 랜덤하게 나오게 하려니까~ 아이템 생성되면서 튕기는것 같습니다~
로그켓 봐도 그 부분이 틀렸다 나오구요~
logcat 메시지도 캡쳐해서 파일 올립니다~~ 도와주십쇼~~
collision.java 소스코드
package com.StarWars;
import java.util.Random;
//----------------------------
// 충돌 판정 - 생성자 없음
//----------------------------
public class Collision {
private Random rnd = new Random();
//----------------------------
// 충돌 판정
//----------------------------
public void CheckCollision() {
Check_1(); // 아군 미사일과 적과의 충돌
Check_2(); // 적 미사일과 아군과의 충돌
Check_3(); // 적군과 아군과의 충돌
Check_4(); // 아군과 보너스와의 충돌
Check_5(); // 아군과 보너스2와의 충돌
if (MyGameView.isBoss) { // Boss Stage
Check_6(); // Boss 미사일과 아군과의 충돌
Check_7(); // 아군 미사일과 보스와의 충돌
}
}
//----------------------------
// 아군 미사일과 적 충돌
//----------------------------
private void Check_1() {
int x, y, x1, y1, w, h;
int r = rnd.nextInt (30) - 20; // 0~19 - Bonus 나올 확률 -----------> 이부분을 어떻게 처리해야 할까요??ㅜㅠ
int d = rnd.nextInt (30) - 19; // 0~19 - Conuss 나올 확률 ----------->
NEXT:
for (int p = MyGameView.mGun.size() - 1; p >= 0; p--) {
x = MyGameView.mGun.get(p).x; // 미사일 좌표
y = MyGameView.mGun.get(p).y;
for (int i = 0; i < 6; i++) { // 모든 적군에 대해 조사
for (int j = 0; j < 8; j++) {
if (MyGameView.mEnemy[i][j].isDead) continue; // 사망자 무시
x1 = MyGameView.mEnemy[i][j].x; // 적군의 좌표
y1 = MyGameView.mEnemy[i][j].y;
w = MyGameView.mEnemy[i][j].w; // 충돌을 조사할 범위
h = MyGameView.mEnemy[i][j].h;
if (Math.abs(x - x1) > w || Math.abs(y - y1) > h) // 충돌 없음
continue;
if (MyGameView.isPower) // 강화 미사일은
MyGameView.mEnemy[i][j].shield -= 4; // 보호막 4씩 감소
else
MyGameView.mEnemy[i][j].shield--; // 일반 미사일
if (MyGameView.mEnemy[i][j].shield > 0) { // 보호막이 있으면
// 작은 폭발은 미사일 위치에
MyGameView.mExp.add(new Explosion(x, y, Explosion.SMALL));
MyGameView.score += (6 - i) * 100; // 득점은 절반
} else {
MyGameView.mEnemy[i][j].isDead = true; // 적군 사망
MyGameView.mMap.enemyCnt--; // 남은 적군 수
// 큰 폭발은 적군의 중심부에
MyGameView.mExp.add(new Explosion(x1, y1, Explosion.BIG));
MyGameView.score += (6 - i) * 200; // 득점
if (r > 0) // 보너스가 있나?
MyGameView.mBonus.add(new Bonus(x1, y1, r)); // 보너스 --------------------> 이부분도 어떻게 해야할지...ㅜㅠ
else if (d > 0) // 보너스가 있나?
MyGameView.mConuss.add(new Conuss(x1, y1, d)); // 보너스
}
MyGameView.mGun.remove(p); // 아군 미사일 제거
continue NEXT;
} // for j
} // for i
} // for p
}
//----------------------------
// 적군 미사일과 아군기 충돌
//----------------------------
private void Check_2() {
if (MyGameView.mShip.undead || MyGameView.mShip.isDead) return;
int x, y, x1, y1, w, h;
x = MyGameView.mShip.x; // 아군기 좌표
y = MyGameView.mShip.y;
w = MyGameView.mShip.w;
h = MyGameView.mShip.h;
// 모든 적 미사일에 대해 조사
for (int i = MyGameView.mMissile.size() - 1; i >= 0; i--) {
x1 = MyGameView.mMissile.get(i).x; // 미사일 좌표
y1 = MyGameView.mMissile.get(i).y;
if (Math.abs(x1 - x) > w || Math.abs(y1 - y) > h) // 충돌 없음
continue;
MyGameView.mMissile.remove(i); // 적 미사일 제거
MyGameView.mShip.shield--; // 아군 보호막 감소
if (MyGameView.mShip.shield >= 0) { // 보호막 남아 있으면
MyGameView.mExp.add(new Explosion(x1, y1, Explosion.SMALL)); // 작은 불꽃
} else { // 보호막 없으면
MyGameView.mShip.isDead = true; // 아군기를 잃음
MyGameView.shipCnt--; // 아군기를 잃음
MyGameView.mExp.add(new Explosion(x, y, Explosion.MYSHIP)); // 큰 불꽃
} // if
break;
} // for
}
//----------------------------
// 아군기와 적기와의 충돌
//----------------------------
private void Check_3() {
if (MyGameView.mShip.isDead) return;
int x, y, x1, y1, w, h;
x = MyGameView.mShip.x; // 아군기 좌표
y = MyGameView.mShip.y;
w = MyGameView.mShip.w;
h = MyGameView.mShip.h;
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 8; j++) {
if (MyGameView.mEnemy[i][j].isDead) continue; // 사망자 무시
x1 = MyGameView.mEnemy[i][j].x;
y1 = MyGameView.mEnemy[i][j].y;
if (Math.abs(x1 - x) > w || Math.abs(y1 - y) > h) // 충돌 없음
continue;
MyGameView.mEnemy[i][j].isDead = true; // 충돌이면 적군도 사망
MyGameView.mMap.enemyCnt--; // 남은 적군 수
MyGameView.score += (6 - i) * 200; // 자폭도 점수 인정
if (MyGameView.mShip.undead) {
MyGameView.mExp.add(new Explosion(x1, y1, Explosion.BIG)); // 적군만 사망
} else {
MyGameView.mShip.isDead = true; // 아군기를 잃음
MyGameView.shipCnt--; // 아군기도 함께 잃음
MyGameView.mExp.add(new Explosion(x, y, Explosion.MYSHIP)); // 아군 파괴 불꽃
}
return;
} // for j
} // for i
}
//----------------------------
// 아군기와 보너스와 충돌
//----------------------------
private void Check_4() {
int x, y, x1, y1, w, h, bonus = 0;
x = MyGameView.mShip.x; // 아군기 좌표
y = MyGameView.mShip.y;
w = MyGameView.mShip.w;
h = MyGameView.mShip.h;
for (int i = MyGameView.mBonus.size() - 1; i >= 0; i--) {
x1 = MyGameView.mBonus.get(i).x; // 보너스 좌표
y1 = MyGameView.mBonus.get(i).y;
if (Math.abs(x - x1) > w * 2 || Math.abs(y - y1) > h * 2) // 충돌 없음
continue;
bonus = MyGameView.mBonus.get(i).kind; // 보너스 종류
MyGameView.mBonus.remove(i); // 보너스 제거
switch (bonus) {
case 1:
MyGameView.isDouble = true; // Double Fire 모드
MyGameView.mShip.undeadCnt = 500; // 무적 모드로 변신
MyGameView.mShip.undead = true;
break;
case 2:
if (MyGameView.gunDelay > 6)
MyGameView.gunDelay -= 2; // 미사일 발사 속도
MyGameView.mShip.undeadCnt = 500; // 무적 모드로 변신
MyGameView.mShip.undead = true;
break;
case 3:
MyGameView.mShip.undeadCnt = 800; // 무적 모드로 변신
MyGameView.mShip.undead = true;
break;
case 4:
MyGameView.mShip.undeadCnt = 800; // 무적 모드로 변신
MyGameView.mShip.undead = true;
break;
case 5:
if (MyGameView.shipCnt < 3) // 우주선 1대 늘려줌
MyGameView.shipCnt++;
MyGameView.mShip.undeadCnt = 500; // 무적 모드로 변신
MyGameView.mShip.undead = true;
break;
case 6:
MyGameView.score += (6 - i) * 400; // 100점 획득
MyGameView.mShip.undeadCnt = 500; // 무적 모드로 변신
MyGameView.mShip.undead = true;
break;
case 7:
MyGameView.score += (6 - i) * 400; // 400점 획득
MyGameView.mShip.undeadCnt = 500; // 무적 모드로 변신
MyGameView.mShip.undead = true;
break;
case 8:
MyGameView.score += (6 - i) * 400; // 400점 획득
MyGameView.mShip.undeadCnt = 500; // 무적 모드로 변신
MyGameView.mShip.undead = true;
break;
case 9:
MyGameView.score += (6 - i) * 400; // 400점 획득
MyGameView.mShip.undeadCnt = 500; // 무적 모드로 변신
MyGameView.mShip.undead = true;
}
} // for
}
//----------------------------
// 아군기와 보너스2와 충돌
//----------------------------
private void Check_5() {
int x, y, x1, y1, w, h, conuss = 0;
x = MyGameView.mShip.x; // 아군기 좌표
y = MyGameView.mShip.y;
w = MyGameView.mShip.w;
h = MyGameView.mShip.h;
for (int i = MyGameView.mConuss.size() - 1; i >= 0; i--) {
x1 = MyGameView.mConuss.get(i).x; // 보너스 좌표
y1 = MyGameView.mConuss.get(i).y;
if (Math.abs(x - x1) > w * 2 || Math.abs(y - y1) > h * 2) // 충돌 없음
continue;
conuss = MyGameView.mConuss.get(i).kind; // 보너스 종류
MyGameView.mConuss.remove(i); // 보너스 제거
switch (conuss) {
case 1:
MyGameView.mShip.isDead = true; // 아군기를 잃음
MyGameView.mExp.add(new Explosion(x, y, Explosion.MYSHIP));
MyGameView.shipCnt--;
break;
case 2:
MyGameView.mShip.isDead = true; // 아군기를 잃음
MyGameView.mExp.add(new Explosion(x, y, Explosion.MYSHIP));
MyGameView.shipCnt--;
break;
case 3:
MyGameView.mShip.isDead = true; // 아군기를 잃음
MyGameView.mExp.add(new Explosion(x, y, Explosion.MYSHIP));
MyGameView.shipCnt--;
break;
case 4:
MyGameView.mShip.isDead = true; // 아군기를 잃음
MyGameView.mExp.add(new Explosion(x, y, Explosion.MYSHIP));
MyGameView.shipCnt--;
break;
case 5:
MyGameView.mShip.isDead = true; // 아군기를 잃음
MyGameView.mExp.add(new Explosion(x, y, Explosion.MYSHIP));
MyGameView.shipCnt--;
break;
case 6:
MyGameView.mShip.isDead = true; // 아군기를 잃음
MyGameView.mExp.add(new Explosion(x, y, Explosion.MYSHIP));
MyGameView.shipCnt--;
break;
case 7:
MyGameView.mShip.isDead = true; // 아군기를 잃음
MyGameView.mExp.add(new Explosion(x, y, Explosion.MYSHIP));
MyGameView.shipCnt--;
break;
case 8:
MyGameView.mShip.isDead = true; // 아군기를 잃음
MyGameView.mExp.add(new Explosion(x, y, Explosion.MYSHIP));
MyGameView.shipCnt--;
break;
case 9:
MyGameView.mShip.isDead = true; // 아군기를 잃음
MyGameView.mExp.add(new Explosion(x, y, Explosion.MYSHIP));
MyGameView.shipCnt--;
break;
case 10:
MyGameView.mShip.isDead = true; // 아군기를 잃음
MyGameView.mExp.add(new Explosion(x, y, Explosion.MYSHIP));
MyGameView.shipCnt--;
}
} // for
}
//----------------------------
// Boss 미사일과 아군과와 충돌
//----------------------------
private void Check_6() {
if (MyGameView.mShip.undead) return;
int x, y, x1, y1;
int w, h;
x = MyGameView.mShip.x;
y = MyGameView.mShip.y;
w = MyGameView.mShip.w;
h = MyGameView.mShip.h;
for (int i = MyGameView.mBsMissile.size() - 1; i >= 0; i--) {
x1 = MyGameView.mBsMissile.get(i).x; // 미사일 좌표
y1 = MyGameView.mBsMissile.get(i).y;
if (Math.abs(x1 - x) <= w && Math.abs(y1 - y) <= h) {
MyGameView.mBsMissile.remove(i); // 적 미사일 제거
MyGameView.mShip.isDead = true; // 아군기를 잃음
MyGameView.mExp.add(new Explosion(x, y, Explosion.MYSHIP));
MyGameView.shipCnt--;
}
}
}
//----------------------------
// 아군 미사일과 Boss와 충돌
//----------------------------
private void Check_7() {
int x1, x2, x3, y1, w, h; // Boss의 Center, Left, Right, 폭
int x, y, damage = 1; // 미사일 좌표, power
if (MyGameView.isPower) damage = 4;
// Boss 3부분 좌표와 폭
w = MyGameView.mBoss.w / 2;
h = MyGameView.mBoss.h;
x1 = MyGameView.mBoss.x;
x2 = x1 - w;
x3 = x1 + w;
y1 = MyGameView.mBoss.y;
for (int i = MyGameView.mGun.size() - 1; i >= 0; i--) {
x = MyGameView.mGun.get(i).x; // 미사일 좌표
y = MyGameView.mGun.get(i).y;
// Boss Center
if (Math.abs(x - x1) < w && Math.abs(y - y1) < h ) {
MyGameView.mBoss.shield[EnemyBoss.CENTER] -= damage;
MyGameView.mGun.remove(i);
// 방어막이 (-)가 될때까지 처리 - Explosion에서 CENTER값 참조함
if (MyGameView.mBoss.shield[EnemyBoss.CENTER] >= 0) {
MyGameView.mExp.add(new Explosion(x, y, Explosion.SMALL));
MyGameView.score += 50;
continue;
}
ClearAllEnemies();
return;
} // if
// 보스의 왼쪽
if (Math.abs(x - x2) < w && Math.abs(y - y1) < h &&
MyGameView.mBoss.shield[EnemyBoss.LEFT] > 0) {
MyGameView.mBoss.shield[1] -= damage;
MyGameView.mGun.remove(i);
if (MyGameView.mBoss.shield[EnemyBoss.LEFT] > 0) {
MyGameView.mExp.add(new Explosion(x, y, Explosion.SMALL));
MyGameView.score += 50;
continue;
}
// Boss 왼쪽 파괴
MyGameView.mExp.add(new Explosion(x2, y1, Explosion.BIG));
MyGameView.score += 1000;
MyGameView.mGun.remove(i);
if (MyGameView.mBoss.shield[EnemyBoss.RIGHT] > 0)
MyGameView.mBoss.imgBoss = MyGameView.mBoss.imgSpt[EnemyBoss.RIGHT];
else
MyGameView.mBoss.imgBoss = MyGameView.mBoss.imgSpt[EnemyBoss.CENTER];
continue;
} // if
// 보스의 오른쪽
if (Math.abs(x - x3) < w && Math.abs(y - y1) < h &&
MyGameView.mBoss.shield[EnemyBoss.RIGHT] > 0) {
MyGameView.mBoss.shield[EnemyBoss.RIGHT] -= damage;
MyGameView.mGun.remove(i);
if (MyGameView.mBoss.shield[EnemyBoss.RIGHT] > 0) {
MyGameView.mExp.add(new Explosion(x, y, Explosion.SMALL));
MyGameView.score += 50;
continue;
}
// Boss 오른쪽 파괴
MyGameView.mExp.add(new Explosion(x3, y1, Explosion.BIG));
MyGameView.score += 1000;
MyGameView.mGun.remove(i);
if (MyGameView.mBoss.shield[EnemyBoss.LEFT] > 0)
MyGameView.mBoss.imgBoss = MyGameView.mBoss.imgSpt[EnemyBoss.LEFT];
else
MyGameView.mBoss.imgBoss = MyGameView.mBoss.imgSpt[EnemyBoss.CENTER];
} // if
} // for
}
//----------------------------
// 모든 적 파괴
//----------------------------
private void ClearAllEnemies() {
int x1, x2, x3, y1, w; // Boss의 Center, Left, Right, 폭
w = MyGameView.mBoss.w / 2;
x1 = MyGameView.mBoss.x;
x2 = x1 - w;
x3 = x1 + w;
y1 = MyGameView.mBoss.y;
// Boss 파괴
MyGameView.mExp.add(new Explosion(x1, y1, Explosion.BOSS));
MyGameView.score += 5000;
// 왼쪽 파괴
if (MyGameView.mBoss.shield[EnemyBoss.LEFT] > 0) {
MyGameView.mBoss.shield[EnemyBoss.LEFT] = 0;
MyGameView.mExp.add(new Explosion(x2, y1, Explosion.BOSS));
}
// 오른쪽 파괴
if (MyGameView.mBoss.shield[EnemyBoss.RIGHT] > 0) {
MyGameView.mBoss.shield[EnemyBoss.RIGHT] = 0;
MyGameView.mExp.add(new Explosion(x3, y1, Explosion.BOSS));
}
// Boss Missile 모두 제거
for (BossMissile tmp : MyGameView.mBsMissile) {
MyGameView.mExp.add(new Explosion(tmp.x, tmp.y, Explosion.BIG));
}
MyGameView.mBsMissile.clear();
// 화면에 남은 적 모두 제거
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 8; j++) {
if (MyGameView.mEnemy[i][j].shield > 0) {
x1 = MyGameView.mEnemy[i][j].x;
y1 = MyGameView.mEnemy[i][j].y;
MyGameView.mExp.add(new Explosion(x1, y1, Explosion.BIG));
MyGameView.mEnemy[i][j].shield = 0;
MyGameView.mMap.enemyCnt--; // 남은 적군 수
}
}
} // for
//Stage Clear는 Explosion에서 처리함
}
}
ArrayIndexOutOfBoundException 이네요.
보니까 Conuss.java 39줄인데 39줄이
for (int i = 1; i < 16; i++) {
imgTemp[i] = Bitmap.createBitmap(sw, sh, Config.ARGB_8888);
canvas.setBitmap(imgTemp[i]);
canvas.drawBitmap(imgTemp[0], 0, 0, null);
}
이부분이 맞는지요
맞다면 imgTemp[] 배열을 사용하실때 범위를 벗어나신것같으신데 for문안에
Log.d 를 다시 찍어보심이 'ㅡ'
로그캣을보건데 아이템생성이 아니라 충돌하고나서 다시 충돌체크하려고할때 에러나는거같은데요?