[XNA-tutorial] Hướng dẫn làm animation đa hướng và nhiều trạng thái cho Sprite
1. Sprite là gì?
Nói một cách nôm na thì sprite và những vật thể có thể di chuyển và tương tác trong game (người chơi, kẻ thù, NPC...). Phân biệt nó với static hay solid object, tức là những đối tượng cứng ko tương tác hay thay đổi trong game (như bức tường, hòn đá...).
2. Tại sao Sprite lại cần animation?
Đơn giản là vì sprite là những thứ gây đc sự chú ý nhất cho gamer (ai mà lại ko chú ý tới người chơi, kẻ thù chứ) . do đó animation sẽ giúp game sống động hơn và giúp gamer nhận đúng những trạng thái khác nhau của sprite (animate cho idle, run hay attack tất nhiên là sẽ phản ánh những trạng thái khác nhau rùi).
Animate ở đây chỉ đơn giản là việc thay đổi những frame (khung hình, tức là những texture của sprite) khác nhau trong một khoảng thời gian rất ngắn để người nhận thấy đó là sự chuyển động của sprite.
Đầu tiên chúng ta nói qua về một Draw() method đầy đủ các tham số:
spriteBatch.Draw(texture, position , sourceRectangle, Color.White, angle, origin, scale, SpriteEffects, depth);
Các tham số lần lượt là:
Texture: bức ảnh load từ Content và sẽ bao phủ lên toàn bộ sprite.
Position: Vị trí mà XNA sẽ Draw sprite lên màn hình của gamer
SourceRectangle: hình chữ nhật trên bức ảnh là chúng ta vừa load vào (chỉ có những vùng trên bức ảnh thuộc hình chữ nhật đó mới đc thể hiện trong game. Bạn có thể khởi tạo một Rectangle với thuộc tính tọa độ X,Y và chiều dài , chiều rộng.
Color: Màu sẽ tô nếu bức ảnh có vùng trống (tuy nhiên tô kiểu AlphaBlend thì nó sẽ tự động không tô màu những vùng ảnh trống)
(float)angle: Góc sẽ xoay sprite (mặc định là 0f)
(Vector2)Origin : tọa độ điểm trung tâm sprite (đặt là tọa độ tâm của một frame), Nếu angle != 0 thì sprite sẽ xoay xung quanh điểm origin.
Scale: Phóng to hay thu nhỏ sprite theo cùng tỉ lệ width/height
SpriteEffect: hiệu ứng lật texture (ngang, dọc hoặc ko dùng)
Depth: Độ sâu (sprite nào có depth cao hơn thì được draw chèn lên trên sprite có detph thấp hơn, nếu cùng depth thì sprite nào đc tạo ra trước sẽ bị sprite Draw đè lên trên)
ở đây mình dùng 2 biến enum để tạo các mặt và trạng thái cho sprite:
Mã:
public enum Status { Idle = 0, Run } //Face public enum Face { Down = 0, DownLeft, Left, LeftUp, Up, UpRight, Right, RightDown, }
Câu lệnh dưới đây đảm bảo là angel luôn ở đoạn [-pi;pi]
Mã:
if (angel < -MathHelper.Pi) { angel += 2 * MathHelper.Pi; } if (angel > MathHelper.Pi) { angel -= 2 * MathHelper.Pi; } Code dưới đây sẽ tìm ra face thích hợp cho sprite tùy theo góc xoay của nó: if (angel >= MathHelper.Pi * 7 / 8 || angel <= -MathHelper.Pi * 7 / 8) face = Face.Down; else if (angel < MathHelper.Pi * 7 / 8 && angel >= MathHelper.Pi * 5 / 8) face = Face.RightDown; else if (angel > MathHelper.Pi * 3 / 8 && angel <= MathHelper.Pi * 5 / 8) face = Face.Right; else if (angel > MathHelper.Pi / 8 && angel <= MathHelper.Pi * 3 / 8) face = Face.UpRight; else if (angel > MathHelper.Pi * -1 / 8 && angel <= MathHelper.Pi / 8) face = Face.Up; else if (angel > MathHelper.Pi * -3 / 8 && angel <= MathHelper.Pi * -1 / 8) face = Face.LeftUp; else if (angel > MathHelper.Pi * -5 / 8 && angel <= MathHelper.Pi * -3 / 8) face = Face.Left; else face = Face.DownLeft;
Code dưới đây sẽ chọn trạng thái phù hợp : đứng yên khi speed quá thấp và chuyển sang trạng thái chạy nếu speed cao hơn
Mã:
if (speed > -0.5f && speed < 0.5f) { status = Status.Idle; } else { status = Status.Run; }
Code dưới đây sẽ thay đổi frame theo một khoảng thời gian là frameTime
Nếu isLooping == true thì hoạt hình sẽ được lặp đi lặp lại (> 1 lần)
Mã:
time += (float)gameTime.ElapsedGameTime.TotalSeconds; while (time > frameTime) { time -= frameTime; if (isLooping) { frameIndex = (frameIndex + 1) % frameCount; } else { frameIndex = Math.Min(frameIndex + 1, frameCount - 1); } } //tao ra frame mới => tao ra animation Rectangle source = new Rectangle(frameIndex * frameWidth+10, frameHeight*(int)face+20, frameWidth-10, frameHeight-20);
trong code của player, chúng ta tạo danh sách textures và add từng texture theo các trạng thái khác nhau như thế này:
textures.Add(game.Content.Load<Texture2D>(Helper.S prite + "Idle"));
textures.Add(game.Content.Load<Texture2D>(Helper.S prite + "Run"));
//Cuoi cùng la Draw
spriteBatch.Draw(textures[(int)status], position , source, Color.White, 0f, origin, 1.0f, SpriteEffects.None, 0.1f);
Trong file mẫu có thêm code về việc tạo màn, code mẫu cho phép bạn control sprite bằng cả mouse lẫn keyboard.
Thân ái!
View more random threads:
Vệ sinh cá nhân là một phần quan yếu của sức khỏe nam giới. Dùng dung dịch vệ sinh mỗi ngày mang lại nhiều ích, giúp loại bỏ vi khuẩn và vi sinh vật gây hại, giúp khu vực cơ quan sinh dục luôn sạch...
Gel vệ sinh cu, bạn trai có nên...