안 드 로 이 드 2048 미니 게임 실현

15241 단어 Android2048게임.
본 고 는 안 드 로 이 드 가 2048 작은 게임 을 실현 하 는 관련 코드 를 소개 하고 여러분 에 게 참고 할 수 있 도록 공유 합 니 다.구체 적 인 내용 은 다음 과 같 습 니 다.

인터페이스 에 따 르 면 주로 4*4 칸 의 사각형 을 실현 하 는 것 이 번 거 롭 고 다른 것 은 모두 간단 합 니 다.전체적으로 4*4 칸 을 실현 하고 GridLayout 를 사용자 정의 하 며 그 중에서 터치 감청 사건 을 추가 하여 일련의 조작 을 하여 게임 의 논 리 를 실현 하고 마지막 에 애니메이션 효 과 를 추가 하면 완성 할 수 있 습 니 다.
다음은 디자인 아이디어 입 니 다.
1.GameView 의 디자인
먼저 하나의 종 류 를 정의 하고 GridLayout 를 계승 하 며 두 가지 구조 방법 을 추가 합 니 다.

public class GameView extends GridLayout {

  //         
  public GameView(Context context) {
    super(context);
    initView();
  }

  public GameView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initView();
  }
  }

다음은 initView()에서 GridLayout 를 4 열 로 설정 하고 터치 이벤트 감청 을 추가 합 니 다.(감청 방법 은 onTouch Event()를 다시 쓸 수 있 고 반환 값 은 true 이면 됩 니 다)터치 방향 을 판단 합 니 다.주로 x 축 과 y 축의 오프셋 을 비교 합 니 다.

 //        
  public void initView(){
    //      
    setColumnCount(4);
    //      
    setOnTouchListener(new OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
          case MotionEvent.ACTION_DOWN:
            setX = event.getX();
            setY = event.getY();
            break;
          case MotionEvent.ACTION_UP:
            offsetX = event.getX() - setX;
            offsetY = event.getY() - setY;
            //      
            if (Math.abs(offsetX) >= Math.abs(offsetY)) {
              if (offsetX > 0) {
                swipright();
              } else if (offsetX < 0) {
                swipleft();
              }
            } else {
              if (offsetY > 0) {
                swipdown();
              } else if (offsetY < 0) {
                swipup();
              }
            }

            break;
        }

        return true;
      }
    });
  }

감청 사건 이 실 현 된 후에 먼저 거기에 놓 고 4*4 의 안에 있 는 작은 칸 을 작은 카드 로 디자인 합 니 다.각 카드 는 하나의 TextView 입 니 다.카드 디자인 이 간단 하고 필요 한 것 을 추가 합 니 다.기본 숫자 는 0 입 니 다.이 때 는 빈 값,즉 빈 카드 입 니 다.

public class Card extends FrameLayout {

  public Card(Context context) {
    super(context);
    tvCard = new TextView(getContext());
    tvCard.setTextSize(40f);
    tvCard.setGravity(Gravity.CENTER);
    LayoutParams lp = new LayoutParams(-1,-1);
    lp.setMargins(15,15,0,0);
    addView(tvCard, lp);
  }
  //      
  private int num;
  private boolean is2048 = true;
  private void judgeIs2048(int num){
    if (is2048){
      if (2048==num){
        Toast.makeText(getContext(),"      2048",Toast.LENGTH_LONG).show();
        is2048 = false;
      }
    }
  }
  public int getNum() {
    return num;
  }

  public void setNum(int num) {
    this.num = num;
    if (num<=0){
      tvCard.setText("");
    }else {
    //                   
      tvCard.setText(num+"");
    }
    switch (num) {
      case 0:
        tvCard.setBackgroundColor(0x33ffffff);
        break;
      case 2:
        tvCard.setBackgroundColor(0xffeee4da);
        break;
      case 4:
        tvCard.setBackgroundColor(0xffede0c8);
        break;
      case 8:
        tvCard.setBackgroundColor(0xfff2b179);
        break;
      case 16:
        tvCard.setBackgroundColor(0xfff59563);
        break;
      case 32:
        tvCard.setBackgroundColor(0xfff67c5f);
        break;
      case 64:
        tvCard.setBackgroundColor(0xfff65e3b);
        break;
      case 128:
        tvCard.setBackgroundColor(0xffedcf72);
        break;
      case 256:
        tvCard.setBackgroundColor(0xffedcc61);
        break;
      case 512:
        tvCard.setBackgroundColor(0xffedc850);
        break;
      case 1024:
        tvCard.setBackgroundColor(0xffedc53f);
        break;
      case 2048:
        tvCard.setBackgroundColor(0xffedc22e);
        break;
      default:
        tvCard.setBackgroundColor(0xff3c3a32);
        break;
    }
    judgeIs2048(num);
  }


  //      ,    
  public boolean equals(Card o) {
    return getNum()==o.getNum();
  }

  //      
  private TextView tvCard;

  public TextView getTvCard() {
    return tvCard;
  }
}

카드 디자인 은 GameView 에 추가 해 야 합 니 다.이 럴 때 onSizeChanged()함 수 를 다시 쓰 십시오.이것 은 프로그램 이 열 렸 을 때 한 번 실 행 됩 니 다.그 를 통 해 카드 크기 를 동적 으로 디자인 하고 카드 를 추가 하 며 게임 을 시작 합 니 다.

@Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, w, oldw, oldh);
    Config.CARD_WIDTH = (Math.min(w,h)-10)/4;
    AddCard(Config.CARD_WIDTH);
    StartGame();

  }

카드 를 추가 하면 처음에는 모두 0,즉 모두 빈 카드 를 추가 합 니 다.

 //    
  private void AddCard(int CARD_WIDTH){
    Card c;
    for (int x = 0;x<4;x++){
      for (int y = 0;y<4;y++){
        c = new Card(getContext());
        c.setNum(0);
        addView(c, CARD_WIDTH, CARD_WIDTH);
        cardMap[y][x] = c;
      }
    }
  }
게임 시작 시 랜 덤 으로 두 장의 카드 를 추가 해 야 합 니 다.수치 2 또는 4,비율 9:1 이 나타 납 니 다.

//    
  public void StartGame(){

    for (int y = 0;y<4;y++){
      for (int x = 0;x<4;x++){
        cardMap[y][x].setNum(0);
      }
    }
    AddRandomCard();
    AddRandomCard();
  }

랜 덤 카드 디자인 추가

//      
  private void AddRandomCard(){
    CardPoint.clear();
    for (int y = 0;y<4;y++){
      for (int x = 0;x<4;x++){
        if (cardMap[x][y].getNum()<=0){
          CardPoint.add(new Point(x,y));
        }
      }
    }
    //            
    Point p = CardPoint.remove((int)(Math.random()*CardPoint.size()));
    cardMap[p.x][p.y].setNum(Math.random()>0.1?2:4);
    MainActivity.getMainActivity().getAnimLayer().createScaleTo1(cardMap[p.x][p.y]);

}
이렇게 대충 틀 을 만 들 었 어 요.
다음은 미끄럼 사건 입 니 다.여 기 는 왼쪽 미끄럼 만 예 로 들 겠 습 니 다.

private void swipleft(){
    boolean status = false;
    for (int y = 0; y < 4; y++) {
      for (int x = 0; x < 4; x++) {

        for (int x1 = x+1; x1 < 4; x1++) {
          if (cardMap[x1][y].getNum()>0) {

            if (cardMap[x][y].getNum()<=0) {

              MainActivity.getMainActivity().getAnimLayer().createMoveAnim(cardMap[x1][y],cardMap[x][y], x1, x, y, y);
              cardMap[x][y].setNum(cardMap[x1][y].getNum());
              cardMap[x1][y].setNum(0);
              x--;
              status = true;
            }else if (cardMap[x][y].equals(cardMap[x1][y])) {
              MainActivity.getMainActivity().getAnimLayer().createMoveAnim(cardMap[x1][y], cardMap[x][y],x1, x, y, y);
              cardMap[x][y].setNum(cardMap[x][y].getNum() * 2);
              cardMap[x1][y].setNum(0);
              MainActivity.getMainActivity().addScore(cardMap[x][y].getNum());
              status = true;
            }
            break;
          }
        }
      }
    }
    if (status){
      AddRandomCard();
      checkGame();
    }
  }

카드 를 추가 할 때마다 게임 종료 여 부 를 판단 해 야 합 니 다.

//    
  private void checkGame(){
    boolean complete = true;

    ALL:
    for (int y = 0; y < 4; y++) {
      for (int x = 0; x < 4; x++) {
        if (cardMap[x][y].getNum()==0||
            (x>0&&cardMap[x][y].equals(cardMap[x-1][y]))||
            (x<3&&cardMap[x][y].equals(cardMap[x+1][y]))||
            (y>0&&cardMap[x][y].equals(cardMap[x][y-1]))||
            (y<3&&cardMap[x][y].equals(cardMap[x][y+1]))) {

          complete = false;
          break ALL;
        }
      }
    }

    if (complete) {
      Toast.makeText(getContext(), "    " + MainActivity.getMainActivity().getScore(), Toast.LENGTH_LONG).show();
    }
  }

디자인 의 전체적인 구 조 는 바로 위 에서 말 한 것들 이다.
애니메이션 효과
애니메이션 효 과 는 주로 생 성,이동,이 세 가지 효 과 를 합 친 것 입 니 다.따라서 FrameLayout 를 계승 하 는 class 를 다시 써 서 게임 인터페이스 에 덮어 씁 니 다.이러한 목적 은 MainActivity 에서 현재 이 종 류 를 예화 한 다음 에 그 방법 을 조작 한 다음 에 미끄럼 을 통 해 애니메이션 을 설정 할 수 있 습 니 다.

public class AnimLayer extends FrameLayout {

  public AnimLayer(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  public AnimLayer(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public AnimLayer(Context context) {
    super(context);
  }



  public void createMoveAnim(final Card from,final Card to,int fromX,int toX,int fromY,int toY){

    final Card c = getCard(from.getNum());

    LayoutParams lp = new LayoutParams(Config.CARD_WIDTH, Config.CARD_WIDTH);
    lp.leftMargin = fromX*Config.CARD_WIDTH;
    lp.topMargin = fromY*Config.CARD_WIDTH;
    c.setLayoutParams(lp);

    if (to.getNum()<=0) {
      to.getTvCard().setVisibility(View.INVISIBLE);
    }
    TranslateAnimation ta = new TranslateAnimation(0, Config.CARD_WIDTH*(toX-fromX), 0, Config.CARD_WIDTH*(toY-fromY));
    ta.setDuration(100);
    ta.setAnimationListener(new Animation.AnimationListener() {

      @Override
      public void onAnimationStart(Animation animation) {}

      @Override
      public void onAnimationRepeat(Animation animation) {}

      @Override
      public void onAnimationEnd(Animation animation) {
        to.getTvCard().setVisibility(View.VISIBLE);
        recycleCard(c);
      }
    });
    c.startAnimation(ta);
  }

  private Card getCard(int num){
    Card c;
    if (cards.size()>0) {
      c = cards.remove(0);
    }else{
      c = new Card(getContext());
      addView(c);
    }
    c.setVisibility(View.VISIBLE);
    c.setNum(num);
    return c;
  }
  private void recycleCard(Card c){
    c.setVisibility(View.INVISIBLE);
    c.setAnimation(null);
    cards.add(c);
  }
  private List<Card> cards = new ArrayList<Card>();

  public void createScaleTo1(Card target){
    ScaleAnimation sa = new ScaleAnimation(0.1f, 1, 0.1f, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    sa.setDuration(100);
    target.setAnimation(null);
    target.getTvCard().startAnimation(sa);
  }

}

마지막 주 레이아웃 파일 은 다음 과 같 습 니 다.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="#fffaf8ef"
  android:orientation="vertical"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context=".MainActivity">
  <LinearLayout
    android:layout_marginTop="15dp"
    android:orientation="horizontal"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textColor="#ff776e65"
      android:text="@string/title"
      android:textSize="50sp"/>
  </LinearLayout>

  <LinearLayout
    android:layout_width="match_parent"
    android:orientation="horizontal"
    android:layout_marginTop="10dp"
    android:layout_height="wrap_content">

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textColor="#ff776e65"
      android:layout_marginLeft="30dp"
      android:textSize="35sp"
      android:text="@string/Score"/>
    <TextView
      android:id="@+id/tvscore"
      android:layout_marginLeft="20dp"
      android:textSize="25sp"
      android:textColor="#ff776e65"
      android:layout_width="70dp"
      android:layout_height="37dp"
      />
    <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/startgame"
      android:layout_marginLeft="40dp"
      android:background="#ffbbada0"
      android:textSize="15sp"
      android:text="@string/start"/>

  </LinearLayout>
  <FrameLayout
    android:id="@+id/gameContainer"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:layout_weight="1">
  <develop.niuli.com.game.GameView
    android:layout_marginTop="40dp"
    android:id="@+id/Gridlayout"
    android:layout_width="match_parent"
    android:background="#ffbbada0"
    android:layout_height="350dp">

  </develop.niuli.com.game.GameView>

  <develop.niuli.com.game.AnimLayer
    android:id="@+id/animLayer"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  </develop.niuli.com.game.AnimLayer>

  </FrameLayout>

</LinearLayout>
이상 은 본문의 전체 내용 이 므 로 여러분 의 학습 에 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기