游戏开发论坛

 找回密码
 立即注册
搜索
查看: 1538|回复: 0

享元模式(Flyweight Pattern)在服务器端游戏地图开发中的

[复制链接]

1

主题

1

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2010-2-6 12:01:00 | 显示全部楼层 |阅读模式
     享元模式(Flyweight Pattern),运用共享技能有效支撑大量细粒度的对象。
     主要目的是减少系统中大量重复的细粒度对象,降低系统运行时的代价,提高系统运行速度。

    享元对象有内部状态与外部状态:
    内部状态,在享元对象的内部并且不会随环境改动而改动的共享部分。
    外部状态,随环境改动而改动的,不能够共享的状态。

    项目背景:该项目是一款以架空战国时代为背景的策略型网络游戏。玩家可以在【地图】上创建【城池】,刷怪等操作。
    为了提升在线人数,【地图】需要足够大,能容纳更多的人创建【城池】。【地图】是用坐标(x,y)点来标识的——我管它叫【坐标点】,【坐标点】有坐标、【城池】Id(如果创建了【城池】)、是否可创建【城池】等属性。
    如果每个【坐标点】创建一个对象,这样的开销是很惊人的,以横坐标1594,纵坐标1594为例,1594乘以1594=2540836,2百多万个对象创建在内存中,这样的系统开销是很大的,如果再做循环等操作,可以想象想性能是怎么样的?(顺便多说一句,据我所知,很多网游地图确实是这样做的!)。
    因此,享元模式(Flyweight Pattern)在这里运用是非常非常的重要。

    分析设计:仔细分析,【坐标点】有两类,一类是没有创建【城池】的——我管它叫【空坐标点】,另一类是已经创建【城池】的——我管它叫【实坐标点】。
    【空坐标点】除了坐标是“外部状态”(随环境改动而改动的),其他属性是“内部状态”,可以共享。【实坐标点】的大部分属性是“外部状态”。

    Java代码实现:

/**
* 抽象地图坐标点
*
* @author  董有红
* @version 1.0, 2009/03/07
*/
public abstract class MapCell {
        /** 横坐标 */
        protected int posx;

        /** 纵坐标 */
        protected int posy;

        /** 城池Id */
        protected int castleId;

        /** 其他属性省略 */
        ……

        /**
         * 设置坐标方法,子类不用过载,可直接使用
         *
         * @param posx 横坐标
         * @param posy 纵坐标
         */
        public void setPos(int posx, int posy) {
                this.posx = posx;
                this.posy = posy;
        }

        /**
         * 抽象方法,判断该坐标点是否可用
         *
         * @return 判断的结果
         */
        public abstract boolean isAvail();

        // 其他方法,省略……
}


/**
* 空坐标点
*
* @author  董有红
* @version 1.0, 2009/03/07
*/
public class EmptyMapCell extends MapCell {
       
        /**
         * 根据城池等级不同,占用的坐标点个数不同,
         * 需要判断该坐标点是否可用
         *
         * @return 判断的结果
         */
        public boolean isAvail() {
                // 代码省略……
        }

        // 其他方法,省略……
}

/**
* 实坐标点
*
* @author  董有红
* @version 1.0, 2009/03/07
*/
public class SolidMapCell extends MapCell {
       
        /**
         * 该坐标点已经被城池占用,不可用
         *
         * @return 判断的结果
         */
        public boolean isAvail() {
                return false;
        }

        // 其他方法,省略……
}


import java.util.*;

/**
* 地图实例创建工厂,采用单例模式
*
* @author  董有红
* @version 1.0, 2009/03/07
*/
public class MapCellFactory {

        /** 持有地图实例创建工厂句柄 */
        private static MapCellFactory factory;

        /** 持有地图坐标的容器 */
        private Map mapCells;

        /**
         * 私有构造器
         */
        private MapCellFactory() {
                mapCells = new HashMap();
                EmptyMapCell emptyMapCell = new EmptyMapCell();
                mapCells.push("emptyMapCell", emptyMapCell);
                SolidMapCell solidMapCell = new SolidMapCell();
                mapCells.push("emptyMapCell", emptyMapCell);
        }

        /**
         * 创建实例工厂,静态方法
         *
         * @return 返回工厂实例
         */
        public static MapCellFactory createMapCellFactory() {
                if (factory == null)
                        factory = new MapCellFactory();
                return factory;
        }
       
        /**
         * 取得地图坐标
         *
         * @param key 建值
         *
         * @return 地图坐标
         */
        public MapCell getMapCell(String key) {
                return (MapCell)mapCells.get(key);
        }

        // 其他方法,省略……
}

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-16 05:42

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表