Pixel drawing app

That isn’t much of an issue.
Redrawing the screen would use extra CPU cycles,
but you won’t need many CPU cycles for a drawing program.

If it’s a problem then you can just wait until the user presses a button before calling arduboy.display().

Being able to see the cursor in all situations requires some thought. If you make it all white, it will disappear in large white areas (and similarly for all black).

You could use all white but put a black boarder around it, like a mouse pointer does. This obscures more of the actual drawn pixels underneath.

You could make the cursor the inverse of the pixels it covers (exclusive “or”). The cursor may become hard to see if the drawn pixel pattern is complex.

You could flash the cursor. This is probably the best but the hardest to accomplish.

Thanks for the interesting discussion, here my progress.


Still nothing really working properly but I see potentials!

Anyway I don’t understand why it always piant white even when mouse is not pressed and some pixels become randomly black…

Line 60:

arduboy.drawPixel(ballx, ballx, BLACK);

should it be? ballx, bally
(Same for line 52?)

1 Like

You’re right. It is working now!

2 Likes

Sorry to bring up coding style so soon but…

This:

if(arduboy.pressed(A_BUTTON)) {
  arduboy.drawPixel(ballx, bally, WHITE);
} else {
  if (cursorArea==0) {
    arduboy.drawPixel(ballx, ballx, BLACK);
 }
}

Would make more sense as:

if(arduboy.pressed(A_BUTTON)) {
  arduboy.drawPixel(ballx, bally, WHITE);
} else if (cursorArea == 0) {
  arduboy.drawPixel(ballx, ballx, BLACK);
}

And of course you can (and should) use && instead of and.
E.g.

if(arduboy.pressed(UP_BUTTON) and bally > 0) {
  bally = bally - cursorshift;
}

Could be:

if(arduboy.pressed(UP_BUTTON) && bally > 0) {
  bally = bally - cursorshift;
}

I can think of a handful of other improvements,
but I don’t want to overload you with suggestions so soon.


The srand(7/8); part gives away that you’ve been reading Crait’s tutorials.

You might want to read this thread:

1 Like

Thanks for the advices, why && is better than “and”?
Does it perform better or is a matter of readability?

Regarding srand I forgot to canceling it from the original code, I guess I don’t need a random function in my code…

Any idea on how to make the blinking cursor? Should I use a timeout or infinite loop.

You could use everyXFrames () to draw the cursor.

I’m sure @Pharap will have a better technical solution though :stuck_out_tongue:

1 Like

As @Keyboard_Camper said, I’d use arduboy.everyXFrames() to flip the cursor at the desired rate. If you set the frame rate to 30 FPS, to change the cursor colour every ½ second you would do it every 15 frames.

I’d keep a global variable for the cursor colour and use it in a function to draw the cursor.

#include <Arduboy2.h>

Arduboy2 arduboy;

byte cursorColour;

void setup() {
  arduboy.begin();
  arduboy.setFrameRate(30);
  arduboy.clear();
}

void loop() {
  //Prevent the Arduboy from running too fast
  if(!arduboy.nextFrame()) {
    return;
  }

  int x = 5, y = 10; // set a fixed x, y location just for testing
  
  if (arduboy.everyXFrames(15)) {
    cursorColour = cursorColour == BLACK ? WHITE : BLACK;
    drawCursor(x, y, cursorColour);
  }

  // rest of loop() code

  arduboy.display();
}

void drawCursor(int x, int y, byte colour) {
  // draw whatever cursor shape is desired at the coordinates
  // given in the arguments and with the given colour

  // For example:
  arduboy.drawLine(x, y - 3, x, y - 1, colour);
  arduboy.drawLine(x, y + 1, x, y + 3, colour);
  arduboy.drawLine(x - 3, y, x - 1, y, colour);
  arduboy.drawLine(x + 1, y, x + 3, y, colour);
}
1 Like

I’m almost there, but still there’s something broken.
The blinking is somehow covered by an always white pixel and the cursor get sometime painted even when Button A is not pressed.
Code here https://github.com/Gusepo/arduboy_1st_test/blob/master/1stgame.ino

I don’t see you using the justpressed variable for anything useful and I’m not sure what you intend to use it for. If you want to detect a button press once until it’s released, the Arduboy2 library has a justPressed() function which is aided by the pollButtons() function.

You call pollButtons() at the start of the loop() after the nextFrame() test. You can then use justPressed() to detect a button press only once.

If you use the pressed() function, it will return true for as long as the button is held down, which may be over multiple frames.

1 Like

It’s mainly about what’s common practice.
&& is the most commonly used variant, to the point that most C++ programmers have probably never even encountered and.

and (and its relatives, e.g. or) are actually caleld the alternative operator representations because they are intended to be alternatives for when &&, || etc are not available for technical reasons.
Those alternative operators only exist because a long time ago there were computers that didn’t have certain symbols (e.g. &, |, ^) on their keyboard or possibly in their text encoding.

Technically a framerate independent solution would be best,
but considering the circumstances that’s probably going to be both too much of a learning curve and not worth the effort (it’s a blinking cursor, not the physics of a virtual world),
so in this case I think arduboy.everyXFrames is a suitable option.

loop is automatically an infinite loop.
When the loop function ends, it starts from the beginning again.

Using everyXFrame would be good enough for the timing,
but the complicated bit would be saving and restoring part of the screen buffer.

Technically it’s not. Unless you specifically write loop() to never exit (which isn’t a good idea), it only performs its function once. loop() keeps starting from the beginning only because main() (which is “hidden” in the Arduino “O/S”) calls it repeatedly.

And note that because of this, you have to be careful with any local variables created in the loop() function. They will be destroyed and cease to exist each time loop() executes from the beginning. If you create a local variable near the start of loop(), then set a value in it somewhere later, it will no longer contain that value when loop() starts again. It will actually be a new instance of that variable.

Which I’ve already written example code for.

If you don’t write your own main, the function will indefinitely be called again after exiting,
hence it’s automatic in the sense that it’s the default behaviour for the environment.
The programmer has to add something extra to change the behaviour.

That’s true of any function.

It’s not the actual copying that’s the difficult part,
it’s the when to save and restore that’s difficult.

1 Like

Not really. You restore before moving the cursor to a new location then save the new area that you’re going to move to before drawing the cursor in the new position.

@Giuseppe I’m not sure if it’s been pointed out but I noticed your git you are using the older Arduboy library rather than the newer Arduboy2 library.

1 Like

That only covers a non-blinking cursor though.
The blinking complicates matters.

You have to factor in whether or not the cursor was blinking before moving and how to handle the A button being pressed (i.e. whether to draw to the screen, or the buffer, or both.)

I’ve made a basic prototype.
Hopefully all of this makes sense,
but if there’s anything you don’t understand yet then don’t hesitate to ask.

1 Like

Thanks! I’m studying it.
I don’t understand what’s happens inside

if(arduboy.everyXFrames(15))

I will try to modify to have just 1 pixel cursor blinking and I’d like also to allow to keep A button clicked and draw. I will try in the weekend and keep everyone posted.

1 Like