18

Android 不规则图像填充 小玩着色游戏

 4 years ago
source link: https://blog.csdn.net/lmj623565791/article/details/45788433
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Android 不规则图像填充 小玩着色游戏

转载请标明出处:
http://blog.csdn.net/lmj623565791/article/details/45788433
本文出自:【张鸿洋的博客】

近期群里偶然看到一哥们在群里聊不规则图像填充什么四联通、八联通什么的,就本身好学务实的态度去查阅了相关资料。对于这类着色的资料,最好的就是去搜索些相关app,根据我的观察呢,不规则图像填充在着色游戏里面应用居多,不过大致可以分为两种:

  • 基于层的的填充
  • 基于边界的填充

那么针对上述两种,我们会通过两篇博文来讲解,本篇就是叙述基于层的填充方式,那么什么基于层的填充方式呢?其实就是一张图实际上是由多个层组成的,每个层显示部分图像(无图像部分为透明),多层叠加后形成一张完整的图案,图层间是叠加的关系,类似下图。

20150517140110724

相信大家如果学过PS,对上述肯定再了解不过了。比如你要绘制一个天空,你可以最底层去绘制蓝天,在上层绘制白云,再上层会执行小鸟。然后三层叠加以后就是一副小鸟在天空翱翔的图了。

二、效果与分析

好了,接下来看下今天的效果。

20150517140141581

ok,可以看到一个简单的着色效果,其实原理很简单,首先呢,该图实际上是由7层组成:

例如下图。

20150517140207742

那么如果我们需要给这幅图的某个位置着色,实际上是给某一层的非透明区域着色。实际上就转化为:

用户点击的(x,y)-> 判断落在哪一层的非透明区域 -> 然后给该层非透明区域着色。

ok,这样原理就叙述清楚了,实际上也是非常的简单,基于该原理,我们可以自定义一个View,然后一幅一幅去绘制图层,最后按照上述步骤去编写代码。不过,我们还有可以偷懒的地方,其实没必要我们自己去一个图层一个图层的绘制,我们可以利用Drawable去完成图层叠加的工作,我们有一类Drawable叫做LayerDrawable,对应的xml为layer-list,我们可以通过使用LayerDrawable极大的简化我们的工作。

三、编码与实现

上述已经描述很清楚了,我再给大家细化一下:

  1. layer-list中去定义我们的drawable
  2. 然后把该drawable作为我们View的背景
  3. 复写onTouchEvent方法
  4. 判断用户点击的坐标落在哪一层的非透明位置,改变该层非透明区域颜色

(一)layer-list

    <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/eel_mask1"/>
    <item
        android:drawable="@drawable/eel_mask2"/>
    <item
        android:drawable="@drawable/eel_mask3"/>
    <item
        android:drawable="@drawable/eel_mask4"/>
    <item
        android:drawable="@drawable/eel_mask5"/>
    <item
        android:drawable="@drawable/eel_mask6"/>
    <item
        android:drawable="@drawable/eel_mask7"/>
</layer-list>

ok,这样我们的drawable就ok了~~没撒说的,不过layer-list可以做很多事情,大家可以关注下。

(二)View代码

package com.zhy.colour_app_01;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import java.util.Random;

/**
 * Created by zhy on 15/5/14.
 */
public class ColourImageBaseLayerView extends View
{

    private LayerDrawable mDrawables;

    public ColourImageBaseLayerView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        mDrawables = (LayerDrawable) getBackground();

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        setMeasuredDimension(mDrawables.getIntrinsicWidth(), mDrawables.getIntrinsicHeight());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        final float x = event.getX();
        final float y = event.getY();
        if (event.getAction() == MotionEvent.ACTION_DOWN)
        {
            Drawable drawable = findDrawable(x, y);
            if (drawable != null)
                drawable.setColorFilter(randomColor(), PorterDuff.Mode.SRC_IN);
        }

        return super.onTouchEvent(event);
    }

    private int randomColor()
    {
        Random random = new Random();
        int color = Color.argb(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));
        return color;
    }

    private Drawable findDrawable(float x, float y)
    {
        final int numberOfLayers = mDrawables.getNumberOfLayers();
        Drawable drawable = null;
        Bitmap bitmap = null;
        for (int i = numberOfLayers - 1; i >= 0; i--)
        {
            drawable = mDrawables.getDrawable(i);
            bitmap = ((BitmapDrawable) drawable).getBitmap();
            try
            {
                int pixel = bitmap.getPixel((int) x, (int) y);
                if (pixel == Color.TRANSPARENT)
                {
                    continue;
                }
            } catch (Exception e)
            {
                continue;
            }
            return drawable;
        }
        return null;
    }

}

ok,代码也比较简单,首先我们把drawable作为view的背景,然后在构造中获取drawable(LayerDrawable)。接下来复写onTouchEvent,捕获用户点击的(x,y),根据(x,y)去找出当前点击的是哪一层(必须点击在非透明区域),最后通过设置setColorFilter去改变颜色即可~很easy吧最后贴下布局文件:

(三)布局文件

<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                tools:context=".MainActivity">

    <com.zhy.colour_app_01.ColourImageBaseLayerView
        android:background="@drawable/eel"
        android:layout_width="match_parent"
        android:layout_centerInParent="true"
        android:layout_height="match_parent"/>

</RelativeLayout>

ok~基于层的的填充就介绍完了,下一篇基于边界的填充,敬请期待~~

群号:264950424,欢迎入群

源码点击下载

微信公众号:hongyangAndroid
(欢迎关注,第一时间推送博文信息)
1422600516_2905.jpg


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK