

Android 不规则图像填充 小玩着色游戏
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.

Android 不规则图像填充 小玩着色游戏
转载请标明出处:
http://blog.csdn.net/lmj623565791/article/details/45788433;
本文出自:【张鸿洋的博客】
近期群里偶然看到一哥们在群里聊不规则图像填充什么四联通、八联通什么的,就本身好学务实的态度去查阅了相关资料。对于这类着色的资料,最好的就是去搜索些相关app,根据我的观察呢,不规则图像填充在着色游戏里面应用居多,不过大致可以分为两种:
- 基于层的的填充
- 基于边界的填充
那么针对上述两种,我们会通过两篇博文来讲解,本篇就是叙述基于层的填充方式,那么什么基于层的填充方式呢?其实就是一张图实际上是由多个层组成的,每个层显示部分图像(无图像部分为透明),多层叠加后形成一张完整的图案,图层间是叠加的关系,类似下图。
相信大家如果学过PS,对上述肯定再了解不过了。比如你要绘制一个天空,你可以最底层去绘制蓝天,在上层绘制白云,再上层会执行小鸟。然后三层叠加以后就是一副小鸟在天空翱翔的图了。
二、效果与分析
好了,接下来看下今天的效果。
ok,可以看到一个简单的着色效果,其实原理很简单,首先呢,该图实际上是由7层组成:
例如下图。
那么如果我们需要给这幅图的某个位置着色,实际上是给某一层的非透明区域着色。实际上就转化为:
用户点击的(x,y)-> 判断落在哪一层的非透明区域 -> 然后给该层非透明区域着色。
ok,这样原理就叙述清楚了,实际上也是非常的简单,基于该原理,我们可以自定义一个View,然后一幅一幅去绘制图层,最后按照上述步骤去编写代码。不过,我们还有可以偷懒的地方,其实没必要我们自己去一个图层一个图层的绘制,我们可以利用Drawable去完成图层叠加的工作,我们有一类Drawable叫做LayerDrawable,对应的xml为layer-list,我们可以通过使用LayerDrawable
极大的简化我们的工作。
三、编码与实现
上述已经描述很清楚了,我再给大家细化一下:
- layer-list中去定义我们的drawable
- 然后把该drawable作为我们View的背景
- 复写onTouchEvent方法
- 判断用户点击的坐标落在哪一层的非透明位置,改变该层非透明区域颜色
(一)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
(欢迎关注,第一时间推送博文信息)
Recommend
-
178
作者简介 敏岳 蚂蚁金服数据前端 在浏览器中,任意的二维平面图形均可以通过path路径的形式描述。然后底层api 直接静态绘制出来。但是如果想动态的绘制路径,浏览器是没有直接支持方式的。 本文就是解决这个问题, 为浏览器补全这个功能,让静态的路径能方便的动态...
-
45
-
106
README.md
-
21
前提:服务器返回图片布局形式,图片大小。如下图的布局形式为[1,3,2,1] 1. 了解FlexboxLayout功能
-
12
2018-03-03 • UGUI中几种不规则按钮的实现方式 UGUI中的按钮默认是矩形的,若要实现非矩形按钮该怎么做呢?比如这样的按钮:
-
12
转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/45954255; 本文出自:【张鸿洋...
-
9
PixiJS+自定义Shader实现不规则图片扫光效果 - 一行代码一行泪 - OSCHINA - 中文开源技术交流社区 用代码保护...
-
6
CSS filter 生成不规则边框.md之前做过很多特殊的布局,比如在这两篇文章 CSS 实现优惠券的技巧 、
-
3
← 大家听说过“一日一餐”(OMAD)饮食法吗majer @ 2023.04.24 , 13:20...
-
9
OPPO K11体验:2000元档也能拍好图,还能小玩几局游戏 ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK