Có hợp lý để viết một công cụ trò chơi bằng C không? [đóng cửa]


53

Mặc dù C ++ có vẻ là vua, nhưng từ những gì tôi đã nói, C vẫn được sử dụng rộng rãi trong các trò chơi, đặc biệt là trên các hệ máy console. Tuy nhiên, việc viết toàn bộ công cụ trò chơi bằng C có hợp lý không? Nếu có, một số lợi thế mà C có trên C ++ là gì? Tại sao ai đó có thể muốn sử dụng C trên C ++?


1
Bảng điều khiển trò chơi sử dụng c ++ FYI!
Alan Wolfe

Tôi thực sự nghĩ rằng C sẽ dễ dàng hơn để viết các trò chơi theo một tỷ lệ nhất định, giả sử hàng chục nghìn LỘC hoặc hơn, chủ yếu vì nó cho phép bạn chỉ tập trung vào các bit và byte mà không cần các loại dữ liệu phức tạp và xây dựng siêu nhanh so với C ++. Nhưng sau một quy mô nhất định (giả sử đạt tới hàng trăm nghìn LỘC), tôi bắt đầu muốn tiếp cận với C ++, nơi tôi thực sự muốn có các kiểu dữ liệu phức tạp, an toàn kiểu hơn, có thể là ngoại lệ, mẫu và thậm chí còn lớn hơn trong scale (giả sử hàng triệu), cho những thứ khác ngoài C ++ để kết hợp với mã C và C ++.

C cũng có thêm lợi thế là có khả năng di động rộng rãi ngay cả đối với ABI, do đó, việc lấy mã C hiện tại của bạn trở nên khá dễ dàng và sau đó bắt đầu sử dụng nó trong các ngôn ngữ khác từ FFI. C ++ khó xử hơn một chút với việc xáo trộn tên, không thể vượt qua ranh giới mô-đun một cách an toàn, các đại diện vtable không giống nhau trên các trình biên dịch, việc triển khai thư viện tiêu chuẩn khác nhau giữa các nhà cung cấp, v.v ... Nói chung tôi thấy các thư viện C tôi viết tồn tại lâu hơn mà không cần thay đổi và đi ra khỏi phong cách, mặc dù phải mất nhiều thời gian hơn để viết bất cứ điều gì quy mô với nó.

Câu trả lời:


49

Tuy nhiên, việc viết toàn bộ công cụ trò chơi bằng C có hợp lý không?

Nó hợp lý, nhưng câu hỏi là nó mua gì cho bạn? Bạn có thể không cần các tính năng C cung cấp tính di động cao và thật đáng tiếc khi từ bỏ tất cả các tính năng mà C ++ cung cấp trừ khi bạn thực sự đặt ra triết lý chống lại nó.

Nếu có, một số lợi thế mà C có trên C ++ là gì?

Thời gian biên dịch tốt hơn?

Tại sao ai đó có thể muốn sử dụng C trên C ++?

Tôi nghĩ rằng đó chủ yếu là một sự lựa chọn thẩm mỹ. Nhiều người thích C vì nó đơn giản và tối thiểu và cảm thấy sạch sẽ. C ++ có rất nhiều tính năng hay (không gian tên một mình làm cho nó đáng sử dụng), nhưng nó cũng lớn và lộn xộn.


3
Cho đến khi Id Tech 4
quang học

9
@Josh: Dễ gỡ lỗi hơn!? Các chương trình C nổi tiếng là khó gỡ lỗi, phần lớn là do con trỏ và quản lý bộ nhớ. Các chương trình C ++ (khi sử dụng các thành ngữ lập trình C ++ thực sự, có xu hướng tránh các con trỏ và quản lý bộ nhớ bất cứ khi nào có thể) là một số thứ tự cường độ dễ dàng hơn để gỡ lỗi.
BlueRaja - Daniel Pflughoeft

14
C có thể được hiểu bởi những người bình thường. C ++ dường như có rất nhiều tính năng và trường hợp cạnh mà các lập trình viên dày dạn tìm hiểu về thậm chí sau một thập kỷ sử dụng nó mỗi ngày để sinh sống.
Jari Komppa

13
C ++ là một ngôn ngữ lớn, nhưng danh tiếng đáng sợ của nó được lan truyền chủ yếu bởi những người vừa đọc truyện kinh dị và không dành thời gian để tìm hiểu nó. Có rất nhiều thứ để học, nhưng bạn nhận được rất nhiều giá trị để đáp lại điều đó. C ++ cho phép bạn thể hiện rất nhiều điều mà C đơn giản là không thể.
khoan hồng

2
@ BlueRaja-DannyPflughoeft #define malloc(x) my_malloc(x) #define free(x) my_free(x)và bạn hiện đang gỡ lỗi bộ nhớ. Với C ++, bạn không bao giờ biết sẽ phân bổ cái gì khi nào, bởi vì có rất nhiều cách để phân bổ bộ nhớ (new, malloc, class constructor, v.v.)
YoYoYonnY

59

Tôi đã làm việc rộng rãi với một công cụ trò chơi thuần C đã xuất xưởng một số sản phẩm, vì vậy điều đó là hoàn toàn có thể. Đây là kinh nghiệm cá nhân của tôi khi làm việc trong cả hai công cụ C vs C ++:

  1. Sử dụng các cấu trúc thuần C cho phép bạn tận dụng kiến ​​thức về sự liên kết của các cấu trúc và sau đó bạn có thể sử dụng thông tin này để xây dựng các lớp liên tục và tuần tự hóa đối tượng của mình. Công cụ mà tôi đã làm việc có một số trình phân tích cú pháp tiêu đề đơn giản sẽ tự động tạo siêu dữ liệu này về các cấu trúc và nó làm cho một số loại hoạt động dữ liệu nhất định trở nên tầm thường. Phân tích cú pháp các tệp tiêu đề C ++ tùy ý về cơ bản là không thể, và ngay khi bạn thêm tính kế thừa và các hàm ảo, bạn sẽ mất khả năng biết chính xác mọi thứ ở đâu trong bộ nhớ
  2. Thời gian biên dịch ngắn hơn đáng kể vì bạn có thể giữ các tệp tiêu đề của mình rất nhỏ gọn và tận dụng các khai báo về cấu trúc chuyển tiếp.
  3. Gỡ lỗi có thể được cải thiện vì không sử dụng các mẫu và kế thừa, rất dễ dàng để tìm ra chính xác một đối tượng nhất định là gì và nó đang làm gì.

Tất cả những lợi ích này cũng có thể đạt được một cách dễ dàng bằng cách sử dụng mã c ++ bị hạn chế không sử dụng các mẫu và kế thừa trên các đối tượng được tuần tự hóa, nhưng quyết định của CTO là sẽ dễ dàng thực thi sự đơn giản hơn nếu các yếu tố khó hiểu hơn của C ++ không có sẵn.

Cá nhân tôi nghĩ rằng điều này hơi cực đoan, vì tôi thực sự đã bỏ lỡ khả năng hoàn toàn khai báo các biến trong các vòng lặp và nhiều cách sử dụng hoàn toàn hợp pháp để kế thừa. Nhưng, nó thực sự không làm chúng ta tốn nhiều năng suất khi kết thúc tất cả những điều được xem xét


5
Thực sự không có gì ngăn cản bạn thực hiện kế thừa trong C. Và nếu bạn sử dụng C99, bạn có thể khai báo các biến trong các vòng lặp.
jsimmons

15
Không đồng ý với điểm 3. Thật dễ dàng để viết mã lộn xộn, khó gỡ lỗi trong C như trong C ++. Gỡ lỗi tốt hơn không phải là thứ vốn có trong ngôn ngữ C.
Dan Olson

7
Ngay cả mã sạch cũng có thể khó hiểu hơn trong C ++ - với tình trạng quá tải, mẫu, hàm ảo và ngoại lệ, khó có thể nhìn nhanh hơn chính xác luồng điều khiển thực tế sẽ là gì.
Kylotan

6
@Dan: Đơn giản là có nhiều thứ hơn, C ++ khó gỡ lỗi hơn. Tất nhiên, bạn có thể hạn chế sử dụng bất kỳ nội dung nào trong số đó, trong trường hợp đó, việc gỡ lỗi dễ dàng như C - vì nó trở thành C.

Ít công cụ hơn thực sự là lý do tôi thích C. Ví dụ, trong CI chỉ có thể sao chép bit và byte xung quanh với memcpybất kỳ thứ gì vì hệ thống loại không cho phép những thứ như sao chép và bộ sao chép. Tôi có thể viết mã khi biết rằng tôi sẽ không phải khôi phục tác dụng phụ ở hầu hết mọi dòng mã đã cho vì tôi không thể thoát khỏi hàm trừ khi tôi hoàn toàn thoát khỏi nó; không có ngoại lệ được ném Tất cả điều này làm cho việc viết cấu trúc dữ liệu trở nên dễ dàng hơn rất nhiều - trong C ++, chỉ cần viết một tiêu chuẩn tuân thủ tiêu chuẩn vectorsẽ rất tốn thời gian, đặc biệt là nếu bạn muốn thực hiện nó ...

18

Tôi đang viết lại một công cụ trò chơi 2D được viết bằng C ++ và Lua thành C và Lua. Cho đến nay kinh nghiệm đã khá tốt. Rõ ràng là thực hiện các hoạt động vectơ và ma trận không có vẻ đẹp trong C. Nhưng ngoài ra, tôi đã tìm thấy trải nghiệm khá mới mẻ sau khi trải qua hơn 10 năm làm nhà phát triển C ++.

C có một số lợi thế so với C ++:

  1. Trình biên dịch sẽ đảm bảo rằng không có mã nào được chạy tại thời điểm khởi tạo tĩnh. Điều đó làm cho nó hoàn toàn an toàn để phân bổ tĩnh dữ liệu toàn cầu như các chuỗi được sử dụng làm khóa, ví dụ
  2. Minh bạch. Trong C gán hoặc phân bổ hoặc xác định một biến sẽ không gây ra vô số mã để chạy. C ++ sẽ tự động tạo các hàm tạo sao chép cho bạn để bạn có ít quyền kiểm soát hơn đối với những gì được thực thi khi thực hiện gán.
  3. Rất nhiều gỡ lỗi có thể thể dễ dàng hơn do không nhận được tên hàm
  4. Sử dụng memcpy trong C thường là ổn , nhưng nó sẽ dễ gây rắc rối trong C ++, vì các hàm tạo sao chép sẽ không được chạy. Cho rằng memcpy nhanh hơn rất nhiều so với std :: copy có vấn đề.

Ngoài ra, có một số lợi thế để đi vào lối suy nghĩ C. Trong C ++, tôi thường thấy mình làm mọi thứ hơi quá mức và trừu tượng. Trong CI thường cắt bỏ những thứ như phương thức get-set và thường phân bổ các mảng có kích thước cố định thay vì sử dụng mảng động. Thường thì tôi kết thúc với mã gỡ lỗi ngắn hơn và dễ dàng hơn trong C. Các cấu trúc dữ liệu thường phẳng hơn và dễ xem hơn trong trình gỡ lỗi.

Công bằng mà nói, tôi sẽ không bao giờ tạo ra một ứng dụng dành riêng cho C. Lý do nó hoạt động mà tôi kết hợp nó với một ngôn ngữ cấp cao hơn như Lua có thể bổ sung cho C rất tốt, vì C không quá mạnh.

Phần mềm id viết hầu hết các công cụ của họ trong CI tin rằng, bạn có thể xem Return to Castle Wolfenstein được viết bằng C.

Tôi đã viết về một số kinh nghiệm của tôi về khả năng mở rộng của C so với C ++nhược điểm của vector STL so với các mảng đơn giản.


11
FYI, trong mọi trường hợp mà tôi đã kiểm tra (đó là, tôi nghĩ, darwin gcc và vc2008), std :: copy sẽ chỉ biên dịch thành một cuộc gọi tới memcpy nếu cả hai loại đều là POD.
Bánh nướng

3
Ngoài ra, vectơ RE: STL so với các mảng đơn giản, tại sao không sử dụng các phần đẹp của vectơ và sử dụng các con trỏ C bình thường thay vì các trình lặp nếu bạn không thích chúng? Bạn chỉ có thể làm & myvector [N]. Nó giống như tốt nhất của cả hai thế giới, giả sử mã C của bạn phân bổ bộ nhớ theo cùng một cách. Hoặc, trong các vòng lặp, hãy xem BOOST_FOREACH. Làm cho nó thậm chí còn đơn giản hơn C.
BRaff

1
Cảm ơn các mẹo về std :: copy memcpy. Tôi không biết điều đó. Khi Alexandrescu đối xử với điều này vài năm trước thì không phải như vậy. Giới thiệu về trình lặp C ++. Chủ yếu là về triết lý, tôi cố gắng lập trình C ++ có nghĩa là chương trình như thế nào vì lợi ích của những người tôi làm việc cùng và tận dụng các tính năng của C ++. Nó chủ yếu được thực hiện để chỉ ra rằng một số cải tiến C ++ như thùng chứa STL không phải lúc nào cũng tốt hơn so với thực hiện theo cách C cũ.
Erik Engheim

7

Như một người khác đã chỉ ra, C ++ mang lại lợi thế cho vai lớn mà bạn có thể đứng (BOOST, STL, v.v.). Cuối cùng, đó là một lựa chọn cá nhân, nhưng tôi sẽ chọn C ++ vì các tài nguyên có sẵn. Nếu có các tính năng trong C ++ mà bạn không muốn sử dụng, thì đừng sử dụng chúng.


1
Lưu ý rằng 99% công cụ trò chơi trong nhà và thương mại tránh xa Boost và STL vì nhiều lý do (đảm bảo hiệu suất, khả năng gỡ lỗi, độ an toàn của luồng, kiểm soát).
Kaj

42
Và 99% số liệu thống kê được tạo thành.
Bánh nướng

Tôi cảm thấy như nó nên là một phần của một quy tắc để trích dẫn tất cả các số liệu thống kê.
Matt Jensen

3

Tôi không nghĩ rằng bất cứ ai sử dụng C độc quyền những ngày này, nó thường được trộn lẫn với một ngôn ngữ cấp cao hơn.

Lập trình trong C có một số lợi ích hơn là, lập trình trong C ++. C ++ có thể làm rất nhiều thứ dưới mui xe mà người dùng không thể nhìn thấy, điều này có thể ảnh hưởng đến hiệu suất nếu bạn không cẩn thận. C ++ có thể cũng là khủng khiếp khi sử dụng bộ đệm, điều này một lần nữa có thể làm giảm hiệu suất của bạn.

Vì vậy, nó có thể mang lại một số lợi ích để viết các phần quan trọng về hiệu năng của trò chơi theo cách giống như C, thay vì theo cách C ++ truyền thống. Tôi chưa bao giờ nghe nói về bất cứ ai, trong những năm gần đây, thực sự viết toàn bộ trò chơi bằng C.

Trên một số nền tảng, như iPhone, sử dụng C ++ có thể tăng kích thước thực thi của bạn với một số kilobyte nhất định (tôi quên mất bao nhiêu, xin lỗi), đó là lý do tại sao một số nhà phát triển iPhone chọn viết mã của họ trong hỗn hợp C và Objective -C.


3

Tôi sẽ cho bạn thêm một vài lý do tại sao việc viết một công cụ trò chơi bằng C thay vì C ++ ngày nay là không hợp lý: STL và BOOST.

Tôi không thể tưởng tượng nó sẽ đáng viết như thế nào listkhi thực hiện một cách triển khai khác khi bạn có thể dựa vào mã hoạt động ngoài hộp (và bạn không phải viết!)


1
Có bất kỳ studio lớn thực sự sử dụng boost? Ngay cả việc sử dụng STL vẫn còn đang được tranh luận, vì tính di động. Ít nhất là cho động cơ console.
sledlime

2
Cá nhân, tôi đang sử dụng Boost.FeftTypes cho tương tác c ++ / lua (xem gamedev.net/reference/programming/features/CPPLuaExport/, ) và thư viện số ngẫu nhiên Boost để tạo số ngẫu nhiên thống nhất (cho các hệ thống hạt). Ngoài ra, Boost.Foreach là gọn gàng. BTW, ai quan tâm nếu các hãng phim lớn không sử dụng BOOST? Họ có nhân lực để viết thư viện STL của riêng họ từ đầu, tôi thì không.
Loris

1
Vâng nhưng cũng nhận ra rằng có thư viện tương tự cho C là tốt.
jsimmons

2
Nhiều người sử dụng boost trong game, tôi tin thế. Nhưng đó là một yêu cầu (hoặc thậm chí là mong muốn) đối với nhiều người trong chúng ta.
Dan Olson

6
Mọi người, những gì bạn tin là không liên quan: hoặc bạn biết hoặc bạn không biết .
o0 '.

3

Viết một công cụ trò chơi bằng C là hợp lý. Nó nhanh và có thể được chuyển đến nhiều hệ thống. Ví dụ: bạn có thể sử dụng cho Android (với việc sử dụng NDK). Bạn có thể sử dụng nó cho iPhone (Objective c chỉ là phần mở rộng của c). Bạn cũng có thể sử dụng nó cho và cho hệ điều hành chính như Linux, Mac hoặc Windows. Nếu bạn cảm thấy thoải mái với c, tôi khuyên bạn nên thử!


2

Tất nhiên là hợp lý. Cá nhân tôi sẽ không làm điều đó và hầu hết những người hâm mộ C mà tôi biết thực sự chỉ viết mã giống như C trong các tệp .cpp. Nhưng các ngôn ngữ tương tự nhau đến mức không thực sự quan trọng.

Về lý do tại sao một người nào đó sẽ chọn làm điều này, tôi nghĩ rằng chủ yếu dựa vào triết lý chống C ++. Cá nhân tôi vẫn không nghĩ rằng đây là một lý do chính đáng để chọn C thay vì "C-style C ++". typedef struct craziness là một lý do đủ tốt để tránh xa C, và có một số người khác.

Thật không may, C và C ++ đều là những ngôn ngữ khá khủng khiếp khi chúng ta tiếp cận nó. Đó là một lý do mọi người đã cố gắng thực hiện nhiều mã của họ trong kịch bản trong những năm gần đây.

Nếu bạn đang tìm kiếm ví dụ về những người làm việc trong C, bạn có thể bỏ qua id khi tôi nhớ lại rằng họ đã bỏ rơi C từ lâu. Cryptic Studios (Star Trek Online) thực hiện tất cả sự phát triển động cơ của họ bằng C. Theo như tôi có thể nói, vâng, đó là vì triết lý nhiều hơn là vì bất kỳ lợi thế hữu hình nào.


0

Có và không. Có tôi đã thực hiện được vài năm trước nhưng tôi cần trò chơi của mình chạy 3D trên máy chủ từ xa 64 bit unix (không phải linux) với các trình phát trên các thiết bị đầu cuối câm. Đó là không tầm thường. C có thể tốt là bạn muốn tích hợp LUA nhưng cuối cùng tôi đã có lua để làm việc trong C ++ vì vậy tôi sẽ nói có, điều đó là có thể nhưng đừng làm điều đó.


0

Có thể một câu trả lời tốt có thể là "sử dụng cả hai"?

Như tôi nghe nói rằng các dự án panda3d có thể được tối ưu hóa, tiêu diệt nút cổ chai bằng cách sử dụng một số cython hoặc hoặc mã hóa lại các phần đó.

Hầu hết thời gian, các phần cần được tối ưu hóa là phần có nhiều lần lặp và lồng hoặc có nhiều tính toán số, do đó, tôi đoán rằng một thỏa hiệp hợp lý sẽ là sử dụng cả hai ngôn ngữ, sử dụng C đối với các phần bao gồm nhiều chương trình cấp thấp, do đó bạn không thể sử dụng sai ngôn ngữ C ++ cho phần cần tốc độ và C ++ cho phần còn lại của trò chơi.

Lý tưởng nhất là bạn thực hiện phần nhanh của động cơ với mức độ cao trong tâm trí, và sau đó sử dụng ngôn ngữ kịch bản hoặc C ++ sẽ sử dụng các vòng lặp / vòng lặp ít hơn nhiều.

Tất nhiên, bạn không bao giờ có thể tạo ra một công cụ như vậy phù hợp với tất cả các nhà phát triển trò chơi sẽ cần phải làm, ngoại trừ nếu bạn dành công cụ của mình cho một loại trò chơi đặc biệt ...

Nhưng đừng chấp nhận lời khuyên của tôi vì tôi không phải là nhà phát triển trò chơi có kinh nghiệm cũng không phải là nhà phát triển có kinh nghiệm ... Tôi nghĩ C buộc bạn phải viết mã nhanh, trong khi viết mã C ++ tốt và nhanh cho một dự án lớn như trò chơi là một điều khác biệt ...


0

C làm việc cho John Carmack , bạn có thể nhận được rất nhiều lợi thế bằng cách sử dụng C, nhưng cho đến khi bạn đến đó để hưởng lợi từ họ, điều đó có thể khiến bạn mất một thời gian.

Tại đây bạn có thể tìm thấy một danh sách các công cụ trò chơi, một số trong số chúng được viết bằng C, có thể bạn có thể hiểu một số cách hiểu về cách thực hiện công cụ trò chơi C bằng cách duyệt qua mã nguồn của chúng.


0

Mã C thường là mã C ++ hợp lệ.

Các vấn đề chính với C ++ là sử dụng nó không chính xác ( Linus Torvalds ghét nó vì lý do này , anh ta cũng có một số vấn đề khác với tính di động của thư viện và vì vậy, anh ta đang làm việc ở cấp hệ điều hành và phải chạy mọi thứ một cách ngẫu nhiên chip ngoài đó).

Ví dụ, hầu như không có lợi thế nào khi sử dụng mảng cstyle [] so với c ++ std :: vector <> (hoặc container tương tự).

Các vectơ là loại an toàn và có thể được kiểm tra giới hạn (bạn có thể truy cập các phần tử bằng cách sử dụng get () hoặc [], ngay cả khi bạn không sử dụng phương thức kiểm tra mảng, bạn vẫn có thể truy vấn kích thước thay vì đặt xung quanh nó bằng con trỏ).

Nhưng vectơ có thể thể chậm hơn nếu, chẳng hạn, bạn không khai báo kích thước mặc định trong hàm tạo. Ngoài ra, việc thêm mọi thứ vào một vectơ có thể gây ra sự chậm lại nếu sau đó nó cần thay đổi kích thước. C ++ 11 cũng bổ sung nhiều lợi thế như khởi tạo thống nhất (bây giờ bạn có thể khai báo và khởi tạo vectơ bằng cùng một cú pháp) và có các hàm tạo di chuyển có thể cho phép bạn tránh sao chép. Bạn thậm chí có thể tạo các trình khởi tạo tùy chỉnh của riêng bạn (nếu bạn muốn làm một cái gì đó ngoài việc sử dụng malloc vì một số lý do).

Hoặc tất nhiên nếu bạn cần thay đổi kích thước mọi thứ, thì vectơ vẫn dễ thực hiện hơn, bạn không phải loay hoay với malloc, sao chép thủ công mọi thứ, v.v.

C ++ cung cấp cho bạn mã hướng đối tượng. Khi được biên dịch, nó sẽ hoạt động hiệu quả vì nó thực sự chỉ là một sự trừu tượng đối với con người làm việc với mã. Mặc dù những thứ như các nhà xây dựng có thể làm chậm việc tạo đối tượng. Nhưng bạn sẽ cần hàm tạo để đặt các giá trị mặc định hoặc nếu không bạn có thể khởi tạo các đối tượng mà không cần sử dụng hàm tạo (bằng cách bỏ đi () 's).

Nhưng định hướng đối tượng làm cho trò chơi lập trình dễ dàng hơn nhiều . Trò chơi thường đối phó với các đối 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.