c# 与flash通信简介
许久不曾写随笔,即使许久的怠惰,是该抬抬头,看看天了。
公司项目,项目要求是在winForm端先获取下位机的肌电信号采集数据,然后根据这些数据的变化来控制flash游戏,这样一些患者在flash游戏中达到肢体训练的效果。
在这里 需要用到c#与flash的通信, 先上通信示例
ActionScript3.0 与ActionScript2.0 略有差异,但和C#的通信方式是不变的。
function xmlToArray(list:XML):Array {
//xml转数组
list.ignoreWhite = true;
var ar:Array = new Array();
var list_node:XMLNode = list.firstChild.childNodes[];
var l:Number = list_node.childNodes.length;
for (var i:Number = ; i<l; i++) {
var node:XMLNode = list_node.childNodes[i];
var ob = new Array();
ob.push(node.childNodes[].childNodes[].nodeValue);
ob.push(node.childNodes[].childNodes[].nodeValue);
ar.push(ob);
}
return ar;
}
ExternalInterface.addCallback("onPlatformMessage",null,onPlatformMessage);
var xmlContent:XML;
var messageName:String, messageType:String, gameId:String;
function onPlatformMessage(args:String) {
xmlContent = new XML(args);
list_arr = xmlToArray(xmlContent);
//fscommand('Message', '<Message name="GAME_SCORE_REPLY" type="2" gameId="4025"><PlayerScore>'+list_arr+'</PlayerScore></Message>');
messageName = xmlContent.firstChild.attributes.name;
messageType = xmlContent.firstChild.attributes.type;
gameId = xmlContent.firstChild.attributes.gameId;
if (messageType == '' && gameId == '') {
switch (messageName) {
case 'GAME_VERSION' :
fscommand('Message', '<Message name="GAME_VERSION_REPLY" type="2" gameId="4025"><GameVersion>1.0</GameVersion></Message>');
break;
case 'PLAYER_ENTER' :
if (gameFinished) {
playerMode = xmlContent.childNodes[].childNodes[].childNodes[].nodeValue;
if (playerMode != ) {
//playerMode=xmlContent.PlayerMode;
playerName = xmlContent.childNodes[].childNodes[].childNodes[].childNodes[].nodeValue;
level = xmlContent.childNodes[].childNodes[].childNodes[].nodeValue;
score = xmlContent.childNodes[].childNodes[].childNodes[].childNodes[].nodeValue;
if(level>)(level=);
gotoAndStop();
fscommand('Message', '<Message name="GAME_ENTER_OK" type="2" gameId="4025"></Message>');
}
}
break;
case 'GAME_PAUSE' :
if (!gameFinished) {
pauseGame(true);
}
break;
case 'GAME_RESUME' :
if (!gameFinished) {
continueGame();
}
break;
case 'GAME_LEAVE' :
gameFinished = true;
fscommand('Message', '<Message name="GAME_LEAVE_OK" type="2" gameId="4025"><PlayerScore>'+score+'</PlayerScore><GameStage>'+level+'</GameStage></Message>');
break;
case 'GAME_HELP' :
break;
case 'GAME_SOUND' :
break;
case 'GET_GAME_SCORE' :
fscommand('Message', '<Message name="GAME_SCORE_REPLY" type="2" gameId="4025"><PlayerScore>'+score+'</PlayerScore></Message>');
break;
case 'GET_GAME_STAGE' :
fscommand('Message', '<Message name="GAME_STAGE_REPLY" type="2" gameId="4025"><GameStage>'+level+'</GameStage></Message>');
break;
case 'SET_GAME_STAGE' :
if (!gameFinished) {
level = xmlContent.childNodes[].childNodes[].childNodes[].nodeValue;
gotoAndPlay();
fscommand('Message', '<Message name="SET_GAME_STAGE_OK" type="2" gameId="4025"></Message>');
}
break;
case 'GET_GAME_STATUS' :
//tmpInt = xmlContent.firstChild.attributes.GameStage;
fscommand('Message', '<Message name="GAME_STATUS_REPLY" type="2" gameId="4025"><GameStatus>'+gameStatus+'</GameStatus></Message>');
break;
case 'SET_LANGUAGE' :
var language = xmlContent.firstChild.attributes.GameLanguage;
break;
default :
searchHighscore();
}
}
//end if
}
//end onPlatformMessage
Flash端的ActionScript2.0代码
如上示例:
Flash接收c#消息方式:
ExternalInterface.addCallback("onPlatformMessage",null,onPlatformMessage);
引号中的onPlatformMessage是flash用于接收c#消息的方法名
后面的onPlatformMessage 是接收到的c#传递的参数,该参数可以有一个或多个(本项目中只用到一个参数)。
然后再onPlatformMessage方法中,AS(ActionScript)会先把c#传递过来的额XML的字符串进行解析,解析之后就可以执行flash的相应动作。
Flash回复c#消息
fscommand('Message', '<Message name="SET_GAME_STAGE_OK" type="2" gameId="4025"></Message>');
C#端的操作
C#端使用的是WinForm形式。
准备工作:
首先添加对 COM 组件 Shockwave Flash Object 的引用,将该组件拖到窗体上之后,可以设置如下关键属性:
Movie: Flash 的存放地址
EmbedMovie: 是否嵌入到程序的资源中。
或者在程序中把flash加载进去:
player.LoadMovie(0, Application.StartupPath + "\\EITest.swf");
// player.Play();
在使用player.Play()中遇到的问题是:
在c#与ActionScript2.0 通信中在Load使用使用Play() 命令可以使用flash正常播放,但在c#与ActionScript3.0 的通信中却遇到了错误。后来查找原因大概是在执行 player.LoadMovie() 的时候是把flash加载进来,player.Play() 会自动播放flash,相当于在ActionScript语法中执行了play方法,这样会与flash中原来的方法造成冲突,最后是没有使用后一步的player.Play()方法。
C# 接收flash的消息:
private void player_FSCommand(object sender, AxShockwaveFlashObjects._IShockwaveFlashEvents_FSCommandEvent e)
{
if (e.command == "Message")
{
lblreceive.Text = e.args;
//游戏载入时,发送参与人的编号和姓名
if (e.args.IndexOf("GAME_LOAD_OK") != -)
{
messageName = "PLAYER_LOAD";
LoadPlayer();
}
}
}
c#接收flash消息
上面的player是与flash通信的客户端的ID,在winForm中注册player的FSCommand的方法,此方法的作用即时在主线程中不停地刷新来接收flash发送给c#的消息。
其中e.command 是flash中 fscommand函数的第一个参数
e.args是flash中 fscommand函数的第二个参数
c#发送给flash的消息
private void Command_SetSpeed(int speed)
{
messageName = "Action_Speed";
player.CallFunction("<invoke name=\"onPlatformMessage\" returntype=\"xml\"><arguments><string>" +
" <Message name=\"" + messageName + "\" type=\"1\" gameId=\"" + gameId + "\"><Speed>" + speed.ToString() + "</Speed></Message>" +
"</string></arguments></invoke>");
}
c#接收flash消息
在c#中使用player.CallFunction()方法向flash发送消息,其中"onPlatformMessage"是flash接收消息的方法名。
在本项目中,向flash发送的消息,只有<string>标签中的消息不用,其他的格式都是通用的。
通信原理及过程:
通信原理个人不甚懂,摘抄他人的解释共享。
其基本过程为:flash中注册函数——将要调用的函数名、参数等信息打包为xml—>将xml传递到flash中执行调用—>执行ActionScript函数—>flash自动将结果打包为xml—>将结果xml传递回C# —>C#解析xml得到返回值
可见,flash与C#通信是通过特定格式的xml文件进行的,因此为了实现通信,C#必须实现一下功能:识别该xml格式以得到flash发送来的信心,将需要传送给flash的信息打包成flash能识别的xml格式。为了使用方便我们可以设计一个代理类专门负责数据的解析与打包工作,这样我们就可以透明的使用该代理类来实现flash与C#间的互相调用。
在flash的示例中有一个IntrovertIM_CSharp项目较好的实现了代理的编写,一般情况下,使用该示例中的ExternalInterfaceProxy类足以满足要求,因此方便起见我也直接采用了该代理类。
该类的使用非常简单,通过将flash控件作为参数传递给该类的构造函数,我们就可以建立一个给控件的代理,简单的响应代理的ExternalInterfaceCall事件及使用代理类的Call()方法就能实现与flash通信,中间的数据转换工作完全由代理透明的实现,用户无需关心。
其它语言及程序课根据上面原理编写自己的代理类来实现数据的解析与打包工作。
c# 与flash通信简介的更多相关文章
- Javascript与Flash通信全解析
原文:https://www.imququ.com/post/39.html Flash已经提供了ExternalInterface接口与JavaScript通信,ExternalInterface有 ...
- Flash Memory 简介【转】
本文转载自:https://linux.codingbelief.com/zh/storage/emmc/ Flash Memory 是一种非易失性的存储器.在嵌入式系统中通常用于存放系统.应用和数据 ...
- socket通信简介
转:http://blog.csdn.net/xiaoweige207/article/details/6211577 “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的 ...
- NAND Flash内部结构简介
介绍 1965年,在双极管被W.Shockley.W.Brattain和J.Bardeen三人发明出来之后,Intel的合作创始人Gordon Moore发现了这样一条法则:当价格不变时,集成 ...
- 转:socket通信简介
转:http://blog.csdn.net/xiaoweige207/article/details/6211577/ 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页 ...
- dubbo结构及通信简介
一.导论 dubbo作为阿里开发优秀的rpc服务框架,现已广泛用于各大rpc项目之间的远程通信,虽然阿里现在已经没有维护dubbo的开发,但是其结构设计也是值得学习. 二.结构简介 这部分只是简单介绍 ...
- ROM、PROM、EPROM、EEPROM、FLASH ROM简介
ROM指的是"只读存储器",即Read-Only Memory.这是一种线路最简单半导体电路,通过掩模工艺, 一次性制造,其中的代码与数据将永久保存(除非坏掉),不能进行修改.这玩 ...
- [转]UART通信简介
1.前言 UART通信,即通用异步收发传输器(Universal Asynchronous Receiver/Transmitter). 串行通信是指利用一条传输线将资料一位位地顺序传送.特点是通信线 ...
- 【转】socket 通信简介
转自:http://blog.csdn.net/xiaoweige207/article/details/6211577/ “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是 ...
随机推荐
- Server Tomcat v7.0 Server at localhost failed to start解决办法
今晚搞了下tomcat,在调试的时候发现报了这样一个错误Server Tomcat v7.0 Server at localhost failed to start 首先,确认了端口号8080是不是被 ...
- 几条sql语句
1.行.列转换 --行转列 ),科目 ),分数 int) ) ) ) ) ) ) ) ) ) --方法1 select 姓名, end) as 语文, end) as 数学, end) as 物理 f ...
- Ruby实现wordCounter
做解密发现的: m={} File.open("test1.txt") do |f| f.each_line do |line| line.chomp! #去除每行结尾的回车(\n ...
- C# 将\u1234类型的字符转化成汉字
用代码获取网页的json数据时,经常会出现\u1234等字符,其实我们是知道他是汉字的 可以用下面的方法将\u1234翻译成汉字 /// <summary> /// /// </su ...
- java获取数据库里表的名字
一.Java方法 // 得到当前数据库下所有的表名 public void getTableNameByCon(Connection con) { try { DatabaseMetaData met ...
- Kettle行列转换
Kettle在控件中拥有行列转换功能,但是行列转换貌似是弄反了. 一.行转列 1.数据库脚本 create TABLE StudentInfo ( studentno int, subject ), ...
- keepalived安装配置(nginx)
环境:centos 6.4 64bit 应用:nginx 目的:keepalived可以让两台服务器处于主备关系,如果主的挂了,备的取得VIP(或者互为主备等关系,文字游戏不纠结), 以实现服务器的高 ...
- 2015年iOS测试现状
本文由 伯乐在线 - nathanw 翻译,dopcn 校稿.未经许可,禁止转载! 英文出处:www.mokacoding.com.欢迎加入翻译小组. 几周前,我决定将将我在 mokacoding 上 ...
- Pintos修改优先级捐赠、嵌套捐赠、锁的获得与释放、信号量及PV操作
Pintos修改优先级捐赠.嵌套捐赠.锁的获得与释放.信号量及PV操作 原有的优先级更改的情况下面没有考虑到捐赠的情况,仅仅只是改变更改了当前线程的优先级,更别说恢复原本优先级了,所以不能通过任何有关 ...
- 替换APK中的jar包文件
[Qboy] 2014年12月21日 这几天,我第一次做的android游戏(WE!青春纪)马上就要上线.上线之前需要把各个渠道的SDK加入到我们游戏中,与渠道进行联运.但是商务很给力,一下子联系了1 ...