You are on page 1of 93

Li ni u

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

V Thnh Vinh (Huyt st)

Gii thiu s luc v XNA v C#:

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://download.microsoft.com/downlo...9-X86-INTL.exe Nu ko xi C# m xi cc ngn ng khc th xem thm ti


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...01-X86-ENU.exe - Tip l download XNA (98.6MB):


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

Bn build ra ri chy th s c nh hnh :

=> Ra ci ca s xanh l v khng c con chut l OK!


Ngun: ko bit na nhng thy y ry trn mng, Thanks tc gi.

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); } } }

y l ni dung c bn ca XNA, Nhim v ca n l hin ln ci mn hnh xanh l: Trong y ch c hm Draw() l th hin

File m lnh th 2 l program.cs:


using System; namespace XNADemo { static class Program { /// <summary> /// The main entry point for the application.

/// </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.

Phn I: class cho clsSprite


Tnh hp thnh ca OOP (Composition): Tt c object chy trn chng trnh u c m lnh hot ng ring ca n c vit li thnh cc hm, method, thuc tnh trong class ca n, tt c chng hp thnh ln class cho object. N c th tha k t nhiu ngun khc nhau, sau ny s ni thm. Tm th , u tin chng ta i t ci n gin nht, m lnh cho mt sprite n gin th hin trn mn hnh: To mt file *.cs t trong th mc cha project, hay add => class cung c Cu lnh using s dng code sn c ca XNA:
using Microsoft.Xna.Framework.Graphics; // for Texture2D using Microsoft.Xna.Framework; // for Vector2

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; }

3.Hm ha Nhim v ca sprite l th hin trn screen, th nn hm chc nng ca n ch cn Draw l :


public void Draw(SpriteBatch spriteBatch) { spriteBatch.Draw(texture, position, Color.White); }

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...

Phn II: Hon thin cho Game1.cs:


Game1 s dng:
#region Using Statements using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Storage; using System.Linq; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Media; using Microsoft.Xna.Framework.Net;

#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 }

Tip theo mt hm load ti nguyn cho game


protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); // Load a 2D texture sprite mySprite1 = new clsSprite(Content.Load<Texture2D>("ball"), new Vector2(0f, 0f), new Vector2(64f, 64f)); }

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 )

Tip l mt hm unload nhm xa cc thnh phn khi b nh khi close game:


protected override void UnloadContent() { // Free the previously alocated resources mySprite1.texture.Dispose(); spriteBatch.Dispose(); }

Hm Update c gi nguyn th v trong qu trnh chy, ch c qui j thay i c.

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

Bi 2 : Di chuyn i tung trn mn hnh


Cc bn c th dng tip project c hon thnh lession ny. Phn I: b sung cho lp clsSprite: Vt mun di chuyn, ta thm vn tc cho n: vector2 velocity Thm kick thuc screen check collided (va chm): vector2 screenSize

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

Thm vo phn nhp d liu:


public clsSprite (Texture2D newTexture, Vector2 newPosition, Vector2 newSize, int ScreenWidth, int ScreenHeight){ texture = newTexture; position = newPosition; size = newSize; screenSize = new Vector2(ScreenWidth, ScreenHeight); }

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; }

Hm cui cng l hm ha th hin ca sprite, rt quen thuc:


public void Draw(SpriteBatch spriteBatch) {

spriteBatch.Draw(texture, position, Color.White); }

Phan II: b sung cho Game1.cs Chng ta to ra 2 sprite ly tn mySpite1 v mySprite2


clsSprite mySprite1; clsSprite mySprite2;

Loadcontent cng c 2sprite (load texture) khi to gi tr tc cho n, theo 2 trc x v y:


protected override void LoadContent() { // Load a 2D texture sprite 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); // Create a SpriteBatch to render the sprite spriteBatch = new SpriteBatch(graphics.GraphicsDevice); // set the speed the sprites will move mySprite1.velocity = new Vector2(5, 5); mySprite2.velocity = new Vector2(3, -3); }

B sung thm hm unLoad:


protected override void UnloadContent() { // Free the previously alocated resources mySprite1.texture.Dispose(); mySprite2.texture.Dispose(); spriteBatch.Dispose(); }

B sung thuc tnh chiu di v rng ca screen


graphics.PreferredBackBufferWidth = 500; graphics.PreferredBackBufferHeight = 300;

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); }

C bn l xong thm hm ha na, n s v sprite1 v sprite2 ln screen:


protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here spriteBatch.Begin(SpriteBlendMode.AlphaBlend); mySprite1.Draw(spriteBatch); mySprite2.Draw(spriteBatch); spriteBatch.End(); base.Draw(gameTime); }

Xong ri, F5 no .

Bi 3: INPUT cho OBJECT bng MOUSE v KEYBOARD


Bi3 ny chng ta s dng thut tan KT va chm khc, ni qua lession 2 Bn c th s dng project ca lession trc + mt v sa i y: Phn I: t lp clsSprite: 1.chung ta khng cn thuc tnh center v radius na. 2.S dng hm va chm:
public bool Collides(clsSprite otherSprite) { // check if two sprites intersect if (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) return true; else return false; }

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 {

GraphicsDeviceManager graphics; SpriteBatch spriteBatch;

// Sprite objects clsSprite mySprite1; clsSprite mySprite2;

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))

Hm mySpite1.Collides s xc nh va chm vi sprite2 tr v true nu c.


{ mySprite1.velocity *= -1;

o chiu chuyn ng ca sprite1


} } }

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 .

Xong ri y, F5 v th con chut hay bn phm i no .

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)

Bi 4 S DNG M THANH TRONG XNA


Ti nguyn: texture ball. 2 sound, mt ci lm backmusic, ci kia lm effectmusic Bt k game u cn phi c cht m thanh gy hng phn cho gamer. C 2 loi ph bin: nhac nn v nhc hiu ng -nhc nn chy khi bt du, kt thc hoc c khi ang play. -nhc hiu ng s c chi ty trng hp: va chm, n im, win... Phn I: Khi to nhng th cn thit Chng ta chun b cho m thanh t mt h thng qun l m thanh ca XNA l phatform Audio Creation Tools.cc bc nh sau:
1. bt u XACT bng cchchn Start Programs Microsoft XNA Game Studio 3.0 Tools Cross-Platform Audio Creation Tool (XACT). 2. trong bang XACT window, chn File New Project to mi audio project, v lu li vi tn MySounds. 3. nhn pha bn tri ca s, MySounds s xut hin vi nhiu thnh phn khc. Kick chut phi vo Wave Bank v la chn New Wave Bank trong ca s hin ra Nh hnh:

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;

Chng ta s dng Hm Initiallize() thit lp m thanh lp (dng lm nhc nn):


protected override void Initialize() { audioEngine = new AudioEngine(@"Content\MySounds.xgs"); // ng dn n file h thng // BN CN add file MySounds.xap vo waveBank = new WaveBank(audioEngine, @"Content\Wave Bank.xwb"); soundBank = new SoundBank(audioEngine, @"Content\Sound Bank.xsb"); myLoopingSound = soundBank.GetCue("notify"); myLoopingSound.Play(); base.Initialize(); }

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); } {

l nhng th rt c bn bn thm m thanh vo game ca bn trong XNA, ht bi 4, Have Fun!

BI 5: Lp trnh Hng i tng C bn ca C# Trong XNA


Ti nguyn: 1 background, 1 image gp chung trong 2 texture ca Ship v Meteor Sound: 2 ting bm (effect-nhc hiu ng),1 tn tn ten (backmusic-nhac nn) Font: 1 font no , chng ta s cn a text ln game Nu rnh C# xin mi qua lun phn II Phn I:Tnh ng gi v Tnh a hnh ca OOP Cu hi t ra: ti sao LT hng i tng hay c s dng khi vit game? Game u tay ca mnh vit bng flash v n thc s rt d, to object ch cn drag and drop, vit m lnh cho tng thng bng phm F9 vi cc thuc tnh sn c (gc, to , m c...) v bin n thnh sprite th thit. KT va chm cc k n gin ch vi 1lnh hitTest. Bn c th tng tng mt thng nhc 17 tui vi game u tay ca n s ho hc ntn?, gi nhn li mnh thy tt c

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();

Kt thc phn I, chng ta s lm project u tin ngay by gi

Phn II: D N U TIN


Trc khi bt u d n, tng l khu rt quan trng, bn c th b vi tun vit game ch nh khng b c vi ngy vit tng. tng ca d n: Chng ta iu khin phi thuyn bng phm mi tn trnh cc vt cn trong khng gian l cc thin thch trnh b n ph hu. Ship v Mteor l nhng component ca game v chng c to ra mt cch ng. Sau mt khang thi gian nht nh s c thm Meteor c to ra tng kh cho game, khi phi thuyn b ph hu, game s c restart li. Chng ta to ra text field hin s lng Meteor AI: tr thng minh nhn to. Mc d project sp vit di y c AI kiu Random tc l n ngu nhin khng ph thuc player, nhng bn cng nn bit cht t v mt AI tt: -D b nh bi: Gamer no cng mun win, nu h ko win c, h s ko i no chi game . -khng d b nh bi: i th qu yu lm gamer thy chn v h i tm mt game kh hn.

-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);

screenBounds = new Rectangle(0,0, Game.Window.ClientBounds.Width, Game.Window.ClientBounds.Height); }

Hm t phi thuyn vo v tr khi bt u:


public void PutinStartPosition() { position.X = screenBounds.Width / 2; position.Y = screenBounds.Height - SHIPHEIGHT; }

Thm m lnh tu c th iu kin , tt nhin n t trong hm Update ni lun KT iu kin ca game:


KeyboardState keyboard = Keyboard.GetState(); //Khi to bn phm if (keyboard.IsKeyDown(Keys.Up)) { position.Y -= 3; } if (keyboard.IsKeyDown(Keys.Down)) { position.Y += 3; } if (keyboard.IsKeyDown(Keys.Left)) { position.X -= 3; } if (keyboard.IsKeyDown(Keys.Right)) { position.X += 3;

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();

Hm Update gip Meteor di chuyn m t restart li khi vt bin :


public override void Update(GameTime gameTime) { // Lun Meteor trong screen if ((position.Y >= Game.Window.ClientBounds.Height) || (position.X >= Game.Window.ClientBounds.Width) || (position.X <= 0)) { PutinStartPosition(); } // di chun meteor position.Y += Yspeed; position.X += Xspeed; base.Update(gameTime); }

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); }

3. Game1.cs Ni mi th hot ng S dng:


using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio;

using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media;

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"; }

Hm thit lp b sung cu lnh sau ghi tiu cho game:


protected override void Initialize() {

base.Initialize(); Window.Title = "RockRain"; }

Hm LoadContent, load ho s dung (graphic, texture) m thanh v SpriteBatch:


protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); // thm vo dch v spritebatch service Services.AddService(typeof(SpriteBatch), spriteBatch); // Load tt c textures gm nh nn v objects backgroundTexture = Content.Load<Texture2D>("SpaceBackground"); meteorTexture = Content.Load<Texture2D>("RockRain"); // Load game font gameFont = Content.Load<SpriteFont>("font"); // Load cc sound trong game explosion = Content.Load<SoundEffect>("explosion"); newMeteor = Content.Load<SoundEffect>("newmeteor"); backMusic = Content.Load<Song>("backMusic"); // Chi nhc nn MediaPlayer.Play(backMusic); }

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);

3.Sau khi add th t n cho ng ch na, cc bn c nh hm no vit m nhn vic ny ko?

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;

Gi hy xy dng mt cc lgic chng c 1 hm start hay dng restart:


private void Start() { // Add the meteors for (int i = 0; i < STARTMETEORCOUNT; i++) { Components.Add(new Meteor(this, ref meteorTexture)); } if (player == null) { player = new Ship(this, ref meteorTexture); Components.Add(player); } //to ra player(Ship) nu cha c player.PutinStartPosition(); //t vo v tr. lastTickCount = System.Environment.TickCount; rockCount = STARTMETEORCOUNT; }

Vit hm bit khi no nn thm meteor:


private void CheckforNewMeteor() { // Add a rock each ADDMETEORTIME if ((System.Environment.TickCount - lastTickCount) > ADDMETEORTIME) { lastTickCount = System.Environment.TickCount; Components.Add(new Meteor(this, ref meteorTexture)); newMeteor.Play(); rockCount++; } } System.Environment.TickCount tr v thi im hin ti ca h thng, System.Environment.TickCount lastTickCount tr v khong time t lc bt u (bn KT xem li c fi th k?) nu n > ADDMETEORTIME, th tip tc nng thi im lastTickCount = thi im hin ti sau ny trong hm Update s tip tc kim tra thi gian chy game m add thm meteor sau khong time ADDMETEORTIME; sau th n gin ri, add thm meteor , newMeteor.Play(); v

tng bin rockCount++;

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...

BI 6 TNH K THA - NNG CP D N.


Phn I: Tnh k tha (Inheritance):Ph nhn-To mi. Nu rnh C# xin mi qua lun phn 2 ! cha rnh lm th hc li C# ri c phn di : Tnh k tha l g? Ch phi bn s dng n ngay t khi code dng u tin trong XNA sao? Gi x i tng A k tha t i tng B chng ta s khai bo: Class A:B {

//Ni dung class } Rt n gin ng khng, cng nh chng ta coded rng:


public class Game1 : Microsoft.Xna.Framework.Game

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:

public virtual void b chy()

Trong class ca Boss:


public override void b chy()

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)

PHN II: NNG CP D N


D n ca chng ta da vo tnh k tha, do , s c 2 loi class (tr thng Game1.cs ra) -Core:cc lp cho php cc object khc trong game k tha.(sprite, mn ...), chng c gom trong mt folder -Class cn li, class ca cc object c th hin(ship;meteor,mn start, mn play, mn end)... D n nng cp s c cc phng php trong vic to ra hot hnh sau 1 khong thi gian (s gii thch sau). Chng ta hc cch lm hot hnh cho sprite thng qua vic to ra v cho chy cc frame ca n. 1 Game Hon chnh cn c mn begin, play v end, y cng l khi u ca mi rc ri Y l SL cng vic fi lm :

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 {

/// <summary> /// </summary> public class Sprite : DrawableGameComponent

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

sprite), n cng ngang ngang nh Mng cha cc frame vy.


protected Vector2 position; protected TimeSpan elapsedTime = TimeSpan.Zero; elapsedTime L bin xc nh thi im trong game, c thit lp l 0 (zero) protected Rectangle currentFrame; currentFrame L HCN bao quanh frame hin thi m XNA ang duyt protected long frameDelay; frameDelay L bin ch thi gian chuyn t frame ny sang frame k n protected SpriteBatch sbBatch;

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 = (SpriteBatch) Game.Services.GetService(typeof (SpriteBatch)); base.Initialize(); }

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;

Nu thi gian nhiu hn thi gian trong framdelay th cu lnh


elapsedTime -= TimeSpan.FromMilliseconds(frameDelay); activeFrame++; if (activeFrame == frames.Count) { activeFrame = 0; }

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 } }

string[] items: items l mng cc string, v chng ta cn 4 chui.

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)

{ selectedIndex = 0; } } //Ngc vi ci trn if (up) { selectedIndex--; if (selectedIndex == -1) { selectedIndex = menuItems.Count - 1; } }

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>

Lp c nh du abstract y l lp o (cn gi l tru tng)


public abstract class GameScene : DrawableGameComponent { /// <summary> /// List of child GameComponents /// </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 cho php Scene hin th v hot ng


public virtual void Show() { Visible = true; Enabled = true; } /// <summary> /// Hide the scene /// </summary>

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"); } } }

2.Lp Meteor ROCKS OF SPACE:


using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using RockRainEnhanced.Core; namespace RockRainEnhanced { /// <summary> /// This class is the Animated Sprite for a Meteor /// </summary> public class Meteor : Sprite {

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; } }

Hm Update: Nu meteor ra khi mn hnh, t n vo v tr c., nu khng th move n i.


public override void Update(GameTime gameTime) { // Check if the meteor still visible if ((position.Y >= Game.Window.ClientBounds.Height) || (position.X >= Game.Window.ClientBounds.Width) || (position.X <= 0)) { PutinStartPosition(); } // Move meteor position.Y += Yspeed; position.X += Xspeed;

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 {

Phn Khai bo bin Danh sch cc Meteor g run game.


protected List<Meteor> meteors;

Hng s SL Cc meteor khi begin private const int STARTMETEORCOUNT = 10; Khong Time to thm Meteor n v miligiy (l 5s)

private const int ADDMETEORTIME = 5000;

m thanh
private AudioLibrary audio;

Texture
protected Texture2D meteorTexture;

Thi gian chy game , begin vi 0. Dng to ra Meteor sau 1 khong 5 s


protected TimeSpan elapsedTime = TimeSpan.Zero;

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 Thit lp: public override void Initialize()


{ meteors.Clear();//clear all meteor Start();

Vng for thit lp cho tt c Meteor


for (int i = 0; i < meteors.Count; i++) { meteors[i].Initialize(); } base.Initialize(); }

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();

meteors.Add(newMeteor); // Set the meteor identifier newMeteor.Index = meteors.Count - 1; return newMeteor; }

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(); } }

B truy Cp d liu Bin ALLMeteors


public List<Meteor> AllMeteors { get { return meteors; } }

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; }

Gi hm ho cho tng Meteor, ho ly t lp Sprite, cc bn c th xem li.


public override void Draw(GameTime gameTime) { // Draw the meteors for (int i = 0; i < meteors.Count; i++) {

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 {

Phn Khai bo bin:


playerIndex c b sung nhm mc ch to ra player 2 public class Player : DrawableGameComponent { protected Texture2D texture; protected Rectangle spriteRectangle; protected Vector2 position; protected TimeSpan elapsedTime = TimeSpan.Zero; protected PlayerIndex playerIndex; protected SpriteBatch sBatch;

Bin screenBounds l HCN c cc cnh l khung ca s game.


protected Rectangle screenBounds; // Cc bin ghi li nng lng v im ca player protected int score; protected int power; INITIALPOWER S thit lp nng lng ban u cho Ship private const int INITIALPOWER = 100;

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); }

Hm t Ship vo ch ca n, tu theo l player1 hay 2


public void Reset() {

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; }

y l b truy cp d liu cho score v power, m bo cho score lun ko m.


public int Score { get { return score; } set {

if (value < 0) { score = 0; } else { score = value; } } }

public int Power { get { return power; } set { power = value; } }

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--; } }

Hm kim tra Ship khi chy game:score, power v control Ship.


public override void Update(GameTime gameTime) { HandleInput(playerIndex); UpdateShip(gameTime); base.Update(gameTime); }

/// <summary> /// Get the ship position

/// </summary>

Hm La chn player m gi hm iu kin ph hp


protected void HandleInput(PlayerIndex thePlayerIndex) { if (thePlayerIndex == PlayerIndex.One) { HandlePlayer1KeyBoard(); } else { HandlePlayer2KeyBoard(); } }

Ham sau gi cho ship lun trong mn hnh.


private void KeepInBound() { if (position.X < screenBounds.Left) { position.X = screenBounds.Left; } if (position.X > screenBounds.Width - spriteRectangle.Width) { position.X = screenBounds.Width - spriteRectangle.Width; } if (position.Y < screenBounds.Top) { position.Y = screenBounds.Top; } if (position.Y > screenBounds.Height - spriteRectangle.Height) { position.Y = screenBounds.Height - spriteRectangle.Height; } }

Hm iu khin cho ngi chi 1


private void HandlePlayer1KeyBoard() { KeyboardState keyboard = Keyboard.GetState(); if (keyboard.IsKeyDown(Keys.Up)) { position.Y -= 3; } if (keyboard.IsKeyDown(Keys.Down)) { position.Y += 3; }

if (keyboard.IsKeyDown(Keys.Left)) { position.X -= 3; } if (keyboard.IsKeyDown(Keys.Right)) { position.X += 3; } }

Hm iu khin cho ngi chi 2


private void HandlePlayer2KeyBoard() { KeyboardState keyboard = Keyboard.GetState(); if (keyboard.IsKeyDown(Keys.W)) { position.Y -= 3; } if (keyboard.IsKeyDown(Keys.S)) { position.Y += 3; } if (keyboard.IsKeyDown(Keys.A)) { position.X -= 3; } if (keyboard.IsKeyDown(Keys.D)) { position.X += 3; } }

V con tu thng qua sBatch:


public override void Draw(GameTime gameTime) { // Get the current spritebatch sBatch = (SpriteBatch) Game.Services.GetService(typeof (SpriteBatch)); // Draw the ship sBatch.Draw(texture, position, spriteRectangle, Color.White); base.Draw(gameTime); } /// <summary> /// Get the bound rectangle of ship position in screen /// </summary>

Hm di quen thuc ri.


public Rectangle GetBounds() { return new Rectangle((int) position.X, (int) position.Y, spriteRectangle.Width, spriteRectangle.Height); } } }

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 khai bo:


protected Texture2D texture; protected Random random;

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(); }

Thit lp vn tc v v tr cho powersource khi n c sinh ra


public void PutinStartPosition() { position.X = random.Next(Game.Window.ClientBounds.Width currentFrame.Width); position.Y = -10; Enabled = false; } public override void Update(GameTime gameTime) {

Cu lnh di c tc dng a li powersoure cho player nu h cha kp n if (position.Y >= Game.Window.ClientBounds.Height)


{ PutinStartPosition(); } // Move

position.Y += 1; base.Update(gameTime); }

Hm KT va chm, tt nhin l vi Ship


public bool CheckCollision(Rectangle rect) { Rectangle spriterect = new Rectangle((int) position.X, (int) position.Y, currentFrame.Width, currentFrame.Height); return spriterect.Intersects(rect); } } }

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;

Hm nhp data: font


public Score(Game game, SpriteFont font, Color fontColor) : base(game) { this.font = font; this.fontColor = fontColor; spriteBatch = (SpriteBatch) Game.Services.GetService(typeof (SpriteBatch)); }

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; } }

Hm ho, ci quan trng nht


public override void Draw(GameTime gameTime) {

Cu lnh di y to 1 chui l score: s im


string TextToDraw = string.Format("Score: {0}", value);

hin ra bng chui trn:


spriteBatch.DrawString(font, TextToDraw, new Vector2(position.X + 1, position.Y + 1), Color.Black);

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:

string[] items = {"One Player", "Two Players", "Help", "Quit"};

To ra thnh phn mi.


menu = new TextMenuComponent(game, smallFont, largeFont);

Nhp Ni dung menu


menu.SetMenuItems(items);

Thm vo mng Components


Components.Add(menu); spriteBatch = (SpriteBatch) Game.Services.GetService( typeof (SpriteBatch)); audio = (AudioLibrary) Game.Services.GetService(typeof(AudioLibrary)); }

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 di y ngc vi hm trn, n dng khi ta mun qua cnh khc.


public override void Hide() { MediaPlayer.Stop(); base.Hide(); }

B truy cp SelectedMenuIndex ly index hin thi ca phn menu c chn

public int SelectedMenuIndex { get { return menu.SelectedIndex; } }

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; }

//Ch rain chy t phi qua tri


if (rockPosition.X <= (Game.Window.ClientBounds.Width - 715)/2) { rockPosition.X += 15; }

//ch rock chy t tri qua phi


else { menu.Visible = true; menu.Enabled = true; MediaPlayer.Play(audio.StartMusic);

//Ni nhc ln
enhancedPosition = new Vector2((rainPosition.X + rainRect.Width enhancedRect.Width/2) - 80, rainPosition.Y); showEnhanced = true; } } else {

//Sau 1 s ch enhanced hin ra v mt i.


elapsedTime += gameTime.ElapsedGameTime; if (elapsedTime > TimeSpan.FromSeconds(1))

{ elapsedTime -= TimeSpan.FromSeconds(1); showEnhanced = !showEnhanced; } } base.Update(gameTime); }

Hm ho: Menu: c class ca n lm vic ny. Chng ta ch v cc ch tiu game ln screen.


public override void Draw(GameTime gameTime) { base.Draw(gameTime); spriteBatch.Draw(elements, rockPosition, rockRect, Color.White); spriteBatch.Draw(elements, rainPosition, rainRect, Color.White); if (showEnhanced) { spriteBatch.Draw(elements, enhancedPosition, enhancedRect, Color.White); } }

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>

public class ActionScene : GameScene {

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));

To 1 b qun l Meteor, t to 1 n Meteor


meteors = new MeteorsManager(Game, ref actionTexture); Components.Add(meteors);

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);

Chun b sn 2 Score ghi im cho 2 player


scorePlayer1 = new Score(game, font, Color.Blue); scorePlayer1.Position = new Vector2(10, 10); Components.Add(scorePlayer1); scorePlayer2 = new Score(game, font, Color.Red); scorePlayer2.Position = new Vector2( Game.Window.ClientBounds.Width - 200, 10); Components.Add(scorePlayer2);

To ra power Source v thit lp cho n theo class ca n m chng ta vit.


powerSource = new PowerSource(game, ref actionTexture); powerSource.Initialize(); Components.Add(powerSource); }

Hm khi Hin th cnh:


public override void Show()

{ MediaPlayer.Play(audio.BackMusic);

Khi to cho b qun l cc meteor (MeteorsManager), t n to ra cc meteor


meteors.Initialize(); powerSource.PutinStartPosition();

khi ng cho 2 player


player1.Reset(); player2.Reset();

Hin th ch pause hoc game over khi cn, mc nh l khng.


paused = false; pausePosition.X = (Game.Window.ClientBounds.Width pauseRect.Width)/2; pausePosition.Y = (Game.Window.ClientBounds.Height pauseRect.Height)/2; gameOver = false; gameoverPosition.X = (Game.Window.ClientBounds.Width gameoverRect.Width)/2; gameoverPosition.Y = (Game.Window.ClientBounds.Height gameoverRect.Height)/2;

Player 2 c hin th v H hay ko tu thuc bin twoPlayer


player1.Visible = true; player2.Visible = twoPlayers; player2.Enabled = twoPlayers; scorePlayer2.Visible = twoPlayers; scorePlayer2.Enabled = twoPlayers; base.Show(); }

Hm thc hin khi n scene


public override void Hide() { // Stop the background music MediaPlayer.Stop(); base.Hide(); }

Cc b truy cp cho cc bin iu khin quan trng


public bool TwoPlayers { get { return twoPlayers; } set { twoPlayers = value; }

} 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; }

Nu 2 player tng vo nhau c 2 u b thit hi.


if (player1.GetBounds().Intersects(player2.GetBounds())) { player1.Power -= 10; player1.Score -= 10; player2.Power -= 10; player2.Score -= 10; } } }

Hm nhn nng lng t powersource


private void HandlePowerSourceSprite(GameTime gameTime) { // Player 1 get the power source if (powerSource.CheckCollision(player1.GetBounds())) {

Chi nhc
audio.PowerGet.Play();

t li b m time, sn sng cho power tip theo


elapsedTime = TimeSpan.Zero;

t li power vo v tr
powerSource.PutinStartPosition();

Tng thm cho player 50 power


player1.Power += 50; }

Nu c playr2 , cng tng t player1


if (twoPlayers) { // Player 2 get the power source if (powerSource.CheckCollision(player2.GetBounds())) { audio.PowerGet.Play(); elapsedTime = TimeSpan.Zero; powerSource.PutinStartPosition(); player2.Power += 50; } }

B m time to ra power trong 15s


elapsedTime += gameTime.ElapsedGameTime; if (elapsedTime > TimeSpan.FromSeconds(15))

{ 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; }

Tr chi kt thc khi player1 hoc 2 dead


gameOver = ((player1.Power <= 0) || (player2.Power <= 0)); if (gameOver) { player1.Visible = (player1.Power > 0); player2.Visible = (player2.Power > 0) && twoPlayers; // Stop the music MediaPlayer.Stop(); }

Lnh d y chy hm update cho ton b component


base.Update(gameTime); }

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) {

Cc component khc t n draw c tr ch gameover v pause


base.Draw(gameTime);

Hin ch pause
if (paused) { // Draw the "pause" text spriteBatch.Draw(actionTexture, pausePosition, pauseRect, Color.White); }

Hin ch game over


if (gameOver) { // Draw the "gameover" text spriteBatch.Draw(actionTexture, gameoverPosition, gameoverRect, 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;

Cc texture lm nn cho tng mn (game1 l lp chy game, tt c resource u phi ti.)


protected Texture2D helpBackgroundTexture, helpForegroundTexture; protected Texture2D startBackgroundTexture, startElementsTexture; protected Texture2D actionElementsTexture, actionBackgroundTexture;

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";

// Khi to cho bn phm


oldKeyboardState = Keyboard.GetState(); }

protected override void LoadContent() {

Nhng th nh thng l
spriteBatch = new SpriteBatch(GraphicsDevice); Services.AddService(typeof (SpriteBatch), spriteBatch);

Thit lp cho object qun l m thanh


audio = new AudioLibrary(); audio.LoadContent(Content); Services.AddService(typeof(AudioLibrary), audio);

// gn 2 texture cho 2 bin cnh help


helpBackgroundTexture = Content.Load<Texture2D>("helpbackground"); helpForegroundTexture = Content.Load<Texture2D>("helpForeground");

Nhp thng tin cho mn help, sau add n vo mng components


helpScene = new HelpScene(this, helpBackgroundTexture, helpForegroundTexture); Components.Add(helpScene);

Load cc thnh phn ho cho mn start


smallFont = Content.Load<SpriteFont>("menuSmall"); largeFont = Content.Load<SpriteFont>("menuLarge"); startBackgroundTexture = Content.Load<Texture2D>("startbackground"); startElementsTexture = Content.Load<Texture2D>("startSceneElements");

Nhp info cho mn start


startScene = new StartScene(this, smallFont, largeFont, startBackgroundTexture, startElementsTexture); Components.Add(startScene);

Tng t, load v thit lp cho mn chi (action) actionElementsTexture = Content.Load<Texture2D>("rockrainenhanced");


actionBackgroundTexture = Content.Load<Texture2D>("SpaceBackground"); scoreFont = Content.Load<SpriteFont>("score"); actionScene = new ActionScene(this, actionElementsTexture,

actionBackgroundTexture, scoreFont); Components.Add(actionScene);

Mn no s bt u th hin, ci ny qu r ri
startScene.Show(); activeScene = startScene; }

Hm iu khin vic show mt scene:


activeScene.Hide(); activeScene K tha t GameScene th nn n cng l mt scene th thit

(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()

{ KeyboardState keyboardState = Keyboard.GetState();

Release phm nter mi c hiu lc


bool result = (oldKeyboardState.IsKeyDown(Keys.Enter) && (keyboardState.IsKeyUp(Keys.Enter))); oldKeyboardState = keyboardState; return result; }

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(); } }

ActionScene thiu hm chuyn mn, chng ta thm n vo:


private void HandleActionInput() { KeyboardState keyboardState = Keyboard.GetState(); bool backKey = (oldKeyboardState.IsKeyDown(Keys.Escape) && (keyboardState.IsKeyUp(Keys.Escape)));

//Khi release phim Esc


bool enterKey = (oldKeyboardState.IsKeyDown(Keys.Enter) &&

(keyboardState.IsKeyUp(Keys.Enter)));

//Khi release phm enter


oldKeyboardState = keyboardState;

// khi gameover nhn Enter chng ta nhy ra mn start


if (enterKey) { if (actionScene.GameOver) { ShowScene(startScene); } Else

//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>

Tng t cho m mn (startScene)


private void HandleStartSceneInput() { if (CheckEnterA()) {

//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; } } }

Hm draw n gin, c bn v n gi hm draw ca tt c ca draw ca cc component, OOP l th y :D


protected override void Draw(GameTime gameTime) { // Begin.. spriteBatch.Begin(); // Draw all Game Components.. base.Draw(gameTime); // End. spriteBatch.End(); } } }

xong, mt game c bn cn nhng th nh vy. Bi vit tm end y,... mt tun vt v See you again!

You might also like