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>