MarcusAseth

Making Breakout - Code Structure help requested

Recommended Posts

MarcusAseth    69
I'm following the list of games a begginner should make suggested by Alpha_ProgDes and I'm about to start making Breakout, though this time I'll go the hardcore way with C++ & SDL instead of Unreal Engine.
I'll figure out  how to write the classes and make it work, though I wanted to ask you guys about what I will need to make and how it should be organized, so that I have a clear roadmap that I can breeze trough step by step, without hitting any dead ends :D
So this are my initial thoughts:
●I will need a "Timer" class which keeps track of ms since last frame
●I will need a "Game" class which has a Timer and takes care of initializing the SDL_Window and SDL_Renderer, also with a destructor that takes care to destroy them.
●I will need a "TextureManager" class which containst a map<string, Texture*> to which I can ask for a texture by its name from within other classes, so pretty much every Actor (taking unreal naming for semplicity here) need to include this "TextureManager". Also texture manager destructor takes care of destroying all the textures.
●I need a base Actor class which will contain member variables x,y centered pivot coordinates for the actor sprite, SDL_Rect for the sprite position/size and a Texture* for the sprite, also virtual draw() and virtual update() methods
Well that all I can think for now, I don't have a very clear idea for how the input handling should be done, is just like a super giant switch inside the game loop, or it is like a class "InputManager" that keep track of which actor is interested in which key input and forward the inputs to the approriete actors or... mh... no idea really how it should be done :S
So, whatever feedback or suggestion or "Structure Roadmap" you can present me to put me on the right tracks, is very welcome! :P 
I only need knowledge of a reasonably correct structure and I will fill in the blanks :)

 

Edited by MarcusAseth

Share this post


Link to post
Share on other sites
Kylotan    10008

My first suggestion is that you don't need to have a list of classes up-front. If we tried to do that for AAA games we'd never start coding.

My other comments:

  • I like to have a separate App class which contains a Game class. Game is for, well, gamey things. I'd create the window and other input/output in the App, as well as an instance of the Game.
  • Actors shouldn't need TextureManagers. There's no part of 'acting' that needs to look up textures. If you want Actors to be responsible for drawing themselves, that's fine (at least at this level), but you should pass in the texture to use in each case.
  • Input handling for a game like this can stay simple. I'd start with a function that is called from the main loop, with the paddle passed in as an argument. Call methods on the paddle to implement movement, based on input state. If you have the separate Game/App system like I do, then the App's input handling can call through to the Game's input handling.

Share this post


Link to post
Share on other sites
Alberth    9525

I usually start at the global picture, instead of the small details. What data do you have, what activities must be done (at high level, so "game map", "textures", "character", and "drawing the screen" is more than enough.

Make big building blocks (eg on a single sheet of paper) where those things roughly go. It should give you an overview of the program as a whole, even though your picture may be wrong, but the only way to find out is by trying to build it.

You will hit dead ends, but it's part of the process. Programs are so complicated, it is impossible to get all the details right on the first try. Don't be afraid of it, learn to recognize it happening, and how to recover from it.

Finally, nobody says you must do all coding in one project. If you want to figure out how to do some detail, eg movement with keys or so, and you don't know how, use paper and your grey matter to work it out. If it needs experimenting, make a small side-program for experiments. When done, apply the knowledge in your main project (which may include code of the experiment, but in general rewriting improves code).

Share this post


Link to post
Share on other sites
Satharis    2449

A classic issue for a lot of people (myself included) is the tendency to over engineer things. Frankly the best way to learn what you need is to just make something and set small goals, milestones if you will. I used to create these really complicated classes before even knowing what I needed, but often it either got thrown away or simply went unused or the architecture changed somewhat so I had to rewrite it anyway. For example, since you're making a breakout game you might just want to start simple, "well I need a game loop and a window, now I need to draw something onscreen, now I need to make a ball, okay now the ball needs to bounce against the edges of the screen and re-spawn."

The first two things you mentioned are fine, for the texture manager I would question if you even need one. Is the game complex enough that sprites require managing? Honestly in most arcade games that isn't the case, sprites may be used only once and the entire game contains a small enough number of them for you to simply load them all in some function and pass them around. Important questions are things like -when- to load them too, if you can you might as well load them all at the start. Frankly unless you KNOW for a fact that you need something to be complex, it is almost always better to start off simple and build up from there.

Share this post


Link to post
Share on other sites
MarcusAseth    69

Thank you for answering guys :)

Quote

The first two things you mentioned are fine, for the texture manager I would question if you even need one. Is the game complex enough that sprites require managing?

Frankly unless you KNOW for a fact that you need something to be complex, it is almost always better to start off simple and build up from there.

I see that point, though my point would be that all the games in the list of games a begginner should make seems like they don't require a TextureManager as well, so even if I don't need a TextureManager right now or to learn how to make a Singleton, when do I get to learn it then?! :P

I am kind of throwing extra stuff in exactly because the project is simple, so the scale is small and I can learn this concepts in realive comfort/safety.

So from my point of view, I actually value something that over-complicate the project if it is just for the sake of learning a new thing, basically making this game is not really the main goal. So if you guys think I could research and apply an interesting design pattern to this project feel free to suggest, because for me is an opportunity to fiinally learn a new/useful thing :P 

Edited by MarcusAseth

Share this post


Link to post
Share on other sites
Satharis    2449
3 minutes ago, MarcusAseth said:

I see that point, though my point would be that all the games in the list of games a begginner should make seems like they don't require a TextureManager as well, so even if I don't need a TextureManager right now or to learn how to make a Singleton, when do I get to learn it then?!

I am kind of throwing extra stuff in exactly because the project is simple, so the scale is small and I can learn this concepts in realive comfort/safety.

So from my point of view, I actually value something that over-complicate the project if it is just for the sake of learning a new thing, basically making this game is not really the main goal. So if you guys think I could research and apply an interesting design pattern to this project feel free to suggest, because for me is an opportunity to fiinally learn a new/useful thing  

Which is fine, I experiment with ideas myself on a regular basis, the problem is it becomes easy for you to start doing that for everything. Particularly when it is that, experimenting, you can quickly get in over your head and make the code a mess of things you aren't sure are good architecture, and dig yourself into a corner that it feels frustrating to get out of.

Sometimes it might be better to experiment on standalone tech demos and things, or to save writing something complex like that until you actually need it. That's a bit of an unspoken rule that people don't often actually explain, software only gets complicated because it needs to. If you could write the next Battlefield game just by making a function that loads all the game data at the start and not bother with subsystems dedicated to managing things, then they probably would.

You might want to consider that the faster you finish a game the faster you get to try another project as well, and possibly explore more concepts or have more challenging rules to write for.

Share this post


Link to post
Share on other sites
Kylotan    10008
6 minutes ago, MarcusAseth said:

all the games in the list of games a begginner should make seems like they don't require a TextureManager as well, so even if I don't need a TextureManager right now or to learn how to make a Singleton, when do I get to learn it then?!

  1. Maybe you never need a TextureManager....
  2. You CERTAINLY don't need a Singleton.
  3. On that list, Ikari Warriors and Super Mario Bros have sufficient numbers of sprites and graphics to make some sort of image asset management worthwhile.
  4. The point of following a list like this in order is that each one introduces new challenges. As the article says, this time around you'll be learning "Lessons of pong, powerups, maps (brick arrangements)". Those are the things you probably want to focus on - how should they be implemented?

Share this post


Link to post
Share on other sites
MarcusAseth    69

Done some progress, I'm thinking to paste here the code I write during this project in case someone notices and point out some ugly stuff I may end up doing so that I avoid ending up with bad coding habits.

I'll put it into spoiler just to not flood the entire page with a single reply :S

The only problem I am currently having is inside Game.cpp, code below:

#define BACKGROUND "Graphics/Background.png";
#define PADDLE "Graphics/Paddle.png";
#define BALL "Graphics/Ball.png";

Game::Game(SDL_Window* Window, SDL_Renderer* Renderer)
	:Window{ Window }, Renderer{ Renderer }
{
	LoadImage(BACKGROUND);
	LoadImage(PADDLE);
	LoadImage(BALL);
}

LoadImage takes a const char* but those 3 macro are not expanding into that for some reason, since VS is giving me a red squigly line... what argument type should that function take in order to work with my Macros? :S


 

Spoiler

 

main.cpp


#include <iostream>
#include "SDL2\SDL.h"
#include "SDL2\SDL_image.h"
#include "App.h"

int main(int argc, char* argv[])
{
	App GameClient;

	while (GameClient.IsRunning())
	{

	}

	return 0;
}

App.h


#pragma once
#include "SDL2\SDL.h"
#include "Game.h"
class App
{
	bool Running = false;
	Uint32  Width = 1280;
	Uint32  Height = 960;
	Uint32  WinFlags = 0;
	Uint32  RenFlags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;
	SDL_Window* Window;
	SDL_Renderer* Renderer;
	Game* GameInstance;

	bool Init();
	bool CreateWindow();
	bool CreateRenderer();
public:
	App();
	~App();
	
	App(const App&) = delete;
	App& operator=(const App&) = delete;
	
	App(App&&) = delete;
	App& operator=(App&&) = delete;
	
	////
	
	inline bool IsRunning()const { return Running; }
};

App.cpp


#include "App.h"
#include "Utility.h"


App::App()
	:Window{ nullptr }, Renderer{ nullptr }
{
	Running = Init();
	
	if (Running)
	{GameInstance = new Game(Window, Renderer);}
}


App::~App()
{
	if (Window) { SDL_DestroyWindow; }
	if (Renderer) { SDL_DestroyRenderer; }
	delete GameInstance;
	SDL_Quit();
}

bool App::Init()
{
	if ( 0 != SDL_Init(SDL_INIT_EVERYTHING)){ return Error(SDL_GetError()); }

	return CreateWindow() ? (CreateRenderer() ? true : false) : (false);
}

bool App::CreateWindow()
{
	Window = SDL_CreateWindow("Breakout",
							  SDL_WINDOWPOS_CENTERED,
							  SDL_WINDOWPOS_CENTERED,
							  Width, Height, WinFlags);
	return Window ? true : Error(SDL_GetError());
}

bool App::CreateRenderer()
{
	Renderer = SDL_CreateRenderer(Window, -1, RenFlags);
	return Renderer ? true : Error(SDL_GetError());
}

Game.h


#pragma once
#include <map>
#include <string>
#include "SDL2\SDL.h"

class Game
{
	SDL_Window* Window;
	SDL_Renderer* Renderer;
	std::map<std::string, SDL_Texture*> Textures;

	bool LoadImage(const char* path);
public:
	Game(SDL_Window* Window, SDL_Renderer* Renderer);
	~Game();

	Game(const Game&) = delete;
	Game& operator=(const Game&) = delete;

	Game(Game&&) = delete;
	Game& operator=(Game&&) = delete;

	////

	SDL_Texture* GetTexture(const char* path)const;
};

Game.cpp


#include "Game.h"
#include "Utility.h"
#include "SDL2\SDL_image.h"

#define BACKGROUND "Graphics/Background.png";
#define PADDLE "Graphics/Paddle.png";
#define BALL "Graphics/Ball.png";

Game::Game(SDL_Window* Window, SDL_Renderer* Renderer)
	:Window{ Window }, Renderer{ Renderer }
{
	LoadImage(BACKGROUND);
	LoadImage(PADDLE);
	LoadImage(BALL);
}


Game::~Game()
{
	for (auto& elem : Textures)
	{ SDL_DestroyTexture(elem.second); }
}

bool Game::LoadImage(const char * path)
{
	if (Textures.find(path) != Textures.end())
	{ return  Error("Ettempting to Load an already Loaded Texture."); }

	SDL_Surface* Surface = IMG_Load(path);
	if (Surface)
	{
		Textures[path] = SDL_CreateTextureFromSurface(Renderer, Surface);
		SDL_FreeSurface(Surface);
		return true;
	}
	else
	{ return Error(SDL_GetError()); }
}

SDL_Texture* Game::GetTexture(const char* path)const
{
	auto& Texture = Textures.find(path);
	return (Texture != Textures.end()) ? Texture->second : nullptr;
}

Actor.h


#pragma once
#include "SDL2\SDL.h"
#include "Game.h"

enum class PivotMode: Uint8 {CENTER,TOP_LEFT};

class Actor
{
SDL_Texture* RequestTexture(const char* path)const;
void SetSpriteRect(Uint32 x, Uint32 y, PivotMode InputMode);
protected:
	Uint32 XCenter;
	Uint32 YCenter;
	SDL_Rect SpriteRect;
	SDL_Texture* Sprite;
	Game* GameRef;
public:
	Actor(Game* GameRef, PivotMode InputMode, Uint32 x, Uint32 y, const char* path);
	virtual ~Actor();

	Actor(const Actor&) = delete;
	Actor& operator=(const Actor&) = delete;

	Actor(Actor&&) = delete;
	Actor& operator=(Actor&&) = delete;

	////
};

Actor.cpp


#include "Actor.h"

#define BACKGROUND "Graphics/Background.png";
#define PADDLE "Graphics/Paddle.png";
#define BALL "Graphics/Ball.png";


Actor::Actor(Game* GameRef,PivotMode InputMode, Uint32 x, Uint32 y, const char* path)
	:GameRef{ GameRef }
{
	if (GameRef)
	{Sprite = RequestTexture(path);}

	if (Sprite)
	{SetSpriteRect(x, y, InputMode);}
}


Actor::~Actor()
{
}

SDL_Texture* Actor::RequestTexture(const char* path)const
{
	return GameRef->GetTexture(path);
}

void Actor::SetSpriteRect(Uint32 x, Uint32 y, PivotMode InputMode)
{
	SDL_QueryTexture(Sprite, NULL, NULL, &SpriteRect.w, &SpriteRect.h);
	switch (InputMode)
	{
		case PivotMode::CENTER:
		{
			SpriteRect.x = x - SpriteRect.w / 2;
			SpriteRect.y = y - SpriteRect.h / 2;
			XCenter = x;
			YCenter = y;
		}break;
		case PivotMode::TOP_LEFT:
		{
			SpriteRect.x = x;
			SpriteRect.y = y;
			XCenter = x + SpriteRect.w / 2;
			YCenter = y + SpriteRect.h / 2;
		}break;
	}
}

 


 

 

Edited by MarcusAseth

Share this post


Link to post
Share on other sites
jpetrie    13157

 

53 minutes ago, MarcusAseth said:

Done some progress, I'm thinking to paste here the code I write during this project in case someone notices and point out some ugly stuff I may end up doing so that I avoid ending up with bad coding habits.

 

Don't use macros for constants. Use "const" or "constexpr" (if your version of C++ has it). 

What is the actual error you're getting when you compile? The "red underlines" produced by Visual Studio are produced by the Intellisense compiler, which is (a) different from the compiler that actually builds your code and (b) often wrong.

Share this post


Link to post
Share on other sites
MarcusAseth    69

I didn't had tried to compile so far (until you asked), otherwise I would have realized that I shouldn't put the ';' at the end of the macro, which was expanding the ';' into LoadImage("Graphics/Background";); :P

Anyway I'll go with constexpr then, thanks :D

 

Share this post


Link to post
Share on other sites
jpetrie    13157
Just now, MarcusAseth said:

I didn't had tried to compile so far (until you asked), otherwise I would have realized that I shouldn't put the ';' at the end of the macro, which was expanding the ';' into LoadImage("Graphics/Background";); :P

Exactly :)

Other stuff, from your hidden code:

  • You don't initialize GameInstance in your App constructor to nullptr; this means that when you get to ~App(), if the game wasn't running, the GameInstance pointer is random garbage. Attempting to delete such a pointer is undefined behavior and will likely crash you. You should consider using std::unique_ptr<Game> to manage this object instead of having to manually manage it.
  • In ~App, you don't actually appear to call SDL_DestroyWindow and friends. You are missing your parentheses.
  • Methods defined in the class definition (IsRunning) are automatically inline; you don't need the keyword. It's largely useless these days anyhow. As a matter of sanity I tend to avoid defining anything in a header, except when needed (templates), because link-time optimization is usually good enough and I like the faster recompiles. Your mileage may vary.
  • This "return Foo() ? (Bar() ? : true : false) : false" construct is horrid. Not only is it redundant (because Bar() is already returning true or false), the nesting makes it onerous to read.
  • I am worried about what the Error() function is actually doing. It very much looks like it conflates recording of the error with presentation or handling of the error, which is not a great long-term pattern.
  • const char* for strings should be reserved, generally, for inter-operation with C APIs in C++. Use std::string and use its c_str() member when you need to pass data to C APIs like SDL.
  • Prefer nullptr to NULL.

 

 

 

Share this post


Link to post
Share on other sites
MarcusAseth    69

Thanks for all the tips and for reading trough my code jpetrie ;)

Resolution of the day: all pointers will be forever initialized to nullptr.

The SDL_DestroyWindow was really careless, but thankfully it gets catched by the compiler

point 4 made me laugh, disgusting people trough code xD

This is my Error() function:

bool Error(const char* err)
{
	std::cout << err << std::endl;
	return false;
}

I either pass the GetError() or a error message written by me, and it always return false.

Though aside from that case where I took the ternary operator TOO FAR, using it like in the code below is "elegant", right? :P

return Window ? true : Error(SDL_GetError());

Anyway I'll be sure to apply all fixes, thanks !

Edited by MarcusAseth

Share this post


Link to post
Share on other sites
jpetrie    13157
1 minute ago, MarcusAseth said:

Though aside from that case where I took the ternary operator TOO FAR, using it like in the code below is "elegant", right?



 

No.

Share this post


Link to post
Share on other sites
jpetrie    13157
3 minutes ago, MarcusAseth said:

This is my Error() function

This looks like a questionable habit to develop.

You're munging together three concerns here: logging, error propagation, and error presentation. These should probably be three different things.

Logging can be useful for recording information about some event at the site of that event, for future diagnostics purposes. You should have a dedicated function for logging things, if you want to use that capability. Things you may want to log are not always errors.

Error propagation is about bubbling errors up to the place where they can be reasonably dealt with, and including all the relevant information about the error in that bubbling. Right now all your error handling boils down to is returning booleans, which the implicit assumption that there is only one way for a thing to fail. This doesn't scale, and in fact you've already scaled past it: several of your functions can return via Error() using two different messages. It's impossible for the caller of LoadImage to know why an image failed to load, and if that error is something that can be recovered from or handled by retrying or what.

Error presentation at this level is usually simple, usually the same as logging. But as you build things that are more and more advanced, this kind of "immediately present the error" approach falls apart. Consider if you were trying to tell the user "Error("Could not connect to login server, try again in five minutes.")." This is a typical message you'd like to surface to a user, and as such will usually be rendered in the UI style of your game. But you can't put up a blocking modal dialog deep inside your code like that; you need to have that error information propagated outwards (as above) and then handled by the appropriate UI presentation layer in your code.

Share this post


Link to post
Share on other sites
MarcusAseth    69

I can and will certainly add the Logging() function, but all after that, is just too much for me to consider right now x_x

First I'll focus on getting a playable game.

Also I don't actually think as what I am doing as "error handling", is just like a warning in the console for me to roughly know "around which part of the code I fucked up and should place a breakpoint and hunt for bugs"

Edited by MarcusAseth

Share this post


Link to post
Share on other sites
jpetrie    13157
4 minutes ago, MarcusAseth said:

Also I don't actually think as what I am doing as "error handling", is just like a warning in the console for me to roughly know "around which part of the code I fucked up and should place a breakpoint and hunt for bugs"

That's reasonable, but then I'd change the name of the Error() function to Log(). :D

You're right to focus on getting a thing that works and is a game first, before worrying about the minutiae of some of my above points. But they are still worth keeping in the back of your mind for consideration as you build new things, because good habits (particularly with respect to dealing with errors in some fashion beyond "oh shit, well, let's just terminate the whole process") are easily to build early.

Share this post


Link to post
Share on other sites
MarcusAseth    69

Small progress today,  trying to get the time stuff right, and probably still isn't, code below.

I've read this whole page again and I am not quite sure of the need/usage for the MAX_FRAMESKIP and that's why I didn't added it to my code x_x

I post the code in case anyone would be so kind to doublecheck :P

GameTimer.h

#pragma once
#include <chrono>
#include <string>
using namespace std::chrono;


class GameTimer
{
	milliseconds MsSinceLastFrame;
	time_point<steady_clock> TimeNow;
public:
	time_point<steady_clock> TimeBegin;
	time_point<steady_clock> PrevUpdateTime;
	time_point<steady_clock> NextUpdateTime;
	
	GameTimer();
	~GameTimer();

	time_point<steady_clock> CurrentTime();
	std::string FPS();
	std::string GameSpeed();

	void RecordTimeSinceLastFrame();
};

GameTimer.cpp

#include "GameTimer.h"



GameTimer::GameTimer()
	:MsSinceLastFrame{0}
{
	TimeBegin = TimeNow = PrevUpdateTime = NextUpdateTime = steady_clock::now();
}


GameTimer::~GameTimer()
{
}

time_point<steady_clock> GameTimer::CurrentTime()
{
	TimeNow = steady_clock::now();
	return TimeNow;
}

std::string GameTimer::FPS()
{
	
	return "| FPS: "+ std::to_string(static_cast<float>(MsSinceLastFrame.count())) + "ms |";
}

std::string GameTimer::GameSpeed()
{
	return "";
}

void GameTimer::RecordTimeSinceLastFrame()
{
	MsSinceLastFrame = duration_cast<milliseconds>(CurrentTime() - PrevUpdateTime);
	PrevUpdateTime = CurrentTime();
}

GameLoop:

void App::GameLoop()
{
	//GameUpdateTickPerSecond   suggested ratio 1/25 seconds = 40ms per udpate
	static duration<uint32_t, std::ratio<1, GameUpdatesPerSec>> GameUpdateTPS{ 1 };

	while (Game->IsRunning())
	{
		Timer->RecordTimeSinceLastFrame();

		while (Timer->CurrentTime() > Timer->NextUpdateTime)
		{
			Game->Update();
			Timer->NextUpdateTime += GameUpdateTPS;
		}

		auto TimeOffset = Timer->CurrentTime() + GameUpdateTPS - Timer->NextUpdateTime;
		auto GameUpdateTPSns = duration_cast<nanoseconds>(GameUpdateTPS);
		
		float Interpolation = float(TimeOffset.count()) / float(GameUpdateTPSns.count());
		Game->Draw(Interpolation);


		/*DEGUB*/LogConsole(std::to_string(Interpolation).c_str());
		std::string AppTitle = "Breakout" + Timer->FPS() + Timer->GameSpeed();
		SDL_SetWindowTitle(Window, AppTitle.c_str());
	}
}

 

Edited by MarcusAseth

Share this post


Link to post
Share on other sites
MarcusAseth    69

I think maybe I should briefly mention something (from my limited understanding) about the chrono library, so maybe other begginners in this section can benefit from it too so that my post/code is less obscure to them and not useful only to me. Also is to review my understanding of it since anyone can correct what I say.

Chrono library is a time library part of the STL, you just need to #include <chrono> in order to use it. Most of the code live inside namespace std::chrono::  .The library doesn't allow inplicit conversions of arithmetic types to durations therefore you can say "seconds MySeconds = 3;//Error" because "3 what?! 3 hours?"

It is mainly composed by 3 things: duration,    time_point,    clocks.

clocks: it has 3 of these, the system_clock which is basically a calender (has functions to convert a time point to a real date), like your Window time, the steady_clock which is basically a stopwatch in nanoseconds (at least on my machine, no idea if this can change) and is great for timing, and lastly the high_resolution_clock which just gives you back one of the other 2 (the one with the shortest tick period).

name_of_one_of_those_3_clocks::now() returns you the current time.

duration: this is a template class on o the form of duration<rap, ratio<num,den>>. It is used to store an arbitrary duration of time, some of the default durations defined in the library are seconds and milliseconds .

Rap is the internal rapresentation used to store the time, it is usually a long long but you can also pass a float or double to it if you want to have your operations on that duration return "fractions of a tick". 

ratio<num,den> is a ratio made up of numerator and denominator used to allow for proper conversion between different duration, seconds default to ratio<1,1> and milliseconds is ratio<1,1000> , so that if you do:

//s is a literal representing seconds, declared with many others in std::literals::chrono_literals 
//but you can just do "using namespace std::chrono;" and it will give you access to those as well
seconds MySeconds = 4s;
milliseconds MyMilliseconds = MySeconds;

//Because of the ratio thing, now MyMilliseconds contains the value 4000

also some default ratios like the one used by milliseconds are provided so that you can do std::milli instead of writing ratio<1,100> 

So in my code in the reply above

static duration<uint32_t, std::ratio<1, GameUpdatesPerSec>> GameUpdateTPS{ 1 };

GameUpdatePerSec is set to 25 and my  GameUpdateTPS contains just 1 of this duration, so that if you convert it to milliseconds or assign one of this to milliseconds you get 40ms ,    1000ms/25 = 40ms.

time_point: this are different than duration because this is a duration from a point in time. You can't just assign a time_point to a duration.

If I have got it right, then:

time_point + time_point returns error

time_point - time_point returns  duration

time_point + duration returns  time_point

time_point - duration returns  time_point

You can always get a duration out of a time_point by calling it's member function time_since_epoch()

Lastly, back to duration, no implicit conversion will happen between a "finer precision" duration and a "coarser precision" duration, so between ms and s for example because you would lose precision, but the implicit conversion will happen the other way around because it is safe to go from coarser to finer.

You can still use duration_cast<Put_To_duration_type_here>(MyTime)  to force that "upward" conversion which will result in truncation of the value stored inside the duration.

And is pretty much the chrono library to my understanding ;)

 

Edited by MarcusAseth

Share this post


Link to post
Share on other sites
Kylotan    10008

MAX_FRAMESKIP exists so that if updates are too slow, you still get to render every once in a while. I would expect it's unlikely you'll hit this problem.

You don't need to set the window title every time through the game loop.

Chrono is part of the standard library. It's not called the STL, and hasn't been for many years.

Share this post


Link to post
Share on other sites
MarcusAseth    69
26 minutes ago, Kylotan said:

Chrono is part of the standard library. It's not called the STL, and hasn't been for many years.

I'm confused by this line, didn't I said the same thing? :D

quoting myself:

Quote

 part of the STL, you just need to #include <chrono>

isn't STL == standard template library == standard library?

Also the window title is holding the ms since last frame display, that's why I keep refreshing it

Edited by MarcusAseth

Share this post


Link to post
Share on other sites
Kylotan    10008

STL is the Standard Template Library. The "Standard Template Library" is an old name for part of the C++ standard library, specifically the containers, algorithms, iterators and functors. These days, we just talk about the standard library, which includes the former bits, plus tons of new stuff. Much of it is templates, but not all.

Sorry, must have missed the milliseconds in the window title. I suggest getting some other form of onscreen text debugging would be a useful thing to do. :)

Share this post


Link to post
Share on other sites
Yxjmir    9

I found a tutorial for making Breakout a while back. It uses OpenGL version 3.3. In my opinion it has a pretty good code structure, but it can be improved upon. It has a static singleton/global resource manager, which just simplifies the loading of assets. "Game Coding Complete" written by Mike McShaffry and David 'Rez' Graham has a better but far more complex way of loading/managing resources. I mentioned it because it contains good examples of how to structure you game, but they're a lot more complex than what you need for Breakout. Here's the link to the tutorial https://learnopengl.com/#!In-Practice/2D-Game/Breakout

Share this post


Link to post
Share on other sites
MarcusAseth    69

I know that OpenGL tutorial :P At a certain point in time during the last year I was following it, I had to abandon it because it wasn't enough clear when he start making shaders and uses GLSL and stuff wasn't compiling on my end, and I had nowhere to ask, but with you guys help now things would probably be different! :)

Thanks for letting me know about Game Coding Complete, not scared about complexity don't worry, (I paused this project because I wanted to do some simple composition using templates for this project and follow what he does in this video which I yet can't understand , so I am studying more C++ and templates right now, beforegoing back to his video multiple times and then resume this project :P ) so eventually I'll be picking up that book

Edited by MarcusAseth

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Similar Content

    • By DKdowneR
      Hi! I made a tile map reading from a file. Almost everything works good, but when a player go out of map, program runs into an error and says that "vector subscript out of range". My question is how to make check for it
      Drawing map : 
      void GameplayScreen::DrawMap(SDL_Renderer *renderer) { for (int y = map.size() - 1; y >= 0; --y) { for (int x = getStartBlockX(), xEnd = getEndBlockX(); x < xEnd && x < map[y].size(); ++x) { if (map[y][x] != "0,0") { int tempX = atoi(map[y][x].substr(0, map[y][x].find(',')).c_str()); int tempY = atoi(map[y][x].substr(map[y][x].find(',') + 1).c_str()); srcRect.x = tempX * 32; srcRect.y = tempY * 32; srcRect.w = 32; srcRect.h = 32; destRect.x = x * 32 + posX; destRect.y = (y * 32 + posY); destRect.w = 32; destRect.h = 32; vBlock[Earth]->Draw(renderer, srcRect, destRect); } } } } getStartBlockX returns first map block, getEndBlockX returns last, so it's like render on screen only a piece of map, not all blocks.
      tempX returns x coordinate of tile image,  tempY y coordinate. So, for example, if map is like :

      0,0 0,0 0,0 0,0 0,0
      0,0 0,0 0,0 0,0 0,0
      1,0 2,0 0,3 1,0 1,0
      0,0 is first block image, 1,0 is one next to the first, 0,3 is 2 under the first block etc.
         
    • By Alpha_ProgDes
      So I've been reading about and watching videos about Smalltalk. It seems like an interesting language and damn near the Father (or Godfather) of all things OOP. But it got me thinking, what languages should a programmer know or even be proficient in to be a dependable programmer (couldn't think of a better word than "dependable")? After giving it some thought, I came up with this list.
      At least 1 programming language from:
      Lisp family of languages ML family of languages Smalltalk family of languages And also the C programming language (not the family, just the language).
      I think this covers all facets of programming and ways of tackling problems. I don't think there's any other language, thinking most of the modern languages, that has done anything that 4 listed above haven't already done. I'm not counting languages like Julia, R, Perl, or Erlang, because they are languages, AFAIK, that seem to solve a very specific problem. They can be general purpose, but again, AFAIK, they're not meant to be.
      Of course, agreements, disagreements, thorough takedowns, and/or overall discussion are welcomed.
    • By Raptor42
      I'm looking to form a new game development team, mostly for training purposes.
      About me:
      I'm a student - Unity C# developer, who worked part-time in this industry for a couple of years already. I've been a lead developer in many "random collab groups" as well as a few companies. I specialize in creating 2D games for Android, but I'm looking forward to trying out new things - especially 3D development.
      Currently, I've got one Android game close to a release so I'd work for this team in my spare time. 
      About the project:
      I've been thinking about creating a simple tycoon-like simulation game for Android (and PC eventually), inspired by the Game Dev Story (initially released by Kairosoft in 1997) https://en.wikipedia.org/wiki/Game_Dev_Story 
      I haven't done much planning though, therefore I'm looking forward to hearing out your ideas.
      Right now, I've only created a test 3D scene using placeholder models and implemented a simple pathfinding system for me to play around with:
      https://i.imgur.com/xAd0l4o.png
      https://i.imgur.com/nHZerOT.png
      I'm looking to work with people who are:
      - willing to take a position of a: 3D modeller/2D artist/Designer
      - not necessarily very experienced, but eager to learn and improve their skills
      - active - check in at least once a day
      If you'd like to apply for a different position which I didn't list here, you are welcome to contact me as well.
      While this project is created mostly for learning purposes, if we ever get to release it and generate any revenue - you will recieve a certain percentage of it.
       
      To Apply:
      Send an email to rk.softwaredev@gmail.com
      Introduce yourself and attach an example of your work (if you have any)
    • By MarcusAseth
      I was doing an experiment, code below:
      template<typename T> struct S { explicit S(T v) :val{ v } {}; T val; }; int main() { S<int> MyS('g'); cout << MyS.val << endl;//Output is 103 return 0; } Even though I am providing T with a type which is int, and I have an explicit constructor, why I have an implicit conversion from char to int? Shouldn't it see that T is int since I'm telling it so and thus give me error for constructing an S out of char?
       
    • By chiqo
      I've read Object Oriented Prograamming C++ 4th Edition. Did some exercises, honestly I'd say I covered 70% of this book. Mark some topics for reread later. then I'm thinking go with The C++ Programming Language [4th Edition] - Bjarne Stroustrup any suggestion will precied. 
      I don't have any programming experience. But I've play a lot of games... Here goes nothing... 
      I'm thinking make a game. (Looked up with unity engine seems like brain surgery to me. )At the beginning my game will have only one big-ass map. 4 type of NPC's 
      Get quests from NPC's, get your reward after finish. 
      Buy metarials (equipment, healt potions etc)
      TeleportGate NPC's 
      Monsters 
      The goal is finish quests, get stronger, learn skills, collect seven unique diamonds among the quests and face with evil creature. 
       
      This is already very complex for me, but I couldnt help myself to think deeper and deeper.Then I thought why not MMORPG... then things get messy. I am keep overthinking, I cant concentrated now. 
      These are what I am thinking on the server side; 
      there will be 4 units. 
      NPC's with static locations (Stroge, Trade, Quests, Gates etc) 
      NPC's with dynamic locations - Monsters
      User Database
      Pool (deal with everything)
       
      NPC's and monsters have pre-set locations, behaviors, shortly they will have their routine. for example lets name four monsters (scylla(FBCD),pyhton(FBCE), satir(FBCF), echidna(FBD0)) also creatures will have locations and health values. I dont want to go further with details. so pool unit has all informations and authority decent manupulations for NPC's and Monsters and get informations logged player via database. when player logged, pool will define a dynamic number as long as player logged and generate viewport for player and send package. a character has charid, charname, charloc(x,y,z), charstatus(idle,walking,flying,attacking etc), charhp(max,current), chararmor, charmp(current,max), charAttackPower, charDefence, charExp(current,max) there would be more informations or less... now 1st player in the pool. . when another player logged assume both player close each other... 2nd player will get viewport including 1st player appereance too.1st player only get 2nd player's appereance.  my point is only send or prepare necessarry packages. lets assume all informations belong a character 4 bytes each. and you send/receive 10 packages per sec... 520bytes per sec for a character with all informations(I know networking doesnt work like this. my point is this is tiny). I still think thats manageable.
      As you can see English is not my main language I hope you get what I meant. this MMORPG idea like a virus(not software virus :)) taking control of my mind. I did some research about MMORPG advanced users says stay away. security issues details details bugs etc its hardcore I understand that. but still... I've desire to learn game programming, please put me right direction. 
       
  • Popular Now