Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 3 của 3
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    Hướng dẫn làm animation đa hướng và nhiều trạng thái cho Sprite bằng XNA

    [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!

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Quá khủng để theo đuổi
    Cảm ơn bạn
    Mình đang cố để hiểu

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    sao không có file mẫu hả bạn... mình đang tìm hiểu cái này

 

 

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •