【发布时间】:2011-04-12 14:33:48
【问题描述】:
我正在尝试创建一个用动作脚本 2 (flash as2) 编写的库存系统 我正在尝试创建一个动态创建库存点,并将影片剪辑远程加载到库存点中的 mc 中。
我找不到任何有关如何执行此操作的在线指南(只有您必须自己创建库存点的手动指南)
有人能指出我正确的方向吗?
非常感谢任何帮助!
谢谢 丹尼尔。
【问题讨论】:
标签: flash actionscript-2
我正在尝试创建一个用动作脚本 2 (flash as2) 编写的库存系统 我正在尝试创建一个动态创建库存点,并将影片剪辑远程加载到库存点中的 mc 中。
我找不到任何有关如何执行此操作的在线指南(只有您必须自己创建库存点的手动指南)
有人能指出我正确的方向吗?
非常感谢任何帮助!
谢谢 丹尼尔。
【问题讨论】:
标签: flash actionscript-2
这听起来像是我可以帮助你的事情,但我需要更多关于你想要做什么的信息。
另外,您使用 AS2 而不是 actionscript 3 是否有充分的理由?
据我所知,听起来您有一个影片剪辑(我们称其为“父容器”),并且您想动态地将另一个剪辑加载到其中。
如果我是正确的,那么您很幸运,因为这是使用 ActionScript 的一种非常常见的方式。上面到处都有指南。我现在正在编写一个在 AS3 中执行此操作的应用程序。给定一个父容器,它会根据用户的导航方式或选择的内容随时间动态地将不同的影片剪辑加载到其中。但是,我的项目是在 AS3 中。
在 AS2 中,同样的技术是使用 MovieClip 的 attachMovie() 方法实现的。
Here is the old support document for that feature.
这里有一个很好的工作示例:
ActionScript.org - Using attachMovie
或者,您可能正在尝试将数据动态加载到您的电影中。同样,这也是 flash 的常见用法,因此您一定能够完成此操作。
以下是一些可能有帮助的示例:
Thorough example on Loading vars that came from PHP
Loading variables from text files
如果这些都没有帮助,请提供更多详细信息,我们都可以更轻松地为您提供帮助。
希望在某种程度上有所帮助,
-gMale
【讨论】:
只需将其设置为将项目放入下一个打开的插槽中。没那么难。
【讨论】:
我不明白您如何想象这个库存系统:它看起来如何?它是如何工作的?
从简化的角度来看,我了解您有一个将从外部源加载的项目列表(使用 LoadVars、xml 文件等解析的 csv 文件)并且您想要显示它们。 我会把它分成这样的:
为了动态地显示项目, 我建议看看MovieClipLoader 类。您可以使用 MovieClip 的 loadMovie() 方法,但与 loadMovie() 方法相比,MovieClipLoader 更灵活(您可以了解项目是否正在加载(%),获取它的尺寸等)。
不管你的数据源是什么,你最终都会得到一个清单对象数组,这些对象具有我认为的属性。
这是显示库存项目的基本方法:
//using dummy data, you would populate the array by parsing loaded vars or xml, whatever works best for you
var dataProvider:Array = [];
var dummyItems:Number = 20;
for(var i:Number = 0 ; i < dummyItems ; i++) dataProvider[i] = {label:'item '+i,source:'http://stackexchange.com/images/icon/stackoverflow.com'};
//make a container
var inventory:MovieClip = this.createEmptyMovieClip('inventory',1);
var inventoryMask:MovieClip = this.createEmptyMovieClip('inventoryMask',2);
inventoryMask.beginFill(0);inventoryMask.lineTo(Stage.width,0);inventoryMask.lineTo(Stage.width,50);inventoryMask.lineTo(0,50);inventoryMask.lineTo(0,0);inventoryMask.endFill();
inventory.setMask(inventoryMask);
//add items to it
for(i = 0 ; i < dummyItems ; i++) makeInventoryRenderItem(dataProvider[i],inventory,i);
//scroll on mouse over
inventory.onRollOver = function():Void{
inventory.onEnterFrame = function(){
inventory._x = -_xmouse;//this is just a stub, replace with any navigation method you wish
}
}
inventory.onRollOut = function():Void{
delete inventory.onEnterFrame;
}
//make a movie clip with a loader and a label
function makeInventoryRenderItem(data:Object,container:MovieClip,index:Number):Void {
var renderItem:MovieClip = container.createEmptyMovieClip(data.label,index);
var loader:MovieClipLoader = new MovieClipLoader();
loader.loadClip(data.source,renderItem);
var handler:Object = new Object();
handler.onLoadInit = function(target:MovieClip):Void{
target._x = (target._width + 2) * index;
var label:TextField = renderItem.createTextField(data.label+'Label',renderItem.getNextHighestDepth(),0,0,40,22);
label.text = data.label;
}
loader.addListener(handler);
}
这是一个预览:
请注意,这不是一种快速/有效的编写方式,而是一种简单的方式,可以更轻松地说明这个想法。
另一种方法:
作为另一种选择,如果文件大小不是问题,您可以使用组件(您可以从它们那里获得大约 70KB 的 bload)。一个优点是,已经有一些方法可以在不涉及太多代码的情况下处理数据,您可以使用 hacky 方式来显示您的项目,或者创建自定义单元格渲染器。
这是使用 List 和 XMLConnector 的基本方法:
在舞台上添加一个 List 组件, 将其命名为 ls
添加一个 XMLConnector(来自 Data 组件)并将其命名为 xml
我使用了这样的结构:
<data>
<item label="item 1" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 2" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 3" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 4" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 5" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 6" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 7" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 8" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 9" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 10" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 11" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 12" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 13" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 14" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 15" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 16" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 17" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 18" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 19" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 20" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
</data>
在组件检查器的 Parameters 选项卡中,您需要将 URL 设置为您的 xml, 以及接收的方向。
接下来是将 xml 模式导入 XML 连接器,这样它就可以“理解”您的 xml 文件的结构。您可以通过按组件检查器的架构选项卡中的 import schema 按钮来执行此操作。它是选项卡右上角的小按钮,带有向下的蓝色小箭头。另外,确保您的结果被选中。
您将看到结果更新,并且将从您的 xml 创建一个数组,您还可以看到每个对象的属性。
现在 xml 架构/结构已导入,我们可以创建绑定。我们通过在组件检查器的 Bindings 选项卡上按 + 图标来做到这一点:
将出现“添加绑定”对话框,您可以在此处选择 Array 元素并按 OK。
在我的例子中,它被称为 item,它可以被称为其他东西,具体取决于 xml,但想法是您选择包含重复 ([n]) 项目的元素。
下一步是将传入的数据绑定到某些东西,在本例中,绑定到我们的列表组件。将方向设置为向外,然后双击绑定到的值:
绑定到对话框将会弹出。这是我们将选择列表的地方,它的数据提供者作为接收者。
这就是您需要做的所有组件检查器。现在你有一些东西可以加载和处理你的 xml 并在它准备好时将数据发送到列表。
现在我们只创建一个空的MovieClip,命名为Icon,我们画一个50x50的边框,因为它会在里面保存stackoverflow图标(48x48),并且我们Export for Actionscript(Linkage)
最后这些步骤涉及 7 行动作脚本。 在主时间轴中,我们触发了 xml 连接器,我们设置了 defaultIcon 样式属性,设置了行高,以便适合库存图像/徽标,并禁用翻转,以避免重绘该事件:
xml.trigger();//trigger the xml loading
ls.setStyle('defaultIcon','Icon');//use your library clip as an icon
ls.setStyle('useRollOver',false);//stop redrawing list item on rollOver
ls.rowHeight = 48;//you should know the size of the inventory item
现在最后 3 行代码非常 hacky,因为我们正在做的是使用列表的图标(通常是重复的同一个库项目)从图标剪辑本身中找到项目的索引,并且因此访问列表、数据提供者以及每个图标剪辑的数据。
我们将这段代码放在 Icon 电影剪辑中:
var index:Number = parseInt(_parent._name.substr(7))-10;//hack #1 use the rendered icon clip's name property to get it's index
var image:MovieClip = createEmptyMovieClip('image',1);
image.loadMovie(_parent._parent._parent.dataProvider.getItemAt(index).source);//hack #2 'clip' up from the icon clip to the list to find the list and source property for current item
就是这样,你会得到一个显示来自 xml 文件的标签和图像的列表:
如果您愿意使用组件,并且只想使用更少代码的 hacky 方式,这是一个选项。如果您仍想使用组件,但以正确的方式使用,您需要创建一个自定义单元渲染器,它将显示每个库存项目的数据。有一个very good tutorial on the flash-db 网站。
HTH
更新:
我刚刚阅读了其余的 cmets。 @gmale 是对的,如果您打算使用图书馆中的物品,则需要 attachMovie。 你可以这样使用它:
theContainerForYourItem.attachMovie('itemLinkageName','someOptionalName',depth);//note depth is a number
这是一个简单的测试,您必须更改 itemSize 和链接字符串(库中的剪辑与代码中使用的名称相同,或者您更新代码中的名称):
var selectedItem:MovieClip;//this will keep track of the selected item
var itemSize:Number = 67;//set this to the size of a inventory item
var inventoryIds:Array = ["New","Folder","Disk","Mail","Graph"];//item linkage ids, make sure you've got some movie clips in library with these ids, or update the array
var inventory:MovieClip = this.createEmptyMovieClip("inventory",0);//container
var level:MovieClip = this.createEmptyMovieClip("level",1);
//create items
for(var i:Number = 0 ; i < inventoryIds.length ; i++){
//create container for item
var itemContainer:MovieClip = inventory.createEmptyMovieClip('item'+i,i);
//draw border, invisible bg
itemContainer.lineStyle(1);itemContainer.beginFill(0,0),itemContainer.lineTo(itemSize,0);itemContainer.lineTo(itemSize,itemSize);itemContainer.lineTo(0,itemSize);itemContainer.lineTo(0,0);itemContainer.endFill();
//position, add library item
itemContainer._x = (itemSize+2) * i;//2 is just spacing
itemContainer.attachMovie(inventoryIds[i],'icon',0);
itemContainer.onPress = itemSelected;//selec item
}
function itemSelected():Void{
//if there was previously an item removed, restore it...depends on your game's logic, u need clicks though
if(lastItem != undefined) restoreItemToInventory();
trace('selected item is: ' + inventoryIds[this.getDepth()]);//trace ths selected item
this.getInstanceAtDepth(0).removeMovieClip();//and remove the icon from the invotory
delete this.onPress;//disable clicks
lastItem = this;//update the last Item for restoring
//draw an item inside the level
var levelItem:MovieClip = level.attachMovie(inventoryIds[this.getDepth()],'icon',0);
levelItem._x = Stage.width * .5;level._y = Stage.height * .5;//position item;
levelItem.onPress = itemUsed;
}
function restoreItemToInventory():Void{
lastItem.attachMovie(inventoryIds[lastItem.getDepth()],'icon',0);//attach the icon again
lastItem.onPress = itemSelected;//make restore click
}
function itemUsed():Void{
this.removeMovieClip();//remove from stage
trace('item is: ' + inventoryIds[lastItem.getDepth()] + ' was used');//do whatever to hero/enemies
restoreItemToInventory();//restore to inventory or not
}
注意,对于每个库项目,我使用一个容器。这样做的原因是,当我删除一个项目时,实际上我只是删除了容器保存的库项目,并且容器仍然存在,并且保持它的深度,这与数组中项目的索引相同.这稍后用于移除/附加库存项目。一般来说,这是一种不好的做法,因为存在紧密耦合的元素,但为了一个简单的演示,就可以了。
如果在您的游戏中,将添加新项目(玩家不会一次拥有所有可能的项目)并删除、使用...这也可能值得学习如何使用 Array 类,尤其是 splice()方法将允许您在给定索引处从数组中添加、删除项目。根据您更新的库存数组,您将显示项目并设置交互性。
【讨论】: