Jump to content
  • Advertisement

Ansou

Member
  • Content Count

    29
  • Joined

  • Last visited

Everything posted by Ansou

  1. Ansou

    C++ Text Adventure Design

    I would recommend doing a more data driven approach, where you store your areas in files. This doesn't directly solve the problem with special functionality for each area, but it makes your code less messy. For the actual problem at hand, you could define requirements for each option in terms of variables that need to be set. If you go for the data driven approach, you could have a map that stores the variables in code, and refer to the variables via strings in the level files. Not sure if this would work for exactly every special functionality, but it could be a good way to generalize some of it anyway.
  2. Your code looks right. The code that is relevant for this particular can be condensed to: SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_CONTROLLERDEVICEADDED: { std::cout << "Controller device added." << std::endl; if (SDL_IsGameController(event.cdevice.which)) { auto controller = SDL_GameControllerOpen(event.cdevice.which); std::cout << "Controller device name = " << SDL_GameControllerName(gamepad.controller) << std::endl; } break; } } } This should still reproduce the same problem. If it does, I suggest that you report this as a bug in SDL.
  3. Ansou

    I want to try Unity

    Unity is not a library, it is a full on game engine. If you're using Unity, you're playing by Unity's rules. Don't expect to have full control over it. If you want to have full control over the system, you need to use your own game engine. Obviously using a custom engine means (probably a lot) more work and losing out on a lot of convenient tools that Unity and Unreal has, but it also has some benefits.
  4. Ansou

    Questions about Error-Handling

    This is well covered in the error handling chapter of Bjarne Stroustrop's book The C++ Programming Language. It's a very good book and I recommend that you read it. To give a short and general answer: Use exceptions whenever an error occurs. That is, whenever something that is not supposed to happen happens. Or what Stroustrup says: When something "exceptional" occurs (something out of the ordinary, could be things other than errors). Using exceptions instead ensures that things can't be left in an invalid state and it automatically destroys every object in the same scope as the exception occurs (very good for resource managment). It also leaves you without the hassle of having to check return values all the time (this is what I don't like about programming in SDL).   So what exactly does 'reject' mean here? Just continue as if nothing wrong happened? It definitely makes sense to throw an exception in this context, unless you have a valid answer to a zero division in the same scope as it occurs in. If an error can only occur because the programmer obviously did something wrong, then yeah, using asserts instead makes sense. A good way to know how you should do error handling is to think to yourself for every error that occurs: What is supposed to happen when this error occurs? Does this function know what should happen? Should the caller of the function decide what will happen? Should the program just crash? Exceptions can't and shouldn't be used all of the time, but if the place the error occurs in doesn't know what should happen, throwing an exception is usually a good way to handle it. Also, don't use try/catch everywhere, not every exception is meant to be caught by every part of the program.
  5. This. Why does it seem like no one has even heard about std::chrono? It feels like I've been repeating myself about it in a couple of threads about time. Yeah, std::chrono::high_resolution_clock uses QPC internally to access time on newer Windows compilers at least. But the plus side is that you won't have to bother with calls to the Windows API and it's very easy to use.
  6. Yeah, considering that it's in the standard library, I would say that it's at least relevant. If it's fast and reliable... Well, it should be, but it's up to the implementation really. On newer Windows compilers, std::chrono::high_resolution_clock is using QueryPerformanceCounter to access time. AFAIK, that's what most other libraries seem to use as well, but with different resolution. std::chrono_high_resolution_clock is supposed to use the highest resolution your machine will give you, so there won't be anything more precise. The really good things about it is that it's completely portable as it's in the standard library and it makes your code look very clean.
  7. First and foremost, I would recommend using std::chrono instead of SDL_GetTicks() as it is more accurate, more portable and it's very easy to convert between different time measures (you could do a type alias for seconds: using Seconds = std::chrono::duration<double, std::ratio<1>>; and then implicitly convert to it from nanoseconds). However, SDL_GetTicks() should still be pretty reliable so it's definitely weird if it would slow down... What framerate do you mean with "very high FPS"? SDL_GetTicks() only returns milliseconds, so if your framerate is around or higher than 1000 I could imagine it being very inaccurate (std::chrono::high_resolution_clock::now returns nanoseconds or the smallest unit your computer can handle). If that is not the cause of the problem, it could be helpful to see a bit of the code that relies on SDL_GetTicks() and maybe parts of your main game loop.
  8. Ansou

    Timer class abstracted

    Have never used the Windows API so I can't give a helpful answer to your actual question, but is there a particular reason why you can't just use std::chrono to keep track of time? Seems like it would save you the work of making different Timer implementations for different platforms.
  9. Ansou

    How to start making games?!

    SDL2 is pretty nice because it provides enough functionality to do pretty much anything you will need, it gives you a lot of control over what you're doing and it's very stable. The problem is that its C syntax doesn't exactly encourage you to write clean and modern C++ code, which means you may have to abstract and make more wrappers, and it also probably has less high-level functionality than some other libs. I did try SFML once earlier and it seemed good for the most part, but because it had some small bugs that I didn't like, I decided to go with SDL2 instead. But they may have fixed those bugs by now, so it could be worth trying.
  10. Well you could always keep a raw pointer or reference to the sprite that you pass to scheduleUpdate.   Something like this: auto spaceship = sprite_sheet_->getSprite("spaceship"); //this returns a unique_ptr // code to intialize spaceship... auto& spaceshipRef = *spaceship.get(); this->addActor( std::move(spaceship) ); // "this" here is a scene this->scheduleUpdate(spaceshipRef , [&](const Actor& actor, float dt) { actor.updateShip(dt); //or whatever } ); It seems like a somewhat decent solution as long as you manage ownership correctly, although I can't say if it's the best solution or not.   We don't know exactly what the getSprite function does though, but if it's not intended to transfer ownership, then you are completely right. Interfaces shouldn't be bloated with smart pointers if the call is not about ownership. But I got the impression that jwezorek wanted the ownership to transfer into the addActor function.
  11. Ansou

    How to start making games?!

    As Lactose said, you really just have to decide what you want to happen in your games and make it happen. Make a basic game loop that handles game objects. Make different objects that has functions for handling logic and interaction between the objects and functions for rendering and just experiment around with making the objects behave in different ways. Start simple and then try something bigger. Once you have gotten into it a bit more, I would definitely recommend reading the book Game Programming Patterns as it can help a quite a bit with getting better structure and design of your game code, although it doesn't focus on teaching the basics of programming game behaviour. Good luck!
  12. I agree that you should keep pixels out of almost all of your code and use another unit, like meters. But to be able to upscale/downscale the images correctly when rendering, you still need to tell the game somewhere which width and height the images were made for, right? Say if a sprite is supposed to cover a meter, then you would need to have a constant or something somewhere in the code that holds how many source pixels a meter is. But for positioning, collision detection and all other game logic, you don't need to know anything about what resolution the images were designed for, you only need to know that when rendering.
  13. Some people still have only one display??   Many people have multiple displays, but isn't it pretty uncommon to play 2D games on more than one display? At least I haven't seen that much, but maybe I'm a bit behind.   EDIT: Having support for multiple displays is great if you go with the option of extending the field of view depending on resolution, but otherwise I don't see a point adjusting to multiple displays. Except for an in-game option to set which display to show the game on of course.
  14. This is a dilemma I've thought way too much about, and the problem is that there is no defined right or wrong. I'm pretty sure that 16:9 is the most common aspect ratio nowadays, so that is what I would recommend to design your game for. Also, for the game I'm currently working on, we decided to make the sprites for 4k (3840 × 2160) resolution because it might become more popular in the coming years, and downscaling usually looks better than upscaling. But if you're doing retro-style graphics, I guess it would be kinda the reversed.   Aside from black bars/frames and letting the player see a different portion of the world depending on resolution, there is also the option of stretching the image to fit the screen. If you decide to fit the game to a specific resolution, you could even let the player choose if they want black bars or stretched images in the options (would probably default to black bars).   In most cases you won't have to worry too much as most players will probably be playing on a 16:9 display and it's totally fine to assume that imo, but making the decision of ensuring that all players see the same portion or not is obvously important as it can affect gameplay (depending on the type of game).
  15. So I get that passing references to unique_ptr's isn't very good. But what about passing collections (say a vector) of unique_ptrs? If I have objects stored in a vector as smart pointers, wouldn't it be problematic to have to make a new vector with raw pointers just to pass the vector to a function?
  16. I'm trying to setup CMake in my project's Git repository so that anyone working on the project can just double click a batch file or something to build the game and then run the generated executable. I guess that they would have to install a compiler and CMake to be able to build the project, but I would prefer it to be as simple as possible to set everything up for every user. I'm currently the only programmer in the team, the rest are artists and designers.   The problem I'm having right now is with linking to the libraries. The game uses SDL2 and its modules image, ttf and mixer. It also uses Boost right now, but I will probably get rid of it once filesystems are introduced in the standard library in C++17.   A thing that confuses me is dynamic and static linking. I understand that Linux makes it easy to use dynamic linking, but I'm working on Windows where there is no standard directory for libraries such as SDL and I don't really know where to put the SDL files. Should I put them in a library folder in the repository to make sure that everyone has acess to the libraries? But the question then is: would that make it so that I'm using static linking instead of dynamic linking and is that a bad idea? And how do I tell CMake where to look?   Linking to libraries wasn't really a problem when I was just working on my local drive in Visual Studio, but since I want to share the project with my team now it feels a lot more confusing.
  17. Thanks for the tips! I know absolutely no Python right now, but I guess it's almost inevitable that I would learn it someday... But I think that will have to wait a little while. We'll see what I do to actually generate the executables. I just discovered the wonderful support that Visual Studio 2017 has for CMake, although that's more fore programming rather than building. Also, out-of-source builds was apparently what I had already been doing, so I'm fine on that at least.
  18.   Sorry if I was being unclear! I never intended to actually store any of the built files on Git. My plan is to set up a batch file (or two as I guess unix needs its own version) that can easily be run to generate the exe file with CMake. The exe file will be generated inside the Git folders, but I will make sure that Git ignores all files in the build directory so it won't take up any space on the repository. Each user will have to run the batch file if they want an up-to-date build.   Regarding art assets and other binary data, I had come to the conclusion that Git could handle that fairly well with LFS. I was also thinking of just storing the work files (like .psd) in the repository and have a script generate the sprite sheets and such from them into the build directory. It just seemed like Git was the best option when I was looking at different version control systems and I would prefer to store assets at the same place as the code. Now the only problem I see with Git is that it doesn't provide file locking, which may or may not become a problem... And of course it can't merge the binary files, but that's just something we have to live with for now.
  19. Thanks for the helpful replies! I will put the libraries in the repository then and link to them in the way that Zipster suggested. Not completely sure about where to put the exe yet, will look more into it. We'll see if we will use virtual drives for development. Probably not right now, maybe later if we decide that it would be useful.   I guess I was also a bit worried about how linking would work when doing installation for the end user, but there will be a couple of years before that will be relevant for us anyway and installers are a whole issue on its own, so I'll worry about it when that time comes.
  20. I have a pretty clear understanding of how pointers, smart pointers and references work, but I'm having a really hard time wrapping my head around when I should use each of them. I've googled it a bit, but I still feel that I need some more clarity.   I very recently started using smart pointers and had been using raw pointers for most things before. Now I understand that I should avoid raw pointers whenever I'm not forced to it by the API I'm using (I'm programming against SDL, which uses raw pointers for its own types). So now I'm trying to figure out when to use references, when to use unique_ptr, when to use shared_ptr and when to use weak_ptr. I'm also not very sure about when to create new objects on the heap and when to create them on the stack/static space, although I feel that I'm starting to understand that better now. I come from Java, where I didn't really have to think about any of this.   I guess I'll try to give some concrete examples of situations in which I am unsure.   Passing to a function that won't store the object Let's say that I have have a member function of a collider class like this: double BoxCollider::getXCollision(Collider & collider) { //First check which type of Collider the argument is (BoxCollider or CircleCollider). Should I use dynamic_cast for this? Seems a bit tricky on references. //Check if and how much the two colliders } Should I be using a reference here? As it is right now, each game object has a unique_ptr to its own collider, which is allocated on the heap before the game object is created. Is it a good idea to use references to objects that are heap allocated and stored as a unique_ptr? My question here is: should I ALWAYS use references as arguments to functions that will process the argument but not store it, if I expect it to not be null (although I can never guarantee it to not be null)? Or are there times when I should use some kind of pointer for this? Passing unique_ptr's are obviously not possible. Also, in this particular case, I need to check if the collider is a CircleCollider or a BoxCollider, which seems more tricky on references than on pointers. Should I still use a reference and use a nestled try/catch instead of a if/else to check the type?   Passing to a function or constructor that will store the object Let's take a look at my GameObject constructor: GameObject::GameObject(double xPosition, double yPosition, std::unique_ptr<GraphicsComponent> graphics, std::unique_ptr<PhysicsComponent> physics, std::unique_ptr<InputComponent> input) : graphics{ std::move(graphics) }, physics{ std::move(physics) }, input{ std::move(input) }, xPosition{ xPosition }, yPosition{ yPosition } { } As you can see, I'm using the component pattern for GraphicsComponent, PhysicsComponent and InputComponent. Right now I'm using unique_ptr to refer to them as they are all constructed on the heap before they are sent to GameObject's constructor. Does this make sense?   I have another example: GameObject has a function called setWorld that tells the GameObject which world it is in. Currently that function takes in a weak_ptr because I don't want the GameObject to own the world as that could cause problems. void GameObject::setWorld(std::weak_ptr<World> world) { this->world = world; } I realized though that the only thing that should own the World object is my main Game object, so would it make more sense to use a unique_ptr to store it in the Game class and a reference to store it in the GameObject class? Or should I even store World as a plain object in Game as the world is loaded in Game? Like this: class Game { public: Game() ~Game() //Other stuff private: World world; } How do I know if I want to store something as a pointer, as a reference or as a plain object?   I was sure that there were something else regarding references that I was uncertain about, but maybe my brain sorted it out. I'll write it here if I come up with more questions. Would be thankful for any help and clarification!  
  21. Thanks for the helpful answers!   When I was reading about smart pointers I got the impression that good practice was to avoid raw pointers like the plague, but I guess I don't have to be too afraid to use them as long as I never use the new or delete keywords (and make sure to check so that they are not null when necessary). Another mental problem that I have is that I have some kind of obsession with wanting to make things thread safe when I really shouldn't have to worry about it... The game that I'm making currently only runs on one thread, but for some reason I still obsess over the possibility that a reference would suddenly become invalid in the middle of using it. Guess I'll just have to stop worrying and instead think about it for the specific codes that need thread safety if/when I decide to use multiple threads.     It did feel like pretty bad design, but I really didn't know how to do it in a better way... I didn't know about the visitor pattern before, but I'll try it out!   I think you misunderstood what I meant here. I meant that I would store the World object as a plain object in Game, created on the stack, instead of a unique_ptr. Then I would pass references of that object to the GameObjects. But since they will be stored I guess I'll use raw pointers in GameObject instead of references. Although the game objects should never outlive the world anyway so it technically shouldn't matter if they store a pointer or a reference. Or I'll try to come up with a way (not involving static/global) to not store a pointer/reference in the GameObject class, but that could result in very cluttered parameter passing...
  22. Just got back to this community after a long period of inactivity!
  23. Ansou

    Slow mouse position

    Oh nvm, I just realized that letting the thread sleep for 20 ms helped... Thank you and sorry for bothering!
  24. Hey everyone! I have a problem when I try to get the position of my cursor. I have a full screen JFrame and I have active rendering with a continously running for loop. In the loop I try to draw a rectangle at the position of the mouse with getMousePosition, but when I move the mouse the rectangle comes after. The cursor is moving exactly like it should, but the rectangle moves really slow. I have around 60 FPS.
  25. Ansou

    Slow mouse position

    Here is the full code for the "game": [source lang="java"]import java.awt.Color; import java.awt.Graphics; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.image.BufferStrategy; import javax.swing.JFrame; public class GameFrame extends JFrame { private static final long serialVersionUID = 1L; private GraphicsEnvironment ge; private GraphicsDevice gd; private BufferStrategy buffer; private boolean running; //Set the game to full screen and start it public static void main(String[] args) { GameFrame game = new GameFrame(); game.setFullScreen(); game.start(); } //Constructor public GameFrame() { super("Game Test"); setDefaultCloseOperation(EXIT_ON_CLOSE); ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); gd = ge.getDefaultScreenDevice(); //the game will stop running if escape is pressed addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent event) { if(event.getKeyCode() == KeyEvent.VK_ESCAPE) { running = false; } } }); } //Make the game full screen and create a buffer strategy public void setFullScreen() { setUndecorated(true); setIgnoreRepaint(true); setResizable(false); gd.setFullScreenWindow(this); createBufferStrategy(2); buffer = getBufferStrategy(); } //Main loop is here public void start() { Graphics g = null; running = true; while(running) { try { g = buffer.getDrawGraphics(); g.clearRect(0, 0, getWidth(), getHeight()); g.setColor(Color.RED); g.fillRect(getMousePosition().x, getMousePosition().y, 20, 20); if(!buffer.contentsLost()) { buffer.show(); } } finally { if(g != null) { g.dispose(); } } } System.exit(0); } }[/source] lwjgl and Slick2D is programmed in Java, right? So there has to be some way to do it properly.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!