t足球数据库
⑴ 数据库如何创建视图
视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。
对其中所引用的基础表来说,视图的作用类似于筛选。定义视图的筛选可以来自当前或其它数据库的一个或多个表,或者其它视图。通过视图进行查询没有任何限制,通过它们进行数据修改时的限制也很少。
视图是存储在数据库中的查询的sql 语句,它主要出于两种原因:安全原因, 视图可以隐藏一些数据,如:社会保险基金表,可以用视图只显示姓名,地址,而不显示社会保险号和工资数等,另一原因是可使复杂的查询易于理解和使用。这个视图就像一个“窗口”,从中只能看到你想看的数据列。这意味着你可以在这个视图上使用SELECT *,而你看到的将是你在视图定义里给出的那些数据列:
既然视图的定义是基于基本表的,哪为什么还要定义视图呢?这是因为合理地使用视图能够带来许多好处:
1、 视图能简化用户操作
视图机制使用户可以将注意力集中在所关心地数据上。如果这些数据不是直接来自基本表,则可以通过定义视图,使数据库看起来结构简单、清晰,并且可以简化用户的的数据查询操作。例如,那些定义了若干张表连接的视图,就将表与表之间的连接操作对用户隐藏起来了。换句话说,用户所作的只是对一个虚表的简单查询,而这个虚表是怎样得来的,用户无需了解。
2、 视图使用户能以多种角度看待同一数据
视图机制能使不同的用户以不同的方式看待同一数据,当许多不同种类的用户共享同一个数据库时,这种灵活性是非常必要的。
3、 视图对重构数据库提供了一定程度的逻辑独立性
数据的物理独立性是指用户的应用程序不依赖于数据库的物理结构。数据的逻辑独立性是指当数据库重构造时,如增加新的关系或对原有的关系增加新的字段,用户的应用程序不会受影响。层次数据库和网状数据库一般能较好地支持数据的物理独立性,而对于逻辑独立性则不能完全的支持。
在关许数据库中,数据库的重构造往往是不可避免的。重构数据库最常见的是将一个基本表“垂直”地分成多个基本表。例如:将学生关系Student(Sno,Sname,Ssex,Sage,Sdept),
分为SX(Sno,Sname,Sage)和SY(Sno,Ssex,Sdept)两个关系。这时原表Student为SX表和SY表自然连接的结果。如果建立一个视图Student:
[sql]view plain
CREATEVIEWStudent(Sno,Sname,Ssex,Sage,Sdept)ASSELECTSX.Sno,SX.Sname,SY.Ssex,SX.Sage,SY.SdeptFROMSX,SYWHERESX.Sno=SY.Sno;
CREATEVIEWVMGRADE
AS
SELECTSno,MAX(Grade)Mgrade
FROMSC
GROUPBYSno
SELECTSC.Sno,CnoFROMSC,VMGRADEWHERESC.Sno=VMGRADE.SnoANDSC.Grade=VMGRADE.Mgrade;
CREATETABLEt_employee(
IDINTPRIMARYKEYAUTO_INCREMENT,
NAMECHAR(30)NOTNULL,
SEXCHAR(2)NOTNULL,
AGEINTNOTNULL,
DEPARTMENTCHAR(10)NOTNULL,
SALARYINTNOTNULL,
HOMECHAR(30),
MARRYCHAR(2)NOTNULLDEFAULT'否',
HOBBYCHAR(30)
);
INSERTINTOlearning.t_employee(ID,NAME,SEX,AGE,DEPARTMENT,SALARY,HOME,MARRY,HOBBY)VALUES(NULL,'小红','女',20,'人事部','4000','广东','否','网球');
INSERTINTOlearning.t_employee(ID,NAME,SEX,AGE,DEPARTMENT,SALARY,HOME,MARRY,HOBBY)VALUES(NULL,'明日','女',21,'人事部','9000','北京','否','网球');
INSERTINTOlearning.t_employee(ID,NAME,SEX,AGE,DEPARTMENT,SALARY,HOME,MARRY,HOBBY)VALUES(NULL,'天天','男',22,'研发部','8000','上海','否','音乐');
INSERTINTOlearning.t_employee(ID,NAME,SEX,AGE,DEPARTMENT,SALARY,HOME,MARRY,HOBBY)VALUES(NULL,'大大','女',23,'研发部','9000','重庆','否','无');
INSERTINTOlearning.t_employee(ID,NAME,SEX,AGE,DEPARTMENT,SALARY,HOME,MARRY,HOBBY)VALUES(NULL,'王下','女',24,'研发部','9000','四川','是','足球');
INSERTINTOlearning.t_employee(ID,NAME,SEX,AGE,DEPARTMENT,SALARY,HOME,MARRY,HOBBY)VALUES(NULL,'无名','男',25,'销售部','6000','福建','否','游戏');
INSERTINTOlearning.t_employee(ID,NAME,SEX,AGE,DEPARTMENT,SALARY,HOME,MARRY,HOBBY)VALUES(NULL,'不知道','女',26,'销售部','5000','山西','否','篮球');
DROPVIEWIFEXISTS视图名
这样尽管数据库的逻辑结构改变了(变为SX和SY两个表了),但应用程序不必修改,因为新建立的视图定义为用户原来的关系,使用户的外模式保持不变,用户的应用程序通过视图仍然能够查找数据。
当然,视图只能在一定程度上提供数据的逻辑独立,比如由于视图的更新是有条件的,因此应用程序中修改数据的语句可能仍会因为基本表构造的改变而改变。
4、视图能够对机密数据提供安全保护
有了视图机制,就可以在设计数据库应用系统时,对不同的用户定义不同的视图,使机密数据不出现在不应该看到这些数据的用户视图上。这样视图机制就自动提供了对机密数据的安全保护功能。例如,Student表涉及全校15个院系学生数据,可以在其上定义15个视图,每个视图只包含一个院系的学生数据,并只允许每个院系的主任查询和修改本原系学生视图。
5、适当的利用视图可以更清晰地表达查询
例如经常需要执行这样的查询“对每个学生找出他获得最高成绩的课程号”。可以先定义一个视图,求出每个同学获得的最高成绩:
[sql]view plain
然后用如下的查询语句完成查询:
[sql]view plain
二、数据准备
1、员工表
[sql]view plain
插入数据:
[sql]view plain
插入的结果:
结果显示插入失败
对于with check option用法,总结如下:
通过有with check option选项的视图操作基表(只是面对单表,对连接多表的视图正在寻找答案),有以下结论: 插入后的数据,通过视图能够查询出来就符合WITH CHECK OPTION 否则就不符合;
首先视图只操作它可以查询出来的数据,对于它查询不出的数据,即使基表有,也不可以通过视图来操作。
1.对于update,有with check option,要保证update后,数据要被视图查询出来
2.对于delete,有无with check option都一样
4.对于insert,有with check option,要保证insert后,数据要被视图查询出来
对于没有where 子句的视图,使用with check option是多余的
7、删除视图
[sql]view plain
等
⑵ 足球经理的FM系统
Football Manager(以下简称FM)系列作为足球经理游戏界的龙头老大(虽然此界中也没几款作品),当得起“艺术”二字。
1984年,Kevin Toms在一个名为ZX Spectrum的游戏平台(慢说如今,便是当时也没几人知道的一个平台)上画了一个圈,创造了我们所知的第一款足球经理游戏。1992年,英国人Paul以及Oliver Collyer 两兄弟蹲在他们的卧室里捣鼓出了一款PC平台上的足球经理游戏,Championship Manager(以下简称CM,要特别注意的是,2004年后的CM与本文提及的CM/FM没有任何关联,因为其开发人员、游戏源代码、引擎技术、球员数据等等游戏设计采用的都是另外一种理念,04年后的FM就是04年前CM),这便是后来风靡全球的CM/FM系列(下文统称为FM系列)的老祖宗。
1993到现在已然17个年头了,时代在变迁,FM系列也一直在变迁,后人们无缘经历FM曾经的传奇和历史,便只能从字里行间去感受FM的风骨。
扑街的游戏各有各的雷点,成功的游戏各有各的卖点。但是成功的游戏系列,无一不经过沉浮起落,也只有遍尝大红大紫与失败潦倒的滋味,不断向上爬向前摸索,才能铸造出经典。FM系列的17年,也逃不脱这样一个沉浮起落的循环。
大多数系列游戏诸如Tomb Raider、Need For Speed、Call Of Duty等等,其发展都是遵循第一代名声大噪,其后几代良莠不齐偶见精品的生长规律,也就是说,大多数系列游戏都有一个成长期、探索期、成熟期、黄金期的发展过程。
而FM系列却是与此不同,自成一家。
下文将会以此入手,把FM历代划分4个时段,一一细数FM历代的引擎特点与战术理念设计变迁。 FM的孕育期
有点资历的老游戏玩家回忆起1993,一定会想起当时红遍天下的横版Prince Of Persia,或者Sid Meier大师的惊世神作Sid Meier’s Civilization,;有点资历的球迷回忆起1993年,应该会想起巴乔两度加冕世界足球先生,或者马赛在欧冠决赛击败米兰陷入贿赂丑闻,也可能会缅怀起那一年过世的英格兰史上第一后卫Bobby Moore。而作为准90后的楼主,1993的时候,还穿着开裆裤,噢不,应该是赤裸着下体满街跑然后跌个狗吃屎……
但不管是玩家,还是球迷,或者楼主,有关1993的记忆里都不会存在FM这个词。
FM系列的前四代,就是在这环境中默默地孕育着。
1993年,Collyer兄弟在伦敦注册了一家名为Sports Interactive(以下简称SI)的公司。 并在原始CM的基础上进行加工,开发出了当时默默无闻的CM 1993。
这里插播一个趣闻,为什么我们要从CM93而非CM Original开始讲起,盖因CMO采用的设计语言是BASIC,其糟糕的平台兼容性以及多如牛毛到令人发指的bug,除了花就是绿的画面,球员全部随机并以号码为名,比赛模拟偶见无厘头计算方式等等问题,据说让Collyer兄弟回忆起往昔时常掩面泪奔。
CM93继承了CMO比赛引擎、球员属性加权计算进行评级等等当时领先整个业界的设计理念的同时,开始第一次引入界面设计、球员真实化、多联赛并行等等设定。虽然仅仅对皇马球员进行了真实化,但是从引入比赛过程中受伤、同步现实联赛赛程、丰富球员转会谈判内容等等措施中都可以察觉到一点端倪,那就是从CM93开始,SI比其他的开发小组更早地确立了她后来赖以统治整个业界的设计思想——真实化。而这也是为什么我们更愿意把CM93作为FM系列起点的根本原因。
从一开始SI就显露出了王的资质,她比同期其他足球经理游戏的开发小组更富想象力,更富市场前瞻力,即使那时的SI只有2个人。我们有理由去臆测这两兄弟是否未来帝,或者章鱼哥(P.S. 章鱼哥也叫Paul)。
SI在93、94两年,陆续推出了3张磁盘作为CM 93的追加磁盘,用于更新游戏中球员数据、联赛赛程、游戏引擎等内容,这也就是后世的补丁。这个想法领先业界起码3年。而那会的大部分游戏开发商甚至都还没有后续服务的概念。后来的FM系列是不管第几代,推出更新补丁这个良好习惯一直被保留了下来,也一直是玩家们所热衷的话题之一。
CM93的时代太过遥远,也因为足球经理游戏在那个年代缺乏关注,其游戏引擎到底如何已经不可考了,但是据收集到的一些资料来看,CM93引擎最大的特点就是,没有特点。因为比赛模拟文字描述太过单一,玩家无法从游戏运行过程中寻觅到规律,比赛中可用的战术调整总的来说就是三个——加强进攻、加强防守以及换人,也无法从胜负关系中察觉到除了球员外能影响比赛进程的因素。因而只能说,比赛引擎跟当时另外两款作品(Premier Manager和The Manager)几乎没区别,也就是毫无特点。至于游戏的战术理念,只能叹一句“噢买尬”,只有两个人的SI根本不敢考虑除了比赛模拟之外的其他事情。
不管从哪个方面来看,CM93都是成功的,她用真实化成功吸引了第一批拥趸去掏钱,然后,后人们应该感谢93年的人们,不要求试玩,不稀罕盗版,没喷子,没五毛,才能让SI赚到俩小钱,去开创FM事业。
Collyer兄弟应该感到庆幸,他们在推出第二代FM——CM 2时刚巧是1995年。如果不是刚刚结束的世界杯抵消了众多买了这款作品的球迷的不满,CM 2一定会扑街。(邪恶臆测:也许CM 2从94跳票到95年也是这原因?)
CM 2比之CM 93几乎就是一个简单的升级包,除了在CM 93的基础上像大部分游戏厂家做的那样使用了新的技术更新了一下画面——然而,你们懂的,FM玩的本来就不是画面,允许并行的联赛数量增加了以及推出多语言版本之外,毫无亮点。至于新加入的语音评论代替文字描述这个功能,拜托了,SI自己都不好意思再提,让游戏的运行和比赛模拟速度降低了一个平方的设计就是一个鸡肋。作为一款续作,CM 2是不成功的,但是作为一款商品,CM 2却是巨成功的。CM 2的开发没有花费多少资金,同时因为推出多语言版本反而让她被全欧洲的球迷所认识。SI挖到了第一桶金,走出了成名的第一步。(小编再次邪恶臆测:也许CM 2的开发初衷就是为了敛财? )
Collyer兄弟翻着账本的时候一定松了一口气,他嘀的终于有奶粉钱招兵买马养FM这个胖娃了。
1996年,CM 96的诞生告诉了我们有钱有人的SI会爆发出怎样一种能量。
刚打开游戏的时候,你会觉得这游戏可能要扑街,因为看起来她跟CM 2几乎一样,这可是两年时间啊,居然没一点变化?
但是当你进入到比赛模拟阶段,你会被感动得泪流满面,因为比赛开始变得不可控制。
这绝对不是反话,足球比赛之所谓为比赛,就是因为他不可控制也不是简单的堆球员。足球比赛是球员技术的较量,但又是教练战术的博弈,同时也是哪边RP更好的比拼,这三者凑到一起,于是就有了那些传世经典的足球比赛。
从CM 96开始,AI(人工智能,比赛引擎属于AI的一部分)的影响开始无处不在,不管是交易球员,还是战术针对性,又或者场上偶见的一些失误,更为难得的是,CM 96对比赛调整功能进行了扩充,而且AI也终于能针对你做出的调整做出反应了。
总的来说,CM 96对AI做出的改动其实不多,只是增强了其对玩家操作的互动以及对联赛规则、球员交易规则真实化。再加上CM96的全名是CM2:96/97赛季,所以在那个年代许多不明真相的媒体都认为96就是CM 2的又一个升级包。
但只要是那个年代FM的玩家都知道,同时多年过去了再回首,才发现FM正是从CM 96开始学会行走,一步一步向今天蹒跚而来。
1997年对于SI来说,从她发行了CM 97开始,注定是个不平凡的年份。而CM 97的叫好叫座(1997年英国本土销售冠军)对她耳语:冷静下来,不要激动,全世界的目光即将汇聚到你身上。
跟CM 96一样,刚打开97的游戏时,你会再次认为这游戏要悲剧。
一样啊,游戏引擎、游戏画面完全一样啊!
跟CM9 6一样,当你玩过了97以后,你会再次被游戏感动得流泪。
97与96之间,只有三个变化。
第一,CAPA(能力与潜能)这个最核心的球员属性,第一次被引入到了FM系列当中;
第二,数据库编辑器这个最牛逼的修改器,第一次被引入到FM系列当中;
第三,全部球星实名制,第一次被引入到FM系列当中。
你还能要求什么?
有读者说,我要求画面和声效!
然而,你懂的,FM玩的本来就不是画面。
然后,更重要的是,CM 93到97的游戏画面几乎没有改变过,除了背景贴图,就是贴图背景,这也是那四年的CM饱受诟病的一大弱点,年轻一点的 FMer见了必然会直呼“雅蠛蝶”,故在此按下不表。
至于声效……FM此物有声效的吗?
如果您实在忍受不了低画质低音质,出门左转,PES和FIFA在招手微笑~~
93-98的5年间,SI一步一步创建起了FM系列的一切核心要素,球员真实化,赛程与现实同步,多联赛并行,巨大的可选数据库,数据库编辑器,游戏引擎,CAPA的设置,比赛战术的模拟。
她出生了,她长大了。然后,她平静的站在帷幔下,阴影里,调整着自己的呼吸,听着观众席的欢呼,看着灯光渐渐黯淡下来的舞台,从嘴角抿出一丝微笑,然后,准备粉墨登场。
FM的黄金期
电子游戏从哪一年诞生已经很难查证了,但几乎所有的游戏玩家都不能忘却99年留给自己的美好回忆。那个时代,Tomb Raider艳绝江湖,Counter-Strike雄霸武林,Age of Empires横扫六合,Star Craft君临天下。
1999对于许多游戏制造商来说,那是许多段传奇的时光,因为win98对DOS的改革为游戏设计带来了更多的可能性。然而对于更多的游戏制造商来说,那是他们苦难的岁月,因为他们没钱没技术没创意去紧跟时代的步伐。
当时,所有的媒体和玩家都被更具操作性、画面更加绚丽的游戏蒙蔽了眼睛,在他们眼中没有画面只有枯燥的文字,没有操作只有简单的鼠标点击,没有联动只有一个人枯坐显示器前的游戏,统统都是垃圾。
于是,顺理成章的,刚刚有了一点名气的FM也随之立即成为许多游戏媒体口诛笔伐、明嘲暗讽的对象,甚至直接就可以收录进牛津词典作为“垃圾”一词的另外一种拼法。
1998年的时候SI(其实早在1995年SI与Edios合并成了Edios Interactive,但实际上游戏的设计一直由SI员工进行,故本文一直使用SI)本该趁着CM 97的大红大紫推出续作,然后她却无端端沉寂了。于是疯狂的媒体爽了,他们觉得SI就是一只纸老虎,已经被市场的趋向吓坏了,自动自觉退出了竞争。
恩,这是技术游戏的胜利,这是艺术游戏的胜利,这是华丽游戏的胜利!
FM这种枯燥乏味功利保守的杂念,玩蛋去吧!
楼主很喜欢看冠军教父,楼主很喜欢的托尼·唐恩说过,抽别人耳光的感觉一定很爽。
99年3月,SI无声无息推出系列中跨世代的第五作,CM 3。
如果不是光盘包装上醒目的Edios Interactive商标,刚打开CM 3的时候,一定会有许多人以为这跟前几作是不同公司发行完全不同的两款游戏。简直不在一个层次啊!
简约朴素、在未来沿用10年之久的左右侧树形菜单,一改前几作游戏界面的混乱;全新的数据后台处理机制,让游戏运行速度上了两个台阶;可供选择大小的数据库,高达2万5千名的球员、职员数量,直逼前作的3倍;全货币、货币价值真实化,青年队和预备队联赛的引入,联赛、杯赛数量的扩充,联赛并行数量提升到15个,让FM系列在真实化道路上的脚步更加坚实;而FM系列核心元素之一——联机系统也从CM 3开始引入,虽然当时只能允许局域网内联机,但也让玩家们初次享受到互爆菊花的快活。
SI得意地笑,这个耳光,抽得你们爽不爽?
喷子们翻翻白眼,好吧,直观表现力上是有了长足的进步,但是啊,还不够还不够,这样的CM 3充其量就是个“精品”,“大作”?你才刚上路呢!
Collyer兄弟笑,得意地笑。
你当咱是仙剑二血狮啊?仅仅换个皮就该叫CM2:99/00而不是CM3了!
为了适应操作系统的变化,CM 3彻底抛弃了以往的游戏战术引擎,而改用全新的阵型图以及WB/WOB(有球/无球)跑位设置——也就是后代FM的核心,我们俗称的球员拉线。
通过拉线,选择狂攻、铁桶阵、攻守平衡、稳守反击、控制节奏这五种现代足球战术方式,终于从99年开始成为FM系列不可或缺的一部分。而与之相应的,后防线站位、多人盯防、传球方式、球队整体节奏等等要素,也醒目的出现在了球队战术板上。
这是FM系列战术理念的第一次进化,甚至可以说,从CM 3开始,FM系列才算有了“战术”这个概念。
而为了搭配战术上的变化,球员能力的概念也很自然要随之发生变化。
这个变化足以颠覆整个足球经理世界。
FM系列诞生之初,对球员能力的描述只有简单的防守、进攻、控球加上守门。此后的续作都有在此基础中增添一些球员属性,但都微不足道。
一直到CM3为止。
从CM 3开始,球员能力才正式被定义为技术精神身体三大类。SI在原来的基础上对球员属性进一步的细化,与各种球队、球员战术设置一一对应,彻底完成了战术设计上的改革。
没错,我们所知的所有球员属性,以及根据这些属性衍生的所谓速度流、技术流或者精神流,都是以CM3作为开端,沿用至今。
这两个根本性的改变,是CM 3取得一切成功的元素,让SI赢得了满堂彩,而这几年间FM系列的大放异彩,与同期其他文字模拟游戏的沉沦相比,SI这个小公司与那些仗着有钱有势有技术的巨头相比,尤为难得。
一款大作,当然要有衬得起他的销量。欧洲游戏年度销售榜上醒目的NO.1,也正式宣告,从这时开始,从这里开始,FM系列即将飞黄腾达。
平步青云摔倒时才最疼,SI似乎也深知这个道理。
CM 3往后的两年里,SI又一次收敛了所有的锋芒,没有盲目推出续作,只是在CM 3原有的基础上,推两款名为新系列游戏(CM 00 1,CM 01 2)实为CM 3的升级包对数据库进行扩充,增加了诸如新闻发布会、记事本、球员对比等一些游戏细节上的内容,以及对游戏进行了优化。
但是这两年的沉寂却不同于98年受到的嘲讽和质疑,CM 3连续3年的红火让所有SI黑退避三舍,而SI不以物喜、冷静默然的表现,仿佛暴雨前的宁静,酝酿着一场席卷全球的飓风。
FM历史上,CM4与CM 03 4实为两款作品,但SI官方一直把这两款作品都称为CM4,所以在本文中把他们合并到一处统一作为CM4同一款产品来写。CM4受众太广,人人心中都有一个不同的CM4,超级难写的,若有不妥之处,请指教。
量变能引起质变。95年到99年,是FM系列的第一次量变,然后有了CM 3。00年到03年,SI用三年的时间,积累起了第二次足以引起质变量变。
2003年3月28日,FM诞生十周年,这是一个伟大的年份,这是一个伟大的日子。天空一声巨响,FM系列史上最成功的作品,所有经历过那个时代的FMer心中永恒的记忆,CM 4,携带一身王霸之气华丽登场。
从FM系列诞生之初一直到2010年10月的今天位置,CM4都足以堪称最华丽的一笔,楼主吐干了肚子里仅有的一点墨水,除了“牛逼”二字,所有形容词都显得如此苍白无力。
CM4开创了FM系列最黄金的时期,是他让无数追星族认识到主帅对于俱乐部的重要性,他让无数伪球迷从fans进化成supporter、从只看场面的小白进化成偶尔也能侃一两句传中你妹呀的老鸟,他培养一个又一个正太控,他孕育了一个又一个恋妖人癖。他创造了一个同时属于真球迷、伪球迷、不真不伪球迷的世界,让我们疯狂迷恋、并投身其中上演一幕又一幕悲喜剧,让我们在一个无比美好的幻想世界里撒播一层又一层Otto Rehhagel光环,创造一段又一段Guy Roux奇迹。
(关于雷哈格尔与居伊鲁,请自行度娘。)
毫不客气的说,对于0304年的球迷,包括那时候连欧冠杯和欧锦赛都听不太清的我自己,CM 4,即为该时代之名!
(鸣谢特邀嘉宾阴沟同学不收一枚屁股币龙套演出!)
直到2010年的今天,你如果问我说“请问CM4对比起前作有什么进化”,我只会回答你:“请问从CM4直到FM2008有什么进化”。
这话虽然有点夸大,但事实就是如此,除了更庞大的数据库、更精美的限制界面,以及添加了一些自定义功能(包括自制皮肤、队徽、头像等),哦最多算上核武器,续作直到FM2008甚至只多了一个3D视角的FM2009与CM4相比,都毫无“进化”二字可言。
从自由度到传球方式到传中落点的拉线,从CM4开始沿用至今;庞大的各种战术选项,从CM4开始沿用至今;从边路进攻到中路突进等等各种战术理念、从速度流到技术流,从CM4开始沿用至今;包括天朝在内的全世界各大洲各大主要国家上百个联赛,从CM4开始沿用至今;PA、CA的重要性已经养妖习惯,从CM4沿用至今;即使进入了10年代,无数FMer依然视之为王道的2D视角,从CM4沿用至今。
……从CM4沿用至今。
……沿用至今。
……至今。
FM系列从05直到即将推出的11,与其说是从CM93演变而来,不如说CM3到CM4的变革才是后续产品赖以生存的根基。
这根基不单指游戏,从CM4开始,第一因为游戏模式的的新颖,第二因为世界足球的蓬勃(感谢完国家然后感谢电视转播的优越),第三则因为多语言甚至包括推出中文版本,让FM系列在全球第一次有了群众基础,有了根基。这其中,就包括当时还蹲在初中每天逃课到煤渣地打滚、课后跑回家继续在电脑上CM4里指挥一串串0和1在绿茵地上打滚的楼主我……
CM4里的0和1吗,你们还好吗?
CM4的玩家们,你们还好吗?
曾记否,JR、薯仔的激突猛进,卡卡、C罗的稚气未脱?曾记否,BT442的威力无匹,NB433的横扫千军?曾记否,AI把健康的一比的Buffon丢替补席上,用Vieri当门将的啼笑因缘?曾记否,被狗咬伤的囧迫不堪、从墙上摔伤的天雷滚滚?
曾记否,还没有下片子的习惯,昼夜开着电脑只为CM的轻狂岁月?
今宵别离后,何日君再来。
凌晨三点,喳喳蝉鸣,淡淡茶香。
我坐在电脑前,对着散发微弱光芒的显示器,感觉今天不是10年10月,而是那个第二天逃课也要让Leedz夺冠的夜,那个不属于张狂初现的魔力鸟,不属于黯然离队的万人迷,不属于挥金如土的阿布,只属于我和CM4的03年夏天。
拼抢,欢呼,嘘声,球,人,奖杯。
兴奋,激动,紧张,焦,燥,感动。
欢迎来到足球经理的世界。
曾记否CM4的广告词?日复一日、年复一年,忠实的写照着每一个FMer。
Don’t lose your head. Sit uprights. Be confident with the players,and the games is coming.
首先冷静,然后坐定,给点自信。你听,开场哨音长鸣。
从默默无闻到大红大紫,许多产品花了一辈子也做不到的事,FM用了十年;从登堂入室到走上神坛,许多公司用了无数代产品也做不了的事,SI用了三代。
CM4如何被称为堪称经营类、竞技类神作已经无需考究了,人人都认为是神作的游戏,还需要考究吗?
不过如果真要找个原因的话,请看下面一组数据:
首发当日,打破英国本土电脑游戏销售记录(因为有demo);
销售一周,打破英国本如游戏销售记录(请大家相信当年PS2的威力);
销售一月,打破欧盟无年龄限制电脑游戏销售记录(大家别忘了03年的COD、玻璃渣的war craft III,恩,虽然这俩都是有年龄限制的……);
销售半年,打破,呃,这个楼主真Google不到还打破神马记录了……
无论如何,CM4的成功让SI上下全体半夜做梦也会笑醒。这种成功来的如此迅疾,以至于前无古人,往后连SI本身推出的后续作品也不可超越。
SI式的成功是不可复制的,在我印象里可以翻找出无数异常霸气但也推出过扑街作品的系列游戏,但这里面绝不会有SI。
SI值得所有急功近利的企业去学习,因为哪怕CM4如此成功,她始终没有迷失了FM的道路,依然诚诚恳恳,一步一个脚印向前走着,根据CM93到CM4的得失,从黄金时代缓步走进FM历史中的探索期。
⑶ 数据库的三级菜单实现
<SCRIPT LANGUAGE="JavaScript">
<!--
function CreateSelect(_FormName,_SName,_SValue,_Ds,_AllOptionStr,ShowType)
{
//三级关链菜单通用版
//作者:海娃, 有问题请到http://www.51windows.Net留言。
if (_FormName=="")
_FormName = "all"
var _DsArr = _Ds.split("|")
var _Ds1,_Ds2,_Ds3
var _Ds1 = _DsArr[0]
var _Ds2 = (_DsArr.length>1)?_DsArr[1]:_DsArr[0]
var _Ds3 = (_DsArr.length>2)?_DsArr[2]:_DsArr[0]
var _SNameArr = _SName.split("|")
var _SName1,_SName2,_SName3
var _SName1 = _SNameArr[0]
var _SName2 = (_SNameArr.length>1)?_SNameArr[1]:_SNameArr[0]
var _SName3 = (_SNameArr.length>2)?_SNameArr[2]:_SNameArr[0]
var _SValueArr = _SValue.split("|")
var _SValue1,_SValue2,_SValue3
var _SValue1 = _SValueArr[0]
var _SValue2 = (_SValueArr.length>1)?_SValueArr[1]:_SValueArr[0]
var _SValue3 = (_SValueArr.length>2)?_SValueArr[2]:_SValueArr[0]
if (ShowType==3){
_AllOptionStr = _AllOptionStr.replace(/\(\(/ig,"\(\("+_Ds3+"\^")
_AllOptionStr = _AllOptionStr.replace(/\{\{/ig,"\{\{"+_Ds2+"\(\("+_Ds3+"\*\*")
}
else if(ShowType==2){
_AllOptionStr = _AllOptionStr.replace(/\{\{/ig,"\{\{"+_Ds2+"\(\("+_Ds3+"\*\*")
}
else if(ShowType==1){
_AllOptionStr = _AllOptionStr.replace(/\(\(/ig,"\(\("+_Ds3+"\^")
}
var AllStr = _Ds1 + "{{"+ _Ds2 + "(("+ _Ds3 +"||"+_AllOptionStr
//alert(AllStr)
var _AR0 = AllStr.split("||");
document.writeln("<select name=\"" + _SName1 + "\" size=\"1\" onChange=\""+_SName1+"redirect(this.options.selectedIndex)\">");
for (var i1 = 0;i1 < _AR0.length;i1++)
{
var Area1Str = _AR0[i1];
var _AR10 = Area1Str.split("{{");
var _AR11 = _AR10[0].split("@");
var Tstr1 = _AR11[0];
var Vstr1 = (_AR11.length==2)?_AR11[1]:_AR11[0]
document.writeln("<option value=\""+Vstr1+"\">"+Tstr1+"<\/option>");
}
document.writeln("<\/select>");
document.writeln("<select name=\"" + _SName2 + "\" size=\"1\" onChange=\""+_SName1+"redirect1(this.options.selectedIndex)\">");
var _AR111 = _Ds2.split("@");
var Tstr11 = _AR111[0];
var Vstr11 = (_AR111.length==2)?_AR111[1]:_AR111[0];
document.writeln("<option value=\""+Vstr11+"\">"+Tstr11+"<\/option>");
document.writeln("<\/select>");
document.writeln("<select name=\"" + _SName3 + "\" size=\"1\">");
var _AR222 = _Ds3.split("@");
var Tstr22 = _AR222[0];
var Vstr22 = (_AR222.length==2)?_AR222[1]:_AR222[0];
document.writeln("<option value=\""+Vstr22+"\">"+Tstr22+"<\/option>");
document.writeln("<\/select>");
document.writeln("<S"+"CRIPT LANGUAGE=\"JavaScript\" defer>");
document.writeln("<!--");
document.writeln("var "+_SName1+"NewAllStr = \""+ AllStr +"\"");
document.writeln("var "+_SName1+"_AR0 = "+_SName1+"NewAllStr.split(\"||\");");
document.writeln("var "+_SName1+"groups=document."+ _FormName +"." + _SName1 + ".options.length;");
document.writeln("var "+_SName1+"group=new Array("+_SName1+"groups)");
document.writeln("for (i=0; i<"+_SName1+"groups; i++){");
document.writeln(" "+_SName1+"group[i]=new Array();");
document.writeln("}");
document.writeln("for (var i1 = 0;i1 < "+_SName1+"_AR0.length;i1++){");
document.writeln(" var Area1Str = "+_SName1+"_AR0[i1];");
document.writeln(" var _AR10 = Area1Str.split(\"{{\");");
document.writeln(" var _AR12 = _AR10[1].split(\"**\");");
document.writeln(" for (var i2 = 0;i2 < _AR12.length;i2++){");
document.writeln(" var Area2Str = _AR12[i2];");
document.writeln(" var _AR20 = Area2Str.split(\"((\");");
document.writeln(" var _AR211 = _AR20[0].split(\"@\");");
document.writeln(" var Tstr2 = _AR211[0];");
document.writeln(" var Vstr2 = (_AR211.length==2)?_AR211[1]:_AR211[0];");
document.writeln(" "+_SName1+"group[i1][i2]=new Option(Tstr2,Vstr2);");
document.writeln(" }");
document.writeln("}");
document.writeln("var "+_SName1+"temp = document."+ _FormName +"." + _SName2);
document.writeln("function "+_SName1+"redirect(x){");
document.writeln(" for (m="+_SName1+"temp.options.length-1;m>0;m--)");
document.writeln(" "+_SName1+"temp.options[m]=null;");
document.writeln(" for (i=0;i<"+_SName1+"group[x].length;i++){");
document.writeln(" "+_SName1+"temp.options[i]=new Option("+_SName1+"group[x][i].text,"+_SName1+"group[x][i].value);");
document.writeln(" }");
document.writeln(" "+_SName1+"temp.options[0].selected=true");
document.writeln(" "+_SName1+"redirect1(0)");
document.writeln("}");
document.writeln("var "+_SName1+"Group2s=document."+ _FormName +"." + _SName2 + ".options.length;");
document.writeln("var "+_SName1+"Group2=new Array("+_SName1+"groups);");
document.writeln("for (i=0; i<"+_SName1+"groups; i++){");
document.writeln(" "+_SName1+"Group2[i]=new Array("+_SName1+"group[i].length)");
document.writeln(" for (j=0; j<"+_SName1+"group[i].length; j++){");
document.writeln(" "+_SName1+"Group2[i][j]=new Array()");
document.writeln(" }");
document.writeln("}");
document.writeln("for (var i1 = 0;i1 < "+_SName1+"_AR0.length;i1++){");
document.writeln(" var Area1Str = "+_SName1+"_AR0[i1]");
document.writeln(" var _AR10 = Area1Str.split(\"{{\");");
document.writeln(" var _AR12 = _AR10[1].split(\"**\");");
document.writeln(" for (var i2 = 0;i2 < _AR12.length;i2++){");
document.writeln(" var Area2Str = _AR12[i2]");
document.writeln(" var _AR20 = Area2Str.split(\"((\");");
document.writeln(" _AR212 = _AR20[1].split(\"^\");");
document.writeln(" for (var i3 = 0;i3 < _AR212.length;i3++){");
document.writeln(" Area3Str = _AR212[i3]");
document.writeln(" _AR3 = Area3Str.split(\"@\");");
document.writeln(" Tstr3 = _AR3[0]");
document.writeln(" Vstr3 = (_AR3.length==2)?_AR3[1]:_AR3[0]");
document.writeln(" "+_SName1+"Group2[i1][i2][i3]=new Option(Tstr3,Vstr3);");
document.writeln(" }");
document.writeln(" }");
document.writeln("}");
document.writeln("var "+_SName1+"temp1=document."+ _FormName +"." + _SName3 + "");
document.writeln("function "+_SName1+"redirect1(y){");
document.writeln(" for (m="+_SName1+"temp1.options.length-1;m>0;m--)");
document.writeln(" "+_SName1+"temp1.options[m]=null");
document.writeln(" for (i=0;i<"+_SName1+"Group2[document."+ _FormName +"." + _SName1 + ".options.selectedIndex][y].length;i++){");
document.writeln(" "+_SName1+"temp1.options[i]=new Option("+_SName1+"Group2[document."+ _FormName +"." + _SName1 + ".options.selectedIndex][y][i].text," + _SName1 + "Group2[document."+ _FormName +"." + _SName1 + ".options.selectedIndex][y][i].value)");
document.writeln(" }");
document.writeln(" "+_SName1+"temp1.options[0].selected=true");
document.writeln("}");
document.writeln("\/\/-->");
document.writeln("<\/script>");
document.writeln("<s"+"cript language=\"JavaScript\">");
document.writeln("<!--");
document.writeln("function "+_SName1+"SetValue(){");
document.writeln(" try{");
document.writeln(" if (\""+_SValue1+"\"!=\"\"){");
document.writeln(" document."+ _FormName +"."+_SName1+".value=\""+_SValue1+"\"");
document.writeln(" "+_SName1+"redirect(document."+ _FormName +"."+_SName1+".options.selectedIndex);");
document.writeln(" if (\""+_SValue2+"\"!=\"\"){");
document.writeln(" document."+ _FormName +"."+_SName2+".value=\""+_SValue2+"\"");
document.writeln(" "+_SName1+"redirect1(document."+ _FormName +"."+_SName2+".options.selectedIndex)");
document.writeln(" if (\""+_SValue3+"\"!=\"\")");
document.writeln(" document."+ _FormName +"."+_SName3+".value=\""+_SValue3+"\"");
document.writeln(" }");
document.writeln(" }");
document.writeln(" }");
document.writeln(" catch(e){");
document.writeln(" }");
document.writeln("}");
document.writeln("window.attachEvent(\"onload\","+_SName1+"SetValue)");
document.writeln("\/\/-->");
document.writeln("<\/script>");
}
//-->
</script>
<%
set conn=Server.CreateObject("ADODB.Connection")
dbpath=Server.MapPath("db1.mdb")
conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Database Password=;Data Source=" & dbpath
dim SelectStr
SelectStr = ""
dim sql1,sql2,sql3
dim rs1,rs2,rs3
dim i1,i2,i3
'使用缓存,application("liststr"),将添加,编辑或删除一个数据时,用application("liststr") = empty清空缓存
application("liststr") = empty
if isempty(application("liststr")) then
'//一级分类开始
sql1 = "select c1id,c1name from class1"
set rs1 = conn.execute(sql1)
i1 = 0
while not rs1.eof
if i1 > 0 then
SelectStr = SelectStr & "||"
end if
SelectStr = SelectStr & rs1("c1name") & "{{"
'显示与值不同时,用下面一行
'SelectStr = SelectStr & rs1("c1name") & "@"& rs1("c1id") &"{{"
'//二级分类开始
sql2 = "select c2id,c2name from class2 where c1name = '"& replace(rs1("c1name"),"'","''") &"'"
set rs2 = conn.execute(sql2)
i2 = 0
while not rs2.eof
if i2 > 0 then
SelectStr = SelectStr & "**"
end if
SelectStr = SelectStr & rs2("c2name") & "(("
'显示与值不同时,用下面一行
'SelectStr = SelectStr & rs2("c2name") & "@"& rs2("c2id") &"(("
'//三级分类开始
sql3 = "select c3id,c3name from class3 where c2name = '"& replace(rs2("c2name"),"'","''") &"'"
set rs3 = conn.execute(sql3)
i3 = 0
while not rs3.eof
if i3 > 0 then
SelectStr = SelectStr & "^"
end if
SelectStr = SelectStr & rs3("c3name")
'显示与值不同时,用下面一行
'SelectStr = SelectStr & rs3("c3name") & "@" & rs3("c3id")
i3 = i3 + 1
rs3.movenext
wend
rs3.close
set rs3 = nothing
'//三级分类结束
i2 = i2 + 1
rs2.movenext
wend
rs2.close
set rs2 = nothing
'//二级分类结束
i1 = i1 + 1
rs1.movenext
wend
rs1.close
set rs1 = nothing
application("liststr") = SelectStr
end if
'//一级分类结束
%>
<SCRIPT LANGUAGE="JavaScript">
<!--
var AllStr1 = "<% = application("liststr") %>"
//-->
</SCRIPT>
<FORM name="HwForm">
<HR>选择一次<br>
<SCRIPT LANGUAGE="JavaScript">
CreateSelect("","S_13|S_23|S_33","","请选择地区@|请选择省份@|请选择城市@",AllStr1,0);
</SCRIPT>
<HR>选择三次<br>
<SCRIPT LANGUAGE="JavaScript">
CreateSelect("HwForm","S_1|S_2|S_3","华北地区|山东|济宁","请选择地区@|请选择省份@|请选择城市@",AllStr1,3);
</SCRIPT>
</FORM>