Mẫu trò chơi 2D C # nhấp để di chuyển?


7

Hiện tại tôi đang học cách sử dụng XNA bằng cách tạo Trò chơi 2D. Cho đến nay tôi vẫn ổn, nhưng tôi muốn thực hiện nhấp chuột để di chuyển thay vì sử dụng các phím để đi bộ nhưng tôi không tìm thấy bất kỳ mẫu nào xung quanh và tôi không biết cách tiếp cận nó.

Tôi biết rằng XNA hoạt động tốt cho các điều khiển xbox và bàn phím nhưng tôi chưa thấy bất cứ điều gì liên quan đến tương tác chuột cả. Tôi không thực sự bận tâm về xbox vì tôi không nhắm đến bất kỳ thứ gì khác ngoài trò chơi trên PC.

Vì vậy, những gì tôi đang tìm kiếm là một số ví dụ về cách tính toán nhấp để di chuyển và nếu biểu tượng chuột được hiển thị trong trò chơi cũng được làm việc từ khung xna hoặc nếu bạn phải tự làm để tạo ra gạch hiện tại phát sáng hoặc hiển thị rằng chuột đang ở đó hoặc một cái gì đó giống nhau.


CẬP NHẬT:

Di chuyển bằng chuột không hoàn toàn giống nhau, bạn phải xem xét các chướng ngại vật ít nhất là trong trường hợp của tôi về những gì tôi đang lên kế hoạch ...

Ví dụ: tôi muốn các nhấp chuột được coi là đi thẳng buộc người dùng phải tự điều hướng trên bản đồ thay vì tự động điều hướng người dùng mỗi lần nhấp, vì vậy, nếu anh ta nhấp qua tường, ví dụ như họ sẽ đi qua tường và dừng lại thay vì tìm tuyến đường đến phía bên kia nếu có một ... một nghi ngờ khác xuất hiện trong đầu tôi khi sử dụng getstate của X và Y, ví dụ như trên cửa sổ cuộn, nó sẽ thực sự nhận ra chuột đang ở đâu hoặc sẽ có nhu cầu của thế giới- tính toán trên màn hình để tiết lộ điểm B được người dùng nhấp vào đâu?


Cảm ơn vì sự giúp đỡ và lời khuyên ...

Tái bút: Ai đó có lẽ có thể thêm thẻ nhấp để di chuyển hoặc thế giới trên màn hình?

PPS: tại sao nó không cho phép tôi thêm thẻ C # vào nó?


Được gắn lại với C # và 2D, không thấy lý do tại sao nhấp để di chuyển hoặc thế giới trên màn hình sẽ cần thiết như các thẻ. Ngoài ra, để mọi thứ có thể được tập trung, có vẻ như câu hỏi thứ hai mà bạn hỏi thực sự có liên quan đến câu hỏi đầu tiên của bạn. Xin vui lòng gửi nó trong một câu hỏi riêng biệt.
Jesse Dorsey

Tại sao bạn có một cửa sổ cuộn? Thông thường cửa sổ chỉ là một cổng xem vào một phần nhất định trong thế giới của bạn. Bạn chắc chắn có thể thực hiện một phương trình tuyến tính từ điểm a đến điểm b. Sau đó, bạn có thể sử dụng một số chức năng uốn cong để thực hiện một số nội dung thú vị như tăng tốc ở đầu và giảm tốc độ ở cuối.
Michael Coleman

Tôi đã đề cập đến nó như một ví dụ, tôi không sử dụng cửa sổ cuộn. Bạn có thể đã bỏ lỡ forcing the user to navigate himself on the map instead of auto-navigating the user per clickcơ bản là khi người dùng nhấp vào một địa điểm xác định, nó sẽ di chuyển cửa sổ khi người chơi di chuyển, nhưng nếu người chơi cố gắng bám vào trong một ngôi nhà nơi cửa đóng lại chẳng hạn, thì nó sẽ đi về phía ngôi nhà trên một đường thẳng và dừng lại ở chướng ngại vật đầu tiên, điều đó có nghĩa là người dùng không có nhấp chuột điều hướng tự động để di chuyển nhưng anh ta phải nhấp theo cách riêng của mình đến nơi anh ta muốn đi.
Giải thưởng

Câu trả lời:


6

Chỉnh sửa: Được rồi, tôi vừa đọc từ một trong những bình luận của bạn rằng bạn không muốn điều hướng tự động. Trong trường hợp đó, chỉ xem xét phần cuối cùng trong bài đăng này ("Đi bộ trên con đường đó") với trường hợp đơn giản là danh sách chỉ lưu trữ nơi chuột của bạn nhấp và tự xóa khi tìm thấy chướng ngại vật. Tôi cũng chỉ nhận thấy rằng bạn đã đề cập đến gạch một lần trong bài viết. Trong trường hợp đó, không cần biểu đồ hiển thị, bản thân lưới có thể được sử dụng để chạy sao A. Dù sao, tôi vẫn đăng bài này như một giải pháp tổng quát hơn cho vấn đề điều hướng nhấp chuột và điểm 2D.

Những gì bạn đang yêu cầu là làm thế nào để tìm đường trên môi trường 2D. Tôi đã viết một bài báo trước khi phác thảo một kỹ thuật có khả năng giải quyết vấn đề đó. Tôi sẽ bắt đầu bằng cách đặt một liên kết đến bài viết, và sau đó thêm một lời giải thích ngắn gọn về thuật toán.

http://www.david-gouveia.com/pathfinding-on-a-2d-poly Cross-map /

Tất nhiên, đây không phải là cách duy nhất để giải quyết nó. Tôi đang sử dụng một biểu đồ khả năng hiển thị. Bạn cũng có thể sử dụng lưới điều hướng. Hoặc một lưới. Biểu đồ khả năng hiển thị có một lợi thế đặc biệt là nó luôn trả về đường đi trực tiếp nhất giữa các điểm mà không cần thực hiện bất kỳ đường thẳng nào. Và xây dựng biểu đồ khả năng hiển thị trên đầu của một đa giác, bạn có thể chỉ định chính xác các vùng có thể đi bộ.

Ý tưởng

Ý tưởng chính ở đây là biểu diễn vùng có thể đi bộ của bạn dưới dạng đa giác và xây dựng biểu đồ khả năng hiển thị bằng các đỉnh lõm của đa giác . Nếu đa giác chứa các lỗ, bạn cũng sẽ sử dụng các đỉnh lồi của chúng .

Tạo một biểu đồ khả năng hiển thị có nghĩa là lấy mọi nút (hoặc đỉnh trong trường hợp này) của biểu đồ và kết nối nó với mọi đỉnh khác mà nó có thể "nhìn thấy". Bạn cần một số kiểm tra tầm nhìn để làm điều này. Cái tôi đã sử dụng được xây dựng dựa trên thử nghiệm giao cắt phân đoạn đơn giản, với một vài kiểm tra được thêm vào.

Sau đó, bất cứ khi nào bạn muốn tìm đường dẫn giữa hai vị trí, bạn tạm thời thêm chúng vào biểu đồ hiển thị và chỉ cần chạy thuật toán tìm đường dẫn A * cổ điển trên đó.

Đây là toàn bộ cấu trúc trông như thế nào:

biểu đồ khả năng hiển thị

Ở đâu:

  • Các đường màu vàng là polgyon đại diện cho nơi bạn có thể đi bộ.
  • Các vòng tròn màu trắng là các đỉnh đa giác tạo nên biểu đồ khả năng hiển thị (các nút)
  • Các đường màu tím kết nối các đỉnh nằm trong tầm nhìn của nhau (các cạnh).
  • Đường màu xanh nhạt là một ví dụ về việc tìm đường đi giữa hai vị trí (chấm xanh và chấm đỏ).
  • Các đường màu lục nhạt là các cạnh tạm thời được thêm vào biểu đồ cùng với các nút bắt đầu và kết thúc trong đường dẫn (chấm xanh lục và chấm đỏ).

Thực hiện

1) Đại diện

Về việc thực hiện điều này, trước tiên bạn cần có một cách để thể hiện một đa giác cho sàn nhà của bạn. Các lớp sau đây là đủ:

public class Polygon
{
    public class SimplePolygon
    {
        List<Vector2> Vertices;
    }

    List<SimplePolygon> Outlines;
    List<SimplePolygon> Holes;
}

2) Chọn nút

Sau đó, bạn cần một cách để đi qua từng đỉnh của đa giác và quyết định xem chúng có phải là các nút trong biểu đồ khả năng hiển thị hay không. Các tiêu chí cho điều đó là các đỉnh lõm trong các phác thảo và các đỉnh lồi trong các lỗ. Tôi sử dụng một chức năng như thế này:

public static bool IsVertexConcave(IList<Vector2> vertices, int vertex)
{
    Vector2 current = vertices[vertex];
    Vector2 next = vertices[(vertex + 1) % vertices.Count];
    Vector2 previous = vertices[vertex == 0 ? vertices.Count - 1 : vertex - 1];

    Vector2 left = new Vector2(current.X - previous.X, current.Y - previous.Y);
    Vector2 right = new Vector2(next.X - current.X, next.Y - current.Y);

    float cross = (left.X * right.Y) - (left.Y * right.X);

    return cross < 0;
}

3) Chọn các cạnh

Bây giờ bạn sẽ cần đi qua từng cặp của các đỉnh này và quyết định xem chúng có nằm trong tầm ngắm hay không. Tôi đã sử dụng phương pháp sau đây làm điểm bắt đầu cho kiểm tra đó:

static bool LineSegmentsCross(Vector2 a, Vector2 b, Vector2 c, Vector2 d)
{
    float denominator = ((b.X - a.X) * (d.Y - c.Y)) - ((b.Y - a.Y) * (d.X - c.X));

    if (denominator == 0)
    {
        return false;
    }

    float numerator1 = ((a.Y - c.Y) * (d.X - c.X)) - ((a.X - c.X) * (d.Y - c.Y));

    float numerator2 = ((a.Y - c.Y) * (b.X - a.X)) - ((a.X - c.X) * (b.Y - a.Y));

    if (numerator1 == 0 || numerator2 == 0)
    {
        return false;
    }

    float r = numerator1 / denominator;
    float s = numerator2 / denominator;

    return (r > 0 && r < 1) && (s > 0 && s < 1);
}

Nhưng phải sử dụng một vài cách hack khác để ổn định cho các trường hợp cạnh, vì vậy nó không phải là điều kiện tốt để đăng. Vẫn đang cố gắng tìm ra một giải pháp sạch và ổn định cho vấn đề này.

4) Xây dựng đồ thị và chạy A-star

Bạn sẽ cần tạo một biểu đồ khả năng hiển thị bằng cách sử dụng các đỉnh và cạnh đó và chạy A * trên đó. Để tìm hiểu cách xây dựng biểu đồ và áp dụng A * Tôi khuyên bạn nên nghiên cứu bài viết sau:

http://bloss.msdn.com/b/ericlippert/archive/2007/10/02/path-finding-USE-a-in-c-3-0.aspx

Sau đó, bạn có thể muốn gói gọn tất cả những thứ này trong một lớp duy nhất, để bạn có một giao diện dễ sử dụng, chẳng hạn như:

public class Floor
{
    public Floor(Polygon polygon) 
    { 
        _polygon = polygon; 
        BuildGraph();
    }

    public IEnumerable<Vector> GetPath(Vector2 start, Vector2 end)
    {
       // Add start and end as temporary nodes and connect them to the graph
       // Run A* on the graph
       // Remove temporary nodes and edges
    }

    private Polygon _polygon;

    private Graph _graph;
}

Bằng cách này, bạn chỉ cần tạo một thể hiện Tầng và gọi phương thức GetPath trên đó bất cứ khi nào bạn cần tìm đường dẫn giữa hai vị trí.

5) Đi trên con đường đó

Cuối cùng, bạn cần phải làm cho nhân vật của bạn đi trên con đường được tạo ra. Anh ta cần phải có một số loại bộ nhớ trong cho điều đó, nhưng không quá khó để thực hiện điều đó. Ví dụ:

  1. Thêm một Danh sách bên trong nhân vật để lưu trữ con đường anh ta hiện đang theo dõi.
  2. Trên mỗi chu kỳ Cập nhật, lấy giá trị đầu tiên từ danh sách và di chuyển nhân vật của bạn về phía đó.
  3. Nếu anh ta đến đủ gần đích, hãy xóa phần tử đầu tiên khỏi danh sách và lặp lại.
  4. Nếu danh sách trở nên trống rỗng, anh ta đã đến đích.

Câu trả lời tuyệt vời, tôi thậm chí sẽ không bận tâm trả lời vì tôi nghĩ bạn đã bao gồm bất cứ điều gì tôi có thể nói. +1
Joshua Hedges

3

Chà ... Trong khi bạn đang học đừng quên rằng Google là người bạn thực sự của bạn trong mục đích cuối cùng này.

Bước 1 là lấy vị trí chuột - http://msdn.microsoft.com/en-us/l Library / bb197572.aspx

Bước 2 là di chuyển sprite đến Vị trí A đến Vị trí B liên quan đến vật lý / chuyển động cơ bản - http://www.xnadevelopment.com/tutorials/thewizard/theWizard.shtml

Ý tưởng giống như việc di chuyển chuột là để đến đích mà người dùng nhấp vào. Bạn vẫn đang đi từ điểm A đến điểm B.

Những gì bạn đang mô tả là một chi tiết triển khai mà bạn có thể xác định cách bạn muốn xử lý. Tôi giả sử bạn làm việc với một số loại lưới. Các gạch trên các lưới này sẽ có các thuộc tính cụ thể như khả năng đi lại. Cố gắng di chuyển sprite của bạn một bước gần hơn theo hướng của đích, nếu một ô không thể đi được, hãy dừng lại.

Nếu bạn muốn sprite của bạn thực sự đạt được sự mong muốn, bạn sẽ muốn thực hiện một thuật toán tìm đường thực tế để phân tích khả năng đi lại của gạch của bạn.


cảm ơn vì liên kết đầu tiên không giúp được gì nhưng liên kết thứ hai không nhiều, tôi đã cập nhật câu hỏi của mình với một vài điểm khác nếu bạn không ngại kiểm tra ... cảm ơn.
Giải thưở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.