Create a Moving Square SSD1306 OLED

I'm currently trying to make a bullet shoot (square) out when a button is pressed in a sort of space invaders game I'm trying to make on an SSD1306 128x64 OLED display. So far this is what ive got but millis is just the most annoying thing ever so I'm struggling to:

  1. Make the bullet move independently from the paddle
  2. When you release the button the bullet keeps moving instead of disappearing

Any help would be awesome!

#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#define OLED_WIDTH 128                               //OLED WIDTH
#define OLED_HEIGHT 64                               //OLED HEIGHT
#define OLED_ADDR   0x3C                             //OUTPUT ADDRESS

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

int buttonState = 0;
int bval = (55);   //bullet val

unsigned long elapsed = 0;   //VARIABLE DELAY
int timeD = 2000;


void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);                                //SERIAL BEGIN 9600
  display.clearDisplay();                            //REFREASH DISPLAY
  elapsed = millis();                                //INITIALIZE VARIABLE DELAY


void myDelay()
  if (millis() - elapsed >= timeD)          //  The delay time has passed
    elapsed = millis();                     // Recharge variable delay


void loop() {
buttonState = digitalRead(buttonPin);
int val = analogRead(A0);
val = map(val, 0, 1023, 0, 118);
display.fillRect(val, 59, 10, 2, WHITE);

if (buttonState == HIGH) {
  digitalWrite(ledPin, HIGH);
  display.fillRect(val+3, bval, 4, 4, WHITE);
  bval = bval - 1;
else if (bval < 0 && elapsed == 0){
  digitalWrite(ledPin, LOW);
  bval = 55;

Describe the program should do, and what it does instead.

You are not using millis() correctly. Study this excellent Blink Without Delay tutorial to learn how it should be used.

When you press a button (PIN 2) a square will appear and move upward to the top of the screen however when I let go of the button the square disappears. i want the square to move to the top of the screen and disappear before I let go of the button.

Actually by adding this line I can unreliably do what I wanted to do

if (buttonState == HIGH || bval > 0 && bval < 55)

But now I want the square to move independently from the bullet so when the button is pressed a new value eg. val2 stores the current value of val but only once so it doesn't keep updating how would do this?

Use a second if statement, within the "button" if statement, that draws the button only if (bval > 0 && bval < 55).

Post your revised code when you get that and millis() working properly, and have more questions.