Professional Documents
Culture Documents
c m vit 1 game cho ring mnh , rng ra th vit 1 game cho VN m mt vi th gii. c m ca mnh l mun VN chng ta c mt ngnh CN gii tr in t ln mnh ngang tm ti Hn chng hn v ri s c ngy bn ty, tu n VN xin mua bn quyn game em v nc n pht hnh la . Hin nay c v s cng c, Ngn ng, mi trng pht trin game, mnh chn XNA bi cc l do sau: -Cc u im nu trong forum, trn internet... -Ca Microsoft m mnh tn nhim thng ny. -Mi trng lm vic chuyn nghip, qun l tt. free khi lm game trn windows. Khi lo sau ny li ko nhau ra to. -NNLT C# n gin, t nhin, d hc v hiu nhanh hn so vi cc NNLT khc. Bi tut ny nhm mc ch nng cao tay ngh cho bn thn v mnh mun ph bin nhng kin thc c bn nht v XNA cho mi ngi. Sau ny nu c cc d n ln trn forum th chc mi ngi u l cc programmer online c ri. Tng lai l iu rt kh on, th nn ta nn hc t ngay by gi i, sau ny nht nh s c lc cn, nht l cc bn theo IT v tnh c cc bn am m IT na. Mt game Nhp vai trc tuyn nhiu ngi chi nu ch da vo tut ny th ko th nhng vit nhng game nh tng bn b, b bch hay chun b cho nhng d n ln hn (c th trong tng lai cc bn l ngi mnh mun cng tc y) th mnh tin ti liu ny s c ch. i vi nhiu ngi, lp trnh v cng vic nhm chn, tm mnh trong 1 ng code, th nhng mun vit game phi bit lp trnh, bn hy nh cng on th v nht khi lp trnh game l lp trnh chng (ngoi ra LT ra cn c vit tng, thut ton, debug... ) Lp trnh khng ch l cng vic l ngh thut cn Lp trnh vin l ngh s, tt nhin ri :D Bi vit da trn ti liu: Beginning XNA 3.0 Game Programming From Novice to Professional nh xut bn APRESS. Bi vit khng th trnh khi sai st, mi gi thc mc kin co j, cc bn b ht vo y thanh_vinh648@yahoo.com (nu bn mnh ko online thng xuyn, cc bn c th dng s D sau: 01649120185-Nghim cm nh my )
ca
Tc Gi
XNA
Khng cn gii thiu chi cho rm r, bn ch cn c Visual Studio v b XNA GSE 3.0 l ok. Chun b mi trng pht trin : - Nng cp Visual Studio : Cc phin bn VS c XNA h tr :
Trch dn:
* Visual C# 2005 Express Edition * Visual Studio 2005 Standard Edition * Visual Studio 2005 Professional Edition * Visual Studio 2005 Tools for the Microsoft Office System * Visual Studio 2005 Team Edition for Software Architects * Visual Studio 2005 Team Edition for Software Developers * Visual Studio 2005 Team Edition for Software Testers * Visual Studio 2005 Team Edition for Database Professionals * Visual Studio 2005 Team Suite + Nu bn ang xi VS C# Express th down ci ny (24.3MB) :
Trch dn:
http://www.microsoft.com/downloads/d...ng=en#filelist ) + Nu bn ang xi cc phin bn VS khc (ko phi Express) th down ci ny (431.7MB khng khip T_T):
Trch dn:
http://download.microsoft.com/downlo...GS20_setup.exe Nu c c ting Anh, bn c th tham kho phn hng dn ca MSDN Lm quen vi XNA By gi ta s tin hnh to mt XNA Project mi Khi ng C#, bn chn New Project -> Windows Game , ri g tn Project vo, nhn OK l to xong :-D
hiu m lnh bt buc cc bn phi hc qua C#, t hc, online j cng c, mnh khng gii thch nhiu v C#,m ch yu l cc thnh phn ca XNA. Thng nhng ci gii thch , lession sau mnh b qua hoc ni s s... Ni dung bi vit ch yu v thut ton v m lnh File m lnh gm c Game1.cs v prgram.cs v nhng th t vit... Ni dung game1.cs: y l file cha nhng m lnh gip 1 game c th chy c bnh thng, tt nhin cu thnh n gm nhiu Component v DrawableGameComponent (class sn c trong XNA) ... y l gii thiu c bn, tuy n gin nhng cc bn nn c qua >= 1 ln
using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; using Microsoft.Xna.Framework.Net; using Microsoft.Xna.Framework.Storage; //Nhng th XNA s dng bn ko cn using ht m tu tng trng hp m s dng namespace WindowsGame1 { /// <summary> /// y l nhng thit lp ban u cho 1 SpriteBatch c bit gi l SpriteBatch v ha, tt c u da trn m ngun ca XNA /// </summary> public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; }
/// <summary> /// Cho php game c th bt u thit lp truc khi bt u chy /// y l ni bn khai bo bin, load Ti nguyn, hm khng fi ha ( ha s c hm khc load) ... /// Thit lp cho cc thnh phn ca game /// </summary> protected override void Initialize() { // Thm vo thit lp logic y, thung cng k cn lm base.Initialize(); } /// <summary> /// hm LoadContent s c gi 1 ln khi chy game v n s load ton b nhng content trong game ca bn /// </summary> protected override void LoadContent() { // to mt SpriteBatch mi, n c dng v texture. spriteBatch = new SpriteBatch(GraphicsDevice); } /// <summary> /// hm UnloadContent c gi 1 ln trong game khi bn out /// n xa sch ni dung cha trong game /// </summary> protected override void UnloadContent() { // khng bt buc fi c, tr d n ln hoc khi bn sing nng. } /// <summary> /// hm Update() hm kt K ca game khi chy /// kim tra kim tra va chm, input (mouse, keyboard), v chi nhc protected override void Update(GameTime gameTime) { // cho phep game out (trn Xbox) if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); // thm vo logic ca game y base.Update(gameTime); //GameTime l 1 bin c bit ch thi gian chy game } /// <summary> /// Hm gi khi cn v th hm s hin ln /// </summary>
protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); //xa mn hnh v thm mn nn (Color.CornflowerBlue) // thm vo m lnh ha. base.Draw(gameTime); } } }
/// </summary> static void Main(string[] args) { using (Game1 game = new Game1()) { game.Run(); } } } }
//ci ni th c yn th, khng nn ng tay v Cc file m lnh: class do user t /N, ci ny do mnh vit v n ko h t u
Bi 1 : a i tung ln Mn hnh
Ti nguyn: mt texture (image) 64x64 c tn ball
u tin khi vit game l Object phi c a ln screen, nghe th n gin nhng trong XNA y l vic kha kh u u, i hi s phi hp gia cc hm trong Game1.cs u tin bn khi ta project mi.cho n 1 ti nguyn (image chng hn)
Ti ca s project, bn click phi chut vo mc Content, chn Add -> Existing Item, hp thoi Add Existing Item m ra v bn tm n file cn a vo project, add n vo
Phn m lnh:
I Mt i tung a ln monitor th cn cc yu t sau: SpriteBatch : mt Sprite c bit , n i din cho mt hoc cc sprite khc trong XNA. N c sn hay t to u c. Texture: i loi l mt bc nh 2D (cng c texture3D) bao ph ln Sprite trong game (thung l bao theo hnh ch nht). Class: lp l thnh phn khng th thiu ca C# v y l ngn ng hung i tung hon ton, bt k sprite no mun th hin iu phi c class rieng ca n.
Cu trc: Namespace => class =>function... Sau class l phn tn lp, t j l ty bn, mnh ly clsSprite
class clsSprite { }
1.Khai bo Sau l phn khai bo bin, cng l cc thnh phn ca class: Vector2 l ci j?, n l 1 cp (2 ci) bin c lin quan n nhau trong game, bn nhn thy v tr ca vt gm c thuc tnh X v Y, tc ca sprite cng th c th theo trong Ox hoac Oy, (nh SpeedX, SpeedY)... tm lum th c th VD. Do , chng ta s dng vector2 cho cc thuc tnh size (height, width) Tung t cho ta position (X,Y) Texture th bt buc ri:
public Texture2D texture { get; set; } // sprite texture, read-only property
public Vector2 position { get; set; } // sprite position on screen public Vector2 size { get; set; } // sprite size in pixel
2.Nhp d liu
Mt hm trng tn vi class s m nhn vai tr ny: rt n gin thi, n nhn texture, position v size ca t bn ngoi lm ca n
public clsSprite (Texture2D newTexture, Vector2 newPosition, Vector2 newSize){ texture = newTexture; position = newPosition; size = newSize; }
Cc yu t c bn nh texture, v tr, mu khi v nhng texture s ln ci White , bn khi lo, thm my ci { na l xong class...
#endregion
C b ht vo cng c, tha > thiu Game1 k th t Microsoft.Xna.Framework.Game Class Game1 cn c b sung, bt u l khai bo cc bin s dng:
GraphicsDeviceManager graphics; clsSprite mySprite1; SpriteBatch spriteBatch;
Mt ha, s dng ci sn c ca XNA Mt Spite, ci chng ta vit class. SpriteBatch, ci i din sprite. Game1 khng cn nhp d liu t bn ngoi nh clsSprite nhng chng ta vn vit hm Game1() thit lp cho n:
public Game1() { graphics = new GraphicsDeviceManager(this); // S dng ha cho chnh n (game1) graphics.PreferredBackBufferWidth = 500; graphics.PreferredBackBufferHeight = 300; //Chiu rng ca s game Content.RootDirectory = "Content"; //Th mc gc cha ti nguyn l content }
mySpite1 s c load texture ln trn n, file name l ball bn add vo ti nguyn ca game (project=>add=>existing items) file ny c size 64x64 pixcel //cu lnh trn c ngha texture bt u ly t ta 0,0 ca ball v kick c l 64x64 (tc l c file ball )
Hm ha: y l ci quan trng nht n s a Sprite ln bng mt texture ball ti v tr nht nh:
protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(SpriteBlendMode.AlphaBlend); mySprite1.Draw(spriteBatch); spriteBatch.End(); base.Draw(gameTime); }
Ch t kiu AlphaBlend ny s cho php chng ta v cc bc nh c ch trng (mt s chung trnh nh photshop lm c) Sprite ca chng ta l mySpite1 s ly spriteBatch m v cho n, truc mt hm Draw lun c lnh Begin(kiu t) v End(); Xong ri, F5 no Lu file mu: c th my bn ko nhn ra file ball.bmp v khc g dn, nu th c xo file ball c i, add mi n vo mc content (kick phi chn add existing item) tng t cho cc lession sau, nu n bo thiu file, file not found th c xo ht ri add li
Thuc tnh ta im trung tm ca Sprite (on sau dng n vit thut tan va chm) Vector2 center Thuc tnh bn kinh sprite(sau dng n vit thut tan va chm) float radius
public Texture2D texture { get; set; } // sprite texture, read-only property public Vector2 position { get; set; } // sprite position on screen public Vector2 size { get; set; } // sprite size in pixels public Vector2 velocity { get; set; } // sprite velocity private Vector2 screenSize { get; set; } // screen size public Vector2 center{ get{ return position + (size/2);} } // sprite center public float radius { get { return size.X / 2; } } // sprite radius
Chng ta ch thm mt d liu l chiu di v rng ca screen. Vit thm mt hm bool tr v true nu c trng gia 2 sprite clsSprite v false nu nguc li:
public bool Collides(clsSprite otherSprite) { // check if two sprites intersect return (this.position.X + this.size.X > otherSprite.position.X && this.position.X < otherSprite.position.X + otherSprite.size.X && this.position.Y + this.size.Y > otherSprite.position.Y && this.position.Y < otherSprite.position.Y + otherSprite.size.Y); }
N tnh ton ta v kick thc 2 sprite xem chng c trng nhau khng, return tr v true nu biu thc trong () uc tha mn. biu din cc bn c th xem hnh dui y:
Hm ny khng cn thit lm v chng ta s dng n trong lession3, chi vit mang tnh minh ha mt cch kim tra va chm khc thi, bn khng thm n vo cng c Sau ny chng ta c cch khc kim tra va chm, l v ln 1 hcn xung quanh mi sprite v kt va cham thng qua 2 hcn .
Thm mt hm kim tra va chm bin ca 2 sprite, so snh khong cch gia trung tm 2 sprite v tng bn knh ca chng: tr v true nu biu thc trong return() uc tha mn. Chung ta s dng hm ny kim tra va chm 2sprite trong qu trnh chay game.
public bool CircleCollides(clsSprite otherSprite) { // Check if two circle sprites collided return (Vector2.Distance(this.center, otherSprite.center) < this.radius + otherSprite.radius); }
Mt hm kim tra c va chm vi bin hay khng? Nu c o gi tr velocity.X hoc velocity.Y. nu khng th sprite di chuyn (position tng theo velocity ca n)
public void Move() { // if well move out of the screen, invert velocity // checking right boundary if (position.X + size.X + velocity.X > screenSize.X) velocity = new Vector2(-velocity.X, velocity.Y); // checking bottom boundary if (position.Y + size.Y + velocity.Y > screenSize.Y) velocity = new Vector2(velocity.X, -velocity.Y); // checking left boundary if (position.X + velocity.X < 0) velocity = new Vector2(-velocity.X, velocity.Y); // checking bottom boundary if (position.Y + velocity.Y < 0) velocity = new Vector2(velocity.X, -velocity.Y); // since we adjusted the velocity, just add it to the current position position += velocity; }
2Sprite khng ch di chuyn m cn tng tc vi nhau:Chng ta kim tra va chm trong hm Update, bi l hm Update s kim tra game trong qu trnh chy thay i n, n s bit khi no 2 sprite chm nhau, chm screenBound hoc l khng.
Nu 2 sprite chm nhau, chng s o tc ca nhau (vn tc ca sprite 1 s chuen qua sprite2 v ngc li) Diu ny nghim ng L bo ton ng lng trong vt l
protected override void Update(GameTime gameTime) { // Move the sprites mySprite1.Move(); mySprite2.Move(); if (mySprite1.CircleCollides(mySprite2)) { Vector2 tempVelocity = mySprite1.velocity; mySprite1.velocity = mySprite2.velocity; mySprite2.velocity = tempVelocity; } base.Update(gameTime); }
Xong ri, F5 no .
Hm ny tr v false nu 2 sprite (ging lession 2) khng va chm v ngc li s tr v true. Hm ni lession2. Cc hm Move() v Draw() khng thay i. Phn II : t lp Game1.cs 1.khai bo: sau class Game1:Microsoft.Xna.Framework.Game; Chng ta cn 2 sprite nh lession trc. Mc Load content ti ha cho cc sprite v thit lp vn tc cho sprite1, cn sprite2 khng cn thit lp tc (velocity) v chng ta s iu khin n t mouse hoc keyboard. Khai bo:
public class Game1 : Microsoft.Xna.Framework.Game {
Hm LoadContent:
protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); mySprite1 = new clsSprite(Content.Load<Texture2D>("ball"), new Vector2(0f, 0f), new Vector2(64f, 64f), graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight); mySprite2 = new clsSprite(Content.Load<Texture2D>("ball"), new Vector2(218f, 118f), new Vector2(64f, 64f), graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight); // set the speed the sprites will move mySprite1.velocity = new Vector2(5, 5); }
Hm checkKeyboard() nm trong hm Update() s c nhim v kim tra phm c nhn trong thgi gian chy game. Ni chung ci j cn kt trong khi run game u put trong hm Update() ny. Chng ta K sprite2
protected void checkKeyboard() { KeyboardState keyboardState = Keyboard.GetState();
Khi to bn phm
if (keyboardState.IsKeyDown(Keys.Up)) mySprite2.position += new Vector2(0, -5);
V tr thay i khi nhn xung (press) vi ta thay i l 5, ty theo hong phm mi tn m ta thay i thch hp bn cn nh trc ta ca XNA l h Oxy vi tm O nm trn gc trn cng bn tri bn, Ox // mt t v Oy Vung gc mt t.
if (keyboardState.IsKeyDown(Keys.Down)) mySprite2.position += new Vector2(0, 5); if (keyboardState.IsKeyDown(Keys.Left)) mySprite2.position += new Vector2(-5, 0); if (keyboardState.IsKeyDown(Keys.Right)) mySprite2.position += new Vector2(5, 0);
if (mySprite1.Collides(mySprite2))
Tip l mt hm iu khin sprite2 bng mouse, khi chy 1 hoc 2 iu c nhng tt nht bn chn ly 1 trong 2 hm cho ln xn.
protected void checkMouse()
{
// Hm lnh s gip sprite2 di chuyn n ta ca mouse if (mySprite2.position.X < Mouse.GetState().X) mySprite2.position += new Vector2(5, 0); if (mySprite2.position.X > Mouse.GetState().X) mySprite2.position += new Vector2(-5, 0); if (mySprite2.position.Y < Mouse.GetState().Y) mySprite2.position += new Vector2(0, 5); if (mySprite2.position.Y > Mouse.GetState().Y) mySprite2.position += new Vector2(0, -5);
Vector2 l 1 cp bin ngha l khi s dng vector ta cng phi dng vi 1 cp gi tr.
if (mySprite1.Collides(mySprite2)) { mySprite1.velocity *= -1; }
} Trong file mu c thm hm cho tay cm ca Xbox rung, nhng trong bi vit mnh remove ri, v hin ti cha c con Xbox no test c .
Lu , file mu c 2 code cho vic control bng mouse hay keyboard, mouse ang phn ghi ch (tc l c // trc cu) mun test cc bn enable on code cho mouse l c, (khi nn disable code cho keyboard cho d thy)
Kick chut phi vo sound banks chn new sound bank V windows => tiltle hrizon Sau drag v drop nhc t wave bank vo cue box, lu n li
Sau khi thc hin xong bn s c file MySounds.xap t n trong folder cha project
Lu , trong file mu, do ng dn file khc nhau ( thc t my bn v project) nn chc my bn ko chay c, tt nht l t to 1 file XAP mi ri kick phi content ca s solution chn add existing item ri add n vo Phan II Thm m lnh Bn s dng li d n c. Thm vo mc khai bo sau lp class Game1:... Cc yu t ca audio:
AudioEngine audioEngine; WaveBank waveBank; SoundBank soundBank; Cue myLoopingSound = null;
m thanh lp notify S coi l nhc nn v n lp li v khng bao gi ngng cho n khi end. Chng ta
t n trong hm thit lp. B sung nhc hiu ng: if (mySprite1.Collides(mySprite2)) { mySprite1.velocity *= -1; soundBank.PlayCue("chord"); }
Khi no sprite1 va chm vi sprite2 chng ta s chi nhc hiu ng n c gi khi s kin ny xy ra, mc ch l bo cho chng ta s va chm ny bng thnh gic, tt nhin khi chi game, nhc hiu ng cng l cch gip chng ta kim sot cuc chi ca mnh tt hn v sng ng hn
Cho nhc chy v dng nhc nn, nhc hiu ng khng cn v n ch c gi khi c s kin c bit (c va chm chng hn) nhng mt s ngi khng cn nhc nn hay v l do no , h mun tt nhc nn i, t code di y v hm Update() n s gip tt hay m nhc nn myLoopingSound Khi bn nhn phm Enter.
if (keyboardState.IsKeyDown(Keys.Enter)) if (myLoopingSound.IsPaused) myLoopingSound.Resume(); else myLoopingSound.Pause(); } base.Update(gameTime); } {
ch l khi u, ci c ch l nhng gii php lp trnh t tm ti c . nhng Khi hc XNA, C# kh hn flash (dng Action Script) c t ln, ko th vit code mt cch cu th, ring vic dng object ln screen cng l vn . Tuy vy C# l ngn ng cht ch, s kh khn khi lp trnh ban u a li chng ta s cn thn + H thng qun l tt ca XNA khin bn phi cn thn tng cu lnh v khng th cha chy mt hm m ta ko bit cch vit bng hot hnh ch hn, mnh nhn ra rng 1 game nh vit bng flash l nhng mt game kha kh, mt d n ln th khng th, lp trnh OOP c nhng c tnh m LT truyn thng (theo tuyn tnh chy t u v cui hay lp trnh hm, th tc, vd: pascal) khng th c c, mnh nht l tnh ng gi, a hnh v k tha. Chc nhiu bn bit v tnh a hnh? Cc bn hc qua c# ri m, mnh hi vng vy T khi bt u tut, chng ta dng n thng OOP ny bi l C# l NNLT hng i tng hon ton, tuy nhin lession chng ta s i su vo vn nu tiu , Phn II s l mt project game u tin ca tut, cng n gin thi . OOP l mt vn kh, nhng th trong tut ny l nhng EXP c kt qua qu trnh LT v lm game hon ton mang tnh c nhn chc khng th hon ton chnh xc c. ng gi (Encapsulation): Class m bn vit ra cho 1 con monster cn gi l tnh ng gi ca OOP. tnh ng gi th hin tt c kh nng ca object trong mt class... bao gm c vic kim sot n bng cch nh du cho thuc tnh v methods(phng thc) l public (t do truy cp), private (hn ch hn)..., hc c th hiu rng tnh ng gi th hin cch s dng t methods (phng thc) nm trong class ca mt object no lm chng trnh tr ln ngn gn v rnh mch, v d nh bn c methods RUN(int speed) cho con sleketon, bn mun cho n speed l 500 : sleketon.RUN(500);... a hnh (Polymorphism): Mt class l gi li ton b kh nng m object c khai bo kiu class c c. Nhng OOP cho php chng ta to ra nhiu objct hot ng da trn class mt cch tng t nhau, nu c mun c s khc nhau trong cch hot ng ca tng object chng ta s s dng tnh k tha (lession sau) ly v d nh, 1 game c 100 con monster, bn s ngi code cho 100 con monster? Tht v vn ng khng. Nhng trong s 100 con monster ging nhau, bn s ch vit m lnh cho 1 con thi v mun to ra 100 con khc s hot ng theo m lnh . C# l NNLT hng i tng hon ton, do bn khi bn vit code th bn cng khi to cho tnh a hnh ca mnh. nhng con monster cng class s hot ng nh nhau trong cng iu kin. S dng tnh a hnh tuy tin li nhng cng cn cn thn ti a, bn nn chc chn c th kim sot 100 con monster khi chung n c ta ra. Lession sau chng ta s s dng tnh tha k nng cp d n. N cng ci thin sc mnh ca tnh a hnh mt cch ng k
Trong XNA, mt th trn screen nu to ra mt cch ng (dng tnh a hnh-m lnh) hay cho d l khng u gi l 1 component v n s k tha t lp
Microsoft.Xna.Framework.DrawableGameComponent Hoc Microsoft.Xna.Framework.GameComponent.
Tnh a hnh th hin trong lp Game1.cs: Lp ca Object no ch cha nhng kh nng ca Object . Bng cu lnh sau t n trong hm LoadContent() hay hm m c gi t nht 1 ln trong Game1.cs:
Services.AddService(typeof(SpriteBatch), spriteBatch);
N s thm component (thnh phn ) vo chng trnh mt cch ng. add component, chng ta dng k thut sau: Int OBJECTCOUNT = 10
for (int i = 0; i < OBJECTCOUNT; i++) { Components.Add(new OBJECT(this, ref OBJECTTexture)); }
Vng lp for trn to ra 10 (s lung) cc OBJECT trn mn hnh. Lnh ny thng l ng vai tr begin cho mt game, n cng thng ch gi 1 ln, tr khi ngi chi gameover v mun restart. xo cc component c to ra theo cch ng chng ta s dng k thut sau:
private void RemoveAllOBJECT() { for (int i = 0; i < Components.Count; i++) { if (Components[i] is OBJECT) { Components.RemoveAt(i); i--; } } }
Cc cmponent c tp hp trong mt mng c tn Components Mng ny do XNA t to. Lnh Components.Count tr v s lng component trong chng trnh, vng lp for s qut ton b cc component v KT xem thng no l OBJECT, nu l n th Remove n i, sai h i xung KT thng tip theo. Chng ta cn mun to ra OBJECT tu theo K , hon cnh ca game nh sau mt thi gian xc nh, khi boss ku thm ca n,.... cu trc nh sau:
private void CheckforNewOBJECT() { if (iu kin c thm OBJECT) { Components.Add(new Meteor(this, ref meteorTexture)); OBJECTCount++; } }
Trong k thut trn chng ta cn: Thm Cu lnh m bo K OBJECT th 2 vn c th ra i Bin OBJECTcount s m s lng OBJECT c to gip chng ta c th kim sot n. V Texture cho component: khc vi trc y, texture c quy nh trong chnh class ca OBJECTiu ny chng ta s i su khi lm 1 project c th, th ln, trong Game1.cs chng ta s dng hm ho rt n gin.
spriteBatch.Begin(SpriteBlendMode.AlphaBlend); base.Draw(gameTime); spriteBatch.End();
-Kh nng thay i: N c th t d tr thnh kh hn khi ngi chi ln tay v gi h ngi xung lu hn chinh phc cc mc mi -Kh nng sng ng: AI cn c tnh logic, c th d on c ging nh l mt con ngi nag chi cng bn vy (di chuyn, tn cng...) gip ngi chi c th phn on v chin thng trong game. Chng ta p dng kh nng tng kh cho tr chi trong project ny. Chng ta tin hnh ly texture cho t`ng object c th trong mt texture chung, ci ny s lm gn li chng trnh trnh import nhiu. Bt tay vo cng vic thi: 1.i tng u tin l phi thuyn (Ship) k tha t
Microsoft.Xna.Framework.DrawableGameComponent
V n s dng:
using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input;
Nh thng l u tin l khai bo bin:Cc thnh phn khng th thiu:Texture,Position, Chiu di, rng ca Ship (hng s) SpriteBatch, Nhng th b sung l Hnh ch nht bao quanh Ship kim tra va chm (spriteRectangle) v Hnh ch nht l khung ca mn hnh th hin. Thuc tnh vn tc khng cn na, chng ta thay iv tr thng qua position. Hng s chiu di v rng ca ship ly chnh xc texture ca ship trn file texture (gm nhiu texture ca cc Object khc nhau)
protected Texture2D texture; protected Rectangle spriteRectangle; protected Vector2 position; protected SpriteBatch sBatch; protected const int SHIPWIDTH = 30; protected const int SHIPHEIGHT = 30; protected Rectangle screenBounds;
screenBounds ch yu l gip vic xc nh va chm vi mn hnh d dng hn thng qua cc cnh ca hcn. Tip theo l hm nhp d liu: Chng ta nhp cho n texture v game ci m n s chy trn
V tr chng ta s thm vo khi to ra n (trong hm khc), mt lnh ly dch v (mt trong s l cho php s dng ship v tnh a hnh) cho sBatch, ci th hin cho Ship
public Ship(Game game, ref Texture2D theTexture) : base(game) { texture = theTexture; position = new Vector2(); sBatch =(SpriteBatch)Game.Services.GetService(typeof(SpriteBatch)); spriteRectangle = new Rectangle(31, 83, SHIPWIDTH,SHIPHEIGHT);
Mt m lnh na m bo cho Ship ko i qu xa, lun nm trn mn hnh: mn hnh c gi thng qua mt hnh ch nht bao quanh n.
if (position.X < screenBounds.Left) { position.X = screenBounds.Left; } if (position.X > screenBounds.Width - SHIPWIDTH) { position.X = screenBounds.Width - SHIPWIDTH; } if (position.Y < screenBounds.Top) { position.Y = screenBounds.Top; } if (position.Y > screenBounds.Height - SHIPHEIGHT) { position.Y = screenBounds.Height - SHIPHEIGHT; }
kim tra Ship c va chm vi Meteor khng, chng ta i KT 2 hnh ch nht bao quanh 2 object , mun vy cn bit HCN ca Ship l ci j , hm sau s tr v gi tr :
public Rectangle GetBounds() { return new Rectangle((int)position.X, (int)position.Y, SHIPWIDTH, SHIPHEIGHT); }
Hm ho: ci thm vo y l XNA s v Ship theo mt hnh ch nht chnh l thng spriteRectangle, HCN bao ph ly phn texture chung (gm c Ship v Meteor) to 31;83 v bao ph hon ton hnh ci phi thuyn trn texture , XNA ct ci hnhcn ny ra m bin n l texture ca Ship. ci ny thm lnh Draw:
public override void Draw(GameTime gameTime) { // V con tu sBatch.Draw(texture, position, spriteRectangle, Color.White); base.Draw(gameTime); }
Xong thng Ship, tip theo l Meteor 2>Class Meteor Meteor ging vi ship v using v tha k.
Meteor t n di chuyn t do ch khng phi control, do thm thuc tnh vn tc v mt s ngu nhin cho n:
public class Meteor : Microsoft.Xna.Framework.DrawableGameComponent { protected Texture2D texture; protected Rectangle spriteRectangle; protected Vector2 position; protected int Yspeed; protected int Xspeed; protected Random random; protected SpriteBatch sBatch;
protected const int METEORWIDTH = 45; protected const int METEORHEIGHT = 45;
y l k thut to ra mt s ngu nhin: random = new Random(this.GetHashCode()); Sau , mt hm Meteor xut hin pha trn screen mt cch ngu nhin v c vn tc ngu nhin:
protected void PutinStartPosition() { position.X = random.Next(Game.Window.ClientBounds.Width - METEORWIDTH); position.Y = 0; Yspeed = 1 + random.Next(9); Xspeed = random.Next(3) - 1; }
Lu mt t random.Next(a) s tr v s random trong(0;a) Hm nhp d liu cho Meteor cng tng t vi Ship:
public Meteor(Game game, ref Texture2D theTexture) : base(game) { texture = theTexture; position = new Vector2(); sBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));
spriteRectangle = new Rectangle(20, 16, METEORWIDTH, METEORHEIGHT); random = new Random(this.GetHashCode()); PutinStartPosition();
Mt Hm to ra mt hnh cn xung quanh Mteor kim tra va chm vi Ship thng qua KT va chm vi hcn bao quanh Ship, tr v True hoc false:
public bool CheckCollision(Rectangle rect) { Rectangle spriterect = new Rectangle((int)position.X, (int)position.Y, METEORWIDTH, METEORHEIGHT); return spriterect.Intersects(rect); }
Phng thc Intersects() Thc s rt hiu qu v n gin khi KT xem 2 HCN c trng nhau khng. Cui cng l Hm ho, n cng nh ca Ship vy:
public override void Draw(GameTime gameTime) { // Draw the meteor sBatch.Draw(texture, position, spriteRectangle, Color.White); base.Draw(gameTime); }
K tha:
public class Game1 : Microsoft.Xna.Framework.Game
Khai bo:
GraphicsDeviceManager graphics; SpriteBatch spriteBatch; private Texture2D backgroundTexture, meteorTexture; // m thanh private SoundEffect explosion; private SoundEffect newMeteor; private Song backMusic; // Thnh phn object private Ship player; private int lastTickCount; private KeyboardState keyboard; private SpriteFont gameFont; private int rockCount; private const int STARTMETEORCOUNT = 10; private const int ADDMETEORTIME = 5000;
Texture gm hnh nn v hnh ca cc object. m thanh chng ta add trc tip nh texture, song s dng nh nhc nn, SoundEffect chc cc bn hiu ri. Khai bo font v chng ta s ghi s lng Meteor hin ti ln mn hnh cho gamer bit m trnh. Mt bin m s lng Meteor gip kim sot chng, hng STARTMETEORCOUNT = 10; v ADDMETEORTIME = 5000; C tc dng a ra s lng Meteor ti thiu khi begin game v Khong Thi gian chng ta to thm meteor tng kh cho tr chi Hm nhp d liu: n ch c j ngoi nhng th bn bit:
public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; }
MediaPlayer.Play(backMusic); S lm chy nhc nn cho n khi end game. Hoc khi bi ht end; 1.n khu to ra cc meteor:
for (int i = 0; i < STARTMETEORCOUNT; i++) { Components.Add(new Meteor(this, ref meteorTexture)); }
Meteor(this, ref meteorTexture)); Nu cc thc mc v cc tham s ths v meteorTexture hy coi li phn nhp d liu ca lp Meteor 2. to ra ship, chng ta ko cn n for bi ch c 1 ship thi m, bi vy nh ngha kiu truyn thng v mng component ca XNA s add n vo:
player = new Ship(this, ref meteorTexture); Components.Add(player);
4.Ngoi ra ta thit lp thi gian lastTickCount l thi im hin ti ca h thng lc bt u na v s lng meteor( rockcount) s bng s Meteor khi u STARTMETEORCOUNT:
lastTickCount = System.Environment.TickCount; rockCount = STARTMETEORCOUNT;
iu j xay ra nu Ship va vo meteor? Bm sau game c restart, chng ta tn dng hm Start restart lun cn cc meteor phi tr v vi 0 ca n bng hm sau:
private void RemoveAllMeteors() { for (int i = 0; i < Components.Count; i++) { if (Components[i] is Meteor) { Components.RemoveAt(i); i--; } } }
Components l mng cha cc component (thnh phn) ca XNA nhc li nu cc bn wen. Tinh lgic ca game: Game ny chi ch yu KT va chm, chng ta cn 1 bin kiu bool lm iu , tt nhin khi begin, cha c va chm nn bin ny nhn false. KT va chm thng qua 1 hcn bao quanh object Ship, chng ta vit hm GetBound ng khng no, t to ra hcn bao quanh ship l vic rt d dng. Foreach th chc cc bn bt ri, n l vng for v lp trong 1 mng c th. Foreach lp trong mng Components v tm nhng object l Meteor, KT va chm vi Ship, nu c th bm, xo sch meteor v bt u li. Trong thi gian chy game, sau 1 khong thi gian ADDMETEORTIME Hm
CheckforNewMeteor();
S to ra mt meteor.
private void DoGameLogic() { // Check collisions bool hasColision = false; Rectangle shipRectangle = player.GetBounds(); foreach (GameComponent gc in Components) { if (gc is Meteor) { hasColision = ((Meteor)gc).CheckCollision(shipRectangle); if (hasColision) { // BOOM!
explosion.Play(); // Remove all previous meteors RemoveAllMeteors(); // Let's start again Start(); break; } } } // Add a new meteor if is time CheckforNewMeteor(); }
Hm Update :Cc k n gin, to ra player nu cha c v thc hin hm DoGameLogic(); N cha ton b game play ca chng ta.
protected override void Update(GameTime gameTime) { keyboard = Keyboard.GetState(); // Start if not started yet if (player == null) { Start(); } // Fun never ends.. DoGameLogic(); // Update all other components base.Update(gameTime); }
Hm ho Draw: Ch yu chng ta to ra 2 texture, 1 ci lm hnh nn backgroundTexture. Ship v Meteor ko cn code bi l chng ta code trong class ca chng, chng t c v khi run Game. In ra s lng Meteor nhm mc ch cho ngi chi bit level ca h, cng nh time bm tr c, tt nhin KQ cui cng player s thua thi vn l h tr c bao lu.String l chui, lnh rockCount.ToString() a SL meteor thnh kiu chui v in ra theo 1 hm in chui k t
spriteBatch.DrawString(gameFont, "Rocks: " + rockCount.ToString(), new Vector2(15, 15), Color.YellowGreen); spriteBatch.End();
protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.Black); // Draw background texture in a seperate pass spriteBatch.Begin(); spriteBatch.Draw(backgroundTexture, new Rectangle(0, 0, graphics.GraphicsDevice.DisplayMode.Width, graphics.GraphicsDevice.DisplayMode.Height), Color.LightGray); spriteBatch.End(); // Start rendering sprites spriteBatch.Begin(SpriteBlendMode.AlphaBlend); // Draw the game components (sprites included) base.Draw(gameTime); // End rendering sprites spriteBatch.End(); // Draw Score spriteBatch.Begin(); spriteBatch.DrawString(gameFont, "Rocks: " + rockCount.ToString(), new Vector2(15, 15), Color.YellowGreen); spriteBatch.End(); } }
Xong F5 i Lession sau s s dng li project ny, cc methods s s dng li nhiu y. D n nng cp s thuc loi cc k phc tp. cc class khng ch vit cho Object m cn c vic qun l m thanh, object v lm nn cho cc class khc + nhiu phng thc mi s c introduced..., Bn nn chun b t tng + cht kin nhn, ko phi chm go u
Z Z z...
C ngha l game ca chng ta k tha t lp Microsoft.Xna.Framework.Game Sn c ca XNA, Game1 tha hng mi thuc tnh, hm, phng thc... ca m n l
Microsoft.Xna.Framework.Game.
Tnh k tha rt tin li cho nhng d n ln, n lm gim khi lng cng vic ca programmer gip chng trnh mch lc, n gin hn, d debug v kim sot. Ni chay kh hiu mnh nu th VD ny. Bn c 3 chng loi monster khc nhau trong game ca bn, chng u bit chy n ch bn, tn cng v b chy khi sp die, th nu chng ta to 1 lp chung cho 3 chng monster trn gi l Monster, sau to ring cho tng con mi con mt class ring k tha t lp Monster. Chng ta ch cn code cho con 1 l melee, con 2 l range, con 3 l boss c skill chng ch hn, khi c li, cng d khoanh vng m debug v chng trnh cng gn hn rt nhiu. Vi VD nu trn, lp Monster s c khai bo nh sau:
public abstract class Monster
{ } Ci ch abstract chc cc bn bit, n nh du lp o, tc l lp lm nn cho cc lp khc k tha, lp o khng to ra i tng khi chy chng trnh, nu c tnh lm iu , C# s bo li. Khi mnh cn code class cho boss, code s nh sau: Public class Boss:Monster { } Tng t Boss s c tt c cc bin, hm, phng thc ca Monster, nh trong mt s trng hp, ko fi l iu bn mong mun. VD: con lnh s chy khi sp die nhng con boss s t chin n cng, khi bn s phi vit li hm b chy ca monster: Trong class ca monster:
ch virtual nh du phng thc o, tc l trong tu trng hp c th, n c th b xung (tc l i hp lun) bi phng thc c nh du override ,phung thc mi ph nhn hon ton phung thc c nu bn cn li ci g t phng thc c, lnh base s lm iu . Ko dng base cho phng thc c nh du override VD, trong lp Monster: Public void bochay(int Speed) Bn mun gi li speed cho boss, trong lp Boss: Public void bochay(int Speed):base(Speed) Bn c th to ra mt phng thc mi bng t kho new, u ny khng ph nhn g t lp m (lp c s, lp cho k tha), ngc li vi abstract l sealed... nhiu lm, cc bn t tm hiu thm ci ny v n l C# thun tu. Mt phn na m nh ra mnh ko gii thch, nhng project dng nhiu qu, l b truy cp d liu (v d ca class Z):
public KIU D LIU TN BIN X { get { return Y L GI TR BIN X S NHN; } set { BIN Y = THIT LP GI TR Y SAU KHI X NHN GI TR; } }
Nhn xt: X vi Y nn c s tng ng cho d nh v chng trnh tng minh, VD: frames vi Frames. N m bo s hi ho gia lp c s v lp m rng, hay gia cc lp khc nhau
Phn get bt buc c, BIN c gi tr tr v, phn set dng thay i bin X nu khng c set, bin ch c th c gi tr (read only), thng chng ta set { BIN Y = value; } thng tin trao i 2 chiu
Chc nng: Cho php mt s bin nh du l protected (ch cho php truy cp t object ca lp hoc lp con ca n) hay private (ch c object ca lp mi truy cp c) c th truy cp bi cc lp khc (tn bin nh du public ..).
Cch s dng: nh ni, ci c dng ph bin vi dng l: khi chng ta cn truy cp bin (thuc tnh) X ca lp Z m li ang lp T ch hn. By gi lp T c thuc tnh M, m X mun ly thng tin t M t lp T, ta vit m lnh T n gin nh sau: Z.X = M; Tt nhin object lp Z c khai bo lp T nh mt object (VD: khi Ship mn action c khai bo tc l Ship.Speed dc khai bo (vi Speed c ci t b truy cp d liu) Cch nhn dang: B truy cp ny c dng ph bin c ch ht trong bi cng kh, cc bn c th da vo cch t tn bin: Cc programmer khi LT thng t tn bin ca lp khng vit hoa u (VD: speed), cn bin truy cp t lp ngoi th ngc li (Speed). Cng nh l cc LTV thng hiu ngm Methods, thuc tnh sn c th dng ch vit hoa cho cc ch ca tn ca n, (VD: SpeedLower) cn ci do LTV vit, th h vit kiu thng cho ch u, sau ch hoa v li ch thng... (VD: speedLower)
OK! bt u no...
A. Class Nhn (core) 1.Sprite.cs Bt u t Sprite.cs, y l nn cho cc object nh PowerSource (ci gip game ko di hn) v Meteor hot ng. Using v k tha ko c j gii thch, ch lu namespace khi t sprite.cs trong folder core thi:
#region Using Statements using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; #endregion namespace RockRainEnhanced.Core {
Khai bo:
private int activeFrame; activeFrame Bin xc nh index(ch s) ca frame chy. Frame l khung hnh cha 1 trng
thi ca sprite no , chng thay i rt nhanh trn mn hnh v lm chng ta c cm gic l vt ang chuyn ng (hot hnh). XNA chy hot hnh cho sprite cng da vo cc khung hnh frame ca sprite , lm cho chng ta cm gic sprite c chy.cng Tng t cho vic lm phim hot hnh hay khi bn s dng flash design.
private readonly Texture2D texture; private List<Rectangle> frames; frames L bin danh sch cc HCN chnh l cc cnh ca khung hnh frame (l cc trng thi ca
Cc bn c th quan st texture ca Meteor m n c bao nhiu frame :D C 3 loi Metor v mi loi c 8 ci frame.
Hm nhp d liu:
public Sprite(Game game, ref Texture2D theTexture) : base(game) { texture = theTexture; activeFrame = 0; }
Ging nh project c, sprite nhp vo n texture v game, thit lp cho Frameactive = 0; (frame u tin)
public List<Rectangle> Frames { get { return frames; } set { frames = value; } }
Code trn gi l 1 b truy cp d liu cho bin Frames kiu List<Rectangle> trong C#, khin cho n lun phi nhn v gi tr ca frames . Hm thit lp:
public override void Initialize() { // Get the current spritebatch
sbBatch c chuyn xung hm ny, thc ra n phn nhp d liu cng ch sao, u c gi khi chy game c. Hm Update():
public override void Update(GameTime gameTime) { elapsedTime += gameTime.ElapsedGameTime; // it's time to a next frame? if (elapsedTime > TimeSpan.FromMilliseconds(frameDelay)) { elapsedTime -= TimeSpan.FromMilliseconds(frameDelay); activeFrame++; if (activeFrame == frames.Count) { activeFrame = 0; } // Get the current frame currentFrame = frames[activeFrame]; } base.Update(gameTime); }
Hm ny thc hin cc cng vic sau: Tnh thi gian chay game thng qua
elapsedTime += gameTime.ElapsedGameTime;
Bin elapsedTime s nhn gi tr v cng b (-> 0) do hm update chy v duyt rt nhanh, khi bin ny mi tng cao hn framedelay 1 to n se thc hin cu lnh
elapsedTime -= TimeSpan.FromMilliseconds(frameDelay);
V elapsedTime ch cn li gi tr tng cao hn 1 to , lnh TimeSpan.FromMilliseconds(frameDelay) tr v gi tr ca framedelay theo miligiy. N tng s framActive ln tc l frame c th chy nhm thc hin hot hnh cho sprite, on sau rp texture vo bn s thy r hn. frames.Count Tr v sl frame ca sprite, nu activeFrame == frames.Count tc l chy ht frame ca sprite v hot hnh s c bt u li. Hm ho
public override void Draw(GameTime gameTime) { sbBatch.Draw(texture, position, currentFrame, Color.White); base.Draw(gameTime); }
Cu lnh currentFrame = frames[activeFrame]; Draw lun ch v frame hin thi. khi qua frame khc currentFrame thay i v KQ l sbBatch.Draw(texture, position, currentFrame, Color.White) cng thay i t sprite c hot hnh. 2.Thnh phn Image: Ci class ny n gin, n ch thun tu thc hin cc cng vic sau: -L /n cho cc thnh phn image: nh nn ca cc mn
public enum DrawMode { Center = 1, Stretch, };
y l dy cc kiu v image, n c dng khi v bckground Phn khai bo drawMode c kiu DrawMode nn n c 2 thnh phn drawMode.Center v drawMode.Center; v drawMode.Center c gi tr 1.
// Texture to draw protected readonly Texture2D texture; // Draw Mode protected readonly DrawMode drawMode; // Spritebatch protected SpriteBatch spriteBatch = null; // Image Rectangle protected Rectangle imageRect;
imageRect L HCN bao quanh imageComponent. K thut dng HCN khoanh vng ly texture trn mt bc nh ta import vo quen thuc lession trc, bn cng thy n hm Draw(GameTime gameTime) Hm nhp data: gm game, Texture cho imageComponent v kiu v n.
ng vi cc kiu v khc nhau l cc HCN bao quanh khc nhau, t a ra cc vng khc nhau trn texture v c cc texture khc nhau. Center: Hnh CN nm chnh gia Texture Background. Nu cc bn s thy texture ca chng ta khc nhau v khc size of screen, chnh xc l cc BackGrround u ln hn screen. Vic dng Rectangle ly texture chnh gia cc texture background gip chng ta c hnh nh tht ca texture hn thi, ch ko th em ht ci texture background to th l v screen c,
HCN to tng trng cho image dng lm texture, HCN to nm pha di, lch bn phi tng trng vng ly texture, do do Screen < texture nn ch c HCN nh tng trng cho HCN bao quanh phn s ly lm background khi dng kiu center v HCN c kich thc = screen Stretch: HCN c to 0;0 trn texture, v c kick thc = screen, khi HCN s v tr nh sau, sau n ly vng texture lm background:
V sao phc tp nh vy, ci ny cng tu trng hp thi, v texture kick thc to qu, c ci ly tm image mi c texture p, c ci ly cnh thi cng p...
public ImageComponent(Game game, Texture2D texture, DrawMode drawMode) : base(game) { this.texture = texture; this.drawMode = drawMode; // Get the current spritebatch // this chnh l ImageComponent spriteBatch = (SpriteBatch)
Game.Services.GetService(typeof (SpriteBatch)); // Create a rectangle with the size and position of the image switch (drawMode) { case DrawMode.Center: imageRect = new Rectangle( (Game.Window.ClientBounds.Width-texture.Width)/2, (Game.Window.ClientBounds.Height - texture.Height)/2, texture.Width, texture.Height); break; case DrawMode.Stretch: imageRect = new Rectangle(0, 0, Game.Window.ClientBounds.Width, Game.Window.ClientBounds.Height); break; } } /// <summary> /// Allows the game component to draw itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> public override void Draw(GameTime gameTime) { spriteBatch.Draw(texture, imageRect, Color.White); base.Draw(gameTime); } } }
3.Class cho thnh phn Menu Mt Menu c to ra hon ton = code, tc l ko c to paint, photoshop hay nhng ci i loi th u nh. Chng ta to ra Menu gamer la chn: 1 player, 2 players, help, out => chng c 4 ci => Menu ca chng ta c 4 thnh phn. User dng phm Mi tn chn 1 trong 4. Cho bui sng ca 1 lp nh thng l:
#region Using Statements using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; #endregion
namespace RockRainEnhanced.Core { /// <summary> /// This is a game component that implements a menu with text elements. /// </summary> public class TextMenuComponent : DrawableGameComponent {
Phn khai bo. thng SpriteBatch cc bn thy ch null ko, null tc l trng rng m vn d SB cng l 1 sprite rng ri, cu lnh ny ch lm NNg thm tng minh, th thi.
// Spritebatch protected SpriteBatch spriteBatch = null; S dng font ch, ci regular dng cho list trong Menu, ci selected dng cho phn c chn trong menu (ta chn = phm mi tn) protected readonly SpriteFont regularFont, selectedFont; // Colors Quy nh mu cho 2 loi font protected Color regularColor = Color.White, selectedColor = Color.Red; // Menu Position V tr Menu protected Vector2 position = new Vector2(); // Items Bin ghi li phn no trong menu c chn, mc nh l 0 (l ci u tin ) protected int selectedIndex = 0; Bin ghi li tn cc thnh phn ca menu private readonly List<string> menuItems; Khi to bn phm // Used for handle input protected KeyboardState oldKeyboardState; Khai bo size // Size of menu in pixels protected int width, height; Thm hiu ng m thanh khi cht v // For audio effects protected AudioLibrary audio; -> Chng ta c 1 class ring v AudioLibrary, S trnh by sau
Phn nhp data: Menu cn nhp v game, 2loi font T kho this ch l chnh i tng ca class Menu ny cn nhp selectedFont. T kho th dng phn bit selectedFont ca class v ca tham s tham chiu selectedFont trong hm nhp data
public TextMenuComponent(Game game, SpriteFont normalFont,
SpriteFont selectedFont) : base(game) { regularFont = normalFont; this.selectedFont = selectedFont; Khi to gi tr (vn l null): menuItems = new List<string>(); // Get the current spritebatch spriteBatch = (SpriteBatch) Game.Services.GetService(typeof (SpriteBatch)); // Get the audio library audio = (AudioLibrary) Game.Services.GetService(typeof(AudioLibrary)); // Used for input handling oldKeyboardState = Keyboard.GetState(); /// <summary> /// Set the Menu Options /// </summary> /// <param name="items"></param>
Hm di y lm nhim v lm sch Menu, t Ni dung cho Menu, sau tnh size ca tng Thnh hn trong Menu, tc l c mi thnh phn khi hm c gi s c width v height.
protected void CalculateBounds() { width = 0; height = 0; foreach (string item in menuItems) //duyt tng chui(gi l nhn cng c label) trong Menu { Vector2 size = selectedFont.MeasureString(item); //Chiu di chui k t nhp vo if (size.X > width) //Tnh width theo size.X (chiu di ca label trong menu) { width = (int) size.X; } height += selectedFont.LineSpacing; //Chiu rng height tnh theo khong cch hng } }
public void SetMenuItems(string[] items) { menuItems.Clear(); menuItems.AddRange(items); CalculateBounds(); } /// <summary> /// Width of menu in pixels /// </summary>
Cc B truy cp d liu, lun tr v gi tr ca width cho Width v Height Lnh set ch quy nh gi tr l value ca chnh n n ko quan trng u.
public int Width { get { return width; } } /// <summary> /// Height of menu in pixels /// </summary> public int Height { get { return height; } } /// <summary> /// Selected menu item index /// </summary> public int SelectedIndex { get { return selectedIndex; } set { selectedIndex = value; } } /// <summary> /// Regular item color /// </summary> public Color RegularColor { get { return regularColor; } set { regularColor = value; } } /// <summary> /// Selected item color /// </summary> public Color SelectedColor {
get { return selectedColor; } set { selectedColor = value; } } /// <summary> /// Position of component in screen /// </summary> public Vector2 Position { get { return position; } set { position = value; } }
Hm Update(): ni mi th Hot ng: Bn thy ch release c quen ko? Th ch Press th no? Cn Drop? Release hiu n gin l 1 s kin (event) din ra khi bn Press 1 phm v ngay sau drop n ra, chng ta tm hiu k thut release phm trong XNA, VD nh:
down = (oldKeyboardState.IsKeyDown(Keys.Down) && (keyboardState.IsKeyUp(Keys.Down)));
Down tr v true khi c event release bng mt php ton && (tc l and )
public override void Update(GameTime gameTime) { //Khi to 2 bn phm KeyboardState keyboardState = Keyboard.GetState(); oldKeyboardState = keyboardState; bool down, up; // Handle the keyboard down = (oldKeyboardState.IsKeyDown(Keys.Down) && (keyboardState.IsKeyUp(Keys.Down))); up = (oldKeyboardState.IsKeyDown(Keys.Up) && (keyboardState.IsKeyUp(Keys.Up))); if (down || up) { audio.MenuScroll.Play(); } // nu release phm down (mi tn hng xung) if (down) { //tng ch s ca thnh phn menu c chn ln 1 (chn Ni dung khc trong //Menu), nu chn ht th tr v Ci list u tin (c index = 0) selectedIndex++; if (selectedIndex == menuItems.Count)
base.Update(gameTime); }
Hm ho: Hm hot ng nh sau: gn position.Y (to y ca Menu) cho y nhm mc ch mi component ca menu u c y (y l bin a phng trong hm Draw) to x th khng cn v mi component u chung nhau to x, (thng hng vi nhau theo chiu dc) Duyt tng thnh phn ca Menu Kt i ang c index my thit t cho n font v color.
public override void Draw(GameTime gameTime) { float y = position.Y; for (int i = 0; i < menuItems.Count; i++) { SpriteFont font; Color theColor; if (i == SelectedIndex) { font = selectedFont; theColor = selectedColor; } else { font = regularFont; theColor = regularColor; }
Draw text c 2 loi, ci bng c ch mu en c v trc, bi l ci j v trc s b xung bi ci sau, chnh l ci text chnh thc ca menu, khng phi bng ca n.
// Draw the text shadow
spriteBatch.DrawString(font, menuItems[i], new Vector2(position.X + 1, y + 1), Color.Black); // Draw the text item spriteBatch.DrawString(font, menuItems[i], new Vector2(position.X, y), theColor); y += font.LineSpacing; } base.Draw(gameTime); } } }
4.Lp Game Scene Tng Mn trong game: y l nn cho cc class sau: mn begin, play, help
#region Using Statements using System.Collections.Generic; using Microsoft.Xna.Framework; #endregion namespace RockRainEnhanced.Core { /// <summary> /// This is the base class for all game scenes. /// </summary>
Trong Game1, do tnh k tha m n c Mng cha component nhng GameScene th ko, n phi t to ra danh sch ring cha cc component ca n.
private readonly List<GameComponent> components; base min gii thch public GameScene(Game game) : base(game) { //dach sch components hin ti vn l null components = new List<GameComponent>(); //Mc nh Scene ny ko hin th v ko hot ng, y l 2 thuc tnh k tha t DrawableGameComponent nn khi to Visible = false;
Enabled = false; }
Hm di ny ngc vi hm trn
public virtual void Hide() { Visible = false; Enabled = false; } /// <summary> /// Components of Game Scene /// </summary>
B truy cp data
public List<GameComponent> Components { get { return components; } }
Hm Update(): Update tng thnh phn rt chi l tru tng chng ta ko h bit components.Count L bao nhiu? Ci ny tu thuc tng scene c th. Update cho nhng thnh phn c php hot ng (enable = true). public override void Update(GameTime gameTime)
{ // Update the child GameComponents for (int i = 0; i < components.Count; i++) { if (components[i].Enabled) { components[i].Update(gameTime); } } base.Update(gameTime);
Hm ho: V tng component ca scene nu n c php hin th (visible = true) v nu n thuc lp DrawableGameComponent hay k tha t lp ny. Tt nhin ci ny ch l gi hm, cn Draw ntn (texture, ch v...) l do class ca tng component quyt nh
public override void Draw(GameTime gameTime) { // Draw the child GameComponents (if drawable) for (int i = 0; i < components.Count; i++) { GameComponent gc = components[i]; if ((gc is DrawableGameComponent) && ((DrawableGameComponent) gc).Visible) { ((DrawableGameComponent) gc).Draw(gameTime); } } base.Draw(gameTime); } } }
C bn l xong phn class nhn (core), sau y s l cc class cho cc object th hin trong game
B. Class Th hin (Extended) 1.AudioLibrary i t ci n gin nht: m thanh: Tt c sound ca game c b vo y, u tin l khai bo (song-nhc nn v Effect-Hiu ng) Sau chng c to b truy cp d liu Cho cc mn trong game, cc s kin din ra c th s dng sound khi chy game (khi ng, n im, va chm...) v 1 hm load sound khi khi ng.
using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Media; namespace RockRainEnhanced { public class AudioLibrary { private SoundEffect explosion; private SoundEffect newMeteor; private SoundEffect menuBack;
private SoundEffect menuSelect; private SoundEffect menuScroll; private SoundEffect powerGet; private SoundEffect powerShow; private Song backMusic; private Song startMusic; public SoundEffect Explosion { get { return explosion; } } public SoundEffect NewMeteor { get { return newMeteor; } } public SoundEffect MenuBack { get { return menuBack; } } public SoundEffect MenuSelect { get { return menuSelect; } } public SoundEffect MenuScroll { get { return menuScroll; } } public SoundEffect PowerGet { get { return powerGet; } } public SoundEffect PowerShow { get { return powerShow; } } public Song BackMusic { get { return backMusic; } } public Song StartMusic { get { return startMusic; } }
public void LoadContent(ContentManager Content) { explosion = Content.Load<SoundEffect>("explosion"); newMeteor = Content.Load<SoundEffect>("newmeteor"); backMusic = Content.Load<Song>("backMusic"); startMusic = Content.Load<Song>("startMusic"); menuBack = Content.Load<SoundEffect>("menu_back"); menuSelect = Content.Load<SoundEffect>("menu_select3"); menuScroll = Content.Load<SoundEffect>("menu_scroll"); powerShow = Content.Load<SoundEffect>("powershow"); powerGet = Content.Load<SoundEffect>("powerget"); } } }
Meteor k tha t sprite. N c tt c .... Cc thuc tnh mi cho Meteor:Tc , kh nng to ra s ngu nhin v index cho m s cho tng Meteor v chng SL rt nhiu.
// Vertical velocity protected int Yspeed; // Horizontal velocity protected int Xspeed; protected Random random; // Unique id for this meteor private int index;
Hm nhp Data: Frames ly d liu t frames thng qua b truy cp, frame l HCN bao quanh ly Texture ca Meteor trn ci image dng lm texture chung to ng ong.
public Meteor(Game game, ref Texture2D theTexture) : base(game, ref theTexture)
{ Frames = new List<Rectangle>(); //Hin ti Frames vn null //Cu lnh di Add frame vo Frames c kiu List //To Y thay i tc l chng ta ly frame tun t t trn -> di Rectangle frame = new Rectangle(); frame.X = 468; frame.Y = 0; frame.Width = 49; frame.Height = 44; Frames.Add(frame); frame.Y = 50; Frames.Add(frame); frame.Y = 98; frame.Height = 45; Frames.Add(frame); frame.Y = 146; frame.Height = 49; Frames.Add(frame); frame.Y = 200; frame.Height = 44; Frames.Add(frame); frame.Y = 250; Frames.Add(frame); frame.Y = 299; Frames.Add(frame); frame.Y = 350; frame.Height = 49; Frames.Add(frame); // Initialize the random number generator and put the meteor in your // start position random = new Random(GetHashCode()); PutinStartPosition(); } Hm t vn tc v to ngu nhin mt khi Meteor c to ra: public void PutinStartPosition() { position.X = random.Next(Game.Window.ClientBounds.Width currentFrame.Width); position.Y = 0; YSpeed = 1 + random.Next(9); XSpeed = random.Next(3) - 1;
B truy cp d liu
public int YSpeed { get { return Yspeed; } set { Yspeed = value; frameDelay = 200 - (Yspeed * 5); //t thi gian chuyn frame k n nhm to hot hnh } } /// <summary> /// Horizontal Velocity /// </summary> public int XSpeed { get { return Xspeed; } set { Xspeed = value; } } /// <summary> /// Meteor Identifier /// </summary> public int Index { get { return index; } set { index = value; } }
base.Update(gameTime); }
Kim tra va chm vi 1 HCN (tt nhin HCN bao quanh Ship ri) vi HCN bao quanh Mteor nhm bit khi no bm hoc restart game.
public bool CheckCollision(Rectangle rect) { Rectangle spriterect =new Rectangle((int) position.X, (int) position.Y, currentFrame.Width, currentFrame.Height); return spriterect.Intersects(rect); } } }
3. Class qun L cc Meteor: To ra, KT va chm, gi ho... Class c v tr rt quan trong, t n to ra, iu khin cc Meteor trong chng trnh, on sau rp v th bin meteors khai bo kiu MeteorsManager rt gn
#region Using Statements using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; #endregion namespace RockRainEnhanced { /// <summary> /// This game component implements a manager for all Meteors in the game. /// </summary> public class MeteorsManager : DrawableGameComponent {
Hng s SL Cc meteor khi begin private const int STARTMETEORCOUNT = 10; Khong Time to thm Meteor n v miligiy (l 5s)
m thanh
private AudioLibrary audio;
Texture
protected Texture2D meteorTexture;
Hm nhp data:
public MeteorsManager(Game game, ref Texture2D theTexture) : base(game) { meteorTexture = theTexture;//Ly texture meteors = new List<Meteor>();//ang null // s dng audio library audio = (AudioLibrary) Game.Services.GetService(typeof(AudioLibrary)); }
Hm Thm Meteor vo game, thit lp index cho tng Meteor nhm xc nh c cc Meteor mt cch ring r, sau thm n vo list cc Meteor. Hm tr v 1 new meteor v n s H ngay lp tc.
private Meteor AddNewMeteor() { Meteor newMeteor = new Meteor(Game, ref meteorTexture); newMeteor.Initialize();
Hm Start to ra cc Meteor cho game, n to ra bin m thi gian elapsedTime nhm bit khi no cn thm meteor public void Start()
{ // Initialize a counter elapsedTime = TimeSpan.Zero; // Add the meteors for (int i = 0; i < STARTMETEORCOUNT; i++) { AddNewMeteor(); } }
Hm di quen thuc ri, c trong lession trc. Tt nhin s dng phng thc mi nhng chc nng th nh c. private void CheckforNewMeteor(GameTime gameTime)
{ // Add a rock each ADDMETEORTIME elapsedTime += gameTime.ElapsedGameTime; if (elapsedTime > TimeSpan.FromMilliseconds(ADDMETEORTIME)) { elapsedTime -= TimeSpan.FromMilliseconds(ADDMETEORTIME); AddNewMeteor(); // Play a sound for a new meteor audio.NewMeteor.Play(); } }
Hm di Kim sot chng trnh to ra Metor v Update cho tng Meteor trong List
public override void Update(GameTime gameTime) { CheckforNewMeteor(gameTime); // Update Meteors for (int i = 0; i < meteors.Count; i++) { meteors[i].Update(gameTime); } base.Update(gameTime); } /// <summary> /// Check if the ship collide with a meteor /// <returns>true, if has a collision</returns> /// </summary>
Hm KT va chm cho tng Object Meteor vi HCN (ca Ship) . Methods CheckCollision(rect) vit trong lp ca Meteor. Hm CheckForCollisions (thm ch s) tr v true nu c bt k va chm no c ghi nhn v restart li meteor va cham.
public bool CheckForCollisions(Rectangle rect) { for (int i = 0; i < meteors.Count; i++) { if (meteors[i].CheckCollision(rect)) { // BOM !! audio.Explosion.Play(); // Put the meteor back to your initial position meteors[i].PutinStartPosition(); return true; } } return false; }
meteors[i].Draw(gameTime); } base.Draw(gameTime); } } }
4.Lp Player (Ship):iu kin Ship v KT Ship va chm... Lp ny ton nhng th chng ta bit, mnh s i nhanh, rt nhanh :
#region Using Statements using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; #endregion namespace RockRainEnhanced {
Hm Nhp d liu:
Tham s tham chiu playerID c tc dng xc nh r rng l ngi chi 1 hay l 2 V c th c 2 player nn texture ca 2 Ship l khc nhau, ta cn c 2 texture khc nhau t cn 2 hcn Khc nhau khi khoanh vng ly texture t cn phi nhp vo rectangle.
public Player(Game game, ref Texture2D theTexture, PlayerIndex playerID, Rectangle rectangle) : base(game) { texture = theTexture; position = new Vector2(); playerIndex = playerID; // Get the current spritebatch sBatch = (SpriteBatch) Game.Services.GetService(typeof(SpriteBatch)); // Create the source rectangle. // This represents where is the sprite picture in surface spriteRectangle = rectangle; screenBounds = new Rectangle(0, 0, Game.Window.ClientBounds.Width, Game.Window.ClientBounds.Height); }
if (playerIndex == PlayerIndex.One)
{ position.X = screenBounds.Width/3; } else { position.X = (int) (screenBounds.Width/1.5); } position.Y = screenBounds.Height - spriteRectangle.Height; score = 0; power = INITIALPOWER; }
Sau 1 giy, tng score hay gim power 1 n v. Khi chi game nu player ht power, h s die. m bo tr chi c tip tc ngi chi buc phi n nhng cc PowerSource nhm ln power chi tp. S c lp khc m nhn game lgic ny.
private void UpdateShip(GameTime gameTime) { // Keep the player inside the screen KeepInBound(); // Update score elapsedTime += gameTime.ElapsedGameTime; if (elapsedTime > TimeSpan.FromSeconds(1)) { elapsedTime -= TimeSpan.FromSeconds(1); score++; power--; } }
/// </summary>
5.Lp cho PowerSource-Th ko di tr chi. Nu ko c thm power, ngi chi s thua m i vi h iu ny ko th v . Phn k tha:
#region Using Statements using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using RockRainEnhanced.Core; #endregion namespace RockRainEnhanced { /// <summary> /// This is a game component that implements Power Source Element. /// </summary> public class PowerSource : Sprite {
Phn nhp data Nhp texture v k thut lm hot hnh tng t Meteor
public PowerSource(Game game, ref Texture2D theTexture) : base(game, ref theTexture) { texture = theTexture; Frames = new List<Rectangle>(); Rectangle frame = new Rectangle();
frame.X = 291; frame.Y = 17; frame.Width = 14; frame.Height = 12; Frames.Add(frame); frame.Y = 30; Frames.Add(frame); frame.Y = 43; Frames.Add(frame); frame.Y = 57; Frames.Add(frame); frame.Y = 70; Frames.Add(frame); frame.Y = 82; Frames.Add(frame); frameDelay = 200; // Initialize the random number generator and put the power source in your // start position random = new Random(GetHashCode()); PutinStartPosition(); }
position.Y += 1; base.Update(gameTime); }
Ngoi ra cn hm to ra powersoucre, n t trong m lnh ca Mn Play chng ta s xem xt sau, hm ho da hon ton vo tnh k tha t Sprite. 6. Lp Score Ni ghi li thnh tch v bo trc ci cht ca player:
#region Using Statements using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; #endregion namespace RockRainEnhanced { /// <summary> /// This is a game component that implements the Game Score. /// </summary>
Hm khai bo
public class Score : DrawableGameComponent { // chun b Spritebatch protected SpriteBatch spriteBatch = null; // ni hin Score , v tr protected Vector2 position = new Vector2(); // cc gi tr s s dng protected int value;// l score protected int power; protected readonly SpriteFont font; protected readonly Color fontColor;
B truy cp
public int Value { get { return value; } set { this.value = value; } } /// <summary> /// Power Value /// </summary> public int Power { get { return power; } set { power = value; } } /// <summary> /// Position of component in screen /// </summary> public Vector2 Position { get { return position; } set { position = value; } }
hin ra chui trn:, vit hi ngc (v thng no ra i sau s ln trn thng trc)
spriteBatch.DrawString(font, TextToDraw, new Vector2(position.X, position.Y), fontColor);
Tng t vic in ra score nhng c thm height kiu s thc l do phi vit power di score, chng ta cn cch dng, height chnh l khong cch gia 2 dng trong font ch dng.
float height = font.MeasureString(TextToDraw).Y; TextToDraw = string.Format("Power: {0}", power); // Draw the text shadow spriteBatch.DrawString(font, TextToDraw, new Vector2(position.X + 1, position.Y + 1 + height), Color.Black); // Draw the text item spriteBatch.DrawString(font, TextToDraw, new Vector2(position.X, position.Y + 1 + height), fontColor); base.Draw(gameTime); } } }
C. Lp cho Cc Mn: K tha t GameScene -Lm hot hnh bng code khi khi u game, cng ging nh lm nh ng, flash vy. -Cch 1 mn c th hot ng: hide v show -1 mn cng gn nh 1 file game1.cs con con vy. -Hm nhp Ni dung cc class Gamescene trc, by gi s c in, ... Training XNA more and more ! 1.Mn khi bt u game gm hot hnh, menu v m nhc :
#region Using Statements using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Media; using RockRainEnhanced.Core; #endregion namespace RockRainEnhanced {
/// <summary> /// This is a game component that implements the Game Start Scene. /// </summary> public class StartScene : GameScene {
Cc th cn thit phi khai bo: Menu: hin nhin phi c Texture background v cho cc ch c lm hot hnh (bng code), audio Hot hnh cho cc ch Rock, Rain v enhanced bn s thy chng chy qua li v nhp nhy (lm hot hnh = code) khi run game. Chng ta cn HCN bao quanh t ch v v tr khi u ca chng
// Misc protected TextMenuComponent menu; protected readonly Texture2D elements; // Audio protected AudioLibrary audio; // Spritebatch protected SpriteBatch spriteBatch = null; // Gui Stuff protected Rectangle rockRect = new Rectangle(0, 0, 536, 131); protected Vector2 rockPosition; protected Rectangle rainRect = new Rectangle(120, 165, 517, 130); protected Vector2 rainPosition; protected Rectangle enhancedRect = new Rectangle(8, 304, 375, 144); protected Vector2 enhancedPosition; protected bool showEnhanced; protected TimeSpan elapsedTime = TimeSpan.Zero;
Hm nhp data: game, 2 loi font cho 2 trng thi ca menu, texture background, texture cho ch Rock Rain Enhanced.
public StartScene(Game game, SpriteFont smallFont, SpriteFont largeFont, Texture2D background, Texture2D elements) : base(game) { this.elements = elements;
nh nn thuc kiu ImageComponent n c phng thc ring th hin, bn xem li hm nhp data cho ImageComponent hiu on m di y:
Components.Add(new ImageComponent(game, background, ImageComponent.DrawMode.Center));
To ra menu, gm cc chui:
Hm di c tc dng th hin mn start, thit t to sn sng cho vic chy hot hnh Rock Rain Enhanced... to cho Menu
public override void Show() { audio.NewMeteor.Play(); rockPosition.X = -1*rockRect.Width; rockPosition.Y = 40; rainPosition.X = Game.Window.ClientBounds.Width; rainPosition.Y = 180; // Put the menu centered in screen menu.Position = new Vector2((Game.Window.ClientBounds.Width menu.Width)/2, 330);
tt c th hin iu cha c khi ch rockrain cha hot hnh xong. Mt hm cha if s KT v khi hot hnh xong cc thuc tnh di y s c true.
menu.Visible = false; menu.Enabled = false; showEnhanced = false; base.Show(); }
Hm Update() -Chy hot hnh => m menu => ch enhanced nhp nhy theo thi gian. Hot hnh rt n gin, chng ta c th dng cc phn mm ho v nh ng ch hn, rp v... cng lm c, tuy nhin ci ji code c code, coding chnh xc hn nhiu... K thut di y tuy n gin nhng rt hu dng.
public override void Update(GameTime gameTime) { if (!menu.Visible) { if (rainPosition.X >= (Game.Window.ClientBounds.Width - 595)/2) { rainPosition.X -= 15; }
//Ni nhc ln
enhancedPosition = new Vector2((rainPosition.X + rainRect.Width enhancedRect.Width/2) - 80, rainPosition.Y); showEnhanced = true; } } else {
2.Cnh (mn) gip : Ci ny n gin ht mc, chng ta thm vo component ca game , nh nn Background v image front (gip ngi chi bit cch control, l nh ca ci GamePad ca XBOX v KeyBoard ca PC.)
#region Using Statements using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using RockRainEnhanced.Core; #endregion namespace RockRainEnhanced { /// <summary> /// This is a game component thats represents the Instrucions Scene /// </summary> public class HelpScene : GameScene {
public HelpScene(Game game, Texture2D textureBack, Texture2D textureFront) : base(game) { //nh nn, ch t... Components.Add(new ImageComponent(game, textureBack, ImageComponent.DrawMode.Stretch)); //nh help, ch t... Components.Add(new ImageComponent(game, textureFront, ImageComponent.DrawMode.Center)); } }
Trong file mu, front image khng c vng trng background th hin nn add background vo cng khng nhn thy c.
3. Mn Action ni play game Chng ta s c nhiu vic tho lun y, thng ny vi Game1.cs na l xong Phn nng cp project, gng ln no !
using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Media; using RockRainEnhanced.Core; namespace RockRainEnhanced { /// <summary> /// This is a game component that implements the Action Scene. /// </summary>
Khai bo bin: Texture actionTexture cha cc thnh phn play game (ship, meteor, power...) mt texture na l background nhng chng ta xp n vo ImageComponent, th c class. Khi nhn nt nter, game s pause ( cho player lm vic bn ca h), nhn Enter sau , game s resume li v cuc chi tip tc, khi trn mn hnh s c ch pause. Khi ngi chi thua (v h c chi c i cng ko win c, ch im cao hn thi) s c ch game over, trong d n ny 2 ch l 2 ci texture, do n cn c v tr v HCN ly texture khi draw: pausePosition
,gameoverPosition
protected Texture2D actionTexture; private AudioLibrary audio; protected SpriteBatch spriteBatch = null; // Game Elements protected Player player1; protected Player player2; protected MeteorsManager meteors; protected PowerSource powerSource; protected ImageComponent background; protected Score scorePlayer1; protected Score scorePlayer2; // Gui Stuff protected Vector2 pausePosition; protected Vector2 gameoverPosition; protected Rectangle pauseRect = new Rectangle(1, 120, 200, 44); protected Rectangle gameoverRect = new Rectangle(1, 170, 350, 48);
2 bin boolean KT xem c pause hay over ko l hin nhin phi c. To b m time v KT xem c phi 2 ngi chi hay ko
protected bool paused; protected bool gameOver; protected TimeSpan elapsedTime = TimeSpan.Zero; protected bool twoPlayers;
Hm nhp data: -nhp nhng th ca 1 GameSnece th thit. -Cn 1 imageComponent lm Bckground -S dng texture, SB v Audio
public ActionScene(Game game, Texture2D theTexture, Texture2D backgroundTexture, SpriteFont font) : base(game) { background = new ImageComponent(game, backgroundTexture, ImageComponent.DrawMode.Stretch); Components.Add(background); actionTexture = theTexture; // Get the current sprite batch spriteBatch = (SpriteBatch) Game.Services.GetService(typeof (SpriteBatch)); // Get the audio library audio = (AudioLibrary) Game.Services.GetService(typeof(AudioLibrary));
Chun b sn 2 player
player1 = new Player(Game, ref actionTexture, PlayerIndex.One, new Rectangle(323, 15, 30, 30)); player1.Initialize(); Components.Add(player1); player2 = new Player(Game, ref actionTexture, PlayerIndex.Two, new Rectangle(360, 17, 30, 30)); player2.Initialize(); Components.Add(player2);
{ MediaPlayer.Play(audio.BackMusic);
} public bool GameOver { get { return gameOver; } } public bool Paused { get { return paused; } set { paused = value; //nhn thng tin t bin paused if (paused) { //Dng chi nhc khi pause MediaPlayer.Pause(); } else { //Sau khi ht pause, m nhc tr li MediaPlayer.Resume(); } } }
Hm gy thit hi cho player Player 1 chc chn phi c, player 2 c hay ko cn tu, dng lnh if KT.
private void HandleDamages() { // Check Collision for player 1 if (meteors.CheckForCollisions(player1.GetBounds())) { // Player penalty player1.Power -= 10; player1.Score -= 10; } // Check Collision for player 2 if (twoPlayers) { if (meteors.CheckForCollisions(player2.GetBounds())) { // Player penalty player2.Power -= 10; player2.Score -= 10; }
Chi nhc
audio.PowerGet.Play();
t li power vo v tr
powerSource.PutinStartPosition();
{ elapsedTime -= TimeSpan.FromSeconds(15); powerSource.Enabled = true; audio.PowerShow.Play(); } } /// <summary> /// Allows the game component to update itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> public override void Update(GameTime gameTime) { if ((!paused) && (!gameOver)) { // Check collisions with meteors HandleDamages(); // Check if a player get a power boost HandlePowerSourceSprite(gameTime);
B truy cp d liu lp Score s truyn im ca playr vo ci hm drraw ca lp score v do , im s s c Update lin tc, tng t cho power
scorePlayer1.Value = player1.Score; scorePlayer1.Power = player1.Power; if (twoPlayers) { scorePlayer2.Value = player2.Score; scorePlayer2.Power = player2.Power; }
Nu player Thua, meteor vn hot ng phng h cay c v mun restart, tt nhin vn bt u t cnh start n action
if (gameOver) { meteors.Update(gameTime); } } /// <summary> /// Allows the game component to draw itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> public override void Draw(GameTime gameTime) {
Hin ch pause
if (paused) { // Draw the "pause" text spriteBatch.Draw(actionTexture, pausePosition, pauseRect, Color.White); }
Mt chng ng di, Game1.cs l tia sng cui ng hm. D.Lp Game1.cs Ci D n ny di l th, bn c nhn thy ko, tt c nhng j ta vit s c qun l bi game1.cs n l linh hn ca bt c game no vit t XNA. Khai bo ton b nhng rsource trong game ng thi b sung theo cc hm iu khin trong tng mn (ci ny chng ta cha vit ng ko no), ng thi quy nh trnh t xut hin cc mn, cn mn no xy ra ci j th chng ta vit trong class ca mn (scene) ca n ri. Chng ta ko s dng g khc l, tt c vn rt quen thuc
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; using RockRainEnhanced.Core; namespace RockRainEnhanced { public class Game1 : Game
Phn khai bo :
{ private readonly GraphicsDeviceManager graphics; private SpriteBatch spriteBatch;
Cac mn ca game, mi mn ta c coi nh l 1 game1.cs nh nh xinh xinh cng c 3 mn vit class v 1 mn chung activeScene , n c gn cho mn hin hnh nhm xc nh chng ta ang mn no (VD: nu mn help th ActiveScene = helpScene)
protected HelpScene helpScene; protected StartScene startScene; protected ActionScene actionScene; protected GameScene activeScene;
// Audio Stuff
private AudioLibrary audio;
// Fonts
private SpriteFont smallFont, largeFont, scoreFont;
//Thit b u v: bn phm, n c ch old tc l bn phm s dng trc, do s dng trc nn n mi c, nu bn c tr nh tt bn s nh n k thut ci t s kin release mt phm.
protected KeyboardState oldKeyboardState;
Hm nhp data
public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content";
Nhng th nh thng l
spriteBatch = new SpriteBatch(GraphicsDevice); Services.AddService(typeof (SpriteBatch), spriteBatch);
Mn no s bt u th hin, ci ny qu r ri
startScene.Show(); activeScene = startScene; }
(hin ti l null tc l ch c j trong ci active ht) th nn chng ta cng nn hide n mn gn cho active mn mun show ra ngoi, Sau cho mn c th hin c gn cho activeScene v show n. l khi khai bo, cn nu chy chng trnh thc s, active c hiu l mn trc (ci chng ta s dng dng chn (mn help khi bit, hiu ht lut, mn action khi gameover...) cn tham s tham chiu scene c hiu l mn chng ta mun ti (mn action l mn chng ta mun ti sau khi d coi qua mn help). Tm li chuyn t mn active n mn scene chng ta s dng hm sau:
protected void ShowScene(GameScene scene) { activeScene.Hide(); activeScene = scene; scene.Show(); }
ci ny th hin tnh ng gi, vic chuyn mn n gin ch l: ShowScene(Gamescene tn mn); Hm Update game, ...
protected override void Update(GameTime gameTime) { // ly input ph hp HandleScenesInput(); //mi component u c hm update ca ring n... base.Update(gameTime); }
Khi nhn Enter, chng ta s dng game li tm thi cho n khi nt enter c nhn ln th 2, bit khi no pause hay ko, hm di y thc hin iu , n tr v true nu ang pause v false nu ngc li.
private bool CheckEnterA()
Mi class cho tng cnh, chng ta cha vit hm input iu khin bng bn phm chuyn mn cho tng thng. hm di y kim tra mn ang chi l mn g m ly input() cho ph hp
private void HandleScenesInput() { // Handle Start Scene Input if (activeScene == startScene) { HandleStartSceneInput(); } // Handle Help Scene input else if (activeScene == helpScene) { if (CheckEnterA()) { ShowScene(startScene); } } // Handle Action Scene Input else if (activeScene == actionScene) { HandleActionInput(); } }
(keyboardState.IsKeyUp(Keys.Enter)));
//Ton t ! tc l gn ngc li gi tr boolean, nu pause ang false th n tr v true v ngc li ng thi m nhc vang li ln, nu pause th nhc n t tt, k thut resume ny cn b sung play cho nhc nn
{ audio.MenuBack.Play(); actionScene.Paused = !actionScene.Paused; } } if (backKey) { ShowScene(startScene); } }
Lu cc bn mt t trnh nhm ln: bin keyboardState cc bn thy n cng hm CheckEnterA() ng khng, v 2 bin ny l 2 hay cng ch l 1? Chng l 2 bin khc nhau hon ton bi l chng c khai bo trong tng hm => y l bin a phng v ch hot ng trong phm vi ca hm , nu em ra ngoi Class ca Game1, trnh bin dch s ko hiu c
/// <summary> /// Handle buttons and keyboard in StartScene /// </summary>
//tu theo ngi chi nhn Enter index no ca menu m a h ti mn ph hp Bin actionScene.TwoPlayers c ngha l actionScene l gc, twoPlayer v bin thuc mn ny v n di quyn ca Action do , du chm . Th hin iu ny
audio.MenuSelect.Play(); switch (startScene.SelectedMenuIndex) { case 0: actionScene.TwoPlayers = false; ShowScene(actionScene); break; case 1: actionScene.TwoPlayers = true; ShowScene(actionScene); break; case 2: ShowScene(helpScene); break; case 3: Exit(); break; } } }
xong, mt game c bn cn nhng th nh vy. Bi vit tm end y,... mt tun vt v See you again!