当前位置:   article > 正文

【Android Studio】图形化数字游戏,小游戏2048。_android studio小游戏

android studio小游戏

手机中的小游戏是一种在日常生活中应用广泛的休闲软件,无论是在超市商店,还是在办公室,或是家庭都有着它的身影。随着移动互联网和智能手机的不断发展和进步,当今市场上已经出现了多种简单轻松的小游戏,几乎每一位智能手机的使用者都会在种类繁多的App网站上下载一些小游戏,这些数字小游戏可以使人们在紧张的工作节奏中很好地放松身心。

系统目标

根据用户对Android数字小游戏的使用要求:
通过鼠标滑动模拟上下左右。
操作简单,易于掌握,界面简洁清爽。
方便进行游戏的触摸操作。
要包含计分和游戏终止功能。
系统运行稳定,不能和手机固有软件冲突,安全可靠
在这里插入图片描述

结构图如下:
在这里插入图片描述
流程图如下:
在这里插入图片描述

运行环境

操作系统:win10
开发工具:Android Studio 2021.3.1
语言:java,xml
虚拟机设备设置:3.4 WQVGA API 30

项目的创建

项目名称为:MiniGame。
添加模板选择:empty Activity。
其余操作不变,选择不带中文的地址。点击Finish,完成创建。

项目的实现

在我们编写代码之前,首先要制定好项目的系统文件夹的组织结构目录,分门别类地管理我们的项目资源,包括不同的界面、类、数据模型、图片资源等,这样不但可以保证系统开发过程的规范性和程序员的可替代性,还有利于保证团队开发的一致性。创建好系统的文件夹后,在开发的过程中,只需要将我们新创建的类文件或者资源文件、脚本文件等保存到相应的文件夹中即可。Android数字小游戏项目所使用的文件夹组织结构如图所示:
可爱

游戏主界面的实现

设计界面布局xml文件

<?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>


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
逻辑的实现

由于小游戏涉及图像的更新和分数统计,又要兼顾总体运行。为了方便调试和修改,也为了更好地分工,采用三个java类文件实现对所有功能的编制。建立工程后,除默认的主程序文件,即Android Studio工程界面中的java文件夹内的"com.example.minigame"包中的"MainActivity.java"文件外,再创建两个"Java Class",分别为“Card.java"和"GameView.java"。下面将三个文件分模块解析。

实现主程序MainActivity

包含数字小游戏的初始化。

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+"");

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
卡片文件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);
     }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
实现游戏交互文件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();
        }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280

选择合适的虚拟设备:
在这里插入图片描述
运行程序:
在这里插入图片描述
得到每一步的步骤。
游戏结束时,弹出提示框。
点击yes或newgame重新游戏。
在这里插入图片描述
希望这些代码对您有用。
感谢您的收看。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/264696
推荐阅读
相关标签
  

闽ICP备14008679号