java 模仿支付成功_一位android渣渣模仿别人写了一个2048小游戏。

 几天前就想写来着,昨天终于动工了。模仿者别人的代码写了大概一个钟的时间,还是很简单的,

软件的实现逻辑现在是基本清楚了,但是完整的描述出来还是有点难。先上图。我是打算在明白这个游戏原理后为这个游戏重新设计一个ui。可以供自己玩耍。可现实狠狠的给了我一刀,目前分数计算出问题了,解决这个问题只能是自己研究透别人代码的实现逻辑,然后才能随心的使用。

2d044b1c35531c8b140843f202c2b3f6.png

这里简单说一下这个软件的几个核心文件(其实也没有其他文件了)。就这么四个,很简单!事实上你只需要创建一个新的安卓项目,然后写完这几个文件,2048就可以玩耍了,当然,要是想要获得更好的体验,就需要对界面精心设计一番。

activity_main.xml

这个是主界面的布局文件,里面就放了两个用来显示分数的TextView。还有自定义的game布局(就是游戏核心逻辑实现的布局)

MainActivity.java

主界面的逻辑实现文件,里面就写了几个更新分数的方法,供game.java, 调用的。

Crad.java

这个是用来处理卡片的,主要负责设置卡片的颜色,之类的,你也可以在这个文件里面去尝试自定义卡片样式。

Game.java

游戏界面布局和游戏主要实现逻辑都在这里面,但是也仅仅只有300行代码。特别注意上下左右滑动的那几个方法,千万不要写错了。全是for循环,(我已经被绕晕)

b928f6808cb330f8854ee003774511b3.png

你可能会遇到的一些问题。

代码写完如果看到的是灰色屏,看向这里,有解决办法。(如果你是按我仿造的那个博客写的)

我发布的代码是可以正常显示界面的,我学习的那个博客的不可以。

2e6536b0552cf10d2bc2a6fc2523105c.png

这是添加卡片的方法,原作者是把这个方法放在其他地方的。但是那样做的话游戏界面加载不出来(游戏界面会是灰色的)。查百度说是因为构造方法生命周期的原因。具体你想知道为啥的话你可以私信我。然后那个  Getwidth() 是这样写的。获取的是屏幕的宽高。

695bb466def2bab89c7efe71cfc1eba6.png

2e17041af5476751e1d3963a1a22fec7.png

上下左右滑动的代码

dc854d2d06d9bdc20352db7d84018380.png

这是整个游戏的核心部分,不管你界面做的再好,没有这个代码,你的软件都将是一张图片而已。我自己写的是有错误的,这里我把正确的代码截图和查看地址给出来。(如果你的游戏写出来不能玩耍,那一定是这里出了问题)

012504abbefa2316867aab1fadba92fd.png

小小的年纪,大大的悲伤

一层一层的for循环,很是让人头大。

#我参照的博客https://blog.csdn.net/qq_34731703/article/details/73380156?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-5

becf3519432617847db59d76b7926514.png

目前我已经被这个搞得头都大了,游戏在玩耍的时候有些卡片会莫名消失,而且如果直接点击的话分数会一直上涨,停不下来。b8bb3663b6df9aa77dbed66d2ce6f7ed.pngb8bb3663b6df9aa77dbed66d2ce6f7ed.pngb8bb3663b6df9aa77dbed66d2ce6f7ed.png。我打算去github找一个项目下载下来看看,成功解决问题的话再来更新。

d42a1fbf0e9881e57927c1025e00688c.png

还有参数下面这条线也搞不懂是什么意思,看ide的提示似乎是想表达你这个参数不建议随意改变,不安全。

1b1aa70bfe8841f1a01984b4913509cc.png

这个问题很久都没找到解决办法。03f4183ab7f908609fbf11bfcd2c1019.png

讨论区

03

全部代码

game.java

package com.example.mygame;import android.annotation.SuppressLint;import android.app.AlertDialog;import android.content.Context;import android.content.DialogInterface;import android.graphics.Point;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.MotionEvent;import android.view.View;import android.widget.GridLayout;import java.util.ArrayList;import java.util.List;import java.util.concurrent.atomic.AtomicBoolean;public class Game extends GridLayout {    //记录4*4的卡片数据    private Crad[][] cadrsMap = new Crad[4][4];    //记录空卡片的集合    private List<Point> emptyPoints = new ArrayList<>();    public Game(Context context) {        super(context);        initGameView();    }    public Game(Context context, AttributeSet attrs) {        super(context, attrs);        initGameView();    }    public Game(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initGameView();    }    //初始化游戏核心布局(方格子)    @SuppressLint("ResourceAsColor")private void initGameView() {        //设置列数        setColumnCount(4);        addcareds(Getwidth(),Getwidth());        //设置颜色        setBackgroundColor(R.color.colorAccent);        //触摸监听事件        setOnTouchListener(new OnTouchListener() {            //4个变量记录初始位置和变化值            private float startX, startY, offsetX, offsetY;            @Override            public boolean onTouch(View v, MotionEvent event) {                switch (event.getAction()) {                    case MotionEvent.ACTION_DOWN:                        //记录初始位置                        startX = event.getX();                        startY = event.getY();                        break;                    case MotionEvent.ACTION_UP:                        //记录偏移量                        offsetX = event.getX() - startX;                        offsetY = event.getY() - startY;                        //X的偏移量大于Y的偏移量                        if (Math.abs(offsetX) > Math.abs(offsetY)) {                            if (offsetX < -5) {                                //向左边滑动的操作                                swpeLeft();                            } else {                                //向右边滑动的操作                                swipeRight();                            }                        } else {                            //向上和向下                            if (offsetY < -5) {                                swipeUp();                            } else {                                swipeDown();                            }                        }                        break;                }                return true;            }        });//        startgame();    }    private int Getwidth() {        DisplayMetrics display  = getResources().getDisplayMetrics();        int cardswidth;        cardswidth = display.widthPixels;        return (cardswidth-10)/4;    }    //当窗口大小改变时执行    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        //记录卡片大小       // int carwidth = (Math.min(w, h) - 10) / 4;        //添加卡片      //  addcareds(carwidth, carwidth);        //开始游戏        startgame();    }    //添加卡片    private void addcareds(int carwidth, int carwidth1) {        Crad card;        for (int i = 0; i < 4; i++) {            for (int j = 0; j < 4; j++) {                card = new Crad(getContext());                card.setNum(0);                //卡片是正方形的,所以长和宽是等高的                addView(card, carwidth, carwidth1);                cadrsMap[i][j] = card;  //将卡片与caedsMAp绑定            }        }    }    private void addRandomcards() {        //清空记录空卡片的集合        emptyPoints.clear();        for (int i = 0; i < 4; i++) {            for (int j = 0; j < 4; j++) {                if (cadrsMap[i][j].getNum() <= 0) {                    emptyPoints.add(new Point(j, i));                }            }        }        //从空卡片里面随机选择一个卡片        Point point = emptyPoints.remove((int) (Math.random() * emptyPoints.size()));        cadrsMap[point.x][point.y].setNum(Math.random() > 0.1 ? 2 : 4);    }    //开始游戏    private void startgame() {        //分数清零        MainActivity.getMainActivity().clearScore();        for (int i = 0; i < 4; i++) {            for (int j = 0; j < 4; j++) {                cadrsMap[j][i].setNum(0);   //初始值为零            }        }        //随机生成两个卡片        addRandomcards();        addRandomcards();    }    //向下移动的方法    private void swipeDown() {        AtomicBoolean flag = new AtomicBoolean(false);        for (int y = 0; y < 4; y++) {            for (int x = 3; x >=0 ; x--) {                for (int x1 = x - 1; x1 >=0; x1--) {                    if (cadrsMap[x1][y].getNum() > 0) {  //如果枚举位置有卡片                        if (cadrsMap[x][y].getNum() <= 0) {  //如果当前位置没有卡片                            cadrsMap[x][y].setNum(cadrsMap[x1][y].getNum());                            cadrsMap[x1][y].setNum(0);                            x++;    //向下移动                            flag.set(true);                        } else if (cadrsMap[x1][y].equals(cadrsMap[x1][y])) {                            cadrsMap[x][y].setNum(cadrsMap[x][y].getNum() * 2);                            cadrsMap[x1][y].setNum(0);                            MainActivity.getMainActivity().addScore(cadrsMap[x][y].getNum());                            flag.set(true);                        }                        break;                    }                }            }        }        if (flag.get()) {            addRandomcards();            checkcomplet();        }    }    //向上移动的方法    private void swipeUp() {        boolean flag = false;        for (int y = 0; y < 4; y++) {            for (int x = 0; x < 4; x++) {                for (int x1 = x + 1; x1 < 4; x1++) {                    if (cadrsMap[x1][y].getNum() > 0) {  //如果美剧位置有卡片                        if (cadrsMap[x][y].getNum() <= 0) {  //如果当前位置没有卡片                            cadrsMap[x][y].setNum(cadrsMap[x1][y].getNum());                            cadrsMap[x1][y].setNum(0);                            x--;    //向上移动                            flag = true;                        } else if (cadrsMap[x][y].equals(cadrsMap[x1][y])) {                                    cadrsMap[x][y].setNum(cadrsMap[x][y].getNum() * 2);                                    cadrsMap[x1][y].setNum(0);                                    MainActivity.getMainActivity().addScore(cadrsMap[x][y].getNum());                                    flag = true;                        }                        break;                    }                }            }        }        if (flag) {            addRandomcards();            checkcomplet();        }    }    //向右移动的方法    private void swipeRight() {        boolean flag = false;        for (int x = 0; x < 4; x++) {            for (int y = 3; y > 0; y--) {                for (int y1 = y - 1; y1 >= 0; y1--) {                    if (cadrsMap[x][y1].getNum() > 0) {  //如果美剧位置有卡片                        if (cadrsMap[x][y].getNum() <= 0) {  //如果当前位置没有卡片                            cadrsMap[x][y].setNum(cadrsMap[x][y].getNum());                            cadrsMap[x][y1].setNum(0);                            y++;    //向右移动                            flag = true;                        } else if (cadrsMap[x][y1].equals(cadrsMap[x][y1])) {                            cadrsMap[x][y].setNum(cadrsMap[x][y].getNum() * 2);                            cadrsMap[x][y1].setNum(0);                            MainActivity.getMainActivity().addScore(cadrsMap[x][y].getNum());                            flag = true;                        }                        break;                    }                }            }        }        if (flag) {            addRandomcards();            checkcomplet();        }    }    //向左移动的方法    private void swpeLeft() {        boolean flag = false;        for (int x = 0; x < 4; x++) {            for (int y = 0; y < 4; y++) {                for (int y1 = y + 1; y1 < 4; y1++) {                    if (cadrsMap[x][y1].getNum() > 0) {  //如果美剧位置有卡片                        if (cadrsMap[x][y].getNum() <= 0) {  //如果当前位置没有卡片                            cadrsMap[x][y].setNum(cadrsMap[x][y].getNum());                            cadrsMap[x][y1].setNum(0);                            y--;    //向前移动                            flag = true;                        } else if (cadrsMap[x][y1].equals(cadrsMap[x][y1])) {                            cadrsMap[x][y].setNum(cadrsMap[x][y].getNum() * 2);                            cadrsMap[x][y1].setNum(0);                            MainActivity.getMainActivity().addScore(cadrsMap[x][y].getNum());                            flag = true;                        }                        break;                    }                }            }        }        if (flag) {            addRandomcards();            checkcomplet();        }    }    //检查是否结束游戏    private void checkcomplet() {        boolean complet = true;        All:        for (int x = 0; x < 4; x++) {            for (int y = 0; y < 4; y++) {                //判断各个位置是否还有空闲的,来判断游戏是否结束                if (cadrsMap[x][y].getNum() == 0 ||                        (x - 1 >= 0 && cadrsMap[x][y].equals(cadrsMap[x - 1][y])) ||                        (x + 1 > 0 && cadrsMap[x][y].equals(cadrsMap[x + 1][y])) ||                        (y + 1 > 0 && cadrsMap[x][y].equals(cadrsMap[x][y + 1])) ||                        (y - 1 >= 0 && cadrsMap[x][y].equals(cadrsMap[x][y - 1]))) {                    complet = false;                    break All;                }            }        }        //游戏结束        if (complet) {            new AlertDialog.Builder(getContext())                    .setTitle("抱歉")                    .setMessage("游戏结束 \n game over")                    .setPositiveButton("再来一次", new DialogInterface.OnClickListener() {                        //重新开始游戏                        @Override                        public void onClick(DialogInterface dialog, int which) {                            startgame();                        }                    });        }    }}

Crad.java

package com.example.mygame;import android.content.Context;import android.graphics.Color;import android.util.Log;import android.view.Gravity;import android.widget.FrameLayout;import android.widget.TextView;import androidx.annotation.NonNull;public class Crad extends FrameLayout {    public String CARD = "cradLog";    //记录卡片颜色    private int [] cardcolor = new int[30];    //卡片的lable组件    private TextView lable;    //默认数字    private int num =  0;//初始化卡片颜色    public void setColor() {        cardcolor[0] = Color.BLUE;        cardcolor[1] = Color.MAGENTA;        cardcolor[2] = Color.MAGENTA;        cardcolor[3] = Color.DKGRAY;        cardcolor[4] = Color.BLACK;        cardcolor[5] = Color.CYAN;        cardcolor[6] = Color.DKGRAY;        cardcolor[7] = Color.YELLOW;        cardcolor[8] = Color.WHITE;        cardcolor[9] = Color.GRAY;        cardcolor[10] = Color.TRANSPARENT;    }    public Crad(@NonNull Context context) {        super(context);        setColor();        lable = new TextView(getContext());        lable.setTextSize(32);        lable.setBackgroundColor(0x33ffffff);        lable.setGravity(Gravity.CENTER);  //布局剧中        LayoutParams lp = new LayoutParams(-1,-1);        lp.setMargins(10,10,0,0);        addView(lable,lp);        setNum(0);    }    //获取数字    public int getNum() {        return num;    }//设置数字    public void setNum(int num) {        this.num = num;        if (num<= 0){            lable.setBackgroundColor(Color.RED);  // 设置为红色            lable.setText("");        }else {            //取log得到X的颜色            int x =(int) (Math.log((double)num));            Log.i(CARD,"日志输出x的值为:"+x);            x%=11;            lable.setBackgroundColor(cardcolor[x]);            lable.setText(num +"");        }    }    public boolean equals(Crad o) {        return num == o.getNum();    }}

Mainactivity.java

package com.example.mygame;import android.os.Bundle;import android.view.Menu;import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {    private static MainActivity mainActivity = null;    private TextView tvsroce;    private int score = 0;    public MainActivity() {        setMainActivity(this);    }    private static void setMainActivity(MainActivity mainActivity) {        MainActivity.mainActivity = mainActivity;    }    public static MainActivity getMainActivity() {        return mainActivity;    }    public void clearScore() {        score = 0;        showScore();    }    public void showScore() {        tvsroce.setText(score + "");    }    public void addScore(int s) {        score += s;        showScore();    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        tvsroce = findViewById(R.id.tvscore);    }    //    三个小圆点  菜单按键    @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.main, menu);        return true;    }}

activity_main.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:paddingTop="30dp"    android:paddingBottom="80dp"    android:orientation="vertical"    tools:context=".MainActivity">    <LinearLayout        android:orientation="horizontal"        android:layout_width="match_parent"        android:layout_height="wrap_content"       >        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="@string/score"/>        <TextView            android:id="@+id/tvscore"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="@string/tvScore"/>    LinearLayout>    <com.example.mygame.Game        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1"        android:id="@+id/gameView"        >    com.example.mygame.Game>LinearLayout>

4144bd42eaa532650612fa5bb6500415.png


The End.

be close to me

和我一起,做一个灵气十足的少年!

031f044a802aee584a8342ec5c7cd8d6.png

都看到这里了点个赞👍(花)再走吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值