Triangle Wave (My first Arduboy game)

This is my first Arduboy Game, Triangle Wave.

TriangleWave.hex (26.3 KB)

You play a as a Triangular Ship, Sawblades will appear randomly and you gain score by shooting them.

This is my first game i made from scratch for the Arduboy, so it’s not perfect…
I might share the source code, but i don’t know if it matters the code being messy…

EDIT: The source code is now released!

3 Likes

Great start!

I score 1 :frowning:

2 Likes

Not at all. Everybody has written messy code at some point,
it’s to be expected from someone who is new to the language.

Though you should specify whether you’re looking for suggestions about how to improve or not.

You should also consider whether you’d be willing to publish the code under an open source licence so others can benefit from it (e.g. by reusing parts of it).

2 Likes

I’m fine with some criticism.

Here it is, under MIT:

1 Like

Neat.

I suggest starting the game on a ground platform so people can get their bearings without moving at first.

With a “Hold up to fly” message overlay that stays until the user press up and starts flying at which point the game will move forward.

It’s a bit jarring when someone presses A to start and then near-instantly crashes.

3 Likes

Thank you for the feedback!
I’ve put some of your improvements on the game, thanks!!

The biggest issue with your code is that inggame is far too long.
You ought to break it up into several smaller functions.

Everywhere you have a comment like // move bullets or // move sawblades,
you could take that code and turn it into a new function,
e.g. void moveBullets(), void moveSawblades().

Most of your other issues are relatively minor.


Though one important issue is your include guards:


The #endif is supposed to go at the end of the file, not right after the #define.

The whole point of having include guards is to make sure the compiler only sees the code in the .h files once, otherwise it produces a ‘multiple definition error’.

For more info, have a look at the Wikipedia article:

1 Like

I know its not standard - though certainly ubiquitous - but I use the #pragma once directive which would remove this issue.

1 Like

It’s one of the few non-standard things I don’t mind recommending.

I’ve heard rumours about why it hasn’t been standardised and I can think of a long list of excuses,
but I think it’s getting to the point where not standardising it is just silly.

(If you want a good laugh, I found a GCC bug report from 2003 where someone claimed “Pragma once is obsoleted, in other words it will be removed in the next version
anyway.
”. Hindsight is a wonderful thing.)

I tried fixing the long inggame() (now renamed to ingame() ) function and the include guards. Is this good?



(i forgot a comment, the commit name is the same as above because i don’t know much git)

1 Like

Yes, that’s much better.

There’s still a number of remaining issues but the majority are stylistic issues which you might not be concerned with.

Examples
  • Use of abbreviations like ‘Objs’, ‘Gen’ and ‘BulSaw’
  • Function names not beginning with verbs
    • E.g. instead of sawbladeGen, have generateSawblades, instead of ingame, have updateGameState, instead of titlescreen have updateTitlescreenState etc.
  • Hungarian notation (e.g. obj_, spr_) is bad
    • You could either get rid of it, or put related objects in a separate namespace
  • Doing struct Type {} object; is fairly common in C but considered bad in C++, it’s better to do struct Type {}; and then later Type object;
  • Assining 0 or 1 instead of false or true to a bool is bad form
    • As is treating 0 and false or 1 and true as synonyms. They are not, 0 and 1 are integers, not booleans.
  • The game states should be represented by an enum class
    • Scoped enumerations (enum class) are typesafe, integers and plain enums (enum) aren’t.
    • Also macros are evil, you should aim to have absolutely no macros in your program if you can manage it.

There’s also a handful that are design issues but only affect the flexibility/scalability of your code.
I.e. they aren’t a problem now but might become a problem if your game grew larger.

Examples
  • Mixing input handling with other code (violates ‘Separation of Concerns’)
    • E.g. drawPlayerObjs should only be a drawing function, but it checks input
  • Other separation of concerns issues
    • E.g. updating backgroundshift whilst drawing the backround. This will cause problems if you want to add a pause feature
  • You aren’t making use of Sprites’ frames capability when you could benefit from it
    • E.g. you have separate sprites for ‘ship up’, ‘ship down’, ‘ship middle’ when you could just have a single spritesheet and use the frames parameter

But there’s one thing that’s a definite issue that you probably aren’t aware of.
String literals are stored in RAM by default, which means when you write something like arduboy.print("Hold Up to Fly!") the "Hold Up to Fly!" is wasting RAM.

The solution to this is to use the F macro provided by Arduino,
i.e. arduboy.print(F("Hold Up to Fly!")).
This stores the string in progmem instead,
and ensures that print knows the string is in progmem rather than RAM.

1 Like