[Android Studio] Graphical digital game, mini game 2048.

Mini games on mobile phones are a kind of leisure software that is widely used in daily life, whether in supermarkets, offices, or families. With the continuous development and progress of mobile Internet and smart phones, a variety of simple and easy mini-games have appeared on the market today. Almost every smartphone user will download some mini-games from a wide variety of App websites. These Digital games can help people relax and unwind from the intense work pace.

system goals

According to the user's requirements for Android digital games:
simulate up, down, left and right by sliding the mouse.
The operation is simple, easy to master, and the interface is simple and refreshing.
Convenient for touch operation of games.
To include scoring and game termination features.
The system runs stably and cannot conflict with the inherent software of the mobile phone. It is safe and reliable.
Insert image description here

The structure chart is as follows:
Insert image description here
the flow chart is as follows:
Insert image description here

Operating environment

Operating system: win10
Development tools: Android Studio 2021.3.1
Language: java, xml
Virtual machine device settings: 3.4 WQVGA API 30

Project creation

The project name is: MiniGame.
Add template selection: empty Activity.
The rest of the operations remain unchanged, select the address without Chinese characters. Click Finish to complete the creation.

Project realization

Before we write code, we must first formulate the organizational structure directory of the project's system folder and manage our project resources by category, including different interfaces, classes, data models, picture resources, etc. This will not only ensure the smoothness of the system development process Standardization and programmer replaceability also help ensure the consistency of team development. After creating the system folder, during the development process, we only need to save our newly created class files, resource files, script files, etc. to the corresponding folder. The folder organization structure used by the Android digital game project is as shown in the figure:
cute

Implementation of game main interface

Design interface layout xml file

<?xml version="1.0" encoding ="utf-8"?>

<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:orientation="vertical"
        tools:context='.MainActivity'>
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <!--  提示文本框      -->
            <TextView
                android:id="@+id/tv_score_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="18dp"
                android:textColor="#000000"
                android:padding="8dp"
                android:text="You Score Is:"/>
            <!--  动态显示分数文本框      -->
            <TextView
                android:id="@+id/tv_score_show"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20dp"
                android:textColor="#000000"
                android:padding="10dp"
                android:text="0"/>
            <!--        作为newgame按钮的文本框-->
            <TextView
                android:id="@+id/tv_newgame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="18dp"
                android:textColor="#000000"
                android:paddingTop="8dp"
                android:paddingLeft="20dp"
                android:text="NEW Game"/>
        </LinearLayout>
        <com.example.minigame.GameView
            android:id="@+id/gv_show"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1">
        </com.example.minigame.GameView>
</LinearLayout>


implementation of logic

Since the mini-game involves image updates and score statistics, it must also take into account the overall operation. In order to facilitate debugging and modification, and to better divide labor, three java class files are used to compile all functions. After creating the project, in addition to the default main program file, which is the "MainActivity.java" file in the "com.example.minigame" package in the java folder in the Android Studio project interface, create two more "Java Classes". They are "Card.java" and "GameView.java" respectively. The three files are analyzed in modules below.

Implement the main program MainActivity

Contains the initialization of digital games.

package com.example.minigame;

import android.app.Activity;
import android.os.Bundle;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class MainActivity extends Activity {
    
    
    TextView score_show;
    GameView gv;
    TextView new_game;
    Handler handler=new Handler(){
    
    
        @Override
        public void handleMessage(Message msg){
    
    
            //TODO Auto-generated method stub

            super.handleMessage(msg);
            int num=msg.arg1;
            score_show.setText(num+"");
        }
    };

    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        score_show=(TextView) findViewById(R.id.tv_score_show);
        gv=(GameView) findViewById(R.id.gv_show);
        new_game=(TextView)findViewById(R.id.tv_newgame);
        new_game.setOnClickListener(new OnClickListener() {
    
    
            @Override
            public void onClick(View arg0) {
    
    
                gv.GameStart();
                gv.score=0;
            }
        });
//设计计时器timer并使用timer定时传递包含分数信息的message,以便界面定时刷新分数
        Timer timer=new Timer();
        timer.schedule(new TimerTask(){
    
    
            @Override
            public void run(){
    
    
                Message msg = new Message();
                msg.arg1 = gv.score;
                handler.sendMessage(msg);
            }
        }, 80 , 150);
        score_show.setText(100+"");

    }
}
Implementation of card file Card.java
package com.example.minigame;

import android.content.Context;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.TextView;

public class Card extends FrameLayout{
    
    
     private TextView text;
     private int number=0;
     public int getNumber(){
    
    
         return number;
     }
     public void setNumber(int number){
    
    
         this.number=number;
         if(number<2){
    
    
             text.setText("");
         }else{
    
    
             if(number>=64){
    
    
                 text.setTextColor(0xffffff00);
             }else{
    
    
                 text.setTextColor(0xff000000);
             }
             text.setText(number+"");
         }
     }
     public Card(Context context){
    
    
         super(context);
         //TODO Auto-generated constructor stub
         text=new TextView(context);
         text.setTextSize(28);
         text.setBackgroundColor(0x9966cccc);
         text.setGravity(Gravity.CENTER);
         LayoutParams params=new LayoutParams(-1,-1);
         params.setMargins(10,10,0,0);
         addView(text,params);
     }
}

Implement game interaction file GameView.java
package com.example.minigame;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Point;
import android.content.DialogInterface;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.GridLayout;

//初始化单元
public class GameView extends GridLayout{
    
    
    private Card cards[][]=new Card[4][4];
    private List<Point>emptyCards=new ArrayList<>();
    Random rd=new Random();
    int score=0;

    public GameView(Context context){
    
    
        super(context);
        //TODO Auto-generated constructor stub
        initGame();
    }
    public GameView(Context context,AttributeSet attrs){
    
    
        super(context,attrs);
        //TODO Auto-generated constructor stub
        initGame();
    }
    public GameView(Context context,AttributeSet attrs,int defStyle){
    
    
        super(context,attrs,defStyle);
        //TODO Auto-generated constructor stub
        initGame();
    }
//游戏初始化函数。主要功能为游戏的输入监听,并定义如何判断用户的游戏的输入,关联到相印的处理函数。
    private void initGame(){
    
    
         setColumnCount(4);
         setBackgroundColor(0xffffcccc);

         setOnTouchListener(new OnTouchListener() {
    
    
             private float startX,startY;
             private float offsetX,offsetY;

             @Override
             public boolean onTouch(View v,MotionEvent event) {
    
    
                 //TODO Auto-generated method stub
                 switch (event.getAction()){
    
    
                     case MotionEvent.ACTION_DOWN:
                         startX=event.getX();
                         startY = event.getY();
                         break;
                     case MotionEvent.ACTION_UP:
                         Gameover() ;
                         offsetX = event.getX()-startX;
                         offsetY = event.getY()-startY;
                         if (Math.abs (offsetX) > Math.abs (offsetY)) {
    
    
                            if (offsetX < -3) {
    
    
                               moveLeft() ;
                               System.out.println("----左");
                            } else if (offsetX > 3) {
    
    
                                moveRight();
                                System.out.println("----右");
                            }
                         } else {
    
    
                             if (offsetY < -3) {
    
    
                                 moveUp();
                                 System.out.println("----上");
                             } else if (offsetY > 3){
    
    
                                 moveDown();
                                 System.out.println("----下");
                             }
                         }
                         break;
                     default:
                       break;
                 }
                 return true;
             }
         });
    }
//游戏触摸响应函数
    private void moveRight() {
    
    
        boolean flage = false;
        for (int y = 0; y < 4; y++) {
    
    
            for (int x = 3; x >= 0;x--) {
    
    
                for (int x1 = x - 1; x1 >= 0; x1--) {
    
    
                    //当同一行为空时,不需处理
                    if (cards[x1][y].getNumber() > 0) {
    
    
                        if (cards[x][y].getNumber() < 2) {
    
    
//将前一张卡片的值移动到当前卡片
                            cards[x][y].setNumber(cards[x1][y].getNumber());
                            cards[x1][y].setNumber(0);
                            x++;
                            flage = true;
                            score += 2;
                        } else if (cards[x][y].getNumber() == cards[x1][y].getNumber()) {
    
    
                            cards[x][y].setNumber(cards[x][y].getNumber() * 2);
                            score += cards[x][y].getNumber();
                            cards[x1][y].setNumber(0);
                            flage = true;
                        }
                        break;
                    }
                }
            }
        }

        if (flage) {
    
    
            creatRandomCard();
        }
    }
        private void moveLeft(){
    
    
                boolean flage = false;
                for(int y =0;y<4;y++){
    
    
                     for(int x=0;x<4;x++){
    
    
                         for(int x1=x+1;x1<4;x1++){
    
    
//当同一行为空时,不需处理
                             if(cards[x1][y].getNumber()> 0) {
    
    
                                 if (cards[x][y].getNumber() < 2) {
    
    
//将前一张卡片的值移动到当前卡片
                                     cards[x][y].setNumber(cards[x1][y].getNumber());
                                     cards[x1][y].setNumber(0);
                                     x--;
                                     flage = true;
                                     score += 2;
                                 } else if (cards[x][y].getNumber() == cards[x1][y].getNumber()) {
    
    
                                     cards[x][y].setNumber(cards[x][y].getNumber() * 2);
                                     score += cards[x][y].getNumber();
                                     cards[x1][y].setNumber(0);
                                     flage = true;
                                 }
                                 break;
                             }
                         }
                     }
                }
            if(flage) {
    
    
                creatRandomCard();
            }
        }
            private void moveDown(){
    
    
                boolean flage = false;
                for(int x=0;x<4;x++){
    
    
                   for (int y =3;y>=0;y--){
    
    
                       for (int y1=y-1;y1>= 0;y1--){
    
    
//当同一行为空时,不需处理
                          if(cards[x][y1].getNumber()>0){
    
    
                              if (cards[x][y].getNumber()< 2) {
    
    
//将前一张卡片的值移动到当前卡片
                                  cards[x][y].setNumber(cards[x][y1].getNumber());
                                  cards[x][y1].setNumber(0);
                                  y++;
                                  flage = true;
                                  score += 2;
                              } else if(cards[x][y].getNumber()== cards[x][y1].getNumber()){
    
    
                                    cards[x][y].setNumber(cards[x][y].getNumber()* 2);
                                    score +=cards[x][y].getNumber();
                                    cards[x][y1].setNumber(0);
                                    flage = true;
                              }
                              break;
                          }
                       }
                   }
                }
                if(flage){
    
    
                    creatRandomCard();
                }
            }
            private void moveUp(){
    
    
                 boolean flage = false;
                 for(int x=0;x<4;x++){
    
    
                    for(int y=0;y<4;y++){
    
    
                        for(int y1=y+1;y1<4;y1++){
    
    
                             if(cards[x][y1].getNumber()> 0){
    
    
                                if(cards[x][y].getNumber()<2){
    
    
                                      cards[x][y].setNumber(cards[x][y1].getNumber());
                                      cards[x][y1].setNumber(0);
                                      y--;
                                      flage = true;
                                      score+=2;
                                } else if(cards[x][y].getNumber()== cards[x][y1].getNumber()) {
    
    
                                    cards[x][y].setNumber(cards[x][y].getNumber() * 2);
                                    score += cards[x][y].getNumber();
                                    cards[x][y1].setNumber(0);
                                    flage = true;
                                }
                                break;}
                        }
                    }
                 }
                 if(flage) {
    
    
                     creatRandomCard();
                 }
            }
        //游戏结束判定以及判定处理
        private void Gameover(){
    
    
           boolean OverGame=true;
           for (int y=0;y<4;y++) {
    
    
               for (int x = 0; x < 4; x++) {
    
    
                   if (cards[x][y].getNumber() <= 0 ||
                           (x > 0 && cards[x][y].getNumber() ==
                                   cards[x - 1][y].getNumber()) ||
                           (x < 3 && cards[x][y].getNumber() ==
                                   cards[x + 1][y].getNumber()) ||
                           (y > 0 && cards[x][y].getNumber() ==
                                   cards[x][y - 1].getNumber()) ||
                           (y < 3 && cards[x][y].getNumber() ==
                                   cards[x][y + 1].getNumber())) {
    
    
                       OverGame = false;
                   }
               }
           }
           if(OverGame){
    
    
               new AlertDialog.Builder(getContext()).setTitle("hi").setMessage("again").
                        setPositiveButton("yes",new DialogInterface.OnClickListener(){
    
    
                            @Override
                            public void onClick(DialogInterface dialog, int which){
    
    
                            //TODO Auto-generated method stub
                               GameStart();
                               score = 0;
                             }
                        }).setNegativeButton("No", null).show();
           }
        }
        //其他函数
        private void AddCard(int width, int height) {
    
    
            Card c;
            for (int y = 0; y < 4; y++) {
    
    
                for (int x = 0; x < 4; x++) {
    
    
                    c = new Card(getContext());
                    cards[x][y] = c;
                    c.setNumber(0);
                    addView(c, width, height);
                }
            }
        }

        @Override
        protected void onSizeChanged(int w,int h,int oldw,int oldh) {
    
    
            //TODO Auto-generated method stub
            super.onSizeChanged(w, h, oldw, oldh);
            int width = (w - 10) / 4;
            AddCard(width, width);
            GameStart();
        }
        private void creatRandomCard() {
    
    
            emptyCards.clear();
            for (int y = 0; y < 4; y++) {
    
    
                for (int x = 0; x < 4; x++) {
    
    
                    if (cards[x][y].getNumber() < 2) {
    
    
                        Point point = new Point(x, y);
                        emptyCards.add(point);
                    }
                }
            }
            int selat = rd.nextInt(emptyCards.size());
            Point p = emptyCards.get(selat);
            emptyCards.remove(selat);
            int number = 0;
            if (rd.nextInt(10) > 4) {
    
    
                number = 4;
            } else
                number = 2;
            cards[p.x][p.y].setNumber(number);
        }
        public void GameStart() {
    
    
            for (int y = 0; y < 4; y++) {
    
    
                for (int x = 0; x < 4; x++) {
    
    
                    cards[x][y].setNumber(0);
                }
            }
            creatRandomCard();
            creatRandomCard();
        }
}

Choose the right virtual device:
Insert image description here
Run the program:
Insert image description here
Get step-by-step instructions.
When the game ends, a prompt box pops up.
Click yes or newgame to restart the game.
Insert image description here
Hope these codes are useful to you.
thanks for watching.

Guess you like

Origin blog.csdn.net/gelly_/article/details/131752332