stackland怎么把堆叠的卡牌拆开

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了stackland怎么把堆叠的卡牌拆开相关的知识,希望对你有一定的参考价值。

stackland怎么把堆叠的卡牌拆开
StackView也是AdapterView Animator的子类,它也用于显示Adapter提供的一系列View。 StackView将会以堆叠(Stack)的方式来显示多个列表项。    为了控制StackView显示的View组件,StackView提供了如下两种控制方式。拖走StackView中处于顶端的View,下一个View将会显示出来。将上一个View拖进StackView,将使之显示出来。通过调用StackView的showNext()、showPrevious()控制显示下一个、上一个组件。二、StackView示例    接下来通过一个简单的示例程序来学习StackView的使用方法。    继续使用WidgetSample工程的listviewsample模块,在app/main/res/layout/目录下创建stackview_layout.xml文件,在其中填充如下代码片段:

        android:orientation="horizontal"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center_horizontal">
            android:id="@+id/prev_btn"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="上一个"/>
            android:id="@+id/next_btn"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="下一个"/>
        android:id="@+id/stackview"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:loopViews="true"/>

    创建一个MyStackAdapter类,继承BaseAdapter类,重写其4个主要方法,具体代码如下:

package com.jinyu.cqkxzsxy.android.listviewsample.adapter;import android.content.Context;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;/** * @创建者 鑫鱻 * @描述 Android零基础入门到精通系列教程,欢迎关注微信公众号ShareExpert */publicclassMyStackAdapterextends BaseAdapter     privateContext mContext =null;    privateint[] mImageIds =null;    publicMyStackAdapter(Context context,int[] imageIds)         this.mContext = context;        this.mImageIds = imageIds;        @Override    publicint getCount()         return mImageIds.length;        @Override    publicObject getItem(int position)         return position;        @Override    publiclonggetItemId(int position)         return position;        // 该方法返回的View代表了每个列表项    @Override    publicView getView(int position, View convertView, ViewGroup parent)         ImageView imageView =null;        if(null== convertView)             // 创建一个ImageViewimageView =new ImageView(mContext);            // 设置ImageView的缩放类型            imageView.setScaleType(ImageView.ScaleType.FIT_XY);            // 为imageView设置布局参数imageView.setLayoutParams(new ViewGroup.LayoutParams(                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));            convertView = imageView;        else             imageView = (ImageView) convertView;                // 给ImageView设置图片资源        imageView.setImageResource(mImageIds[position]);        return imageView;   

    接下来为StackView提供Adapter,使用自定义的BaseAdapter。新建StackViewActivity.java文件,加载上面新建的布局文件,具体代码如下:

package com.jinyu.cqkxzsxy.android.listviewsample;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import android.widget.StackView;import com.jinyu.cqkxzsxy.android.listviewsample.adapter.MyStackAdapter;publicclassStackViewActivityextendsAppCompatActivityimplements View.OnClickListener     privateStackView mStackView =null;    privateButton mPrevBtn =null;    privateButton mNextBtn =null;    privateint[] mImageIds =             R.drawable.image_01, R.drawable.image_02, R.drawable.image_03, R.drawable.image_04,            R.drawable.image_05, R.drawable.image_06, R.drawable.image_07, R.drawable.image_08    ;    @Override    protectedvoid onCreate(Bundle savedInstanceState)         super.onCreate(savedInstanceState);        setContentView(R.layout.stackview_layout);        // 获取界面组件mStackView = (StackView) findViewById(R.id.stackview);        mPrevBtn = (Button) findViewById(R.id.prev_btn);        mNextBtn = (Button) findViewById(R.id.next_btn);        // 为AdapterViewFlipper设置AdapterMyStackAdapter adapter =newMyStackAdapter(this, mImageIds);        mStackView.setAdapter(adapter);        // 为三个按钮设置点击事件监听器mPrevBtn.setOnClickListener(this);        mNextBtn.setOnClickListener(this);        @Override    publicvoid onClick(View view)         switch (view.getId())            case R.id.prev_btn:                // 显示上一个组件                mStackView.showPrevious();                break;            case R.id.next_btn:                // 显示下一个组件                mStackView.showNext();                break;            default:                break;           

    修改程序启动的Activity,运行程序,可以看到下图所示界面效果。

    点击上一个或下一个按钮时,StackView将会将组件分别显示出来。当拖动StackView的组件时,也可以实现同样的效果。
参考技术A 首先登陆stackland平台选择卡牌操作,选择堆叠的卡牌后点击鼠标右记选择拆分卡牌即可。 参考技术B stackland把堆叠的卡牌拆开,需要装备手套提升到最高技能,提升技能需要先去人际星接任务,找到守卫。然后打败蝙蝠,然后坐船去虚灵星打败骷髅怪,然后找到守卫就可以提升装备了

如何制作一个羊了个羊游戏1:堆叠牌的拾取

本文首发于微信公众号【小蚂蚁教你做游戏】,欢迎关注领取更多学习做游戏的原创教程资料,每天学点儿游戏开发知识。

嗨!大家好,我是小蚂蚁。

最近“羊了个羊”小游戏爆火。一下子让想做微信小游戏或者想学做微信小游戏的人多了很多,因为小蚂蚁一直都在长期的制作微信小游戏开发的教程,以及制作微信小游戏,所以我无缘无故的也因为这波热度得到了不少的“羊毛”。

不少人建议我写个“羊了个羊”游戏的制作教程,想了一下,为什么不写呢?反正我也是要长期持续写教程的,写别的游戏也是写,那为什么不写写当下如此爆火的游戏呢?羊毛都怼到脸上了,再不薅几把就显得有点儿奇怪了。

好了,废话不多说了。欢迎跟随者小蚂蚁开启你的游戏开发制作之旅。

这个系列教程会包含很多节(我也不知道几节能够写完),我会带你从零开始制作一个“羊了个羊”类型的消除游戏。通过学习教程,你将能够自己动手制作一个“羊了个羊”类型的游戏,并且是一个第二关可以闯过的游戏。

教程所使用的游戏开发工具是【微信小游戏制作工具】,这是微信官方出品的用于制作微信小游戏的开发工具,全中文环境,可视化的积木编程,面向的是没有任何开发经验的普通人,很容易上手,借助它你可以快速的制作出自己的微信小游戏。

接下来,让我们正式开始第一节的内容吧!

“羊了个羊”游戏本质上还是一个消除游戏,在下方的槽中凑满三个一样的图标即可消除。它跟其它消除游戏的最大的不同,在于它的布局方式上。一般的消除游戏都是一种平面的布局,即整体上是几行几列的平面,但是“羊了个羊”游戏中是一种堆叠的布局,即在一层上会叠加另一层,甚至很多层。

这比平面的布局多了一个“”的概念,图标是一层一层排列的,第一层的图标上如果有第二层图标压着它,那它就不可拾取,这个多层的堆叠布局就是这个游戏实现的难点之一。

这节课中我们就先来解决这个“堆叠牌拾取”的难点。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_小游戏

如图,我们将会制作一个这样的示例,一共有两层牌,第一层牌是 3 行 x 5 列,第二层牌是 3 行 x 4列。可拾取的牌用白色表示,不可拾取的牌用红色表示,游戏开始后,显示两层牌的布局,点击白色牌时,白色牌消失(相当于拾取),点击红色牌,红色牌不会消失(相当于不可拾取),每拾取一张牌后,所有剩余牌的状态都会刷新,如果当前牌由不可拾取状态,变为可拾取状态,则它的颜色会由红色变为白色。(文字描述有些长,大家可以借着上方的动图来理解这个示例要做的事情)

两层牌堆叠的初始布局

我们先来实现两层牌的初始布局。其实我们可以先来看看如何创建一层,因为创建一层后,再创建一层就是两层了。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_游戏开发_02

如图是第一层的 3x5 的网格布局,我们先计算出它的左上角的起点的位置。计算公式在图中列出了,如果你之前有看过小蚂蚁的教程,就应该知道,关于这个网格布局的计算我已经讲过太多次了,所以这次我就不再讲了,拿出你的纸和笔,画一画,写一写,这两个计算公式就能很好理解了。

在计算出左上角的起点位置之后,我们就可以从这里开始,依次的去一行一行的创建每一张牌了。那如何设置每张牌的位置呢?

如何制作一个羊了个羊游戏1:堆叠牌的拾取_微信_03

如图,在知道一些已知条件之后,我们可以根据右边的计算公式,计算得到网格布局中的每个位置上的张牌的坐标。

这样第一层牌的计算公式就有了,接着看第二层牌。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_小游戏_04

如图,绿色的网格表示第二层牌,第二层牌压在第一层牌之上,而且它相对于第一层牌还有一个向上向右的偏移,从图中可以很直观的看出来,第二层左上角的起点位置,相对于第一层左上角的起点位置,向右上方偏移了半个格子,所以计算公式也很容易推出来,除了起点位置的计算不同,第二层牌的坐标位置的计算公式与第一层牌是一样的。

到这里,创建两层堆叠牌的理论基础我们就搞定了,接下来到微信小游戏制作工具中实现一下。

来到微信小游戏制作工具中,首先我们准备两个素材。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_微信_05

如图,一个是“卡牌”的图片,一个是“创建卡牌”的方块,这个方块不会在游戏中显示,它只是用于放置创建卡牌的积木逻辑。

接着,我们再创建一些全局变量

如何制作一个羊了个羊游戏1:堆叠牌的拾取_游戏开发_06

第一层起点位置X/Y:用于记录第一层卡牌左上角起点的位置;

第二层起点位置X/Y:用于记录第二层卡牌左上角起点的位置;

单元格的宽度/高度:用于设置每个卡牌所占用的格子的宽度和高度(这里我们把格子的大小设置为 100x120);

当前创建的卡牌层级:用于区分当前创建的是第一层卡牌还是第二层卡牌;

行/列迭代:用于循环中的遍历;

网格中点位置X/Y:用于设置整个网格布局的中心位置。

除了这些全局变量之外,我们还创建了两个表格数据(这个在后续会用到)。

第一层表格:用于记录第一层卡牌的状态;

第二层表格:用于记录第二层卡牌的状态;

接着来看一下“创建卡牌”精灵上的积木逻辑。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_游戏开发_07

如何制作一个羊了个羊游戏1:堆叠牌的拾取_微信_08

根据之前推导出的计算公式,先计算出两层网格的左上角起点的位置,接着使用双重循环,一行一行的创建卡牌,这里注意了,我们使用“当前创建的卡牌层级”这个变量来区分创建的是哪一层的牌,另外每一层创建多少张牌,是根据这一层的表格来确定的(这个稍后会讲),除此之外,在创建卡牌前我们还进行了一个判断,只有表格中当前位置上的数据为 1 时,才创建卡牌,可以先猜一下为什么要这样。

接着,再看一下卡牌上的积木逻辑。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_小游戏_09

卡牌被创建出来之后,根据不同的层级,来计算和设置自己的坐标位置(计算用的就是我们上方推导出的卡牌位置坐标的计算公式)。

你应该也发现了,在卡牌克隆逻辑刚开始的时候,我们设置了几个变量,这几个变量都是位于“卡牌”上的局部变量。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_小游戏_10

行/列号:记录当前卡牌在整个网格布局中的行列号位置;

层级:记录当前卡牌位于第几层;

是否可抽取:用于判断当前的卡牌是否可以点击拾取(如果上方被其它卡牌压住了就不能拾取);

到这里,两层牌堆叠的初始布局就制作好了,可以点击预览看一下。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_网格布局_11

因为我们在创建第二层牌之前等待了 0.5 秒,所以能够明显的看出两层牌的创建顺序。

检测卡牌的状态

完成初始布局之后,接着我们来实现第二个功能,每张牌都有两个状态,一个是可拾取状态,一个是不可拾取状态。我们使用不同的颜色来区分卡牌的状态,红色表示不可拾取,白色表示可拾取。

两层共计 27 张牌,如何判断哪张牌是可拾取的,哪张牌是不可拾取的呢?接下来我们就需要借助数据抽象了。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_网格布局_12

如图,我们将两个表格中填满了数字 1,1 表示的就是这个位置上有牌,如果一个位置上的牌被取走了,我们就把该位置上的 1 设置为 0,表示这个位置上没有牌了。

这里我们把这两个表格平铺开了,因为这样方便查看,其实它们在游戏中更像是下面这样。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_网格布局_13

看起来很混乱,所以后续讲解的时候我们还是将它们平铺开来,但是你要能够自己脑补它们堆叠的样子。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_网格布局_14

来看一下这张图,左下角的蓝色牌是第一层的牌,它目前是不可拾取状态,如果它要变成拾取状态的话,就需要拿走第二层左下角第一张红色的牌,对不对?也就是说,第一层某个位置上的牌能不能拾取,要取决于第二层有没有牌压在它上面,如果有的话,那它就是不可拾取状态,否则的话是可拾取状态

接着再来看一下另外两种情况。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_小游戏_15

如何制作一个羊了个羊游戏1:堆叠牌的拾取_微信_16

一种是有两张牌压着蓝牌,一种是有四张牌压着蓝牌。

第一层牌到底能不能拾取,好像不但跟第二层牌有关,而且还跟它自己的位置有关,有的位置只有一张牌压着它,有的位置有两张压着它,有的位置有四张牌压着它.....看起来好像是没有什么规律,但是作为一个游戏开发者,你一定要相信,它背后肯定是有规律的,而找到这个规律,就是解决这个问题的关键。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_小游戏_17

如图,就是我找到的规律,假设当前需要判断第一层牌中行列号为 (2,4) 的牌的状态,那就需要判断第二层 4 个位置上是否有牌,这四个位置分别为(2,4),(3,4),(2,3),(3,3),第一层上的所有牌的状态判断都满足这个规律。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_小游戏_18

如何制作一个羊了个羊游戏1:堆叠牌的拾取_网格布局_19

对于边角位置也依然满足这个规律,因为有些位置超出了第二个表格边界,超出表格边界的位置其实就相当于没有牌。

如果你的抽象能力不是很强的话,这部分读起来会很困难,不过没关系,我建议你利用现实中的道具来帮助自己理解。比如我在找这个规律的时候,就借助扑克牌来帮助自己理解这些抽象的数据表格。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_网格布局_20

好了,找到规律了,这个问题就解决一大半了。接下来,让我们去小游戏制作工具中实现一下吧!

还记得我们之前创建的两个表格数据吗?它们中的内容如下:

如何制作一个羊了个羊游戏1:堆叠牌的拾取_微信_21

如何制作一个羊了个羊游戏1:堆叠牌的拾取_游戏开发_22

要实现所有卡牌状态的更新,我们需要借助通知,所以在数据区中创建一个“刷新卡牌”的通知。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_游戏开发_23

接着来看一下“刷新卡牌”的积木逻辑。这段逻辑位于“卡牌”精灵上。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_小游戏_24

如何制作一个羊了个羊游戏1:堆叠牌的拾取_游戏开发_25

看上去挺长的,其实实现的就是我们上方找到的那个规律,分别判断第二层表格中的四个位置,如果任何一个位置上有牌,那么第一层这个牌就不能抽取,否则的话,就能抽取。图中你看到的那个很长的判断积木,其实就是为了判断这个位置是否超出了第二个表格的边界,位于边界之外的我们也当作无牌的情况。最后,如果当前牌是第二层的话,那全部设置为可抽取状态,因为目前第二层就是最上层了。

最后,再来看一下卡牌点击的积木逻辑。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_小游戏_26

如果当前牌不能抽取的话,我们就让它抖动一下,如果能抽取的话,根据它的层级设置对应的表格中的数据为 0 (表格这个位置上没有牌了),另外每当有牌被取走了,我们都应该刷新一下剩余牌的状态,这里使用了对所有卡牌的通知,让剩余的所有卡牌刷新自己的状态,最后删除掉抽取的这个卡牌。(这里暂时做简单的删除处理,在游戏中抽取的卡牌应该移动到下方的卡槽中,这个我们后续做到的时候再讲)

这样,一个堆叠牌的拾取功能就完成啦!什么?有点儿难呐?多看几遍,尽量去理解,然后多动手做,难一点的事情做到后才会有满满的成就感,加油!

在这个示例中,我们使用的是 3x5,3x4 这样满满当当的布局,如果不想要这样满当的布局该怎么做?正常游戏中每一关的布局可都是不一样的呢!

很简单,调整一个两个表格中数据即可,有牌的地方放个 1 ,没牌的地方放个 0。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_小游戏_27

如何制作一个羊了个羊游戏1:堆叠牌的拾取_网格布局_28

再次预览一下,就有新的关卡布局啦!

如何制作一个羊了个羊游戏1:堆叠牌的拾取_微信_29

在这篇教程里,我们学到了两层堆叠牌的实现,那三层呢?四层呢?五层呢?...... 原理都是一样的,接下去就是你动手挑战的机会啦!


欢迎关注小蚂蚁的微信公众号【小蚂蚁教你做游戏】,学习更多游戏开发原创教程。

如何制作一个羊了个羊游戏1:堆叠牌的拾取_网格布局_30

以上是关于stackland怎么把堆叠的卡牌拆开的主要内容,如果未能解决你的问题,请参考以下文章

力扣2022年1024卡牌活动,程序员怎么判断自己的卡牌能否组成1024?那就愉快地编程实现吧︕

[usaco dec 15] 卡牌游戏 cardgame [贪心]

Dracoo Master天龙卡牌大师

CSS3习题2(卡牌旋转)

利用浏览器缓存抓取网络资源:炉石传说所有卡牌png图片地址

100行代码教你写个卡牌翻翻乐小游戏