Jump to content
 Share

Cyber_Spectre

Simple C++ Game

Recommended Posts

Posted  Edited by Cyber_Spectre

This is a simple game, wanna play? Then download it here:

 

https://drive.google.com/file/d/117Kd71IbPZCSBTxZHycjkq3K7qxR9Mwn/view?usp=sharing

 

 

firstGame.PNG.765b1790746a799485f196c14af9e384.PNG

It was created using SFML (https://www.sfml-dev.org/) and C++.

 

Further down the road I will be making more games, much more complex. Now that this has become a new hobby of mine.  Enjoy!

 

*If the download link doesn't work let me know.*

Edited by Cyber_Spectre

- Spectre

Share this post


Link to post
Share on other sites


Are you okay with posting the source code here?  There's an icon with brackets?  Thank you for posting this- I'm super paranoid about downloading things; I'm also always curious to look at someones style and approach.


PoorWDm.png?width=360&height=152

Share this post


Link to post
Share on other sites


It's amazing how differently every C++ programmer writes their code. My writing style is a little unorthodox. I am a C-style/OOP hybrid. I don't use headers with classes like a normal person either haha. I pretty much just use header files as a way to segment my code and make it easier to navigate. I might be able to provide some examples at some point. Maybe. The issue is my best code tends to be for projects that AREN'T open source. Like games.

 

I'll provide an example of how many header files I'll use with a few snips of the code I'm currently working on. This is code for an actual game that'll be published to steam once finished. So this is all I can show you.

 

image.thumb.png.bed9ab26def2d61593c2ff7f4330ed61.png

 

image.thumb.png.a2866bc829c387ab3f065fcccd7e3b23.png

 

unknown.png

 

Another habit I tend to have is to do this:

 

void functionThing(int x)
{
 	if(x != 0) return;
  
  	runOtherFunction();
  	setUpStuff();
  	Stuff::GetStuff(x).wew();
}

Rather than this:

 

void functionThing(int x)
{
 	if(x > 0)
	{
		runOtherFunction();
  		setUpStuff();
  		Stuff::GetStuff(x).wew();
	}
}

I always get the boolean stuff out of the way first. That way resources are never wasted for code that doesn't need to be ran.


I write programs and stuff.

 

If you need to contact me, here is my discord tag: Dustin#6688

 

I am a busy person. So responses may be delayed.

1840045955_Thicco(1).thumb.png.87c04f05633286f3b45b381b4acc4602.png

 

Share this post


Link to post
Share on other sites


This is very interesting, I haven't seen a C++ programmer write  like this. I might test this out? Have you noticed any performance differences with writing your code directly in header files, compared to their source  files? Overall, every programmer writes differently. In regards to your game what is it about? And Steam? I admire you for doing this. Good luck on your goal, I'll be cheering you. Furthermore, thanks for sharing your coding style and a little bit of your game. If you ever need a beta tester, I would not mind testing it out.


- Spectre

Share this post


Link to post
Share on other sites


Posted  Edited by _Rocket_

My programs usually have a single .cpp file. Yes, it is main.cpp

 

And of course, all the function calls are called inside main() to get the code running. Most of the code is ran though various core.h files, which usually has some kind of void process(); method that I can call. core.h will import all the different header files needed. And of course each additional header file can import other header files if needed.

 

This helps me know exactly where I need to go to add any additional functionality that my program has. It might not be the most efficient way to do this, but it's how I like to do it.

 

I write my code to be as efficient with resources as possible. Sometimes this can sacrifice readability. For example:

 

//How a normal person does this:

bool check(unsigned int& x)
{
  if(x < 10000)
  {
    x += 1;
    run(); 
    return true;
  }
  else {
    return false;
  }
}

//How I do this:

bool check(unsigned int& x)
{
  if(++x >= 10000) return false;
  
  run();
  return true;
}

It isn't instantly readable but it DOES actually use less resources to run. ++x and x++ is kind of "built in" to the CPU's functionality so it's actually ever so slightly quicker. And of course, a single if is faster than if else. It's negligible, but it's still faster. It saves a single jump call when you look at this code in assembly. (At least I'm pretty sure it does)

 

Doing it like this does not have any impact on resource use since you are technically running the same code. It's just spread out into different header files. I think it might take slightly longer for the compiler to compile your code, though. But in conclusion, your programs performance during runtime is not influenced by how many header files you have. Header files or no header files, it's going to come out as machine code anyways.

Edited by _Rocket_

I write programs and stuff.

 

If you need to contact me, here is my discord tag: Dustin#6688

 

I am a busy person. So responses may be delayed.

1840045955_Thicco(1).thumb.png.87c04f05633286f3b45b381b4acc4602.png

 

Share this post


Link to post
Share on other sites


To be honest, I'd take @_Rocket_'s advice with a grain of salt. It is often a bad idea to do micro-optimizations right off the bat. Your code might use one or two instructions less, but you'd not feel any difference unless it's a very critical part of the code. However, with the reduced readability you'll have a hard time understanding, debugging, and expanding your code. I'd rather recommend writing your code how you'd like to write, and then find "hot paths" through profiling tools, and then do the micro-optimizations as the very last step or only if necessary.

 

I threw the two pieces of code into a compiler for fun, and the readable version seemingly uses less instructions: https://godbolt.org/z/dh4vpT Our dear compilers are very smart, and they can optimize a lot of things for us, but we can quickly confuse the compiler by trying to be smart ourselves. This is another reason why I recommend letting testing dictate what code you micro-optimize.

 

You should also avoid putting implementations into header files. Header files are intended to only contain definitions (not implementations), so you can use the defined behavior without having to recompile the code which would slow your compilation down and probably increase your binary's file size. This happens because the pre-processor just stuffs everything you #include into the "same file" and then compiles that. Thus if you split the code into .h and .cpp, it will work after linking since the defined behavior can be found in another compilation unit (the .cpp). The other way around the behavior will be compiled every time you use.

 

So first solution (split code into .h and .cpp): store compiled code in one compilation unit and use it through linking in other units.

Second solution (having your code in .h): Store the compiled code in every compilation unit that uses it. In some cases the latter is faster due to in-lining, but then you're really deep into micro-optimizing. :P You can read a little more about it here: https://stackoverflow.com/a/583271

 

Personally, I'd just stick with the classic .h+.cpp. 😄

 

EDIT: Aren't the two code snippets different too? If I gave it a reference to a variable containing 10000, then the first code snippet would not modify the variable, but the 2nd snippet will always add 1.


Wanna know what I am up to? Take a look at my personal Trello board or my cards on the Development Trello board!

Share this post


Link to post
Share on other sites


Honestly @NickI appreciate the response. I love being able to learn new things about programming. There's still a LOT I'm yet to learn. Just because I'm a game developer doesn't mean I'm a better programmer than everyone else. Honestly the only reason why I can develop a game is due to my crazy work ethic.

 

I might eventually look into how to further optimize my code writing. I want to finish this game project first, though. Otherwise I'm gonna add extra stress to myself. But when that time comes I would actually like to see if you couldn't give me a few pointers about properly structuring .cpp's and headers because I never actually bothered learning about that stuff hahaha. I just went off and did my own thing with them.

 

I'm still gonna do the if(!bool) return; thing though, even if it does result in a couple extra instructions during compile time. It just looks so much cleaner to me.

 

And yes you can see "pointers" as a pun.

 


I write programs and stuff.

 

If you need to contact me, here is my discord tag: Dustin#6688

 

I am a busy person. So responses may be delayed.

1840045955_Thicco(1).thumb.png.87c04f05633286f3b45b381b4acc4602.png

 

Share this post


Link to post
Share on other sites


I consider someone extremely talented if their work is robust and easy to interpret.  I personally like the style.  Really great work.  I appreciate that you shared it with us.


PoorWDm.png?width=360&height=152

Share this post


Link to post
Share on other sites


6 hours ago, _Rocket_ said:

I'm still gonna do the if(!bool) return; thing though, even if it does result in a couple extra instructions during compile time. It just looks so much cleaner to me.

I actually don't think there is much difference in terms of instructions between doing this or not. And I agree with you that it is much cleaner as you avoid a lot of nested if-statements. My software architecture professor taught us to do it too. 😄 Just to show it working I'll share an example in Lua:

local whitelist = {"35", "36", "37", "38", "39", "40", "41", "42", "43", "14", "15", "16", "24", "25", "26" }

hook.Add("PlayerUse", "SWRPButtons", function (ply, ent)
    --print(ent:GetModel())
    local e = ent:GetModel()
    e = tostring(e)
    if !table.HasValue(whitelist, tostring(ply:Team())) then
        if ent:GetClass() == "func_button" then
                if e == "*426" || e == "*424" || e == "*413" || e == "*425" || e == "*176" || e == "*159" || e == "*158" || e == "*157" || e == "*371" || e == "*370" || e == "*412" || e == "*413" || e == "*486" || e == "*487" || e == "*726" || e == "*187" || e == "*58" || e == "*405" || e == "*187" || e == "*58" || e == "*696" || e == "*40" || e == "*43"    then
                return false;
                end
        end
    else
        return true;
    end
end);

This code has a lot of issues, so I made a few changes an adapted above technique and it came a lot easier on the eye (at least to me):

local whitelisted_teams = {"35", "36", "37", "38", "39", "40", "41", "42", "43", "14", "15", "16", "24", "25", "26" }
local restricted_buttons = {"*426", "*424", "*413", "*425", "*176", "*159", "*158", "*157", "*371", "*370", "*412", "*413", "*486", "*487", "*726", "*187", "*58", "*405", "*187", "*58", "*696", "*40", "*43"}

hook.Add("PlayerUse", "SWRPButtons", function (ply, ent)
    -- Ignore non-buttons
    if ent:GetClass() ~= "func_button" then return end

    -- Ignore buttons that are not restricted.
    local e = tostring(ent:GetModel())
    if !table.HasValue(restricted_buttons, e) then return end
    
    -- Reject use if the player is not on a whitelisted team.
    if !table.HasValue(whitelisted_teams, tostring(ply:Team())) then return false end
end);

 


Wanna know what I am up to? Take a look at my personal Trello board or my cards on the Development Trello board!

Share this post


Link to post
Share on other sites


@Nick @_Rocket_

 

Thank you both for sharing your coding styles and making this thread very interesting. Thanks for the "godbolt" website, I'll be using this more often. A neat fact I learned is that switch statements are faster than nested if-else-if statements, here's the link to the original thread: https://stackoverflow.com/questions/2158759/case-vs-if-else-if-which-is-more-efficient

 

Results:

http://www.blackwasp.co.uk/SpeedTestIfElseSwitch.aspx

 

 

@Beaker

I've been good man, how you have been? I'll be on soon!

 


- Spectre

Share this post


Link to post
Share on other sites


Posted  Edited by Joshy

One of my personal favourites although I suspect it's the least for others.

 

 

There is a hardware reason for that.  Conditional if/else statements have exactly the same hardware implementation as a switch.  It's called a multiplexer (commonly referred to as MUX).  What happens when you cascade your if statements you're also cascading a MUX in the hardware, which inherently increases the physical length the signal has to travel.  I show the logic for a MUX at the end of the guide.

 

What's happening in your switch statement is also a MUX.  If you only have two cases it's the same as the if else statement.  If you add more cases, then it's not cascading...  it's cascoding (things are stacked on top of each other).  The hardware becomes substantially larger and more complicated for the hardware person, but the physical length the actual signal has to travel from left to right is substantially shortens as it passes through less combinational logic.

 

I show the visualization in another guide, but I don't refer to the MUX at that topic.

 

 

I'd personally be curious to see a test that does just one if-else statement versus a switch that has two cases (or one case and a default) because it's physical characteristics should be the same.

Edited by Joshy

PoorWDm.png?width=360&height=152

Share this post


Link to post
Share on other sites


Posted  Edited by Joshy

I decided to scan it just in case you really were curious.

 

6erhho0.jpg

 

edit: A second look since I scanned it in quickly I am noticing I made a mistake on that C one at the very bottom it really that 3-bit AND not a 2-bit one otherwise the output is A or C if you're intending only for A.

 

 

Yes, I've been a little bored during this COVID 19 shelter in place stuff.

 

The key thing here is that all your software is backed by hardware.  It's possible to sweep through different commands first before reaching the other in software, but the cascade if is already at a physical disadvantage compared to the switch.  The drawing at the very end is only for a 2 bit if or switch with three plausible outcomes (technically four), and so I could see it having a very large impact when it's larger like 32 bits or many many cascaded stages.

Edited by Joshy

PoorWDm.png?width=360&height=152

Share this post


Link to post
Share on other sites


I really like how much you seem to be in this.  I thought most schools were out, but maybe CS it makes sense it can be taken online.  I'm going back to school myself for a graduate degree, but if I can manage the time I've been thinking about taking computer science classes at a community college if I can manage the time.  What year are you?

 

I'm curious to hear what they say and maybe even a little about their background.  I remember for one class project we decided to make an optical keyboard, but it was only a few keys for proof of concept.  We were asking him how to program the controller to make it work and he brought up all of this stuff...  I was so mad because I was like what do you mean "logic gates"?  Like...  how are we going to get ANDs and ORs?  It was a really great project I cannot believe I could actually find a copy of the picture because it was from about 7 or 8 years ago.  It worked as expected and was more advanced than what we had proposed to the professor you can see from the four dots we made each dot a "key" and then it responded to various type of swipes.

 

1lXl9Kk.jpg

 

 


PoorWDm.png?width=360&height=152

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


×
×
  • Create New...