[初级教程]第十一节--一个完整的例子2-随机散落的图片2
注:本节中所用到的代码为 AS3 版本。
一、前期回顾
在教程《随机散落的图片1》里,大家已经学会了一种小图的展现方式,即小图片在场景里随机散落。那么这一节我们对其展现形式进行扩充,再增加一种小图的出现形式。我们称为整齐排列。
另外在本节中,我们也会将会对上节里面提出的问题进行探讨,以及给出我们遇到类似问题的解决方案。
二、本节概述
其实对于一个相册展现形式来说,小图的排列方式往往会有很多不同,而点击小图出大图以及其他功能基本都是大同小异。在这里我们就“整个系统的可扩展性”来做一些探讨,以体现使用 WeeMVC 来解决此类问题时所带来开发优势。
具体思路是:由 WeeMVC 框架中的控制器层通过调用“变换小图排列方式”命令类,即可实现很多种相册展现形式。这里我们需要再编写一种小图排列方式来体现多种展现形式的相互切换。好,下面我们开动!
我们先来看效果图,如下所示:
三、实现例子的基础部分
首先我们在上一节编写单个 《随机散落的图片1》里的一些类。
文档类:Main(本程序的入口,也是将 WeeMVC 导入到本程序的地方)
命令类:StartupCommand(WeeMVC 系统初始化命令类)、InitCommand(本程序加载完毕之后第一个调用的命令类)、ShowBigCommand(显示大图命令类)
模型类:DataProxy(模型类)、ImageVO(数据集合)
视图类:BigImage(大图容器)
以上的类在本节中我们将继续用。
四、新增功能
在这里首先明白我们的目标,我们之前已有一个小图随机散落的效果了,所以这里要增加一个新效果,让图片整齐排列成三行四列。
那么想想,同样是两个小图排列,是不是有一部分完全一样的,比如小图的加载、小图上面的鼠标事件等,我们可以把这些功能抽象出来做一个基类,因为最终是要加载在视图场景中,我们这么命名:BaseScenes。
/**
* 基本场景类
* 2010-8-30 12:10
* @author zking
*/
package application.view.scenes {
import application.actions.ShowBigCommand;
import application.view.ImagesContainer;
import flash.display.MovieClip;
public class BaseScenes extends MovieClip {
protected var m_mediator:ImagesContainer;
protected var m_items:Array = new Array();
//中介者模式
public function setMediator(mediator:ImagesContainer):void {
m_mediator = mediator;
}
public function creatItem(list:Array):void {
//创建小图的排列方式 这个在子类里重
写!
}
//这玩意就是 回调函数………
public function onMouseClick(index:uint):void {
//当鼠标点击小图的时候,将小图当前的索引值,通过命令模式,传递给大
图
m_mediator.sendWee(ShowBigCommand, index);
}
protected function changeDepthsToHighest(newItem:MovieClip):void {
var highest:int = 0;
for each(var item:MovieClip in m_items) {
if (this.getChildIndex(item) > highest) {
highest = this.getChildIndex(item);
}
}
//将 newItem 交换至最高深度
this.swapChildrenAt(this.getChildIndex(newItem), highest);
}
}
}
然后我们继承于这个基类,来扩展需要展现的两种图片排列效果类。
1--图片随机排列类 ImagesRandom(此类即是上一节中的视图类):
...
//创建小图的排列方式 这里重写父类方法
override public function creatItem(list:Array):void {
...这里的内容和我们上节的 内容完全一样
}
2--图片整齐排列类 ImagesOrder:
...
//创建小图的排列方式 这里重写父类方法
override public function creatItem(list:Array):void {
...主要内容也一样,
//最后出现的排列方式不同
TweenLite.to(m_image,3, { alpha:1, x:100 + i % 4 * 120, y: 70 + Math.floor( i / 4 ) * 120, scaleX:0.7, scaleY:0.7, rotation:360, ease:Strong.easeInOut } );
}
然后我们将编写一个放置这些排列效果的容器类 ImagesContainer,其实这个类可以理解成一个中介者, 而ImagesRandom、ImagesOrder 就是与它相关的同学类。
/**
* 加载图片展现方式
* 2010-8-30 14:08
*/
package application.view {
import org.weemvc.as3.view.View;
import application.view.scenes.BaseScenes;
import application.view.scenes.ImagesOrder;
import application.view.scenes.ImagesRandom;
import application.actions.ChangeScenesCommand;
import flash.events.MouseEvent;
import flash.display.MovieClip;
public class ImagesContainer extends View {
protected var m_panel:MovieClip;
protected var m_index:uint;
protected var m_imageBox:BaseScenes;
public function ImagesContainer(panel:MovieClip) {
m_panel = panel;
}
//把展现方式添加到场景中
public function addScene(type:uint, data:Array):void {
removeScence();
switch (type) {
case ChangeScenesCommand.RANDOM_SCENE:
m_imageBox = new ImagesRandom();
break;
case ChangeScenesCommand.ORDER_SCENE:
m_imageBox = new ImagesOrder();
break;
}
if(m_imageBox) {
m_imageBox.creatItem(data);
m_panel.addChild(m_imageBox);
m_imageBox.setMediator(this);
}
}
//从场景删除
protected function removeScence():void {
if(m_imageBox) {
m_panel.removeChild(m_imageBox);
}
}
}
}
然后我们需要编写一个命令类 ChangeScenesCommand 来判断到底该使用哪个展现方式。
/*
* 改变场景命令
* 2010-8-30 11:28
* @author zking
*/
package application.actions {
import org.weemvc.as3.control.SimpleCommand;
import application.model.DataProxy;
import application.view.ImagesContainer;
public class ChangeScenesCommand extends SimpleCommand {
public static const RANDOM_SCENE:uint = 0; //随即散落形式
public static const ORDER_SCENE:uint = 1; //整齐排列形式
override public function execute(data:Object = null):void {
var model:DataProxy = modelLocator.getModel(DataProxy);
var imagesContainer:ImagesContainer = viewLocator.getView(ImagesContainer);
//将Model 发送的数据,加入到场景展示方式里
imagesContainer.addScene(data.type,model.list);
}
}
}
/**
* 控制面板
* 2010-8-30 17:59
* @author zking
*/
package application.view {
import org.weemvc.as3.view.View;
import application.actions.ChangeScenesCommand;
import flash.events.MouseEvent;
import flash.display.MovieClip;
public class ControlPanel extends View {
protected var m_panel:MovieClip;
public function ControlPanel(panel:MovieClip) {
m_panel = panel;
m_panel.btn_random.addEventListener(MouseEvent.CLICK, onRandomClickHandler)
m_panel.btn_order.addEventListener(MouseEvent.CLICK,onOrderClickHandler)
}
public function onRandomClickHandler(e:MouseEvent):void {
sendWee(ChangeScenesCommand, { type:ChangeScenesCommand.RANDOM_SCENE } );
}
public function onOrderClickHandler(e:MouseEvent):void {
sendWee(ChangeScenesCommand, { type:ChangeScenesCommand.ORDER_SCENE } );
}
}
}
五、重点剖析
在这个管理小图效果切换过程中里我们使用到了一个新的模式--中介者模式(点击这里查看中介者模式介绍)。当然,还有更好的实现,这里也可以使用策略模式或者工厂方法来完成。从这个例子中我们可以看出,使用了 WeeMVC 的好处在于:当我们的需求有了新变化的时候,可以很方便的进行扩展,原有大部分类基本可以保持不变或者稍作修改即可继续使用,达到复用的效果。
在《随机散落的图片1》中,我们遇到的问题是采用这些办法解决的:
1、场景中的效果切换按钮,如果频繁点击,就会出现死机现象。
这里我们在点击某个小图之后,立即禁用小图 panel,等待大图关闭之后才再次启用小图的鼠标事件响应。
六、课后练习
请考虑以下实现:
- 使用策略模式来管理多个小图效果的切换。并比较与现在的实现有何不同。
- 使用简单工厂来管理多个小图效果的切换。并比较与现在的实现有何不同。
七、demo 下载
八、问题反馈
没有看明白?直接问此篇教程的作者。联系方式:zyj10222#126.com(#号换成@,此地址同时也是 MSN 帐号)
