Tạo game bóng nẩy đơn giản cho Windows Phone 7

Posted: 06/05/2011 in XNA Game
Tags: ,

mục tiêu là làm 1 game bóng nẩy ,chạm vào thành là bật lại. Game chạy trên hệ điều hành window phone 7.

preview :

video demo : http://www.youtube.com/watch?v=Ji5sOrayM_M

1.chuẩn bị
-kiến thức về lập trình C#
-kiến thức về XNA framework
-Visual studio 2010
-window phone tool develop , cài cho VS2010 ,download ở trang chủ Microsoft
2. tạo project
-sau khi cài window phone tool cho VS2010 ,bộ tool này đã bao gồm emulator,XNA,silvelight. sau khi cài chúng sẽ được bổ sung vào menu new project của VS2010
-tạo project window phone game

thêm 1 số tài nguyên cần thiết
-images: add bình thường
-font : bạn chuột phải chọn add->new item->chọn spritefont->điền tên ->OK
bạn có thể mở file *.font để thay đổi kích cỡ,kiểu font
3. Code

Tạo đối tượng ball.cs

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.Input.Touch;
usingMicrosoft.Xna.Framework.Media;namespace Zstar_Ball_Game
{
public class Ball
{
private GraphicsDeviceManager graphics;
private Texture2D texture;//sprite bóng
private Vector2 location;//vị trí của bóng
private Point size = new Point(48, 48);//kích thước của bóng
private SpriteFont font;//font để vẽ chữ
private Vector2 direction;//hướng chuyển động của bóng
private float h = 0.5f;//bước chuyển động
public Ball(GraphicsDeviceManager g, Random rand)
{
this.graphics = g;
this.location = new Vector2(rand.Next(200), rand.Next(200));//random ngẫu nhiên vị trí bóng
this.direction = new Vector2(rand.Next(1, 3), rand.Next(1, 3));//random ngẫu nhiên hướng chuyển động
this.h = rand.Next(1, 5) * rand.Next(1, 3) * 0.5f;//random ngẫu nhiên bước chuyển động
}
public void LoadContent(ContentManager content, string path)
{
this.texture = content.Load<Texture2D>(path);
this.font = content.Load<SpriteFont>("Font/SpriteFont1");
}
public void Update()
{
MouseState mouse = Mouse.GetState();
if (mouse.LeftButton == ButtonState.Pressed)
{
this.Press = true;
}
else this.Press = false;
if (this.Press)
{
if (mouse.X > 0 && mouse.Y > 0 && mouse.X + size.X <= this.graphics.PreferredBackBufferWidth && mouse.Y + size.Y <= this.graphics.PreferredBackBufferHeight)
this.Location = new Vector2(mouse.X, mouse.Y);
}
//di chuyển
this.location += this.direction * h;
if (!outside())
{
if (location.X * location.Y < 0) this.location = new Vector2();
}
}
public bool outside()
{
if (this.Location.X < 0)
{
this.direction = new Vector2(-this.direction.X, this.direction.Y);
return true;
}
if (this.Location.Y < 0)
{
this.direction = new Vector2(this.direction.X, -this.direction.Y); return true;
}
if (this.Location.X + this.size.X > this.graphics.PreferredBackBufferWidth)
{
this.direction = new Vector2(-this.direction.X, this.direction.Y); return true;
}if (this.Location.Y + this.size.Y > this.graphics.PreferredBackBufferHeight)
{
this.direction = new Vector2(this.direction.X, -this.direction.Y);
return true;
} return false;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(this.texture, this.location, Color.White);
//spriteBatch.DrawString(this.font, this.location.ToString(), this.location + new Vector2(0, -20), Color.White);
}
public Vector2 Location
{
get { return this.location; }
set { this.location = value; }
}
public bool Press
{
get;
set;
}}
}

tạo đôi tượng BallManager.cs
mục đích của lớp này là quản lí bóng cho dễ,có thể thêm nhiều bóng rất dễ dàng

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.Input.Touch;
usingMicrosoft.Xna.Framework.Media;namespace Zstar_Ball_Game
{
public class BallManager
{
private Random rand = new Random();
private Ball[] balls;
private int num = 6;
private string[] paths = new string[] { "Images/ball4", "Images/ball2", "Images/ball3" };
public BallManager(GraphicsDeviceManager graphics, Random rand)
{
balls = new Ball[num];
for (int i = 0; i < balls.Length; i++)
{
balls[i] = new Ball(graphics, rand);
}
}
public void LoadContent(ContentManager content)
{
for (int i = 0; i < balls.Length; i++)
{
balls[i].LoadContent(content, paths[rand.Next(paths.Length)]);
}
}
public void Draw(SpriteBatch spriteBatch)
{
for (int i = 0; i < balls.Length; i++)
{
balls[i].Draw(spriteBatch);
}
}
public void Update()
{
for (int i = 0; i < balls.Length; i++)
{
balls[i].Update();
}
}
}
}

code ở Game1.cs

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.Input.Touch;
usingMicrosoft.Xna.Framework.Media;namespace Zstar_Ball_Game
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
private GraphicsDeviceManager graphics;
private SpriteBatch spriteBatch;
private BallManager ballManager;
private SpriteFont font;
private string s = "Hello Zstar !\nWelcome to Window phone OS Emulator";
private Random rand = new Random();
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
this.ballManager = new BallManager(graphics, rand);
s += "\nScreen : (" + this.graphics.PreferredBackBufferWidth + "," + this.graphics.PreferredBackBufferHeight + ")";TargetElapsedTime = TimeSpan.FromTicks(333333);
}protected override void Initialize()
{
base.Initialize();
}protected override void LoadContent()
{spriteBatch = new SpriteBatch(GraphicsDevice);
this.ballManager.LoadContent(Content);
this.font = Content.Load<SpriteFont>("Font/SpriteFont1");
}protected override void UnloadContent()
{}protected override void Update(GameTime gameTime)
{

if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
this.ballManager.Update();
base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.DarkCyan);

// TODO: Add your drawing code here
spriteBatch.Begin();
this.ballManager.Draw(spriteBatch);
spriteBatch.DrawString(font, s, new Vector2(), Color.Orange);
spriteBatch.End();
base.Draw(gameTime);
}
}
}


sau đó F5, chạy thử ta được kết quả :
video demo : http://www.youtube.com/watch?v=Ji5sOrayM_M

…………………………………… sau đây là phần giải thích chi tiết
như vậy là chúng ta có 3 lớp Ball.cs,BallManager.cs,Game1.cs
mấy lệnh trong if sẽ quyết định đến sự bật trở lại của bóng, tôi sẽ giải thích kĩ hơn trong hình sau :vector màu đỏ là vector hướng chuyển động
1. hàm update trong ball.cs
-ý của tôi là khi nhấn “chuột trái” (chuột trái ở emulator trên computer tương đương nhấn tay vào màn hình touch trên window phone 7) thì các bóng sẽ được set lại vị trí tại chuột

public void Update()
{
MouseState mouse = Mouse.GetState();
if (mouse.LeftButton == ButtonState.Pressed)
{
this.Press = true;
}
else this.Press = false;
if (this.Press)
{
if (mouse.X > 0 && mouse.Y > 0 && mouse.X + size.X <= this.graphics.PreferredBackBufferWidth && mouse.Y + size.Y <= this.graphics.PreferredBackBufferHeight)
this.Location = new Vector2(mouse.X, mouse.Y);
}
//di chuyển
this.location += this.direction * h;
if (!outside())
{
if (location.X * location.Y < 0) this.location = new Vector2();
}
}

this.graphics.PreferredBackBufferWidth
this.graphics.PreferredBackBufferHeight

xác định kích thước của màn hình window phone, lệnh if dài loằng ngoằng ở trên có nghĩa là nếu dí chuột vào phạm vi màn hình thì mới set lai vị trí bóng
vì bóng có kích thước , nên xuất hiện lượng size trong đoạn if trên

2. hàm outside trong ball.cs

hàm này xác định xem bóng có còn ở trong khung màn hình hay không ?

public bool outside()
{
if (this.Location.X < 0)
{
this.direction = new Vector2(-this.direction.X, this.direction.Y);
return true;
}
if (this.Location.Y < 0)
{
this.direction = new Vector2(this.direction.X, -this.direction.Y); return true;
}
if (this.Location.X + this.size.X > this.graphics.PreferredBackBufferWidth)
{
this.direction = new Vector2(-this.direction.X, this.direction.Y); return true;
}if (this.Location.Y + this.size.Y > this.graphics.PreferredBackBufferHeight)
{
this.direction = new Vector2(this.direction.X, -this.direction.Y);
return true;
} return false;
}
đó là lí do tại sao tôi code trong hàm if như thế 3.lớp ballmanager.cslớp này thì đơn giản rồi, tôi tạo 1 mảng đối tượng ball(6 quả), viết hàm update chung,draw chung,load content chung
vì thế bạn thấy game1.cs code đơn giản hơn, ít rối rắm
kết luận :
-mình ko có thời gian viết chi tiết, ai thắc mắc cứ hỏi
-có thể đọc thêm các tut xna trước mà tôi đã viết
-window phone OS dùng silverlight,XNA để phát triển ứng dụng,game- nếu run mà game ko hiện ra thì làm như sau

Comments
  1. zstar says:

    window phone 7 sử dụng XNA framework để làm game ,silverlight để code ứng dụng

  2. nguyễn văn trường says:

    Anh ơi, anh có các file ảnh và file nguồn của chương trình không hả anh? Nếu có anh có thể post lên đây để cho em và mọi người cùng xem và học tập với anh. Em cảm ơn anh nhiều !

  3. BakaNeko says:

    nice!
    Minh cung dang tap lam game tren win dow phone 7.
    Dang viet 1 cai game ne^^.
    Hi vong sau nay co the trao doi them.^^

  4. BakaNeko says:

    tneu cac ban chau bit nhiu thi len codeproject.com va msdn ay.
    Len do search 1 hoi se ra ah^^.

  5. BakaNeko says:

    Bajn co bit ve cach nao cho vu random sao cho ko bit trung lap ko??
    minhcho random ma no cu random 1 so hoai.
    Hi vong ban giup do~.

  6. zstar says:

    hi bạn !
    vấn đề random số không trùng nhau cũng khá đơn giản
    bạn add tất cả các số cần random vào 1 List hoặc vector , sau đó bạn random chỉ số index của List hoặc vector. sau đó bạn lấy phần tử ở vị trí index đó. đồng thời remove phần tử ở vị trí đó
    regards!

  7. BakaNeko says:

    Thi minh random chi so index ma. Chinh vi cai chi so index cu ra 1 gia tri hoai nen moi kho? ne.T_T

  8. BakaNeko says:

    y minh la minh muon random tu 0 den 8
    code cua minh nhu vay ne
    random rnd=new random();
    int index =rnd.next(9);
    kho? 1 cai la no cu ra 1 so hoai 1 lan ay. vi neu nhu minh d au vao danh sach rui xoa danh sach thi 1 hoi cai danh sach do trong tron vay la het xai tip dc.
    neu minh ko hiu dung y bang noi o tren thi xin loi truoc nha^^.
    Rat vui vi co the trao doi voi ban^^.

  9. duongnguyen says:

    thanks much

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s