Jump to content

Best C Library for 2D Games?


MDZhB

Recommended Posts

I'm not super experienced in C, so I've decided to write a project I've been wanting to do for a while in C. It's going to be a bullet shooter engine, which can interpret different scripts to make any number of unique games. Think RPG maker but for bullet shooters. Anyway, I want the finished product to look something like this:

484680-ms_7.jpg

Nothing too fancy, just a bunch of 2D sprites, animations, and hitboxes, as well as some info on the side somewhere. I've figured out the logic of the main game loop, and it's all stuff I've done before, so the only challenge with that will be C syntax itself.

Unfortunately, I have almost no experience in graphics programming. I want it to be cross-platform, so I've done some research, and it looks like OpenGL and SDL are good candidates. I'm leaning towards SDL, because I have no need for 3D and I don't mind working at a lower level.

However, I wanted to see if anyone has any experience or recommendations on these two or anything else. So, in general, what is a good C library for creating 2D games?

Link to comment
Share on other sites

sdl just gives you a put pixel function iirc. but it gives you everything else you need to make a game (sound, input, etc). id go with opengl and sdl (you kind of have to since sdl provides you a gl canvas that opengl can render to).  i used both libs in my c++ game engine that never really got past the line draw phase and a lua version that has textures. map your sprites to polys and you can render them in any orientation and use the z axis to handle sprite render order, you also have access to fast alpha blending for weapon effects (its actually how i handle my 2d elements). of course my knowledge of opengl doesn't really go past old legacy versions where you dont even have shaders (like my lua engine only uses opengl 1.3 and i get my rendering context from iup rather than sdl). 

you might also want a bitmap library, but i like to use tga bitmaps since the format is just an 18 byte header and the rest is pixels. you just load the file, read the first 18 bytes to get the bbp and image size and load the pixels into a dynamic array (malloc). if you use opengl compressed textures become an option but i think for a 2d game id want uncompressed images. 

Edited by Nuke
Link to comment
Share on other sites

You mean for the graphics (1) or for the event handling (2) ?

For (1) there are OpenGL, Vulkan and DirectX. The first two are platform independent Windows and Linux/Unix.

For (2), to make the event handling platform independent, there is sdl (overpowered imo) or glfw3 (i like it, lean and yet encompassing everything), glut or its successor freeglut (outdated) and many others. I think boost and qt offer these tings too, but i do not know. If you combine glfw and opengl you even have a default framebuffer for the first tries until it gets to more sophisticated applications, like multipass rendering, transform feedback, etc ....

If you are planning only for one platform, then i'd use the functionality of that. For linux that'll be xcb or xlib and probably others. For mobile, have a look at Vulkan examples e.g. from Pavel Lapinsky or Sascha Willems.

Do you know gamedev.net ?

Edited by Green Baron
Link to comment
Share on other sites

I must say, i am only doing this since a year or so, learned and learning C++, graphics programming, made the mistake of trying to get behind Vulkan (well, i dug the basics) or analyzing other peoples code, which doesn't help me at all. And i have other things to do. What i want to say is that i am not a knowledgeable person. That's why i mentioned to gamedev.

:-)

Link to comment
Share on other sites

AFAIK you should only use libraries that contains what you want to use. (you can even write your own library, C++ allows this.)

For what functions that should be there... well, I never managed to have a windowed GUI on my programs... and I've only read stuff off this site !

Link to comment
Share on other sites

If you want to do C, just do OpenGL, honestly. It has C bindings, and while it can do fancy stuff with extensions, you don't have to dive head-deep. You can do easy 2D stuff with minimal setup.

C++20 might get standardized 2D graphics via io2d library. There is a proposal for it, but it's in a very uncertain state at the moment. That said, if you want to take a deep dive into the world of modern C++, three is a reference implementation of io2d that you can use in your engine and replace with standard C++ if and when that gets released.

Edit: Looks like graphics TS has been deferred, meaning definitely not C++20. They're still working on it, so it still has a chance of being a C++23 or later feature. The reference implementation is still maintained, however, so the option of using it in your project is open.

Edited by K^2
Link to comment
Share on other sites

1 hour ago, YNM said:

AFAIK you should only use libraries that contains what you want to use. (you can even write your own library, C++ allows this.)

For what functions that should be there... well, I never managed to have a windowed GUI on my programs... and I've only read stuff off this site !

the only gui library ive ever been able to use is iup. its mostly for lua but i do believe you can use it in c/++. 

Link to comment
Share on other sites

I can recommend Dear Imgui for guis. It is not hard to understand and fast as lightning, there are wrappers for Vulkan, OpenGL and DirectX that come with it. But it is C++. Which you will, one C gets boring in a few months, switch to anyway because it makes some things so much easier.

The look is like this:
  mCzy4kal.png

 

Edited by Green Baron
Link to comment
Share on other sites

Ok, so I've done some more research (taking cues from your replies :)) and it looks like I was a bit confused about what I need. I'll use OpenGL for graphics, and SDL for window handling and input/output. So far I've actually got the beginning of the game logic running in python with plain ASCII, and it looks good so far:

5ine84.PNG

(It's shooting three sets of concentric circles, one slow dense set in the center, and two faster, sparser sets on the sides.)

16 minutes ago, Green Baron said:

Which you will, one C gets boring in a few months, switch to anyway because it makes some things so much easier. 

One of my primary interests is low level programming. One of the most fun things I've ever written was an ATAPI driver in 32 bit assembly, running on raw hardware. Trust me, I don't need it to be easy. :wink:

Anyway, I'm going to go make myself an egg for brainfood, and then I'm going to start reading through documentation.

Link to comment
Share on other sites

if you want to get really low level get you an arduino and one of those ili9341 lcd screens. you have all kinds of bandwidth constraints do to the spi interface so you have to do a lot of sprite swapping with the background to keep things fluid. not to mention a lot less memory, a lot less storage, and a rather sluggish cpu. 

Link to comment
Share on other sites

23 hours ago, MDZhB said:

One of my primary interests is low level programming. One of the most fun things I've ever written was an ATAPI driver in 32 bit assembly, running on raw hardware. Trust me, I don't need it to be easy.

On smaller projects, it's sometimes fun to do things the most challenging way. But it rarely pays off on larger ones. Just because you can make headway with the wrong tool, doesn't mean you should if you can get more done with less time spent.

In this particular case, you can probably write the whole thing in C and not have to sacrifice much. Although, you will probably already be writing hacks. I used to work in a game studio that had an in-house C engine. One of the things that stuck in my mind is the way UI widgets worked. There was a struct Widget. And then a UI component that was also a widget, would include it.

struct Button
{
	struct Widget widget;
	// ...
};

Now you can pass pointer to Button to a generic function that handles any Widget by simply type-casting the pointer. Yes, that is basically an inherited member function call implemented entirely in C. (Indeed, that's how inheritance actually works in C++) The peak of insanity was character movement code, however, which had something not entirely unlike virtual functions implemented for different movement types.

Back when that code base was started, about 15 years ago, there was a very good reason to stick with C. C++03 was a new thing back then, and even with these improvements, it was a clunky language that took forever to compile and brought loss of performance with it. If you wanted a high performance engine that was easy to work with, you wrote it in C. At least, the heavily used portions. But C++ isn't the same anymore. Compilers and optimizers got a lot better, and the standard enforces many good practices. Today, if you are finding yourself hacking in inheritance, virtuals, lambdas, or templates into C code, it's a sure sign that you should be writing in C++.

Big part of working with the write language is not whether it makes it easier to solve problems or not. Where it really counts is when you have to revisit code you wrote months back. C code gets really hard to follow once it gets sufficiently complex. C++ can get worse if you write bad code, but it gives you many opportunities to make it very easy to follow if you do it right.

Edited by K^2
Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...