Make Game With Arduino Mega

by JBS84 in Circuits > Arduino

105 Views, 2 Favorites, 0 Comments

Make Game With Arduino Mega

20240427_120220.jpg

Create a Video Game with Arduino Mega and joypad.

Supplies

20240427_123143.jpg

Materials to be used:

1) Arduino Mega

2) Breadboard

3) Resistors

4) A Joy for Arduino

5) A click button

6) Connection wires

7) Socket for RCA (AV)

8) A box to create a Joy pad

9) An RCA (AV) cable to connect Arduino to your TV

Libraries to use:

1) TvOut library to connect Arduino to TV via RCA (AV)

2) TimerThree library to manage 3 timer for sound effects

Game Code:

1) A game code (provided in the listing)

Assembly Hardware

TestGame_bb.jpg

The drawing shows the connections to be made, which as you can see are very simple.

Take:

1 x 10k Resistor

1 x 470k Resistor

1 x 1k Resistor

2 RCA Connectors (Video/Audio)

1 Switch Button

1 x 2-axis joystick (x/y)

1 Mega Arduino

Everything must be mounted on the breadboard as shown in the drawing above.

Below you can download the Fritzing file of the project.

Downloads

Library

First download the Avamander TVout library from your favorite IDE, the classic Arduino 1.6/1.8, Arduino 2.0 or, and this is what I usually use, the "Visual Micro" for Visual Studio.


This is the GitHub link to download the library.


Remember that inside the TVout folder in Arduino Libraries, on your disk, you have to bring out the TVoutfonts folder. Look for this folder inside TVout and read the file "README.md"


Download the TimerThree library that will be used for the sound effects here's the GitHub link.


From this link you can download the project for Visual Micro on GitHub.

Software (Platform)

01.jpg

A part of the sketch that runs the Platformer game.

TIMSK3 = 0b00000001;//###### ENABLE INTERRUPT TIMER 3 (attiva interrupt timer 3)

//###### 

mxstart = analogRead(ASSE_X);

//Serial.println(mstart); return;

if (mxstart > 510) { xhero += 1; if (xhero > 100) { xhero = 100; } }

if (mxstart < 490) { xhero -= 1; if (xhero < 2) { xhero = 2; } }

mxend = mxstart;


//###### LINEE LIVELLO

for (byte t = 13; t <= 103; t += 15) { TV.draw_line(0, t, 103, t, WHITE); }

//###### BUCHI LIVELLO

for (uint8_t t = 0; t < 6; t++) {

for (uint8_t t1 = 0; t1 < 4; t1++) {

xdel = mbuco[t][t1];

if (xdel > 0) { TV.draw_line(xdel, (t * 15) + 13, xdel + 5, (t * 15) + 13, BLACK); }

}

}

//###### PORTA

porta(97, endlevel);


//###### CROCE (CROSS)

for (uint8_t t = 0; t < maxobj; t++) {

if (objlive[t]) {

//TV.draw_rect((xobj[t] + 1) - wdobjcol[t] / 2, (yobj[t] - 1) - hgobjcol[t] / 2, wdobjcol[t], hgobjcol[t], WHITE);

croce(xobj[t], yobj[t], WHITE);

}

}


//###### CUORE (HEART)

if (lifelive) {

//TV.draw_rect(xlife - wdlifecol / 2, (ylife + 1) - hglifecol / 2, wdlifecol, hglifecol, WHITE);

cuore(xlife, ylife, WHITE);

}

TIMSK3 = 0b00000000;//###### DISABLE INTERRUPT TIMER 3 (disattiva interrupt timer 3)


//###### MOSTER

for (uint8_t t = 0; t < totmos; t++) {

moster(oxmos[t], oymos[t], posmoster[t], nxmos, BLACK);

xmos[t] += psxmos[t];

if (xmos[t] > oxmos[t]) { posmoster[t] = 1; }

else if (xmos[t] < oxmos[t]) { posmoster[t] = 0; }

if (xmos[t] > dsmos[t] || xmos[t] < lsmos[t]) { psxmos[t] = -psxmos[t]; }

moster(xmos[t], ymos[t], posmoster[t], nxmos, WHITE);

oxmos[t] = xmos[t]; oymos[t] = ymos[t];

}


//###### EXPLOSION

if (liveexp) {

explosion(oxexp, oyexp, BLACK);

explosion(xexp, yexp, WHITE);

}

oxexp = xexp;

oyexp = yexp;


//###### SCORE GAME

printScore(0, 105, score, 0);


//###### ENERGY HERO

TV.draw_rect(52, 105, 50, 4, WHITE, BLACK);

TV.draw_rect(52, 106, energy, 2, WHITE, WHITE);


//###### 

hero(oxhero, yhero, poshero, BLACK);



//###### 

uint8_t btnslt = digitalRead(BUTTON_ONE_PIN);


if (btnslt && !btnPress) {

if (slt == false) {

slt = true; yslt = yhero; psslt = -.5; btnPress = true;

effect(5);

}

}

else if (!btnslt) { btnPress = false; }


//###### COLLISIONE

if (slt) {

yhero += psslt;

if (yhero < yslt - 15) { psslt = .5; }

if (psslt > 0) {

if (!TV.get_pixel(xhero - 1, yhero + 6) && !TV.get_pixel(xhero, yhero + 6) && !TV.get_pixel(xhero + 1, yhero + 6)) {

slt = false;

}

}

}

else {

//###### COLLISIONE

if (!TV.get_pixel(xhero - 1, yhero + 6) && !TV.get_pixel(xhero, yhero + 6) && !TV.get_pixel(xhero + 1, yhero + 6)) {

slt = false;

yhero += 1;

}

}


//###### HERO

if (xhero > oxhero) { poshero = 1; }

else if (xhero < oxhero) { poshero = 0; }

hero(xhero, yhero, poshero, WHITE);

oxhero = xhero;


//###### HERO COLLISION MOSTER

for (uint8_t t = 0; t < totmos; t++) {

if ((xmos[t] - 1) + wdmoscol[t] / 2 > xhero - wdherocol / 2 && (xmos[t] - 1) - wdmoscol[t] / 2 < xhero + wdherocol / 2 &&

(ymos[t] - 1) + hgmoscol[t] / 2 > (yhero + 2) - hgherocol / 2 && (ymos[t] - 1) - hgmoscol[t] / 2 < (yhero + 2) + hgherocol / 2) {

energyHero(-.1);

effect(0);

}

}


//###### HERO COL OBJECT

for (uint8_t t = 0; t < maxobj; t++) {

if (objlive[t]) {

if ((xobj[t] + 1) + wdobjcol[t] / 2 > xhero - wdherocol / 2 && (xobj[t] + 1) - wdobjcol[t] / 2 < xhero + wdherocol / 2 &&

(yobj[t] - 1) + hgobjcol[t] / 2 > yhero - hgherocol / 2 && (yobj[t] - 1) - hgobjcol[t] / 2 < yhero + hgherocol / 2) {

croce(xobj[t], yobj[t], BLACK);

objlive[t] = false;

score += 10;

endobj -= 1;

if (endobj == 0) { endlevel = true; }

xexp = xobj[t]; yexp = yobj[t]; liveexp = true;

effect(3);

}

}

}


//###### HERO COL LIFE (CUORE)

if (lifelive) {

//TV.draw_rect(xlife - wdlifecol / 2, (ylife + 1) - hglifecol / 2, wdlifecol, hglifecol, WHITE);

if (xlife + wdlifecol / 2 > xhero - wdherocol / 2 && xlife - wdlifecol / 2 < xhero + wdherocol / 2 &&

(ylife - 2) + hglifecol / 2 > yhero - hgherocol / 2 && (ylife - 2) - hglifecol / 2 < yhero + hgherocol / 2) {

cuore(xlife, ylife, BLACK);

lifelive = false;

energyHero(1);

score += 100;

xexp = xlife; yexp = ylife; liveexp = true;

effect(4);

}

}


//###### HERO COL DOOR END LEVEL

if (endlevel) {

if (xhero + wdherocol / 2 > 100 && xhero - wdherocol / 2 < 103 && yhero < 9) {


level += 1;

TV.clear_screen();

//###### PRINT LEVEL

printLevel(level);

//###### 

effect(6);

unsigned long tmlev = millis();

while (millis() - tmlev <= 2000)

{

TIMSK3 = 0b00000000;//disattiva interrupt timer 3

TV.delay_frame(1);

TIMSK3 = 0b00000001;//attiva interrupt timer 3

}

//###### 

TV.clear_screen();

//###### END LEVEL

currPosLevel += 1;

if (currPosLevel >= endLevelEarth) {

//###### 

if (PlatformSpace == 0) {

//###### 

PlatformSpace = 1;

//###### 

SeletTypeStartGame();

return;

}

}


//###### GENERATORE DI SPAZI NELLA MAPPA

generaMappa();

//###### GENERATORE MOSTRI

generaMostri();

generaoggetti();

btnPress = false;

endlevel = false;


//###### START HERO

xhero = 5;

yhero = 85;

slt = false;

}

}

Software (Space)

02.jpg
03.jpg

A part of the sketch that runs the Space game.

TIMSK3 = 0b00000001;//###### ENABLE INTERRUPT TIMER 3 (attiva interrupt timer 3)

//###### PREPARA TERRA

vi += pvi;

if (pvi > 0 && vi >= ovi + vl) {

vl = random(20) + 1;

ovi = vi;

if (vi - vl < 5) { pvi = 0.25; }

else { pvi = -0.25; }

}if (pvi < 0 && vi <= ovi - vl) {

vl = random(20) + 1;

ovi = vi;

if (vi + vl > 50) { pvi = -0.25; }

else { pvi = 0.25; }

}


//###### 

mystart = analogRead(ASSE_Y);

if (mystart > 510) { yhero += 1; if (yhero > 100) { yhero = 100; } }

if (mystart < 490) { yhero -= 1; if (yhero < 0) { yhero = 0; } }

myend = mystart;


//###### 

mxstart = analogRead(ASSE_X);

if (mxstart > 510) { xhero += 1; if (xhero > 100) { xhero = 100; } }

if (mxstart < 490) { xhero -= 1; if (xhero < 2) { xhero = 2; } }

mxend = mxstart;


TIMSK3 = 0b00000000;//###### DISABLE INTERRUPT TIMER 3 (disattiva interrupt timer 3)


//###### FIRE BUTTON

uint8_t btnslt = digitalRead(BUTTON_ONE_PIN);

if (btnslt && !btnPress) {

fire += 1;

if (fire > 4) { fire = 0; }

if (fireon[fire] == false) {

fireon[fire] = true; xfire[fire] = xhero + 2; yfire[fire] = yhero + 1; btnPress = true;

oxfire[fire] = xfire[fire]; oyfire[fire] = yfire[fire];

effect(2);

}

}

else if (!btnslt) { btnPress = false; }


//###### FIRE MOVE

for (uint8_t t = 0; t < 5; t++) {

if (fireon[t]) {

TV.set_pixel(oxfire[t], oyfire[t], BLACK);

xfire[t] += 1;

if (xfire[t] >= 102 || TV.get_pixel(xfire[t], yfire[t])) { fireon[t] = false; oxfire[0] = 0; oyfire[0] = 0; }

//###### COLLISION FIRE WITH ALIEN

for (uint8_t t1 = 0; t1 < totAlien; t1++) {

if (liveastro[t1]) {

if (xfire[t] > xalien[t1] - 2 && xfire[t] < (xalien[t1] - 2) + 4 && yfire[t] > yalien[t1] && yfire[t] < yalien[t1] + 4) {

liveastro[t1] = false;

xexp = xalien[t1];

yexp = yalien[t1];

fireon[t] = false;

liveexp = true;

score += 50;

energyHero(.2);

effect(4);

}

}

}

//###### COLLISION FIRE WITH MISSILE

for (uint8_t t1 = 0; t1 < totmiss; t1++) {

if (livemiss[t1]) {

if (xfire[t] > xmiss[t1] - 1 && xfire[t] < (xmiss[t1] - 1) + 2 && yfire[t] > ymiss[t1] - 3 && yfire[t] < (ymiss[t1] - 3) + 5) {

livemiss[t1] = false;

xexp = xmiss[t1];

yexp = ymiss[t1];

fireon[t] = false;

liveexp = true;

score += 10;

effect(3);

}

}

}


}

}


//###### HERO BLACK

astro(oxhero, 1 + oyhero, BLACK);


//###### ALIEN

for (uint8_t t = 0; t < totAlien; t++) {

if (liveastro[t]) {

alien(oxalien[t], oyalien[t], nxmove, BLACK);

if (iniastro[t] == 1) { pxalien[t] -= .2; }

if (pxalien[t] <= 70 && iniastro[t] == 1) { iniastro[t + 1] = 1; }

if (pxalien[t] <= 60 && iniastro[t] == 1) { iniastro[t] = 2; iniastro[t + 1] = 1; }

if (iniastro[t] == 2) { a[t] += 1; if (a[t] > 156) { a[t] = 0; } }

if (iniastro[t] > 0) {

xalien[t] = pxalien[t] + 20 * fcos[a[t]];

yalien[t] = pyalien[t] + 20 * fsin[a[t]];

}

//###### COLLISION ASTRO WITH HERO

if (xhero > xalien[t] - 2 && xhero<(xalien[t] - 2) + 4 && yhero > yalien[t] && yhero < yalien[t] + 4) {

energyHero(-.5);

effect(0);

}

}

}


//##### FINE ALIEN

endAlien = true;

for (uint8_t t = 0; t < totAlien; t++) { if (liveastro[t] && iniastro[t] > 0) { endAlien = false; } }


//###### MISSILE

endmiss = true;

for (uint8_t t = 0; t < totmiss; t++) {

if (livemiss[t]) {

endmiss = false;

xmiss[t] -= psmiss[t]; if (xmiss[t] <= 0) { xmiss[t] = 102; psmiss[t] = 1; startmiss[t] = 30 + random(10) * 5; }

if (xmiss[t] == 102) { ymiss[t] = (103 - vi) - 3; }

if (xmiss[t] <= startmiss[t]) {

ymiss[t] -= (float)random(40, 100) / 100; psmiss[t] = (float)random(50, 100) / 100;

}

missile(oxmiss[t], oymiss[t], 0, BLACK);

//###### COLLISION MISSILE WITH HERO

if (xhero > xmiss[t] - 1 && xhero<(xmiss[t] - 1) + 2 && yhero>ymiss[t] - 3 && yhero < (ymiss[t] - 3) + 5) {

energyHero(-1);

effect(0);

}

}

}


//###### FINE EARTH SPACE

if (endLevelEarthSpace > 0) {

endAlien = false;

endmiss = false;

currPosEarthSpace++;

if (currPosEarthSpace >= endLevelEarthSpace) { endAlien = true; endLevelEarthSpace = 0; }

}


//###### FINE ALIEN/MISSILE

if ((endAlien && astromiss == 0) || (endmiss && astromiss == 1)) {

//###### END LEVEL

currPosLevel++;

if (currPosLevel >= endLevelSpace) {

level += 1;

TV.clear_screen();

//###### 

printLevel(level);

//###### 

effect(6);

unsigned long tmlev = millis();

while (millis() - tmlev <= 2000)

{

TIMSK3 = 0b00000000;//###### DISABLE INTERRUPT TIMER 3 (disattiva interrupt timer 3)

TV.delay_frame(1);

TIMSK3 = 0b00000001;//###### ENABLE INTERRUPT TIMER 3 (attiva interrupt timer 3)

}

//###### 

TV.clear_screen();

//###### 

if (PlatformSpace == 1) {

//###### 

PlatformSpace = 0;

//###### 

SeletTypeStartGame();

return;

}

}

spaceearth = random(0, 3);//###### DECIDE QUALE MODELLO SI SPAZIO TERRA

callnext();

}


//###### EXPLOSION

if (liveexp) { explosion(oxexp, oyexp, BLACK); }


//###### TERRAIN (TERRENO)

switch (spaceearth)

{

case 0:

if (random(0, 2) == 0) {

//###### ABOVE (SOPRA)

TV.draw_line(103, 0, 103, vi, WHITE);

}

else {

//###### ABOVE CRINE (SOPRA STORTO)

TV.draw_line(103, 0, 100, vi, WHITE);

}

break;

case 1:

if (random(0, 2) == 0) {

//###### UNDER (SOTTO)

TV.draw_line(103, 103 - vi, 103, 103, WHITE);

}

else {

//###### CRINE UNDER (SOTTO STORTO)

TV.draw_line(103, 103 - vi, 100, 103, WHITE);

}

break;

case 2:

//###### ABOVE/UNDER CRINE ROAD (SOPRA/SOTTO STRADA STORTA)

TV.draw_line(103, 0, 100, vi, WHITE);

TV.draw_line(100, vi + 20, 103, 103, WHITE);

break;

default:

break;

}


//###### SCORE GAME

printScore(1, 105, score, 1);


//###### ENERGY HERO

TV.draw_line(52, 105, 52, 109, BLACK);

TV.draw_rect(53, 105, 50, 4, WHITE, BLACK);

TV.draw_rect(53, 106, energy, 2, WHITE, WHITE);


//###### SCROLLING

TV.shift(1, LEFT);


//###### FIRE

for (uint8_t t = 0; t < 5; t++) {

if (fireon[t]) {

TV.set_pixel(xfire[t], yfire[t], WHITE);

oxfire[t] = xfire[t];

oyfire[t] = yfire[t];

}

}


//###### HERO WHITE

astro(xhero, 1 + yhero, WHITE);


//###### ALIEN

for (uint8_t t = 0; t < totAlien; t++) {

if (liveastro[t]) {

//TV.draw_rect(xalien[t], yalien[t], 4, 4, WHITE);

if (iniastro[t] > 0) {

alien(xalien[t], yalien[t], nxmove, WHITE);

oxalien[t] = xalien[t];

oyalien[t] = yalien[t];

}

}

}


//###### MISSILE

for (uint8_t t = 0; t < totmiss; t++) {

if (livemiss[t]) {

missile(xmiss[t], ymiss[t], 0, WHITE);

oxmiss[t] = xmiss[t];

oymiss[t] = ymiss[t];

}

}


//###### EXPLOSION

if (liveexp) { explosion(xexp, yexp, WHITE); }

oxexp = xexp;

oyexp = yexp;


oxhero = xhero;

oyhero = yhero;


//###### COLLISION HERO WITH EARTH

//TV.set_pixel(xhero + 2, 1 + yhero, WHITE);

if (TV.get_pixel(xhero + 2, yhero + 1)) {

energyHero(-1);

yhero -= 10; if (yhero <= 0) { yhero = 0; }

effect(0);

}

else if (TV.get_pixel(xhero + 2, yhero)) {

energyHero(-1);

yhero += 10; if (yhero >= 100) { yhero = 100; }

effect(0);

}

}

Final Sketch

Here you can find the final sketch in Arduino *.ino format.

Downloads