http://hi.baidu.com/dabstudio
http://www.mt2a.com
http://www.mt2a.com/tag.php?name=flash
一些经验,写给多点触摸开发刚入门的同志
本帖最后由 NICK_LEE 于 2009-6-11 16:05 编辑
大家好,很高兴看到有这样一个多点触摸论坛的存在
我大概07年开始接触到多点触摸的概念,当然也是通过Jeff Han那段神奇的视频认识到的(什么?你还没看过?赶紧补课吧~)
Jeff Han在TED大会上的视频地址:
http://www.ted.com/talks/jeff_ha ... gh_touchscreen.html
一直到现在,也做了很多多点触摸方面的应用,看到论坛中还是很多新加入的伙伴,不知道怎样开始,我觉得作为一个老鸟(呵呵,总算也混了段时间了),有必要写一篇入门级的文章,让大家尽快可以加入多点触摸的开发行列。
当然以下我主要从软件的角度去谈多点触摸的开发,至于硬件上的DIY,这篇文章暂不涉及,大家上网找找吧,有很多的教程的~
第一,touchlib
首先,我们先从总体结构上谈谈多点触摸软件。
现在我们自己DIY的触摸屏都是属于OpticalMultitouch,说白了就是用红外灯把你手指照亮,然后用摄像头去捕捉你的手指的位置来实现多点触摸。所以,在最低层要有一个摄像头的检测软件,用于捕捉跟踪你的手指位置,这个属于计算机视觉领域的活,别怕,现在开源世界里面已经有了好几个用于多点触摸捕捉的软件了,其中比较早也比较经典的一个就是touchlib。这个软件我没记错的话
大概07年中间的时候发布,后来又修改了好久,现在版本已经基本稳定在ver.401。很久没有变化了。
touchlib是用C++编写,最终是以dll(动态链接库)的形式发布,随着touchlib项目一起的(具体参见touchlib源码)还有几个用C++编的例子,比如smoke,mousedrive,osc等。有的看官读到这里也许会问了,那我要开发多点触摸程序,就必须用C++了?非也。
如果您是位C++程序员,并且也只准备用C++来开发多点触摸的程序,那么您就别往下看了,去好好看看touchlib里面带的例子吧,看会了就可以开发了。如果您想用其他开发语言(如as3),那就请继续往下看。
第二,OSC
在上面提到的几个例子中,有一个程序要特别注意的就是osc。要理解这个程序,你就不得不了解两个协议:osc和tuio。osc,全名(opensound control),是一个通信协议,定义了一些传输时用的格式,为了方便数据传输用的,比较底层,了解就可以了。
tuio,全名(A Protocol for Table Based Tangible User Interfaces),如果要理解osc.exe机制的话,这个协议可不能放过,它定义了如何在程序中表示触摸界面上出现的实体,如手指。这是touchlib和as3通信的格式。
看到这里有的看官是不是已经开始犯晕了,没事,不想看这些协议也没问题,我画张图您就全明白了~
摄像机--〉touchlib --〉osc --〉flosc --〉as3
又有人问了,这个flosc是个什么东西啊?这是个用java写的类似于桥一样的东西,将osc的消息(tuio格式)经过flosc传给as3。
好了消息传过来了,现在就让我们开始解析以下as3的结构(想用as3开发的同志,下面注意看吧)
第三,AS3
先从AS3这个文件夹上看(什么?AS3文件夹在哪里?请上http://code.google.com/p/touchlib/自己下载先),里面一共有三个文件夹ext,int,src。其中ext是外部一些as3库,像pv3d之类的,就甭管它了。src文件夹中是各个flash例子的fla文件也暂时不管了。
最重要的就是int这个文件夹中的东西。
int文件夹中又有三个文件夹(靠,耍我们啊~),其中com_old就别去管它了,过时了(人家标明了old嘛)。app文件夹咱们一会儿再去看它。现在先来看flash这个文件夹中的东西。flash文件夹里面只有一个event文件夹,再下去就是五个文件了,这五个就是AS3中实现多点触摸功能最核心的五个类了,咱们一个个看下来:
TUIO
.as -- 这个是最主要的类,有两个功能,1.与osc(不会已经忘了它是干什么的吧?看看上面那张图)进行通信,接收osc传来的tuio格式的消息。2.将tuio格式的消息转化为TUIOObject,并且dispatch多点触摸事件。重点去看processMessage这个函数,基本功能都在里面了。
TUIOObject.as -- 这个是类说的白话一点就表示了触摸屏上的触摸点。
TouchEvent.as -- AS3多点触摸事件的定义都在里面了。因为现在AS3 api没有文档,所以要好好看这里面定义的事件类型。
TUIOCursor.as -- 不是很重要的一个类,只是用于调试用的光标。
TUIOSimulator.as -- 看名字就知道了,一个模拟器。其实现在好得模拟器很多,也用不到这个功能了。
好了,最重要的五个文件已经解析完了,当然如果你要理解其中机制的话,还是要你自己去阅读源码,毕竟我不能替代你去读。
下面回到app文件夹,里面又有两个文件夹core和demo。demo从名字上就知道了,是flash实例的源文件,这个先放放。先来看core文件夹,哎哟,这个里面的东西太多了,还是先挑重要的看吧,action文件夹是最重要的一个,因为所有多点的动作(如,放大,缩小,旋转)都是这个里面的类实现的。说句老实话,因为这个里面的类不是一个人写的,所以比较混乱,一共有两个分支:
RotatableScalable.as,这个是最早的一个现实旋转和缩放的类,用起来也比较简单,但代码有点混乱。另一个分支是
Multitouchable.as,其他开发者觉得老的类结构不好,想写个更清楚的,就出现了这个类,由这个类又衍生了好多其他的类。
所以,该文件夹下面的类都是继承或者是由这两个类改编而来的。具体的大家就自己看吧。好了,解析的部分先写那么多吧(好累啊~)。以上的部分是给想要研究多点触摸机制的同志看的,如果您觉得我不想知道这些,我就想立刻开始开发多点触摸程序,该从哪里开始呢?
我的建议是,看src文件夹底下的例子吧,这是最快的方法。再下载一个TUIO模拟器和flosc网桥就可以了立刻进行开发了!
模拟器的下载地址:
http://nuigroup.com/forums/viewthread/1495/
这个帖子中的附件都有了。好了,各位看官努力吧
也欢迎到我的博客看看(虽然更新不够快~):
http://hi.baidu.com/summer150
创建你的第一个Flash多点触摸程序(图文详尽教程)
多点触摸, Flash
本帖最后由 Thons 于 2009-8-7 23:06 编辑
//-------------------------------------------------------------------
//原文地址:
http://wiki.nuigroup.com/Building_Your_First_Application
//Translator:Thons
//感谢panther的投递
//-------------------------------------------------------------------
//首先,必须使用SVN文件,否则可能无法正常工作
如何使用SVN?
1.创建一个新的
Flash
文件(ActionScript 3);
=============================================================================
2.点击一下画布(舞台),这个时候文件属性面板就应该被激活了;
=============================================================================
3.点击“尺寸”按钮;
4.改变尺寸至1024*768,帧率大于30FPS;
=============================================================================
5.点击“设置”按钮(在“尺寸”按钮下面);
6.在“ActionScript 版本”一栏中,选择“ActionScript 3”,并点击右面的“设置”按钮;
=============================================================================
7.在下面的“类路径(classpath)”一栏中,点击 + 按钮并输入
1.../ext
2.以此类推
3.../int
=============================================================================
8.保存这个Flash文件到
touchlib
文件夹中的AS3/src文件夹下,并起一个名字,比如touch.fla ;
=============================================================================
9.在AS3/int/app/demo文件夹下,创建一个新的文件夹,命名为MyTouchApp(这个可以不同,但是考虑到类路径和package。这个名字必须准确);
=============================================================================
10.创建一个新的ActionScript文件;
=============================================================================
11.保存为MyTouchApp.as,在AS3/int/app/demo/MyTouchApp文件夹里;
=============================================================================
12.返回至Flash文件里,也就是上面说的touch.fla ;
=============================================================================
13.在文档类(Document Class)里填入app.demo.MyTouchApp.MyTouchApp ;
=============================================================================
14.选择“矩形”按钮,在画布(舞台)上画一个矩形,要求尺寸漫过并大于整个舞台;
=============================================================================
15.右击刚刚画的矩形,选择“转换为元件”;
=============================================================================
16.确保矩形为MovieClip,然后点击确定
=============================================================================
17.保存文件。返回至MyTouchApp.as中;
=============================================================================
18.从例子中拷贝并粘贴代码(确保在此之前,代码区域里没有任何字符);
=============================================================================
19.保存文件,返回至touch.fla文件中;
=============================================================================
20.发布文件,现在应该可以工作了。
*****************************************************
代码示例
//这段代码用来显示每个触点下面的小红圈
=============================================================================
package app.demo.MyTouchApp{ //adds a circle where you touch (no resize)
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.geom.*;
public class MyTouchApp extends Sprite {
public function MyTouchApp() {
//--------connect to TUIO-----------------
TUIO.init(this,'localhost',3000,'',true);
trace("MyTouchApp Initialized");
//----------------------------------------
addEventListener(TouchEvent.MOUSE_DOWN, touchDown); //run touchdown, when touched
}
public function touchDown(e:TouchEvent):void{
var curPt:Point = parent.globalToLocal(new Point(e.stageX, e.stageY)); //convert touch points to x,y
var circle:Sprite = new Sprite(); //create a new sprite
circle.graphics.lineStyle(10, 0xff0000); //set line width to 10px and red
circle.graphics.drawCircle(0,0,40); // draw a 40px circle
circle.x = curPt.x; //put it where touch is (x cord)
circle.y = curPt.y; //put it where touch is (y cord)
addChild(circle); //add the circle where touch happened
}
}
}
=============================================================================
//这段代码允许你缩放舞台以及让触点下面出现小红圈
//下面的代码只是继承自RotatableScalable类。里面的内容只针对上述讲的东西,因为每个App构造函数不同。
=============================================================================
package app.demo.MyTouchApp{
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.geom.*;
import app.core.action.RotatableScalable;
public class MyTouchApp extends RotatableScalable {//allows it to be scaled around
public function MyTouchApp() {
//--------connect to TUIO-----------------
TUIO.init(this,'localhost',3000,'',true);
trace("MyTouchApp Initialized");
//----------------------------------------
addEventListener(TouchEvent.MOUSE_DOWN, touchDown);//run touchdown, when touched
}
public function touchDown(e:TouchEvent):void {
var curPt:Point=parent.globalToLocal(new Point(e.stageX,e.stageY));//convert touch points to x,y
var circle:Sprite = new Sprite();//create a new sprite
circle.graphics.lineStyle(10, 0xff0000);//set line width to 10px and red
circle.graphics.drawCircle(0,0,40);// draw a 40px circle
circle.x=curPt.x;//put it where touch is (x cord)
circle.y=curPt.y;//put it where touch is (y cord)
addChild(circle);//add the circle where touch happened
}
}
}
=============================================================================
//这段代码的作用是使你在触摸的时候,手指下面出现红色的涟漪(不支持选择和缩放的时候出现这个效果)
=============================================================================
package app.demo.MyTouchApp{
import flash.events.TUIO; // allows to connect to touchlib/tbeta
import flash.display.*;
import flash.events.*;
import flash.geom.*; // needed for curPt;
public class MyTouchApp extends Sprite {
var ripple:Ring; //ring class at end of code
var ripples:Array = new Array(); // holds the list of rings to be animated
var color:uint = 0xff0000;
var radius:Number = 10;
var thickness:Number = 5;
public function MyTouchApp() {
//--------connect to TUIO-----------------
TUIO.init(this,'localhost',3000,'',true);
trace("MyTouchApp Initialized");
//----------------------------------------
stage.addEventListener(TouchEvent.MOUSE_DOWN, onTouchDown);
addEventListener(Event.ENTER_FRAME, rippler);
}
private function onTouchDown(e:TouchEvent):void { // makes a ripple, puts it in the array and starts the rippler
var curPt:Point=parent.globalToLocal(new Point(e.stageX,e.stageY));
ripple = new Ring(thickness, radius, color); // all defined above
ripple.x=curPt.x; // x pos of touch
ripple.y=curPt.y; // y pos of touch
addChild(ripple); // adds the ripple to the stange
ripples.push(ripple); // adds it to the ripples array so it can be animated
}
private function rippler(e:Event):void {
for (var i:uint = 0; i < ripples.length; i++) { // cycle through the ripples on stage and animate them
ripples.width *= 1.15;
ripples.height *= 1.15;
ripples.alpha -= .05;
if (ripples.alpha < .01) { // when the ripple's alpha is below 1% remove it from the stage, and the array
removeChild(ripples);
ripples.splice(i, 1);
}
}
}
}
}
import flash.display.Sprite; // ring class
class Ring extends Sprite {
public function Ring(thickness:Number = 10, radius:Number = 40, color:uint = 0xff0000) {
graphics.lineStyle(thickness, color);
graphics.drawCircle(0,0,radius);
graphics.endFill();
}
}
=============================================================================
//这段代码联合了触摸和鼠标操作。
//当你用鼠标点击的时候,会出现一个小红圈,同时也允许用鼠标来模拟手指进行选择和缩放。
=============================================================================
package app.demo.MyTouchApp{
import flash.display.*;
import flash.events.*;
import app.core.action.RotatableScalable;
public class MyTouchApp extends RotatableScalable {
public function MyTouchApp() {
//--------connect to TUIO-----------------
TUIO.init(this,'localhost',3000,'',true);
trace("MyTouchApp Initialized");
//----------------------------------------
addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); // adds an event listener looking for a mouse click - runs "onMouseDown"
}
private function onMouseDown(event:MouseEvent):void { //creats a circle when the mouse is clicked
var circle:Sprite = new Sprite();
circle.graphics.lineStyle(10, 0xff0000); //set line width to 10px and red
circle.graphics.drawCircle(0,0,40); // draw a 40px circle
circle.x = mouseX; //put it where the mouse clicked
circle.y = mouseY;
addChild(circle); //add the circle to the plane
}
}
}
=============================================================================
//这个小程序在舞台上以x轴的随机值分布一些圆环。每个圆环都可以移动和缩放。这个效果可以通过对RotatableScalable类的继承很简单的实现
=============================================================================
package app.demo.MyTouchApp{
import flash.events.TUIO;// allows to connect to touchlib/tbeta
import flash.display.Sprite;
public class MyTouchApp extends Sprite {
private var num:Number=5; // number of rings to put
var ring:Ring; //ring class (at bottom)
public function MyTouchApp():void {
//--------connect to TUIO-----------------
TUIO.init(this,'localhost',3000,'',true);
trace("MyTouchApp Initialized");
//----------------------------------------
// put "num" rings randomly on the stage
for (var i:int = 0; i < num; i++) {
ring = new Ring();
ring.x = Math.random() * stage.stageWidth;
ring.y = Math.random() * stage.stageHeight;
addChild(ring);
}
}
}
}
import flash.display.Sprite; // ring class
import app.core.action.RotatableScalable;
class Ring extends RotatableScalable {
public function Ring(thickness:Number = 10, radius:Number = 40, color:uint = 0xff0000) {
//---RotatableScalable options------------
//noScale = true;
noRotate = true;
//noMove = true;
//----------------------------------------
graphics.lineStyle(thickness, color);
graphics.drawCircle(0,0,radius);
graphics.beginFill(0xffffff);
graphics.drawCircle(0,0,radius);
graphics.endFill();
}
}
=============================================================================
//现在我们稍微整合一下代码,做一个简单的画图程序
=============================================================================
package app.demo.MyTouchApp{
import flash.events.TUIO; // allows to connect to touchlib/tbeta
import flash.display.*;
import flash.events.*;
import flash.geom.*; // needed for curPt;
public class MyTouchApp extends Sprite {
private var color:uint = 0xff0000; // color of lines
private var thickness:Number = 30; // thickness of lines
private var blobs:Array = new Array(); // blobs we are currently interacting with
private var lines:Array = new Array(); // array to hold the lines
public function MyTouchApp():void {
//--------connect to TUIO-----------------
TUIO.init(this,'localhost',3000,'',true);
trace("MyTouchApp Initialized");
//----------------------------------------
addEventListener(TouchEvent.MOUSE_DOWN, downEvent, false, 0, true); // run when finger down
addEventListener(TouchEvent.MOUSE_UP, upEvent, false, 0, true); // run when finger up
addEventListener(Event.ENTER_FRAME, updater, false, 0, true); // keep running
}
// updates/draws the drawn lines by:
// cycling through all existing blobs
// getting the id of each blob
// use that id to get the line, as the lines are named after their blobs (eg line1280 )
// tuioobj is the blob - see how it is called by request using the blob id?
// if it is not there remove it from the blobs array.
// draw the next segment of the line using lineTo and current loc (tuioobj.x, tuioobj.y)
function updater(e:Event):void {
for (var i:int = 0; i < blobs.length; i++) {
var tuioobj:TUIOObject=TUIO.getObjectById(blobs.id);
// if not found, then it must have died..
if (! tuioobj) {
removeBlob(blobs.id);
} else if (parent != null) {
lines["line"+blobs.id].graphics.lineTo(tuioobj.x, tuioobj.y);
}
}
}
// when touched, this calls addblob with the blob ID and the X/Y of where it started
public function downEvent(e:TouchEvent):void {
var curPt:Point=parent.globalToLocal(new Point(e.stageX,e.stageY));
addBlob(e.ID, curPt.x, curPt.y);
e.stopPropagation();
}
// When a finger stops touching, call removeBlob
public function upEvent(e:TouchEvent):void {
removeBlob(e.ID);
e.stopPropagation();
}
// This takes the sent ID, x,y and puts it all in the blobs array
// It then creats a new sprite, and sets the starting loc of the line
// The line is put in an array called lines, so it can be called over and over by name
// if the lines did not have unique names you could only draw one line at a time
// so each line is named in the array after the id of the blob (EG line1280)
function addBlob(id:Number, origX:Number, origY:Number):void {
blobs.push( {id: id, origX: origX, origY: origY, myOrigX: x, myOrigY:y} );
var line:Sprite = new Sprite();
lines["line"+id] = line;
lines["line"+id].graphics.lineStyle(thickness, color); //<-- config above
lines["line"+id].graphics.moveTo(origX, origY); //starting point of line to be drawn
addChild(lines["line"+id]); // add line to stage
}
// when called, this function removes the blobs from the array
// cycles through the blobs array until the blob is found by its ID, then it is removed.
function removeBlob(id:Number):void {
for (var i=0; i < blobs.length; i++) {
if (blobs.id==id) {
blobs.splice(i, 1);
return;
}
}
}
}
}
=============================================================================
[教程]图片的缩放和旋转,初学者进
multi-touch, actionscript, 多点触摸, flash
最近MTer初学者问我图片缩放怎么写,就写了个简单例子,高手就不要看了,哈。
先说说思想,就是建立一个支持缩放和旋转的容器,然后,把图片装进这个容器,那么图片也就支持缩放和旋转了。
1,建立一个MTimage.fla文件,存储在..\touchlib\AS3\int文件夹下。
2,建立一个MTimage.as文件,存储在..\touchlib\AS3\int文件夹下。
3,输入代码:
package
{
import flash.events.TUIO;
import flash.events.TouchEvent;
import flash.net.URLRequest;
import flash.display.Sprite;
import app.core.action.*;
import flash.display.Loader;
public class MTimage extends Sprite
{
private var imageContainer:RotatableScalable=new RotatableScalable();//建一个支持缩放和旋转的容器
private var imageLoaderoader=new Loader();
public function MTimage()
{
TUIO.init(this,'localhost',3000,'',true);//和mt服务器建立连接
init();
}
private function init()
{
addChild(imageContainer);
imageLoader.load(new URLRequest("image.jpg"));//加载图片
imageContainer.addChild(imageLoader);//把图片装进支持缩放和旋转的容器
}
}
}
4,在.fla文件的文档类输入:MTimage。
5,运行。