Help With Game Develeopment

Hi everyone! Need some help. On @crait 's ToChars tool, whenever I attempt to upload my sprite (which is actually just an image for the title screen of a game I am working on) I just get the same binary characters over and over again.

Here is my image;
TitleScreen%20(2)

And here is what I get when I use ToChars, with the only parameters changed being the height and width parameters to match the resolution of the image, 128x64.

Any help is appreciated!

I think the problem is that your blacks aren’t black, they’re slightly off-black (specifically (2, 2, 2) in RGB).

If I edit the image and replace the (2, 2, 2) values with (0, 0, 0), like so:
b6ff119f842ce2111badaa037635cc87b7bc04f9

Then I get a different result:

In full:

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x1f, 0xf, 0x8f, 0xc7, 0xc7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf1, 0xf1, 0xf1, 0xe1, 0xc3, 0x87, 0x8f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x8f, 0x87, 0xc3, 0xe1, 0xf1, 0xf1, 0xf1, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xe3, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xc7, 0xc7, 0x8f, 0xf, 0x1f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x3, 0x80, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x3f, 0x3, 0x3, 0x3, 0x3, 0x3f, 0x3f, 0x3f, 0x3, 0x3, 0x3, 0x3, 0x3f, 0x3f, 0x3f, 0x3, 0x3, 0x3, 0x3, 0x3f, 0x3f, 0x3f, 0x3, 0x3, 0x3, 0x3, 0x3f, 0x3f, 0x3f, 0x3, 0x3, 0x3, 0x3, 0x3f, 0x3f, 0x1f, 0xf, 0x7, 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x80, 0x3, 0x1f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x7, 0x00, 0xe0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xe2, 0xe2, 0x6, 0x6, 0xdc, 0xc0, 0x9e, 0x5e, 0xc0, 0xdc, 0xdc, 0x1c, 0xd0, 0x80, 0x1c, 0xc0, 0x9c, 0x9c, 0x9c, 0x1c, 0x1c, 0x9c, 0x9c, 0x9c, 0xc0, 0xdc, 0xdc, 0xdc, 0x1c, 0xdc, 0xdc, 0xc0, 0xde, 0xde, 0xde, 0xde, 0x6, 0x6, 0xe2, 0xe2, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x00, 0x7, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7, 0x00, 0xf0, 0x3c, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1, 0xf7, 0x6, 0x21, 0xc3, 0xe7, 0xc0, 0xb7, 0x77, 0x64, 0xe9, 0xe7, 0xef, 0xcf, 0x00, 0x00, 0xef, 0xef, 0xef, 0xef, 0xe7, 0xf7, 0xf7, 0xf0, 0xf7, 0xf7, 0xf7, 0x7, 0xb7, 0x1, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0xbf, 0xbf, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf0, 0x00, 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x9f, 0x9f, 0x8f, 0x87, 0xc7, 0xe1, 0xe0, 0xfc, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x7f, 0xbf, 0xbf, 0xbf, 0x7f, 0xff, 0x7f, 0x3f, 0xbf, 0x3f, 0x7f, 0x1, 0xff, 0x7f, 0xbf, 0xbf, 0xbf, 0x7f, 0xff, 0x3f, 0x7f, 0xbf, 0xbf, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x3e, 0xbc, 0xb2, 0xae, 0x80, 0xbe, 0xbe, 0xbe, 0x3c, 0x3c, 0x00, 0x5d, 0x00, 0x00, 0x7d, 0x3d, 0xbd, 0xbc, 0x2, 0xb8, 0xbc, 0x80, 0xbc, 0xbe, 0xbe, 0x3e, 0xa2, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xef, 0xef, 0xef, 0xef, 0x00, 0xff, 0xef, 0x1, 0xef, 0xff, 0xef, 0x1, 0xef, 0xff, 0x7f, 0xbf, 0xbf, 0xbf, 0x7f, 0x3f, 0xff, 0x7f, 0xbf, 0xbf, 0xff, 0x1, 0xff, 0x7f, 0xbf, 0xff, 0xff, 0xfc, 0xe0, 0xe1, 0xc7, 0x87, 0x8f, 0x9f, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xfc, 0xf9, 0xfb, 0xf9, 0xfc, 0xf8, 0xff, 0xfc, 0xfa, 0xfa, 0xfa, 0xfa, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x00, 0x00, 0xf0, 0xf6, 0xf7, 0xf0, 0xf7, 0xf7, 0xf7, 0x7, 0xf7, 0xf7, 0xe7, 0xef, 0x6f, 0x28, 0x43, 0x00, 0x00, 0xcf, 0xcf, 0xcf, 0xef, 0xe0, 0xf7, 0xf7, 0x7, 0xf7, 0xf7, 0xf7, 0xf0, 0xf7, 0xf6, 0xf0, 0x00, 0x00, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xfc, 0xfb, 0xfb, 0xfb, 0xfc, 0xf8, 0xff, 0xfc, 0xfb, 0xfb, 0xff, 0xf8, 0xfe, 0xfd, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xdf, 0xdf, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x7f, 0xff, 0x3f, 0x9f, 0xdf, 0x9f, 0x3f, 0xff, 0x7f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x7, 0x3, 0x1, 0x00, 0x00, 0x00, 0x30, 0xb8, 0x3d, 0x9d, 0x9d, 0x81, 0xad, 0xb5, 0x81, 0x38, 0xbd, 0x3d, 0xbc, 0x80, 0xbd, 0xbc, 0xb1, 0xa4, 0x8c, 0x1d, 0xbd, 0xbd, 0x81, 0xbd, 0x3d, 0xbd, 0xbc, 0xbd, 0xbd, 0xbd, 0x81, 0xbd, 0xbd, 0x3d, 0xb8, 0xb0, 0x80, 0x00, 0x00, 0x1, 0x3, 0x7, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xfd, 0xfd, 0xfe, 0x83, 0xf7, 0xfb, 0xf7, 0xff, 0xc7, 0xab, 0xff, 0xa7, 0xab, 0xdb, 0xff, 0xa7, 0xab, 0xdb, 0xff, 0xff, 0xff, 0xff, 0x80, 0xfb, 0xfb, 0xfb, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0xf7, 0xf7, 0x7, 0xe0, 0xe7, 0x7, 0xf3, 0x3, 0x73, 0x4, 0xf6, 0xf7, 0xf0, 0x7, 0xf7, 0xf7, 0xf7, 0x7, 0xf7, 0xf7, 0x00, 0xf7, 0xe7, 0xe7, 0x7, 0xd0, 0xd7, 0xb7, 0x7, 0x97, 0xd7, 0xb7, 0x7, 0x27, 0xe0, 0x7, 0xf7, 0xf7, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 

By the way, other image converters are available, and generally white on black is preferred for sprites because unlit pixels (i.e. black) drain less power than lit pixels (i.e. white).

2 Likes

OK Great, thank you so much for helping me out.

Once I’ve gotten the basic framework into place for this trial game of sorts, I will go back to change things like the images to improve battery life.

One more, slightly off topic thing; could you maybe point me to where I can learn about coding projectiles (such as the bullets from @filmote 's 1943: Battle of Midway? Thanks!

1 Like

Bullets are simply an image that you move across the screen.

I created a simple struct:

struct Bullet {
  uint8_t x;
  uint8_t y
  bool active;
}

And an array of Bullets:

Bullet bullets[10];

When I want to fire a bullet, I circle through the elements of the array and find one that is inactive and use it.

You can save memory by removing the ‘active’ property by assigning a value of (say) 255 to either the X or Y value to indicate that it is inactive.

BTW, the tutorial you are using is quite old and refers to the original Arduboy library rather than the Arduboy2 library. The graphics structure changed between the two libraries with many new features found in the later version.

If you are using the Arduboy2 library (and you really should be!), use the Team ARG grpahics convertor found here:

https://teamarg.github.io/arduboy-image-converter/

2 Likes

I’ll make sure to use Team A.R.G’s graphics converter. Thank you!

1 Like

One more question :blush:

As of right now the way I am changing the angle at which the gun on the tower is, I have multiple different frames and am switching between them to change the angle. Is there a better way I can do this? I only need to change 4-10 pixels each frame; by pressing up or down.

You could leave the gun out of the sprite you drew and instead use drawLine, fillRect, fillRoundRect, etc. whatever fits the shape the most to draw the gun over the sprite. Changing the x&y values with user impute would then redraw the shape as it “moves”. I’m assuming this is from a side angle and not top down since you said up/down

arduboy.drawBitmap(0,0 playField, 128, 64);
arduboy.drawLine(x1, y1, x2, y2, WHITE);
if( arduboy.justPressed(UP_BUTTON) == true){
      y2++;
}
if( arduboy.justPressed(DOWN_BUTTON) == true){
      y2--;
}`

So it took me a few minutes to figure out that the “drawLine” function needed a color assigned XD, but otherwise, it is a much better solution that what i had before. Greatly reduced my overall storage usage.

In case anyone wants to look at it, here is what I have so far. It’s pretty much just the code to display the images and move the gun on the tower. I am brand new to C++, having spent all of thirty minutes going through the tutorials, and maybe a total of 90 minutes actually working on this XD. Any suggestions or comments are greatly appreciated!

//ThaddeusSM
//03/16/18

//Libraries
#include <Arduboy2.h>
Arduboy2 arduboy;

//Variables
const unsigned char titleScreen[] PROGMEM = { 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x1f, 0xf, 0x8f, 0xc7, 0xc7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf1, 0xf1, 0xf1, 0xe1, 0xc3, 0x87, 0x8f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x8f, 0x87, 0xc3, 0xe1, 0xf1, 0xf1, 0xf1, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xe3, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xc7, 0xc7, 0x8f, 0xf, 0x1f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x3, 0x80, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x3f, 0x3, 0x3, 0x3, 0x3, 0x3f, 0x3f, 0x3f, 0x3, 0x3, 0x3, 0x3, 0x3f, 0x3f, 0x3f, 0x3, 0x3, 0x3, 0x3, 0x3f, 0x3f, 0x3f, 0x3, 0x3, 0x3, 0x3, 0x3f, 0x3f, 0x3f, 0x3, 0x3, 0x3, 0x3, 0x3f, 0x3f, 0x1f, 0xf, 0x7, 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x80, 0x3, 0x1f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x7, 0x00, 0xe0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xe2, 0xe2, 0x6, 0x6, 0xdc, 0xc0, 0x9e, 0x5e, 0xc0, 0xdc, 0xdc, 0x1c, 0xd0, 0x80, 0x1c, 0xc0, 0x9c, 0x9c, 0x9c, 0x1c, 0x1c, 0x9c, 0x9c, 0x9c, 0xc0, 0xdc, 0xdc, 0xdc, 0x1c, 0xdc, 0xdc, 0xc0, 0xde, 0xde, 0xde, 0xde, 0x6, 0x6, 0xe2, 0xe2, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x00, 0x7, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7, 0x00, 0xf0, 0x3c, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1, 0xf7, 0x6, 0x21, 0xc3, 0xe7, 0xc0, 0xb7, 0x77, 0x64, 0xe9, 0xe7, 0xef, 0xcf, 0x00, 0x00, 0xef, 0xef, 0xef, 0xef, 0xe7, 0xf7, 0xf7, 0xf0, 0xf7, 0xf7, 0xf7, 0x7, 0xb7, 0x1, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0xbf, 0xbf, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf0, 0x00, 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x9f, 0x9f, 0x8f, 0x87, 0xc7, 0xe1, 0xe0, 0xfc, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x7f, 0xbf, 0xbf, 0xbf, 0x7f, 0xff, 0x7f, 0x3f, 0xbf, 0x3f, 0x7f, 0x1, 0xff, 0x7f, 0xbf, 0xbf, 0xbf, 0x7f, 0xff, 0x3f, 0x7f, 0xbf, 0xbf, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x3e, 0xbc, 0xb2, 0xae, 0x80, 0xbe, 0xbe, 0xbe, 0x3c, 0x3c, 0x00, 0x5d, 0x00, 0x00, 0x7d, 0x3d, 0xbd, 0xbc, 0x2, 0xb8, 0xbc, 0x80, 0xbc, 0xbe, 0xbe, 0x3e, 0xa2, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xef, 0xef, 0xef, 0xef, 0x00, 0xff, 0xef, 0x1, 0xef, 0xff, 0xef, 0x1, 0xef, 0xff, 0x7f, 0xbf, 0xbf, 0xbf, 0x7f, 0x3f, 0xff, 0x7f, 0xbf, 0xbf, 0xff, 0x1, 0xff, 0x7f, 0xbf, 0xff, 0xff, 0xfc, 0xe0, 0xe1, 0xc7, 0x87, 0x8f, 0x9f, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xfc, 0xf9, 0xfb, 0xf9, 0xfc, 0xf8, 0xff, 0xfc, 0xfa, 0xfa, 0xfa, 0xfa, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x00, 0x00, 0xf0, 0xf6, 0xf7, 0xf0, 0xf7, 0xf7, 0xf7, 0x7, 0xf7, 0xf7, 0xe7, 0xef, 0x6f, 0x28, 0x43, 0x00, 0x00, 0xcf, 0xcf, 0xcf, 0xef, 0xe0, 0xf7, 0xf7, 0x7, 0xf7, 0xf7, 0xf7, 0xf0, 0xf7, 0xf6, 0xf0, 0x00, 0x00, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xfc, 0xfb, 0xfb, 0xfb, 0xfc, 0xf8, 0xff, 0xfc, 0xfb, 0xfb, 0xff, 0xf8, 0xfe, 0xfd, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xdf, 0xdf, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x7f, 0xff, 0x3f, 0x9f, 0xdf, 0x9f, 0x3f, 0xff, 0x7f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x7, 0x3, 0x1, 0x00, 0x00, 0x00, 0x30, 0xb8, 0x3d, 0x9d, 0x9d, 0x81, 0xad, 0xb5, 0x81, 0x38, 0xbd, 0x3d, 0xbc, 0x80, 0xbd, 0xbc, 0xb1, 0xa4, 0x8c, 0x1d, 0xbd, 0xbd, 0x81, 0xbd, 0x3d, 0xbd, 0xbc, 0xbd, 0xbd, 0xbd, 0x81, 0xbd, 0xbd, 0x3d, 0xb8, 0xb0, 0x80, 0x00, 0x00, 0x1, 0x3, 0x7, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xfd, 0xfd, 0xfe, 0x83, 0xf7, 0xfb, 0xf7, 0xff, 0xc7, 0xab, 0xff, 0xa7, 0xab, 0xdb, 0xff, 0xa7, 0xab, 0xdb, 0xff, 0xff, 0xff, 0xff, 0x80, 0xfb, 0xfb, 0xfb, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0xf7, 0xf7, 0x7, 0xe0, 0xe7, 0x7, 0xf3, 0x3, 0x73, 0x4, 0xf6, 0xf7, 0xf0, 0x7, 0xf7, 0xf7, 0xf7, 0x7, 0xf7, 0xf7, 0x00, 0xf7, 0xe7, 0xe7, 0x7, 0xd0, 0xd7, 0xb7, 0x7, 0x97, 0xd7, 0xb7, 0x7, 0x27, 0xe0, 0x7, 0xf7, 0xf7, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
};
const unsigned char PROGMEM Gameplay1[] =
{
// width, height,
128, 64,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0xff, 0x7f, 0x3e, 0x18, 0x18, 0xf8, 0x1e, 0x1f, 0x3f, 0x7e, 0xf8, 0xf8, 0xf8, 0x3e, 0x1f, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x04, 0xfc, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0xfc, 0x04, 0x0f, 0xff, 0xf0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x59, 0xc9, 0x49, 0x49, 0x49, 0x7f, 0x51, 0x51, 0x59, 0xc9, 0x49, 0x49, 0xff, 0xff, 0xa2, 0xa2, 0xff, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x10, 0x1f, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x10, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x04, 0xfc, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0xfc, 0x04, 0x04, 0x04, 0x05, 0x07, 0x07, 0x0e, 0x1c, 0xfc, 0xf8, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x0c, 0x0f, 0x4c, 0x8c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c, 0x0c, 0x8c, 0x8c, 0x0c, 0x4c, 0x0c, 0x0e, 0x0f, 0x4f, 0x0f, 0x08, 0x08, 0x08, 0x48, 0x48, 0x48, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x88, 0x48, 0x48, 0x48, 0x48, 0x08, 0x08, 0x08, 0x08, 0x08, 0xc8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xc8, 0x88, 0x48, 0x08, 0x08, 0x08, 0x08, 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x48, 0x48, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x88, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xc8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x48, 0x08, 0x08, 0x08, 0x08, 0x08, 0x88, 0x88, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
0x00, 0x00, 0x08, 0x18, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x08, 0x00, 0x20, 0x21, 0x60, 0x00, 0x00, 0x04, 0x03, 0x04, 0x04, 0x00, 0x40, 0x20, 0x00, 0x00, 0x0e, 0x08, 0x06, 0x00, 0x22, 0x60, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x60, 0x20, 0x46, 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x40, 0x00, 0x30, 0x0c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x10, 0x20, 0x28, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x01, 0x10, 0x50, 0x00, 0x05, 0x04, 0x00, 0x00, 0x1c, 0x30, 0x00, 0x00, 0xe0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x84, 0x04, 0x04, 0x00, 0x70, 0x00, 0x03, 0x06, 0x00, 0x60, 0x00, 0x09, 0x01, 0x01, 0x01, 0x00, 0x04, 0x01, 0x21, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x20, 0x24, 0x06, 0x00, 
};



int gamestate = 0;
int justpressed = 0;
int x1 = 20;
int y1 = 28;
int x2 = 28;
int y2 = 28;

//Setup Script
void setup() {
  arduboy.begin();
  srand(7/8);
  arduboy.setFrameRate(30);
  arduboy.clear();
}

//Game Code
void loop() {
  if(!arduboy.nextFrame()) {
    return;
  }
  arduboy.clear();
  switch(gamestate){
    case 0:
    arduboy.drawBitmap(0, 0, titleScreen, 128, 64, WHITE);
    if(arduboy.pressed(A_BUTTON) and justpressed == 0) {
      justpressed = 1;
      gamestate = 1;
    }
      break;
    case 1:
    arduboy.drawBitmap(0, 0, Gameplay1, 128, 64, WHITE);
    arduboy.drawLine(x1, y1, x2, y2, WHITE);
    if(arduboy.pressed(A_BUTTON) and justpressed == 0) {
      justpressed = 1;
      gamestate = 0;
    }
    if(arduboy.pressed(UP_BUTTON)) {
      y2--;
    } 
    if(arduboy.pressed(DOWN_BUTTON)){
      y2++;
    }
    if(y2 > 40) {
      y2--;
    } else if(y2 < 14) {
      y2 ++;
    }
      break;
   }
  if(arduboy.notPressed(A_BUTTON)) {
    justpressed = 0;
  }


  arduboy.display();
}

Its looking good.

if(arduboy.pressed(UP_BUTTON)) {
   y2–;
}
if(arduboy.pressed(DOWN_BUTTON)){
   y2++;
}
if(y2 > 40) {
   y2–;
} 
else if(y2 < 14) {
   y2 ++;
}

[/quote]

In a couple of spots you have y2-; which should. be y2 - -;

The way you have implemented the gun looks a little strange as the gun stretches at the top and bottom of the arc. Currently you store X1/y1 and x2/y2 coordinates for the barrel and you can calculate a 1:n gradient and move the bullets forward 1: and up or down n each frame.

An alternate approach that makes the gun look a little better as it rotates through its arc is to actually not store the coordinates of the right hand side of the barrel but instead have an angle you increase / decrease with the A and B buttons. You could then calc the end point using a little trigonometry and get a better rendering.

The angle can then be used to calculate the gradient for the actual bullet movement.

I would change the bullet struct to look like this:

struct Bullet {
  uint8_t x;
  uint8_t y
  uint8_t xDelta;
  int8_t yDelta;
  bool active;
}

So when you launch the bullet you calculate the number of pixels you want the bullet to move each frame in both the X or Y axis and store them in the bullet struct. On each frame, loop through the bullets and for each active one, increase the X and Y by the delta. Y can be negative if they are shooting up in the air. As the bullet hots the ground or leaves the screen set it to inactive.

How can I change the way the gun rotates so that I can use the angle to calculate the bullet travel? Also, am I correct in assuming that I put the bullet struct code into my gameplay gamestate?

Edit: I looked at those places which showed one minus sign instead of two, it seems as though it was just the webpage that formatted it like that. Next time I share a big piece of code, I’ll upload it to github or something.

So your gun starts at X1 and Y1, right?

Define another variable that records the angle of the gun from say -30 degrees to 30 degrees above the horizon.

To calc the barrel end position, use the maths:

x2 = x1 + cos(angle) * barrelLength;
y2 = y1 + sin(angle) * barrelLength;

To the calc the XDelta and yDelta for the bullet, you can take the ratio of cos(angle) compared with sin(angle). When the angle is 45 degrees sin() and cos() will return the same value (0.707…) so the ration is 1:1 or 1 upward and 1 right movement per frame.

When the guns barrel is at 30 degrees, sin() returns 0.500 and cos() returns 0.866 which is a 1:1.732 ratio. Therefore for every 1.732 the bullet travels in the right direction, it travels one pixel in the Y direction.

The Arduboy sucks at sin / cos / tan and floating point in general.

Have a look at > Arduboy 3D demo and [WIP] 3D starfield Demo for discussion and code on how to do it in such a little environment.

@Pharap released a great little library for fixed point calculations if you find the math and rendering is too slow or two large (from a memory point of view) when using floating points. See here > A Fixed Point Arithmetic Library

Finally, shooting at arbitrary angles is probably one of the hardest things you can do on an Arduboy. Stick at it and ask questions!

If it all gets too hard, you can change the gun movement so it only moves between fixed, known angles - you can then have an array of the pre-calculated barrel end points and gradients. It will make the game easier to program but not quite as nice.

That makes sense as I simply couldn’t compile it and it was complaining about some unknown character at that point.

Alright, so i went ahead and installed @Pharap’s library, but I’m pulling a blank on what to do next. I have created the variable “gunAngle” for storing the angle of my gun; but I’m not sure how to measure said angle.

You don’t need to measure it, it just increases and decreases based on the players pressing the A and B button. Everything is then calculated from it.

Doesn’t your original code:

if(arduboy.pressed(UP_BUTTON)) {
   y2–;
}
if(arduboy.pressed(DOWN_BUTTON)){
   y2++;
}
if(y2 > 40) {
   y2–;
} 
else if(y2 < 14) {
   y2 ++;
}

Simply become:

#define MIN_GUN_ANGLE -30;
#define MAX_GUN_ANGLE 30;

if(arduboy.pressed(UP_BUTTON)) {
   gunAngle--
}
if(arduboy.pressed(DOWN_BUTTON)){
   gunAngle++;
}
if(gunAngle > MAX_GUN_ANGLE) {
   gunAngle = MAX_GUN_ANGLE;
} 
else if(gunAngle < MIN_GUN_ANGLE) {
   gunAngle = MIN_GUN_ANGLE;
}

I have used angles in degrees here but you may find that Radians work better in the Arduboy environment.

@Pharap’s library is a fixed point library but does not specifically address your situation. Unfortunately, you will still need to know how the maths works - google sin / cos / tan for an explanation.

Alright, I actually got it (sort of) working in my own code, but i think i better check out for now. Thanks for all of your help. I will continue working on it tomorrow.

No problem. Sorry my answers were a little ‘you could do this’ or ‘you could do that’ and they all led to areas that the Arduboy is not great at (floating point, sin / cos / tan) but if you get it right, the game will be great!

Suggestion 1:
Consider moving your images into a separate file and #include-ing that file.

Suggestion 2:
Avoid srand, use arduboy.initRandomSeed(),
unless you actually want the same random numbers each time.

Suggestion 3:
You don’t need your justPressed variable, Arduboy2 has a justPressed function, e.g. arduboy.justPressed(A_BUTTON)

Suggestion 4:
All the functions that take a colour are set to use WHITE by default if you don’t provide it so you could omit those if you wanted.

Suggestion 5:
Use &&, not and.
and is obscure and rarely used, and I’m pretty sure it only originally existed to provide support for computers that used a character encoding that didn’t have and ampersand (back in the days where computers used things other than ASCII and Unicode-based encodings).

Suggestion 6:
Instead of incrementing/decrementing y2 and then trying to correct it afterwards, avoid having to increment/decrement in the first place.
e.g.

if(arduboy.pressed(UP_BUTTON)) {
  if(y2 > 14) // y2 cannot go below 14
    y2--;
}
if(arduboy.pressed(DOWN_BUTTON)){
  if(y2 < 40) // y2 can only go up to 40
    y2++;
}

Incorporating @filmote’s gun angle code that becomes:

if(arduboy.pressed(UP_BUTTON)) {
  if(gunAngle > MIN_GUN_ANGLE)
    gunAngle--;
}
if(arduboy.pressed(DOWN_BUTTON)){
  if(gunAngle < MAX_GUN_ANGLE)
    gunAngle++;
}

Some other tips:

Tip 1:
Consider getting a Github account and posting your code there.
It makes it easier to ask for feedback without cluttering the forum with large blocks of code.

Tip 2:
If you do post code on the forum, format it using ` (graves).

For in-line code you can use single graves.
E.g. doing `this` would get you this

For blocks of code you can do:
```
this
```
Which becomes:

this

You can also specify the language by putting it after the first three graves, e.g.
```cpp
this
```
Becomes:

this

@ThaddeusSM, if you decide to try using fixed points,
I suggest you read A Fixed Point Primer first, to understand how they work.
Otherwise you might be a bit surprised by which numbers they can and can’t represent.

The short version is that they represent the stuff after the decimal point as a fraction over a power of two, so they have limited precision.
In the case of the Arduboy though, you don’t really need good precision because the screen is small.

I agree with @filmote here.
Working with angles almost always requires using fractional numbers (i.e. floating points or fixed points) and usually involves pi, trigonometry and other not very fun maths.

Personally I think this would be the best approach for a beginner to use.
(And for anyone who isn’t very good at maths, like me a few years ago.)

@ThaddeusSM, depending on how good your maths skills are and how much programming experience you have, you might want to do this instead. It won’t look as nice, but it would be easier to do and you wouldn’t have to do as much reading.

More importantly, look up “Unit Circle”.
I never fully understood sine or cosine until I saw a diagram of a unit circle.

In fact I think the explanation that worked for me was this one.
“Maths is fun” is my favourite website for maths stuff because it explains things in plain English instead of using a load of maths symbols that only experts understand anyway (like and and ).


(P.S. My ears are burning from all the @-mentions :P.)

No it doesn’t. If you leave off the color parameter for drawLine() (and the other drawing functions) it defaults to WHITE. That is, if you’re using the recommended Arduboy2 library, not the Ardbuboy library.

https://mlxxxp.github.io/documents/Arduino/libraries/Arduboy2/Doxygen/html/index.html

@ThaddeusSM,
I’ve done this for your previously posted code.