안녕하세요~ 두결입니다.
지난시간에는 팝업창에 현재 게임단계 및 성공메세지를 표시하고, 팝업화면 닫기 버튼 및 다음단계 이동버튼까지 추가해보았습니다.
이번시간에는
그림짝맞추기 2단계를 구현해보도록 하겠습니다.
▣ 2단계 초기화하기
먼저, 2단계 초기화 부터 해보겠습니다.
// 새게임 시작
private void NewGame()
{
InitImageArray(); //초기화
}
새게임하면 InitImageArray() 초기화 함수를 호출하였습니다.
// 리소스의 이미지ID를 배열에 초기화 해주는 함수
private void InitImageArray()
{
nArrImageID = new int[MAX_IMAGECOUNT];
nArrImageID[0] = R.drawable.imagepair_01; nArrImageID[1] = R.drawable.imagepair_02;
nArrImageID[2] = R.drawable.imagepair_03; nArrImageID[3] = R.drawable.imagepair_04;
nArrImageID[4] = R.drawable.imagepair_05; nArrImageID[5] = R.drawable.imagepair_06;
nArrImageID[6] = R.drawable.imagepair_07; nArrImageID[7] = R.drawable.imagepair_08;
nArrImageID[8] = R.drawable.imagepair_09; nArrImageID[9] = R.drawable.imagepair_10;
nCurImageCount = 4;
nArrSelectImageID = new int[nCurImageCount];
bPairOK = new boolean[nCurImageCount];
Random random = new Random();
int nRandom = 0;
// 총 이미지중에 Random값 현재 게임이미지 개수 / 2 개만 뽑아오기
for(int i=0;i<nCurImageCount/2;i++)
{
nRandom = random.nextInt(MAX_IMAGECOUNT);
nArrSelectImageID[i] = nArrImageID[nRandom];
for(int j=0;j<i;j++)
{
if (nArrSelectImageID[i] == nArrSelectImageID[j])
{
i--;
}
}
}
// 동일한 이미지를 2개씩 배열에 복사
for(int i=0;i<nCurImageCount/2;i++)
{
nArrSelectImageID[i+(nCurImageCount/2)] = nArrSelectImageID[i];
}
// 이미지 위치 랜덤으로 설정하기
nArrImagePos = new int[nCurImageCount];
Random randomPos = new Random();
for(int i=0;i<nCurImageCount;i++)
{
nArrImagePos[i] = randomPos.nextInt(nCurImageCount);
for(int j=0;j<i;j++)
{
if (nArrImagePos[i] == nArrImagePos[j])
{
i--;
}
}
}
for (int i = 0; i < nCurImageCount; i++) {
Log.d("[이미지위치 배열]", "nArrImagePos[ " + i + " ] = " + nArrImagePos[i]);
}
}
InitImageArray()함수인데 여기에 2단계 로직을 넣어보겠습니다.
switch(nGameStage)
{
case 1:
nCurImageCount = 4; // 1단계 이미지 개수 4개
break;
case 2:
nCurImageCount = 6; // 2단계 이미지 개수 6개
break;
}
여기에서는 위와같이 이미지 개수만 다르게 설정하면 될것 같네요...
▣ 2단계 6개 동적 ImageView생성하기
// 새게임 시작
private void NewGame()
{
InitImageArray(); // 초기화
CreateImageView(); // 동적 ImageView 생성
}
다음으로 CreateImageView()를 호출하였습니다.
// 동적으로 ImageView 생성해주는 함수
@SuppressLint("ClickableViewAccessibility")
private void CreateImageView()
{
// ArrayList에 새로운 값 추가
for(int i=0; i<nCurImageCount; i++)
{
ImageView imgvDynamic = new ImageView(getApplicationContext());
arrayListImage.add(imgvDynamic);
}
fImagePosX = new float[nCurImageCount];
fImagePosY = new float[nCurImageCount];
fImagePosX[0] = 0.1f; fImagePosY[0] = 0.3f;
fImagePosX[1] = 0.9f; fImagePosY[1] = 0.3f;
fImagePosX[2] = 0.1f; fImagePosY[2] = 0.67f;
fImagePosX[3] = 0.9f; fImagePosY[3] = 0.67f;
for(int i=0;i<nCurImageCount;i++)
{
ImageView imgvCur = arrayListImage.get(i);
imgvCur.setImageResource(nArrSelectImageID[nArrImagePos[i]]);
imgvCur.setId(View.generateViewId());
imgvCur.setBackgroundResource(R.drawable.round_border_style);
imgvCur.setPadding(7,7,7,7);
constraintLayout.addView(imgvCur);
// ImageView의 가로, 세로 크기 설정
layoutParams = imgvCur.getLayoutParams();
layoutParams.width = 415;
layoutParams.height = 510;
imgvCur.setLayoutParams(layoutParams);
// ImageView의 위치 설정
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(constraintLayout);
constraintSet.connect(imgvCur.getId(), ConstraintSet.TOP, constraintLayout.getId(), ConstraintSet.TOP, 0);
constraintSet.connect(imgvCur.getId(), ConstraintSet.LEFT, constraintLayout.getId(), ConstraintSet.LEFT, 0);
constraintSet.connect(imgvCur.getId(), ConstraintSet.RIGHT, constraintLayout.getId(), ConstraintSet.RIGHT, 0);
constraintSet.connect(imgvCur.getId(), ConstraintSet.BOTTOM, constraintLayout.getId(), ConstraintSet.BOTTOM, 0);
constraintSet.setHorizontalBias(imgvCur.getId(), fImagePosX[i]);
constraintSet.setVerticalBias(imgvCur.getId(), fImagePosY[i]);
constraintSet.applyTo(constraintLayout);
// 이미지 터치이벤트
int nPos = i;
imgvCur.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch(motionEvent.getAction())
{
case MotionEvent.ACTION_DOWN:
if(bPairOK[nPos])
{
Toast.makeText(getApplicationContext(),"이미 맞춤!",Toast.LENGTH_SHORT).show();
break;
}
if(!bGameStart)
{
Toast.makeText(getApplicationContext(),"잠시후에 게임이 시작됩니다.!",Toast.LENGTH_SHORT).show();
break;
}
imgvCur.setImageResource(nArrSelectImageID[nArrImagePos[nPos]]);
if(nFirstTouchImageID ==0)
{
nFirstTouchImageID = nArrSelectImageID[nArrImagePos[nPos]];
imgvFirstTouch = imgvCur;
nFirstTouchImagePos = nPos;
}
else
{
nSecondTouchImageID = nArrSelectImageID[nArrImagePos[nPos]];
imgvSecondTouch = imgvCur;
nSecondTouchImagePos = nPos;
// 동일한 ImageView를 연속으로 터치했을때의 처리
if(imgvFirstTouch == imgvSecondTouch)
{
nSecondTouchImageID = 0;
imgvSecondTouch = null;
nSecondTouchImagePos =0;
Toast.makeText(getApplicationContext(),"연속 터치!",Toast.LENGTH_SHORT).show();
}
else
{
CheckSameImage(imgvFirstTouch, nFirstTouchImageID, nFirstTouchImagePos,
imgvSecondTouch, nSecondTouchImageID, nSecondTouchImagePos); // 같은 그림인지 체크
nFirstTouchImageID = 0;
nSecondTouchImageID = 0;
imgvFirstTouch = null;
imgvSecondTouch = null;
nFirstTouchImagePos = 0;
nSecondTouchImagePos =0;
}
}
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
break;
}
return true;
}
});
}
}
이게 CreateImageView()함수인데요..
여기에서도 2단계 로직을 넣어보겠습니다.
private void CreateImageView()
{
// ArrayList 초기화
if(!arrayListImage.isEmpty())
{
for(int i=0;i<arrayListImage.size();i++ )
{
ImageView imgvCur = arrayListImage.get(i);
if(imgvCur !=null)
{
constraintLayout.removeView(imgvCur);
}
}
arrayListImage.clear();
}
// ArrayList에 새로운 값 추가
for(int i=0; i<nCurImageCount; i++)
{
ImageView imgvDynamic = new ImageView(getApplicationContext());
arrayListImage.add(imgvDynamic);
}
먼저, 1단계만 있을때는 ArrayList를 초기화할필요가 없었는데..
2단계를 시작할때는 이미 ArrayList가 있는 상태이기 때문에 위와같이 초기화 해주고 ConstraintLayout.removeView()로
모든 ImageView를 삭제해주었습니다.
switch(nGameStage)
{
case 1:
fImagePosX[0] = 0.1f; fImagePosY[0] = 0.3f;
fImagePosX[1] = 0.9f; fImagePosY[1] = 0.3f;
fImagePosX[2] = 0.1f; fImagePosY[2] = 0.67f;
fImagePosX[3] = 0.9f; fImagePosY[3] = 0.67f;
break;
case 2:
fImagePosX[0] = 0.1f; fImagePosY[0] = 0.2f;
fImagePosX[1] = 0.9f; fImagePosY[1] = 0.2f;
fImagePosX[2] = 0.1f; fImagePosY[2] = 0.5f;
fImagePosX[3] = 0.9f; fImagePosY[3] = 0.5f;
fImagePosX[4] = 0.9f; fImagePosY[4] = 0.8f;
fImagePosX[5] = 0.9f; fImagePosY[5] = 0.8f;
break;
}
그리고, 게임단계에따라서 이미지의 위치를 설정해주었습니다.
▣ 2단계 카운트다운 타이머 로직 수정하기
다음으로
// 새게임 시작
private void NewGame()
{
InitImageArray(); // 초기화
CreateImageView(); // 동적 ImageView 생성
StartCountDownTimer(); // 5초 카운트다운 타이머 생성
}
새게임시작할때 StartCoundDownTimer()를 호출하였습니다.
// 5초 카운트다운 타이머
private void StartCountDownTimer()
{
cdTimer = new CountDownTimer(6000,1000) {
@Override
public void onFinish() {
// blank 이미지 표시하기
for(int i=0;i<nCurImageCount;i++) {
ImageView imgvCur = arrayListImage.get(i);
FlipCardAnimation(imgvCur);
}
bGameStart = true;
}
@Override
public void onTick(long l) {
txtv_CountDown.setText((l / 1000) + "");
}
};
cdTimer.start();
}
5초 카운트다운 타이머인데요..
여기에서도 2단계로직을 넣어보면
// 5초 카운트다운 타이머
private void StartCountDownTimer()
{
// 타이머가 이미 있으면 종료하기
if(cdTimer !=null)
{
cdTimer.cancel();
cdTimer = null;
}
카운트 다운 타이머가 이미 있으면 종료하는 로직 추가하였습니다.
여기까지 잘 되는지 한번 실행해보겠습니다.

네 1단계가 끝나면 2단계 6개 이미지도 잘 보이네요..^^
이번시간은 여기까지만 하구요~
다음시간은 2단계 완료하고 3단계 8개 이미지까지 해보도록 해보겠습니다.
그럼, 이만~
감사합니다. ^^
