Làm cách nào để điều chỉnh nguồn gốc của vòng quay cho một nhóm các họa tiết?


7

Tôi hiện đang nhóm các sprite lại với nhau, sau đó áp dụng chuyển đổi xoay vòng khi vẽ:

private void UpdateMatrix(ref Vector2 origin, float radians)
{
     Vector3 matrixorigin = new Vector3(origin, 0);
     _rotationMatrix = Matrix.CreateTranslation(-matrixorigin) * Matrix.CreateRotationZ(radians) *  Matrix.CreateTranslation(matrixorigin);
}

Trong đó nguồn gốc là điểm trung tâm của nhóm các họa sĩ của tôi. Tôi áp dụng chuyển đổi này cho mỗi sprite trong nhóm.

Vấn đề của tôi là khi tôi điều chỉnh điểm gốc, toàn bộ nhóm sprite của tôi sẽ tự định vị lại trên màn hình.

Làm thế nào tôi có thể phân biệt điểm quay được sử dụng trong chuyển đổi, từ vị trí của nhóm sprite? Có cách nào tốt hơn để tạo ma trận biến đổi này không?

BIÊN TẬP

Đây là phần có liên quan của hàm Draw ():

Matrix allTransforms = _rotationMatrix * camera.GetTransformation();

spriteBatch.Begin(SpriteSortMode.BackToFront, null, null, null, null, null, allTransforms);

for (int i = 0; i < _map.AllParts.Count; i++)
{
    for (int j = 0; j < _map.AllParts[0].Count; j++)
    {            
       spriteBatch.Draw(_map.AllParts[i][j].Texture, _map.AllParts[i][j].Position, null, Color.White, 0, _map.AllParts[i][j].Origin, 1.0f, SpriteEffects.None, 0f);
    }
}

Tất cả điều này hoạt động tốt, một lần nữa, vấn đề là khi một vòng quay được đặt và điểm gốc được thay đổi, vị trí của nhóm sprite được bù trên màn hình.

Tôi đang cố gắng tìm ra một cách để điều chỉnh điểm gốc mà không gây ra sự thay đổi vị trí.

EDIT 2 Tại thời điểm này, tôi đang tìm cách giải quyết vì điều này không hiệu quả. Có ai biết một cách tốt hơn để xoay một nhóm các sprite trong XNA không? Tôi cần một phương pháp cho phép tôi sửa đổi điểm xoay (gốc) mà không ảnh hưởng đến vị trí của nhóm sprite trên màn hình.

EDIT 3 Tôi nghĩ rằng nếu tôi có thể đặt lại tọa độ màn hình thành (0,0) tại vị trí sprite của mình, về cơ bản nó sẽ cho phép tôi đặt lại vị trí gốc mà không cần di chuyển. Tôi về cơ bản cần một cách để thiết lập vị trí / xoay hiện tại, sau đó bắt đầu từ đầu. Có ai biết nếu có thể làm cho sprite của tôi nguồn gốc màn hình mới?

CHUYỂN ĐỘNG GỐC KHÔNG CÓ ROTATION:

Không xoay

CHUYỂN ĐỘNG GỐC VỚI ROTATION (chú ý cách nó dịch chuyển lên trên):

Với Xoay


Nghe có vẻ như một câu hỏi tôi đã hỏi gần đây: gamedev.stackexchange.com/questions/19297/NH
not Meat

Vấn đề của tôi là khi có một vòng quay và nguồn gốc được sửa đổi, toàn bộ nhóm sprite sẽ thay đổi trên màn hình. Làm thế nào để bạn xử lý này duyên dáng?
jgallant

Chúng tôi có thể thấy khu vực mã của bạn gọi spitebatch.draw không?
ClassicThunder

Khi bạn nói rằng vị trí của nhóm sprite thay đổi trên màn hình, điều này có làm cho nguồn gốc ở cùng một vị trí màn hình không? Xem nếu bạn có thể hiển thị điểm gốc với một số điểm đánh dấu trực quan và so sánh ảnh chụp màn hình.
ChrisC

Nếu góc quay bằng 0 - vị trí không dịch chuyển. Vấn đề là khi nguồn gốc của xoay được thay đổi, ma trận xoay kết thúc sẽ dịch chuyển vị trí của nhóm các sprite vì nó được xoay ở một vị trí khác. Điều này có ý nghĩa, nhưng tôi muốn tránh hoàn toàn hành vi này.
16:30

Câu trả lời:


6

Tôi đã thực hiện điều này trên trình soạn thảo thế giới của tôi. Tôi có thể nhóm các nhóm cùng nhau và xoay chúng hoặc chia tỷ lệ thành một nhóm xung quanh nguồn gốc tùy ý (trong trường hợp của tôi cũng là trung tâm của nhóm). Tôi sử dụng một cái gì đó như thế này:

// Origin should be supplied in World-Space
void RotateGroup(IEnumerable<Sprite> sprites, Vector2 origin, float angle)
{
    Matrix transform =  Matrix.CreateTranslation(-origin.X, -origin.Y, 0f) *
                        Matrix.CreateRotationZ(angle) *
                        Matrix.CreateTranslation(origin.X, origin.Y, 0f);

    foreach(Sprite sprite in sprites)
    {
        sprite.Position = Vector2.Transform(sprite.Position, transform);
        sprite.Rotation += angle;
    }
}

Tôi chỉ đơn giản gọi phương thức này khi tôi muốn xoay toàn bộ nhóm của mình và phương thức tính toán một vị trí và xoay mới cho mỗi sprite để tạo ảo giác rằng chúng đang thay đổi thành một nhóm.

Quan trọng nhất, tôi không chuyển bất kỳ ma trận đặc biệt nào cho chức năng vẽ của mình. Mỗi sprite vẫn có vị trí, vòng quay và nguồn gốc riêng biệt, độc lập với việc họ có ở trong một nhóm hay không.

Điều này có nghĩa là nguồn gốc của nhóm là khái niệm và chỉ cần thay đổi giá trị đó sẽ không gây rối với các họa tiết của bạn. Giá trị chỉ được sử dụng khi xoay nhóm để chỉ định vị trí của trục, nhưng không phải khi vẽ.

Tóm lại, ma trận duy nhất bạn nên chuyển đến SpriteBatch.Begin là ma trận View của bạn, không có gì khác. Mỗi sprite nên được vẽ theo các thuộc tính riêng lẻ của nó và nếu bạn muốn xoay chúng thành một nhóm, hãy chơi xung quanh các thuộc tính đó, không phải xung quanh mã bản vẽ.


0

Hãy thử thay đổi

spriteBatch.Draw(_map.AllParts[i][j].Texture, _map.AllParts[i][j].Position, null, Color.White, 0, _map.AllParts[i][j].Origin, 1.0f, SpriteEffects.None, 0f);

đến

spriteBatch.Draw(_map.AllParts[i][j].Texture, _map.AllParts[i][j].Position + _map.AllParts[i][j].Origin, null, Color.White, 0, _map.AllParts[i][j].Origin, 1.0f, SpriteEffects.None, 0f);

Đối số thứ hai là vị trí của điểm gốc nên nếu bạn thay đổi điểm gốc từ 0,0 mặc định, bạn phải bù cho điểm đó.


Thuộc tính Origin ở đây, là nguồn gốc của Texture, không phải nhóm Sprite.
jgallant

0

Đợi đã, bạn muốn xoay tất cả các sprite cùng một lúc .. sau đó thay đổi nguồn gốc thành texture. Thong và texture.height ... và không thay đổi nó .. chỉ thay đổi xoay vòng thực tế của sprite .. và làm điều này cho tất cả các sprite .. và đặt vòng quay của tất cả các sprite thành một biến float duy nhất .. hãy tin tôi, nó hoạt động !!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.