관리 메뉴

드럼치는 프로그래머

[안드로이드] 제10강좌 - 기억력게임만들기 본문

★─Programing/☆─Android

[안드로이드] 제10강좌 - 기억력게임만들기

드럼치는한동이 2011. 5. 30. 17:08

@@@ 기억력 메뉴 게임 만들기 @@@

1. 도형 3가지 (원,사각형,삼각형)

2. 도형의 색상과 크기(임의로 정의)

3. 사용자 선택 - 1) 빈화면 선택 - 선택 내용 무시

                       2) 새로운 도형 선택 - 화면 초기화 - 기존도형(원래위치)

                                                                     - 새로운 도형(임의로 ) - 기존 도형과 절대로 겹치기 않는다

                                                                                                   - 화면에 걸치지도 않는다.

                       3) 기존 도형 선택 - 경고창(새로운 게임 or 종료)

 

@@ 기본 구조 @@

package. ~~~~~~~~~~~~~~~~~~~;

 

public class ~~~ extends Activity {

       onCreate(){

       }

       class shape{

       }

       class GameView{

       }

} 

 

@@@ java @@@

 

package com.android.game;

import android.app.Activity;
import android.os.Bundle;

import java.util.*;

import android.app.*;
import android.content.*;
import android.graphics.*;
import android.os.*;
import android.view.*; //사용할 모든것 선언


//게임 뷰를 담는 액티비티 선언
public class Testgame extends Activity {
    /** Called when the activity is first created. */
 GameView gv;
 //게임화면을 가지고 있는 클래스 선언
 
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        gv = new GameView(this);
        setContentView(gv);
    }      
        //도형 하나에 대한 정보 클래스
        class Shape{
         final static int RECT =0;  //3가지 모형에 대하여 정수로 선언을 해둠. 내가 만든 상수로써 각 도형의 값이 what에 저장이 됨.
         final static int CIRCLE =1;  //what값을 꺼내면 무슨 도형인지 알 수 있다.
         final static int TRIANGLE =2;
         
         int what;
         int color; //정수형 color를 만들어서 난수로써 색상 지정
         Rect rt;   //사각형 형태로 정로를 가지고 있는 객체,
     
        } //shape 클래스 종료


        //게입 뷰 클래스 : 실질적인 메인
        class GameView extends View{
         //그리기 모드.빈화면 또는 도형 출력
         //게임 진행 속도
         //현재 그리기 모드
         //생성된 도형의 목록
         final static int BLANK =0;  //그리기 모드 빈 화면 또는 도형 출력
         final static int PLAY=1;
         final static int DELAY=1500; //게임 진행 속도
         int status;  //현재 그리기 모드
         
         //생성된 도형의 목록
         ArrayList<Shape> arShape = new ArrayList<Shape>(); //하나의 도형을 입력가능하도록 기본도형과 겹치지않고 화면에 벗어나지 않음
         Random Rnd = new Random(); //임의도 도형을 생성하기위해
         Activity mParent; //부모를 연력하기 위해,
         
         //게임 뷰 클래스 생성자
         public GameView(Context context){
          super(context);
          mParent = (Activity)context;
          
          //빈화면으로 시작하고 잠시 후에 게임 시작
          status = BLANK;
          mHandler.sendEmptyMessageDelayed(0,DELAY); //괄호 안에 0 이면 게임 무한 반복
          //어플리케이션을 일정시간 대기 시작 대기 시작과 같이 조절 가능
          //아주 유용함, 쓰레드 슬립도 대체가능함
         }
         //onDraw() 매서드
         public void onDraw(Canvas canvas){
          //검정색 배경으로 지운다 빈화면 지우기만 하고 리턴
          canvas.drawColor(Color.BLACK);
          if (status == BLANK){
          return;
          }
          //도형 목록을 순회하면서 도형 정보대로출력하다.
          int idx;
          for(idx =0; idx < arShape.size(); idx++){
           Paint Pnt = new Paint();
           Pnt.setColor(arShape.get(idx).color);
           Rect rt = arShape.get(idx).rt;
           switch (arShape.get(idx).what){
           case Shape.RECT: 
            canvas.drawRect(rt,Pnt); //사각형
            break;
           case Shape.CIRCLE:
            canvas.drawCircle(rt.left+rt.width()/2, rt.top+rt.height()/2, rt.width()/2, Pnt);
            break; //원은 반을 나눠서 중심점을 나눠서 입력
           case Shape.TRIANGLE:
            Path path = new Path();
            path.moveTo(rt.left+rt.width()/2, rt.top);  //왼쪽에서 폭을 반 나눈 것을 top으로 지정
            path.lineTo(rt.left, rt.bottom);   //top에서 사각형의 왼쪽으로 아래
            path.lineTo(rt.right, rt.bottom); //top에서 사각형의 오른쪽 아래
            canvas.drawPath(path, Pnt); //path는 선을 그리기 위안 메소드
            break;
           }
          }
         }
         
         //onTouchEvent매서드
         public boolean onTouchEvent(MotionEvent event){
          //터치 동작에 따라서 ACTION_DOWN,UP등이 발생
          if(event.getAction() == MotionEvent.ACTION_DOWN){
           int sel;
           sel = FindShapeIdx((int)event.getX(),(int)event.getY());//위치 값이 아래의 FindShapeIdx로 넘어감
           
           //빈 바닥을 직으면 무시한다
           if(sel==-1){
            return true;
           }
           
           //마지막 추가된 도형을 제대로 찍었으면 다음 단계로 진행
           //빈 화면 잠시 보여준 후 새 도형 추가
           if(sel == arShape.size()-1){
            status = BLANK;
            invalidate();
            mHandler.sendEmptyMessageDelayed(0, DELAY); //클릭 후 잠시 쉬엇다가 다시 화면 나옴
           }
           // 엉뚱한 도형을 찍었으면 질문 후 게임 종료 또는 시작
           else{
            new AlertDialog.Builder(getContext())
            .setMessage("재미있지?! 또할래?!")
            .setTitle("게임 끝!!")
            .setPositiveButton("한번더?!", new DialogInterface.OnClickListener() {
       public void onClick(DialogInterface dialog, int whichButton) {
        arShape.clear();
        status=BLANK;
        invalidate();
        mHandler.sendEmptyMessageDelayed(0, DELAY);
       }
      })
      .setNegativeButton("안해", new DialogInterface.OnClickListener(){
       public void onClick(DialogInterface dialog, int whichButton){
        mParent.finish(); //액티비티가 종료
       }
      })
      .show();
           }
           return true;
          }
          return true;
         }
         
         
         //새로운 도형은 목록에 추가하는 매서드
         void AddNewShape(){
          Shape shape = new Shape();
          int idx;
          boolean bFindIntersect;
          Rect rt = new Rect();
          
             //기존 도형과 겹치지 않는 새 위치를 찾는다
          for(;;){
           //크기는 32,48,64 중 하나 선택
           int Size = 32+16*Rnd.nextInt(2);
           //위치는 난수로 선택,
           rt.left = Rnd.nextInt(getWidth());
           rt.top = Rnd.nextInt(getHeight());
           rt.right = rt.left + Size;
           rt.bottom = rt.top + Size;
           //화면을 벗어나면 안됨
           if(rt.right > getWidth() || rt.bottom > getHeight()){
            continue;
           }
           //기존 도형 순회하면서 겹치는지 조사.
           bFindIntersect = false;
           for(idx = 0; idx < arShape.size(); idx ++){
            if(rt.intersect( arShape.get(idx).rt)==true) {
             bFindIntersect = true;
            }
           }
            //겹치지 않을 때 확정, 겹치면 계속 재위치 선정
            if(bFindIntersect== false){
             break;
            }
           }
          
           //새 도형 정보 작성, 모양, 색상 등을 난수 선택
           shape.what = Rnd.nextInt(3);
           
           switch (Rnd.nextInt(5)){
           case 0:
            shape.color=Color.WHITE;
            break;
           case 1:
            shape.color=Color.RED;
            break;
           case 2:
            shape.color=Color.GREEN;
            break;
           case 3:
            shape.color=Color.BLUE;
            break;
           case 4:
            shape.color=Color.YELLOW;
            break;
           }
           shape.rt = rt;
           arShape.add(shape);
          } 
         
          //x.y우치의 도형 번호르 찾는 매서드, 도형이 없는 위치면 -1 리턴
          int FindShapeIdx(int x, int y){
           int idx;
          
           for(idx=0; idx<arShape.size();idx ++){
            if(arShape.get(idx).rt.contains(x,y)){
             return idx;
            }
           }
           return -1;
          }
          
          //새 도형을 추가하고 화면을 다시 그리기. 시간 딜레이를 주기 위해 핸들러 사용
          Handler mHandler =new Handler(){
           public void handleMessage(Message msg){
            AddNewShape();
            status = PLAY;
            invalidate(); //invalide()가 출력되면 onDraw()메소드가 했던일을 완전히 초기화 시켜줌,

                               //반드시 리와인쓰레드 쪽에서만 가능함., 다른곳에서는 사용 불가능.

           
            String title; //화면에서 타이틀의 이름을 변경 가능하도록 한다, 단계별로 증가.
            title = "MemotyPower-"+ arShape.size() + "단계";
            mParent.setTitle(title);
           }
        };
    } //game클래스 종료
}




Comments