[XNA]chuyển động của nhân vật trong XNA (phần 1)

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

bài này mình sẽ hướng dẫn các bạn tạo chuyển động cho nhân vật trong XNA
Bài 1 : tìm hiểu về chuyển động của Nhân vật trong Game

1.chuẩn bị
download XNA game studio 3.1 từ trang của Microsoft ,cài đặt cho Visual studio 2008

tạo 1 project mới : Visual C#->XNA 3.1->Windows game->OK

Hình ảnh

2.Sprite image 2D là gì ?
Sprite image 2D thực chất là 1 image tập hợp tất cả các tư thế cơ bản của nhân vật theo một qui luật nào đó
ví dụ về Sprite image
Hình ảnh

3.phân tích ví dụ trên
– Hàng 1 : là tập hợp các tư thế cơ bản của nhân vật khi nhân vật chuyển động từ dưới lên trên
– Hàng 2 : là tập hợp các tư thế cơ bản của nhân vật khi nhân vật chuyển động từ trái qua phải
– Hàng 3 : là tập hợp các tư thế cơ bản của nhân vật khi nhân vật chuyển động từ trên xuống dưới
– Hàng 4 : là tập hợp các tư thế cơ bản của nhân vật khi nhân vật chuyển động từ phải qua trái

4.Làm sao để tạo chuyển động từ Sprite ?
-Nhân vật hiển thị trong Game được cắt từ 1 trong các tư thế ở trong Sprite image ở trên.Tạm gọi là khung cắt
-Do các tư thế xếp cách đều nhau nên việc xác định chính xác khung cắt hết sức dễ dàng.Cả sprite image được xem như 1 ma trận 2 chiều các tư thế
-Khi cần nhân vật chuyển động. giả sử cần nhân vật chuyển động từ dưới lên trên.Ta sẽ cho chỉ số dòng của khung cắt bằng 0 đồng thời cho chỉ số cột lặp lại từ 0->4 và chỉ stop khi nhận được lệnh stop từ chương trình.
-Như vậy tập hợp các tư thế nhân vật chuyển động từ dưới lên được load trong thời gian ngắn làm cho chúng ta có cảm giác nhân vật bước đi từ dưới lên như thật vậy.
-Với các hướng chuyển động khác thì cũng làm tương tự nhưng phải thay đổi chỉ số dòng của khung cần cắt cho đúng với hướng chuyển động mà ta mong muốn

Bài 2 : Code chuyển động nhân vật trong XNA

trong cửa sổ Solution Explorer tìm đến Content ->Chuột Phải->Add->Existing item->chọn 1 cái image nền(nen.png)+chọn sprite trên(man.png)

Xây dựng lớp NhanVat.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.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;namespace chuyen_dong_nhan_vat
{
public class NhanVat
{
private Game1 Game;
private Texture2D text;//sprite nhan vat
private Point khungnhin=new Point(0,0);//vi tri khung nhin
private Point gioihan=new Point(5,4);//gioi han khung nhin
private byte kichthuoc=60;//kich thuoc khung nhin 60x60
private int buocChay = 3;//do dai moi buoc nhan vat
private Point viTri = new Point(0,0);//vi tri nhan vat tren man hinh
private HuongChuyenDong huongChuyenDong;
private bool dangChay = false;
private System.Windows.Forms.Timer capNhat_X;

public NhanVat(Game1 game)
{
this.Game = game;
this.capNhat_X = new System.Windows.Forms.Timer();
this.capNhat_X.Interval = 100;
this.capNhat_X.Enabled = true;
capNhat_X.Tick += new EventHandler(capNhat_X_Tick);
}

private void capNhat_X_Tick(object sender, EventArgs e)
{
//X chay tu 0->4
//cap nhat dong tac nhan vat
if (dangChay)
{
if (this.khungnhin.X < this.gioihan.X - 1)
{
this.khungnhin.X += 1;
}
else this.khungnhin.X = 0;
}
else this.khungnhin.X = 0;
}
public void LoadContent(ContentManager Content)
{
this.text = Content.Load<Texture2D>("man");
}
public void Update()
{
KeyboardState keys = Keyboard.GetState();
if (keys.IsKeyDown(Keys.Left))
{
//di chuyen tu phai qua trai
huongChuyenDong = HuongChuyenDong.PhaiQuaTrai;
DiChuyen();
return;
}
if (keys.IsKeyDown(Keys.Right))
{
//di chuyen tu trai qua phai
huongChuyenDong = HuongChuyenDong.TraiQuaPhai;
DiChuyen();
return;
}
if (keys.IsKeyDown(Keys.Up))
{
//di chuyen tu duoi len tren
huongChuyenDong = HuongChuyenDong.DuoiLenTren;
DiChuyen();
return;
}
if (keys.IsKeyDown(Keys.Down))
{
//di chuyen tu tren xuong
huongChuyenDong = HuongChuyenDong.TrenXuongDuoi;
DiChuyen();
return;
}
this.dangChay = false;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Begin();
spriteBatch.Draw(this.text, new Rectangle(this.viTri.X, this.viTri.Y,this.kichthuoc,this.kichthuoc), new Rectangle(this.khungnhin.X * this.kichthuoc, this.khungnhin.Y * this.kichthuoc,this.kichthuoc,this.kichthuoc), Color.White, 0, Vector2.Zero, SpriteEffects.None, 0);
spriteBatch.End();
}
private void DiChuyen()
{
this.dangChay = true;
//Y chay tu 0->3

//cap nhat huong chay
if (huongChuyenDong == HuongChuyenDong.DuoiLenTren)
{
this.viTri.Y -= this.buocChay;
this.khungnhin.Y = 0;
}
else if (huongChuyenDong == HuongChuyenDong.TrenXuongDuoi)
{
this.viTri.Y += this.buocChay;
this.khungnhin.Y = 2;
}
else if (huongChuyenDong == HuongChuyenDong.TraiQuaPhai)
{
this.viTri.X += this.buocChay;
this.khungnhin.Y = 1;
}
else if (huongChuyenDong == HuongChuyenDong.PhaiQuaTrai)
{
this.viTri.X -= this.buocChay;
this.khungnhin.Y = 3;
}
raNgoaiBanDo();

}
private void raNgoaiBanDo()
{
int xMax = this.Game.Window.ClientBounds.Width;
int yMax = this.Game.Window.ClientBounds.Height;
if (viTri.X < 0) this.viTri.X += buocChay;
if (viTri.X > xMax-kichthuoc) this.viTri.X -= buocChay;
if (viTri.Y < 0) this.viTri.Y += buocChay;
if (viTri.Y + buocChay > yMax-kichthuoc) this.viTri.Y -= buocChay;

}
}
}

xây dựng enum HuongChuyenDong.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace chuyen_dong_nhan_vat
{
public enum HuongChuyenDong
{
TraiQuaPhai,
PhaiQuaTrai,
TrenXuongDuoi,
DuoiLenTren,
}
}

code trong Game1.cs như sau


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;

namespace chuyen_dong_nhan_vat
{

public class Game1 : Microsoft.Xna.Framework.Game
{
private GraphicsDeviceManager graphics;
private SpriteBatch spriteBatch;
private NhanVat nhanVat;
private Texture2D nen;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
nhanVat = new NhanVat(this);
}

protected override void Initialize()
{

base.Initialize();
}

protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
this.nen = Content.Load<Texture2D>("nen");
this.nhanVat.LoadContent(this.Content);//load sprite cua nhan vat
}

protected override void UnloadContent()
{

}

protected override void Update(GameTime gameTime)
{

if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
this.nhanVat.Update();//update chuyen dong nhan vat
base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(this.nen,new Vector2(0,0),Color.White);
spriteBatch.End();
this.nhanVat.Draw(this.spriteBatch);//ve nhan vat len man hinh
base.Draw(gameTime);
}
}
}

xong rồi ! đây là kết quả
bây giờ nhấn các phím <- ^ -> nhân vật sẽ chuyển động rất mượt

Hình ảnh

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