在Cocos2dx中。对大图的处理已经封装好了一套自己的API,可是在Unity3D中貌似没有类似的API(好吧,实际上是有的,并且功能更强大),或者说我没找到。

只是这也在情理之中,毕竟Unity3D是做3D的。要分割图片的地方还是非常少的。

由于我用Unity3D主要是用于做2D游戏的(PS:非常蛋疼吧?我也认为),所以就不得不考虑切图和播放序列帧这两个在2D上常见的功能了,以下废话不多说。

我的任务是把以下这张图分割成16块。而且依照动画的序列播放出来。

查Unity3D的使用手冊的过程中,我发现了一个类:Texture2D,他是继承Texture的,主要是用于创建2D纹理的,很符合切图的须要。

首先,我们须要载入大图。载入大图有一个很easy的方法。就是创建一个public的Texture2D类成员变量,然后在编辑器中直接拖动到上去给他赋值就能够了。

当然也能够採用动态载入图片资源的方法,这样的方法比較麻烦。须要把图片先转换成二进制流,然后赋值给Texture2D

	//载入图片资源
void LoadTexture()
{
using (FileStream file = File.Open (Application.dataPath + "/Textures/Player.png", FileMode.Open))
{
using (BinaryReader reader = new BinaryReader(file))
{
m_texPlayer = new Texture2D (192, 256, TextureFormat.ARGB4444, false);
texture.LoadImage (reader.ReadBytes((int)file.Length));
}
}
}

载入完之后就要分割了。主要思路就是,两个for循环,一个表示行,一个表示列,然后再循环每一个像素点。把每一个像素点里面的颜色复制出来给分割的Texture2D,最后把Texture2D组合成一个4x4的矩阵数组。

以下是第一步:

        for (int i = 0; i < m_iMinPicColumnCount; ++i)
{
for (int j = 0; j < m_iMinPicRowCount; ++j)
DePackTexture(i, j);
}

上面的终于处理调用了一个DePackTexture,这个函数是用于实际上的分割的。

    //切图
void DePackTexture(int i, int j)
{
int cur_x = i * m_iMinPicWidth;
int cur_y = j * m_iMinPicHeight; Texture2D newTexture = new Texture2D(m_iMinPicWidth, m_iMinPicHeight); for (int m = cur_y; m < cur_y + m_iMinPicHeight; ++m)
{
for (int n = cur_x; n < cur_x + m_iMinPicWidth; ++n)
{
newTexture.SetPixel(n - cur_x, m - cur_y, m_texPlayer.GetPixel(n, m));
}
}
newTexture.Apply();
m_texPlayers[i, j] = newTexture;
}

切图值得注意的就是两点,一点就是找好位置,还有一点就是运行完SetPixel操作后一定要运行Apply,不然是没有效果的。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

以下是帧序列动画,帧序列动画实际上就是将图片依照一定的顺序载入上去,值得注意的是全部的GUI操作一定要放到OnGUI里面。

    void DrawAnimation(Texture[,] tex, Rect rect)
{
//绘制当前帧
GUI.DrawTexture(rect, tex[m_iCurFram, m_iCurAnimation], ScaleMode.StretchToFill, true, 0.0f);
//计算限制帧的时间
m_fTime += Time.deltaTime;
//超过限制帧切换贴图
if (m_fTime >= 1.0 / m_fFps && m_bStop == false)
{
//帧序列切换
m_iCurFram = ++m_iCurFram % m_iMinPicRowCount;
//限制帧清空
m_fTime = 0;
//超过帧动画总数从第0帧開始
if (m_iCurFram >= tex.Length)
{
m_iCurFram = 0;
}
}
}

然后没有什么了,代码还是非常easy的。以下附上所有的代码。这个我做成了一个小的demo,含有动画的開始和暂停功能。并且还有动画的帧速调整的功能。

(最后会附上demo的地址)

using UnityEngine;
using System.Collections;
using System; public class CTexture : MonoBehaviour
{
//大图的人
public Texture2D m_texPlayer;
//小图的人
private Texture2D[,] m_texPlayers;
//当前帧
private int m_iCurFram;
//当前动画
private int m_iCurAnimation;
//限制帧的时间
private float m_fTime = 0; //小图的宽和高
public int m_iMinPicWidth = 48;
public int m_iMinPicHeight = 64;
//一行有多少个小图
public int m_iMinPicRowCount = 4;
//一列有多少个小图
public int m_iMinPicColumnCount = 4; //动画控制
//暂停
private bool m_bStop = false;
//一秒多少帧
private float m_fFps = 4; private string m_sFps = ""; void Start()
{
m_texPlayers = new Texture2D[4, 4];
m_iCurAnimation = 0;
m_sFps = m_fFps.ToString();
//载入图片资源
LoadTexture(); for (int i = 0; i < m_iMinPicColumnCount; ++i)
{
for (int j = 0; j < m_iMinPicRowCount; ++j)
DePackTexture(i, j);
}
} void Update()
{
if(Input.GetKeyDown(KeyCode.A))
{
m_iCurAnimation = 2;
}
if (Input.GetKeyDown(KeyCode.S))
{
m_iCurAnimation = 3;
}
if (Input.GetKeyDown(KeyCode.W))
{
m_iCurAnimation = 0;
}
if (Input.GetKeyDown(KeyCode.D))
{
m_iCurAnimation = 1;
}
} void OnGUI()
{
DrawAnimation(m_texPlayers, new Rect(100, 100, m_iMinPicWidth, m_iMinPicHeight)); if(GUI.Button(new Rect(200,20,80,50),"開始/暂停"))
{
m_bStop = m_bStop == false ? true : false ;
} m_sFps = GUI.TextField(new Rect(200, 80, 80, 40), m_sFps);
if (GUI.Button(new Rect(200, 150, 50, 40), "应用"))
{
m_fFps = float.Parse(m_sFps);
}
} //载入图片资源
void LoadTexture()
{
using (FileStream file = File.Open (Application.dataPath + "/Textures/Player.png", FileMode.Open))
{
using (BinaryReader reader = new BinaryReader(file))
{
m_texPlayer = new Texture2D (192, 256, TextureFormat.ARGB4444, false);
texture.LoadImage (reader.ReadBytes((int)file.Length));
}
}
} //切图
void DePackTexture(int i, int j)
{
int cur_x = i * m_iMinPicWidth;
int cur_y = j * m_iMinPicHeight; Texture2D newTexture = new Texture2D(m_iMinPicWidth, m_iMinPicHeight); for (int m = cur_y; m < cur_y + m_iMinPicHeight; ++m)
{
for (int n = cur_x; n < cur_x + m_iMinPicWidth; ++n)
{
newTexture.SetPixel(n - cur_x, m - cur_y, m_texPlayer.GetPixel(n, m));
}
}
newTexture.Apply();
m_texPlayers[i, j] = newTexture;
} void DrawAnimation(Texture[,] tex, Rect rect)
{
//绘制当前帧
GUI.DrawTexture(rect, tex[m_iCurFram, m_iCurAnimation], ScaleMode.StretchToFill, true, 0.0f);
//计算限制帧的时间
m_fTime += Time.deltaTime;
//超过限制帧切换贴图
if (m_fTime >= 1.0 / m_fFps && m_bStop == false)
{
//帧序列切换
m_iCurFram = ++m_iCurFram % 4;
//限制帧清空
m_fTime = 0;
//超过帧动画总数从第0帧開始
if (m_iCurFram >= tex.Length)
{
m_iCurFram = 0;
}
}
}
}

demo地址:http://download.csdn.net/detail/baijiajie2012/8092625

【跟我一起学Unity3D】代码中分割图片而且载入帧序列动画的更多相关文章

  1. java如何从一段html代码中获取图片的src路径

    java如何从一段html代码中获取图片的src路径 package com.cellstrain.icell.Test; import java.util.ArrayList;import java ...

  2. 示例:WPF中自定义StoryBoarService在代码中封装StoryBoard、Animation用于简化动画编写

    原文:示例:WPF中自定义StoryBoarService在代码中封装StoryBoard.Animation用于简化动画编写 一.目的:通过对StoryBoard和Animation的封装来简化动画 ...

  3. JAVA-替换html中图片的路径-从html代码中提取图片路径并下载(完整版)

    transHtml方法实现提取网络图片中得图片路径,将其重新下载到本地,并替换html中原来得路径 package com.googosoft.until; import java.io.Buffer ...

  4. 用正则从html代码中提取图片路径

    $str = '<div align="center"> <img src="http://www.99tyg.com/public/images/e8 ...

  5. Unity3D GUI中的图片跟随鼠标旋转脚本

    var Mid : Texture2D; var mouse : Texture2D; //鼠标图片 var mousePs = Vector2.zero; //鼠标的位置 private var a ...

  6. Unity3D GUI中的图片尾随鼠标旋转脚本

    var Mid : Texture2D; var mouse : Texture2D; //鼠标图片 var mousePs = Vector2.zero; //鼠标的位置 private var a ...

  7. 代码中引用res里的颜色、图片

    1.imageButton userImgButton 在代码中设置图片,使用res/Drawable 里的图片 Resources res = getResources(); Bitmap inDr ...

  8. 代码: 两列图片瀑布流(一次后台取数据,图片懒加载。下拉后分批显示图片。图片高度未知,当图片onload后才显示容器)

    代码: 两列图片瀑布流(一次后台取数据,无ajax,图片懒加载.下拉后分批显示图片.图片高度未知,当图片onload后才显示容器) [思路]: 图片瀑布流,网上代码有多种实现方式,也有各类插件.没找到 ...

  9. imagesLoaded – 检测网页中的图片是否加载

    imagesLoaded 是一个用于来检测网页中的图片是否载入完成的 JavaScript 工具库.支持回调的获取图片加载的进度,还可以绑定自定义事件.可以结合 jQuery.RequireJS 使用 ...

随机推荐

  1. Day 3 EX 购物车自写

    # -*- coding: utf_8 _*_# Author:Vi import copygoods = [0,[1,'iphone',20],[2,'ipad',2500]]salary = in ...

  2. 【Codeforces Round #457 (Div. 2) C】Jamie and Interesting Graph

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 找比n-1大的最小的素数x 1-2,2-3..(n-2)-(n-1)长度都为1 然后(n-1)-n长度为(x-(n-2)) 然后其他 ...

  3. 【Codeforces Round #457 (Div. 2) B】Jamie and Binary Sequence

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 把n分解成二进制的形式. n=2^a0+2^a1+...+2^a[q-1] 则固定就是长度为q的序列. 要想扩展为长为k的序列. 可 ...

  4. scroolspy滚动监听插件

    <nav id="nav" class="navbar navbar-default"> <a href="#" clas ...

  5. qt多线程

    为什么要用多线程? 传统的图形用户界面应用程序都只有一个执行线程,并且一次只执行一个操作.如果用户从用户界面中调用一个比较耗时的操作,当该操作正在执行时,用户界面通常会冻结而不再响应.这个问题可以用事 ...

  6. 记Bootstrap Table两种渲染方式

    这里主要区别两种Bootstrap Table的数据渲染方式,一.属性渲染方式,二.JS渲染方式 工作直接接手前人的,之前都直接在table标签上渲染属性,后面因为项目需要,同一页面的表格,需要申请不 ...

  7. 洛谷——P1073 最优贸易 ([NOIP2009] )

    https://www.luogu.org/problem/show?pid=1073 题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个 城市之间最多 ...

  8. php訪问mysql数据库

    PHP訪问Mysql数据库 PHP能够通过mysql接口和mysqli接口訪问mysql数据库. 须要加入mysql和mysqli接口才干訪问mysql数据库. windows下配置amp: a.安装 ...

  9. js进阶 14-7 jquery的ajax部分为什么需要对表单进行序列化

    js进阶 14-7 jquery的ajax部分为什么需要对表单进行序列化 一.总结 一句话总结:如果用ajax传递表单的数据,如果不进行表单的序列化,要一个参数一个参数的写,太麻烦,序列化的话,一句代 ...

  10. 15、python学习手册之:列表和字典

    1.列表属于可变序列,支持在原处的修改 2.在标准python解锁器内部,列表就是C数组而不是链接结构 3.内置函数map对序列中的各项应用一个函数并把结果收集到一个新的列表中 eg:list(map ...