2008-12-11 26 views
88

Để giải trí, tôi đang cố gắng viết một trong những trò chơi trên bàn yêu thích của con trai tôi như một phần mềm. Cuối cùng tôi mong đợi để xây dựng một giao diện người dùng WPF trên đầu trang của nó, nhưng ngay bây giờ tôi đang xây dựng máy mô hình các trò chơi và các quy tắc của nó.Bất kỳ mô hình nào để lập mô hình trò chơi trên bảng?

Khi tôi làm điều này, tôi tiếp tục thấy các vấn đề mà tôi nghĩ là phổ biến với nhiều trò chơi trên bàn và có lẽ những người khác đã giải quyết chúng tốt hơn tôi.

(. Lưu ý rằng AI để chơi trò chơi, và các mẫu xung quanh hiệu suất cao là không thú vị với tôi)

Cho đến nay mô hình của tôi là:

  • Một số loại không thay đổi đại diện cho các đơn vị trong game hộp, ví dụ xúc xắc, kẻ carô, thẻ, một hội đồng quản trị, không gian trên bảng, tiền bạc vv

  • Một đối tượng cho mỗi người chơi, trong đó có các nguồn lực người chơi (ví dụ như tiền, điểm số), tên của họ, vv

  • Một đối tượng đại diện cho trạng thái của trò chơi: người chơi, người quay đầu, bố cục của các peices trên bảng, v.v.

  • Máy trạng thái quản lý chuỗi lần lượt. Ví dụ, nhiều trò chơi có một trò chơi nhỏ trước khi mỗi người chơi cuộn để xem ai đi trước; đó là trạng thái bắt đầu. Khi lượt của người chơi bắt đầu, đầu tiên họ quay, sau đó họ di chuyển, sau đó họ phải nhảy tại chỗ, sau đó người chơi khác đoán những gì giống gà họ, sau đó họ nhận được điểm.

Có một số tác phẩm nghệ thuật mà tôi có thể tận dụng không?

EDIT: Một điều tôi nhận ra thời gian gần đây là trạng thái trò chơi có thể được chia thành hai loại:

  • game tạo tác nhà nước. "Tôi có $ 10" hoặc "tay trái của tôi là màu xanh".

  • Trạng thái chuỗi trò chơi. "Tôi đã tăng gấp đôi gấp đôi, người tiếp theo đưa tôi vào tù". Một máy trạng thái có thể có ý nghĩa ở đây.

EDIT: Những gì tôi đang thực sự tìm kiếm ở đây các cách tốt nhất để thực hiện nhiều turn-based trò chơi như cờ vua hay Scrabble hay Monopoly là. Tôi chắc rằng tôi có thể tạo ra một trò chơi như vậy chỉ bằng cách bắt đầu hoàn thành, nhưng, giống như các mẫu thiết kế khác, có thể có một số cách để làm cho mọi thứ diễn ra trôi chảy hơn mà không rõ ràng nếu không có nghiên cứu cẩn thận. Đó là những gì tôi hy vọng.

+2

Bạn đang xây dựng một số loại Hokey Pokey, Monopoly, charades mashup? –

+0

Bạn sẽ muốn một máy trạng thái cho bất kỳ quy tắc nào dựa vào trạng thái (err ...) giống như quy tắc tăng gấp đôi ba cho Độc quyền. Tôi sẽ đăng một câu trả lời đầy đủ hơn nhưng tôi không có kinh nghiệm làm điều này. Tôi có thể pontificate về nó mặc dù. – MSN

Trả lời

107

có vẻ như đây là một chủ đề cũ 2 tháng mà tôi vừa mới nhận thấy bây giờ, nhưng cái quái gì. Tôi đã thiết kế và phát triển khung chơi cho một trò chơi hội đồng quản trị được nối mạng trước đây. Chúng tôi đã có một kinh nghiệm rất dễ chịu khi làm việc với nó.

Trò chơi của bạn có thể ở trong trạng thái vô hạn (gần) vì các hoán vị của những thứ như số tiền mà người chơi A có, số tiền mà người chơi B có, và v.v. khá chắc chắn bạn muốn tránh xa các máy nhà nước. Ý tưởng đằng sau khuôn khổ của chúng tôi là đại diện cho trạng thái trò chơi dưới dạng cấu trúc với tất cả các trường dữ liệu với nhau, cung cấp trạng thái trò chơi hoàn chỉnh (ví dụ: nếu bạn muốn lưu trò chơi vào đĩa, bạn viết cấu trúc đó ra).

Chúng tôi đã sử dụng Command Pattern để thể hiện tất cả các hành động trò chơi hợp lệ mà người chơi có thể thực hiện. Dưới đây sẽ là một hành động ví dụ:

class RollDice : public Action 
{ 
    public: 
    RollDice(int player); 

    virtual void Apply(GameState& gameState) const; // Apply the action to the gamestate, modifying the gamestate 
    virtual bool IsLegal(const GameState& gameState) const; // Returns true if this is a legal action 
}; 

Vì vậy, bạn thấy rằng để quyết định có một động thái có giá trị, bạn có thể xây dựng hành động đó và sau đó gọi hàm IsLegal của nó, đi qua trong trạng thái trò chơi hiện tại. Nếu nó hợp lệ và người chơi xác nhận hành động, bạn có thể gọi hàm Áp dụng để thực sự sửa đổi trạng thái trò chơi.Bằng cách đảm bảo rằng mã trò chơi của bạn chỉ có thể sửa đổi trạng thái trò chơi bằng cách tạo và gửi các hành động pháp lý (vì vậy nói cách khác, Hành động :: Áp dụng các phương thức là điều duy nhất trực tiếp sửa đổi trạng thái trò chơi), sau đó bạn đảm bảo rằng trò chơi của mình trạng thái sẽ không bao giờ không hợp lệ. Hơn nữa, bằng cách sử dụng mẫu lệnh, bạn có thể sắp xếp các bước di chuyển mong muốn của người chơi và gửi chúng qua mạng để được thực hiện trên các trạng thái trò chơi của người chơi khác.

Có kết thúc bằng một dấu ấn với hệ thống này hóa ra là có một giải pháp khá thanh lịch. Đôi khi các hành động sẽ có hai hoặc nhiều giai đoạn. Ví dụ, người chơi có thể hạ cánh trên một tài sản trong Độc quyền và bây giờ phải đưa ra quyết định mới. Trạng thái trò chơi là gì khi người chơi lăn xúc xắc, và trước khi họ quyết định mua một tài sản hay không? Chúng tôi đã quản lý các tình huống như thế này bằng cách giới thiệu thành viên "Hành động bối cảnh" của trạng thái trò chơi của chúng tôi. Ngữ cảnh hành động thường là null, cho biết trò chơi hiện không ở trạng thái đặc biệt nào. Khi người chơi cuộn xúc xắc và hành động lăn xúc xắc được áp dụng cho trạng thái trò chơi, nó sẽ nhận ra rằng người chơi đã hạ cánh trên thuộc tính không sở hữu và có thể tạo ngữ cảnh hành động "PlayerDecideToPurchaseProperty" mới chứa chỉ mục của người chơi chúng tôi đang chờ quyết định từ. Vào thời điểm hành động RollDice đã hoàn thành, trạng thái trò chơi của chúng tôi thể hiện rằng nó hiện đang chờ người chơi được chỉ định quyết định có nên mua bất động sản hay không. Giờ đây, phương pháp IsLegal của mọi hành động khác trở nên dễ dàng, ngoại trừ các hành động "BuyProperty" và "PassPropertyPurchaseOpportunity", chỉ là hợp pháp khi trạng thái trò chơi có ngữ cảnh hành động "PlayerDecideToPurchaseProperty".

Thông qua việc sử dụng các bối cảnh hành động, không bao giờ có một điểm trong thời gian sống của trò chơi hội đồng quản trị mà cấu trúc trạng thái trò chơi không thể hiện chính xác những gì đang diễn ra trong trò chơi tại thời điểm đó. Đây là một tài sản rất mong muốn của hệ thống trò chơi hội đồng quản trị của bạn. Nó sẽ dễ dàng hơn nhiều cho bạn để viết mã khi bạn có thể tìm thấy mọi thứ bạn muốn biết về những gì đang xảy ra trong trò chơi bằng cách chỉ kiểm tra một cấu trúc.

Hơn nữa, nó mở rộng rất độc đáo với môi trường mạng, nơi khách hàng có thể gửi hành động của họ qua mạng tới máy chủ, có thể áp dụng hành động cho trạng thái trò chơi "chính thức" của máy chủ và sau đó lặp lại hành động đó các khách hàng khác để họ áp dụng nó vào trạng thái trò chơi được sao chép của họ.

Tôi hy vọng điều này là súc tích và hữu ích.

+3

Tôi không nghĩ nó ngắn gọn, nhưng nó rất hữu ích! Được thăng hạng. –

+0

Vui vì nó hữu ích ... Những phần nào không súc tích? Tôi rất sẵn lòng làm một chỉnh sửa làm rõ. –

+0

Tôi đang xây dựng một trò chơi theo lượt ngay bây giờ và bài đăng này thực sự hữu ích! – Kiv

3

Three Rings cung cấp thư viện Java LGPL. Nenya và Vilya là thư viện cho các công cụ liên quan đến trò chơi.

Tất nhiên, điều đó sẽ hữu ích nếu câu hỏi của bạn đề cập đến các hạn chế về nền tảng và/hoặc ngôn ngữ bạn có thể có.

+0

"Cuối cùng tôi hy vọng sẽ xây dựng một giao diện người dùng WPF" - điều đó có nghĩa là .NET.Ít nhất, theo như tôi có thể nói. –

+0

Súp bảng chữ cái mà tôi không biết. – jmucchiello

+0

Vâng, tôi đang làm .NET, nhưng câu hỏi của tôi không phải là ngôn ngữ hoặc nền tảng cụ thể. –

8

Tất nhiên có rất nhiều, nhiều, nhiều, nhiều, nhiều, nhiều, nhiều tài nguyên về chủ đề này. Nhưng tôi nghĩ rằng bạn đang trên con đường bên phải chia các đối tượng và cho phép họ xử lý các sự kiện/dữ liệu của riêng mình và cứ thế.

Khi thực hiện trò chơi trên bảng xếp kề, bạn sẽ thấy thật thú vị khi có thói quen ánh xạ giữa mảng bảng và hàng/col và ngược lại, cùng với các tính năng khác. Tôi nhớ trò chơi hội đồng quản trị đầu tiên của tôi (từ lâu trước đây) khi tôi đấu tranh với cách lấy hàng/col từ boardarray 5.

1 2 3 
4 (5) 6 BoardArray 5 = row 2, col 2 
7 8 9 

Nostalgy. ;)

Dù sao, http://www.gamedev.net/ là một nơi tốt để biết thông tin. http://www.gamedev.net/reference/

+0

Tại sao bạn không chỉ sử dụng mảng 2 chiều? Sau đó trình biên dịch có thể xử lý việc này cho bạn. –

+0

Lý do của tôi là đây là một thời gian dài trước đây. ;) – Stefan

+1

gamedev có một tấn nếu công cụ, nhưng tôi đã không nhìn thấy khá những gì tôi đang tìm kiếm. –

17

Cấu trúc cơ bản của công cụ trò chơi của bạn sử dụng State Pattern. Các mục trong hộp trò chơi của bạn là singletons các lớp khác nhau. Cấu trúc của mỗi tiểu bang có thể sử dụng Strategy Pattern hoặc the Template Method.

A Factory được sử dụng để tạo người chơi được chèn vào danh sách người chơi, một singleton khác. GUI sẽ tiếp tục xem trên Công cụ trò chơi bằng cách sử dụng Observer pattern và tương tác với điều này bằng cách sử dụng một trong một số đối tượng Lệnh được tạo bằng cách sử dụng Command Pattern. Việc sử dụng Observer và Command có thể được sử dụng trong ngữ cảnh Passive View Nhưng chỉ có thể sử dụng bất kỳ mẫu MVP/MVC nào tùy theo sở thích của bạn. Khi bạn lưu trò chơi, bạn cần lấy một số memento của trạng thái hiện tại

Tôi đề xuất xem xét một số mẫu trên site này và xem có bất kỳ mẫu nào lấy bạn làm điểm xuất phát hay không. Một lần nữa trái tim của hội đồng quản trị trò chơi của bạn sẽ là một máy nhà nước. Hầu hết các trò chơi sẽ đại diện bởi hai tiểu bang trước trò chơi/thiết lập và trò chơi thực tế. Nhưng bạn có thể có nhiều tiểu bang hơn nếu trò chơi bạn đang làm mẫu có một số chế độ chơi khác nhau. Các quốc gia không phải tuần tự, ví dụ: wargame Axis & Battles có một bảng chiến đấu mà người chơi có thể sử dụng để giải quyết các trận đánh. Vì vậy, có ba tiểu bang trước trận đấu, bảng chính, bảng chiến đấu với các trò chơi liên tục chuyển đổi giữa bảng chính và bảng chiến đấu. Tất nhiên trình tự lần lượt cũng có thể được đại diện bởi một máy trạng thái.

5

Nhiều tài liệu tôi có thể tìm thấy trực tuyến là danh sách tài liệu được xuất bản. Phần ấn phẩm của Game Design Patterns có liên kết đến các phiên bản PDF của các bài báo và đề tài. Nhiều người trong số này trông giống như các tài liệu học thuật như Design Patterns for Games. Ngoài ra còn có ít nhất một cuốn sách có sẵn từ Amazon, Patterns in Game Design.

13

Tôi vừa hoàn thành thiết kế và triển khai trò chơi dựa trên trạng thái sử dụng đa hình.

Sử dụng một lớp trừu tượng cơ sở gọi là GamePhase rằng có một phương pháp quan trọng

abstract public GamePhase turn(); 

Điều này có nghĩa là tất cả các đối tượng GamePhase giữ tình trạng hiện tại của trò chơi, và một cuộc gọi đến turn() nhìn vào nhà nước và lợi nhuận hiện tại của nó GamePhase tiếp theo.

Mỗi bê tông GamePhase có các hàm tạo giữ trạng thái trò chơi toàn bộ trạng thái trò chơi. Mỗi phương pháp turn() có một chút quy tắc trò chơi bên trong chúng. Trong khi điều này lan truyền các quy tắc xung quanh, nó giữ các quy tắc liên quan gần nhau. Kết quả cuối cùng của mỗi turn() chỉ là tạo ra GamePhase tiếp theo và chuyển trạng thái đầy đủ sang giai đoạn tiếp theo.

Điều này cho phép turn() trở nên rất linh hoạt. Tùy thuộc vào trò chơi của bạn một trạng thái cụ thể có thể phân nhánh cho nhiều loại giai đoạn khác nhau. Điều này tạo thành một biểu đồ của tất cả các giai đoạn trò chơi.

Ở cấp độ cao nhất mã để lái nó rất đơn giản:

GamePhase state = ...initial phase 
while(true) { 
    // read the state, do some ui work 
    state = state.turn(); 
} 

này là cực kỳ hữu ích như tôi bây giờ có thể dễ dàng tạo ra bất kỳ tiểu bang/giai đoạn của trò chơi để thử nghiệm

Bây giờ để trả lời phần thứ hai của câu hỏi của bạn, điều này hoạt động như thế nào trong nhiều người chơi? Trong một số GamePhase s yêu cầu đầu vào của người dùng, một cuộc gọi từ turn() sẽ yêu cầu PlayerStrategy hiện tại của họ cho trạng thái/giai đoạn hiện tại. Strategy chỉ là giao diện của tất cả các quyết định có thể có mà Player có thể thực hiện. Thiết lập này cũng cho phép Strategy được triển khai với AI!

Cũng Andrew Lên trên nói:

Trò chơi của bạn có lẽ có thể được trong một (gần) số lượng vô hạn của các quốc gia vì sự hoán vị của những thứ như bao nhiêu tiền người chơi A có, bao nhiêu tiền người chơi B có, và vv ... Vì vậy, tôi khá chắc chắn bạn muốn tránh xa các máy nhà nước.

Tôi nghĩ tuyên bố đó rất gây hiểu lầm, trong khi đúng là có rất nhiều trạng thái trò chơi khác nhau, chỉ có một vài giai đoạn trò chơi. Để xử lý ví dụ của mình, tất cả nó sẽ là một tham số số nguyên cho các hàm tạo của lớp bê tông GamePhase s.

Monopoly

Ví dụ về một số GamePhase s sẽ là:

  • GameStarts
  • PlayerRolls
  • PlayerLandsOnProperty (FreeParking, GoToJail, Gò, vv)
  • PlayerTrades
  • PlayerPurchasesProperty
  • PlayerPurchasesHouses
  • PlayerPurchasesHotels
  • PlayerPaysRent
  • PlayerBankrupts
  • (Tất cả Chance và Community Chest thẻ)

Và một số tiểu bang ở cơ sở GamePhase là:

  • Danh sách người chơi
  • Current Player (của những người chuyển)
  • cầu thủ tiền/tài sản
  • Nhà/Khách sạn Properties
  • cầu thủ Vị trí

Và sau đó một số giai đoạn sẽ ghi lại trạng thái của mình khi cần thiết, ví dụ PlayerRolls sẽ ghi số lần người chơi cuộn gấp đôi liên tiếp. Khi chúng tôi rời khỏi giai đoạn PlayerRolls, chúng tôi không quan tâm đến các cuộn liên tiếp nữa.

Rất nhiều giai đoạn có thể được tái sử dụng và liên kết với nhau. Ví dụ: GamePhaseCommunityChestAdvanceToGo sẽ tạo giai đoạn tiếp theo PlayerLandsOnGo với trạng thái hiện tại và trả lại. Trong hàm tạo của PlayerLandsOnGo trình phát hiện tại sẽ được chuyển đến Go và số tiền của chúng sẽ được tăng thêm 200 đô la.

1

Có một số nghệ thuật trước đây mà tôi có thể tận dụng không?

Nếu câu hỏi của bạn không cụ thể về ngôn ngữ hoặc nền tảng. thì tôi khuyên bạn nên xem xét các Mẫu AOP cho Nhà nước, Vật lưu niệm, Lệnh, v.v.

Câu trả lời .NET cho AOP ???

Cũng cố gắng để tìm thấy một số trang web thú vị như http://www.chessbin.com

2

Tôi đồng ý với câu trả lời Pyrolistical và tôi thích cách ông làm việc (tôi chỉ đọc lướt các câu trả lời khác mặc dù).

Thật trùng hợp tôi cũng đã sử dụng đặt tên "GamePhase" của mình. Về cơ bản những gì tôi sẽ làm trong trường hợp của một trò chơi hội đồng quản trị theo lượt là có lớp GameState của bạn có chứa một đối tượng của GamePhase trừu tượng như đã đề cập bởi Pyrolistical.

phép nói rằng các quốc gia trò chơi là:

  1. cuộn
  2. Move
  3. Mua/Đừng mua

Bạn có thể có các lớp thừa kế bê tông cho mỗi tiểu bang . Có các chức năng ảo ít nhất cho:

StartPhase(); 
EndPhase(); 
Action(); 

Trong hàm StartPhase(), bạn có thể đặt tất cả các giá trị ban đầu cho trạng thái, ví dụ như vô hiệu hóa đầu vào của người chơi khác và vv.

Khi cuộn.EndPhase() được gọi sau đó đảm bảo con trỏ GamePhase được đặt ở trạng thái tiếp theo.

phase = new MovePhase(); 
phase.StartPhase(); 

Trong MovePhase :: StartPhase() này bạn có thể đặt chuyển động còn lại của người chơi đang hoạt động sang số tiền được chuyển trong giai đoạn trước.

Bây giờ với thiết kế này tại chỗ bạn có thể sắp xếp ra vấn đề "3 x đôi = tù" của bạn bên trong giai đoạn Roll. Lớp RollPhase có thể xử lý trạng thái riêng của nó. Ví dụ:

GameState state; //Set in constructor. 
Die die;   // Only relevant to the roll phase. 
int doublesRemainingBeforeJail; 
StartPhase() 
{ 
    die = new Die(); 
    doublesRemainingBeforeJail = 3; 
} 

Action() 
{ 
    if(doublesRemainingBeforeJail<=0) 
    { 
     state.phase = new JailPhase(); // JailPhase::StartPhase(){set moves to 0};    
     state.phase.StartPhase(); 
     return; 
    } 

    int die1 = die.Roll(); 
    int die2 = die.Roll(); 

    if(die1 == die2) 
    { 
     --doublesRemainingBeforeJail; 
     state.activePlayer.AddMovesRemaining(die1 + die2); 
     Action(); //Roll again. 
    } 

    state.activePlayer.AddMovesRemaining(die1 + die2); 
    this.EndPhase(); // Continue to moving phase. Player has X moves remaining. 
} 

Tôi khác với Pyrolistical trong đó nên có một giai đoạn cho mọi thứ kể cả khi người chơi truy cập vào ngực cộng đồng hoặc gì đó. Tôi sẽ xử lý tất cả điều này trong MovePhase. Điều này là bởi vì nếu bạn có quá nhiều giai đoạn tuần tự, người chơi sẽ rất có khả năng cảm thấy quá "hướng dẫn". Ví dụ, nếu có một giai đoạn mà người chơi chỉ có thể mua tài sản và sau đó CHỈ mua khách sạn và sau đó CHỈ mua nhà, nó giống như không có tự do. Chỉ cần slam tất cả những phần đó vào một BuyPhase và cung cấp cho người chơi sự tự do để mua bất cứ thứ gì anh ta muốn. Lớp BuyPhase có thể dễ dàng xử lý các giao dịch mua nào là hợp pháp.

Cuối cùng, hãy giải quyết bảng trò chơi. Mặc dù một mảng 2D là tốt tôi muốn khuyên bạn nên có một đồ thị gạch (nơi một gạch là một vị trí trên diễn đàn). Trong trường hợp độc quyền, nó sẽ là một danh sách liên kết gấp đôi. Sau đó, mỗi gạch sẽ có một:

  1. previousTile
  2. nextTile

Vì vậy, nó sẽ dễ dàng hơn nhiều việc phải làm một cái gì đó như:

While(movesRemaining>0) 
    AdvanceTo(currentTile.nextTile); 

Chức năng AdvanceTo thể xử lý bước của bạn bằng cách bước hoạt hình hoặc bất cứ điều gì bạn thích. Và cũng giảm đi các động thái còn lại của khóa học.

RS Lời khuyên của Conley về Mẫu quan sát cho GUI là tốt.

Tôi chưa đăng nhiều trước đây. Hy vọng điều này sẽ giúp một ai đó.

Các vấn đề liên quan