{"id":426,"date":"2026-09-16T00:57:05","date_gmt":"2026-09-15T23:57:05","guid":{"rendered":"https:\/\/kuliahelektro.org\/?p=426"},"modified":"2026-09-16T00:57:05","modified_gmt":"2026-09-15T23:57:05","slug":"game-legend-ini-bisa-dibikin-pake-arduino-tetris-oled-display-joystick-di-wokwi-game-tetris","status":"publish","type":"post","link":"https:\/\/kuliahelektro.org\/?p=426","title":{"rendered":"Game LEGEND ini bisa dibikin pake Arduino (Tetris) Oled Display + Joystick di WOKWI #game #tetris"},"content":{"rendered":"\n<p><br><strong><strong><br>Tutorial ESP32: Game LEGEND ini bisa dibikin pake Arduino (Tetris) Oled Display + Joystick di WOKWI #game #tetris<\/strong><\/strong><\/p>\n\n\n\n<p>Pada bagian ini akan dibahas pembuatan proyek game legendaris Tetris berbasis mikrokontroler Arduino UNO, layar OLED Display SSD1306 0.96 inci (I2C), dan <em>analog joystick<\/em> sebagai pengontrol pergerakan blok, serta software simulasi WOKWI. Skematik rangkaian ditunjukkan pada Gambar 1, program Arduino pada Kode 1, dan video pembuatan pada tautan Video 1. Pergerakan blok Tetris (rotasi, geser kiri\/kanan, dan <em>drop<\/em>) diproses menggunakan pembacaan sinyal analog joystick. Layar OLED akan merender grafis blok secara <em>real-time<\/em>, menghitung skor per baris yang berhasil dihancurkan, serta menampilkan kondisi <em>game over<\/em> saat susunan blok telah mencapai batas atas.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/youtu.be\/ROd6Rh7evUw?si=5LsUCBafL4Fjf6ke\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" loading=\"lazy\" width=\"778\" height=\"846\" src=\"https:\/\/kuliahelektro.org\/wp-content\/uploads\/2026\/09\/image-11.png\" alt=\"\" class=\"wp-image-427\" srcset=\"https:\/\/kuliahelektro.org\/wp-content\/uploads\/2026\/09\/image-11.png 778w, https:\/\/kuliahelektro.org\/wp-content\/uploads\/2026\/09\/image-11-276x300.png 276w, https:\/\/kuliahelektro.org\/wp-content\/uploads\/2026\/09\/image-11-768x835.png 768w\" sizes=\"(max-width: 778px) 100vw, 778px\" \/><\/a><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><strong>Gambar 1. Skematik rangkaian sistem<\/strong><\/p>\n\n\n\n<p>Pemetaan PIN:<br>* <strong>OLED DISPLAY 0.96 INCH I2C<\/strong><br>GND => GND<br>VCC => 5V<br>SDA => SDA \/ 20<br>SCL => SCL \/ 21<br>* <strong>JOYSTICK<\/strong><br>VCC => 5V<br>JOY_X => A0<br>JOY_Y => A1<br>BTN => 2<br>GND => GND<br>* <strong>BUZZER<\/strong> <strong>dan LED<\/strong><br>GND \u2013 GND<br>OUT \u2013 6<\/p>\n\n\n\n<p class=\"has-text-align-center\"><strong>Kode Arduino 1. Kode Program<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ALFIAN CENTER\r\n\/\/SUBSCRIBE\r\n\r\n#include &lt;Arduino.h>\r\n#include &lt;U8g2lib.h>\r\n#include &lt;Wire.h>\r\n\r\n\/\/ ================= DISPLAY ==================\r\nU8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);\r\n\r\n\/\/ ================= PIN ==================\r\n#define JOY_X   A0\r\n#define JOY_Y   A1\r\n#define BTN_ROT 2\r\n#define BUZZER  6\r\n\r\n\r\n\/\/ALFIAN CENTER\r\n\/\/SUBSCRIBE\r\n\/\/ ================= BOARD ==================\r\n#define COLS 10\r\n#define ROWS 16\r\nint board&#91;ROWS]&#91;COLS];\r\n\r\n\/\/ ================= PIECES ==================\r\nconst byte tetrominoes&#91;7]&#91;4]&#91;4] = {\r\n  { {0,1,0,0}, {0,1,0,0}, {0,1,0,0}, {0,1,0,0} }, \/\/ I\r\n  { {1,1,0,0}, {0,1,1,0}, {0,0,0,0}, {0,0,0,0} }, \/\/ Z\r\n  { {0,1,1,0}, {1,1,0,0}, {0,0,0,0}, {0,0,0,0} }, \/\/ S\r\n  { {1,0,0,0}, {1,1,1,0}, {0,0,0,0}, {0,0,0,0} }, \/\/ J\r\n  { {0,0,1,0}, {1,1,1,0}, {0,0,0,0}, {0,0,0,0} }, \/\/ L\r\n  { {1,1,1,0}, {0,1,0,0}, {0,0,0,0}, {0,0,0,0} }, \/\/ T\r\n  { {1,1,0,0}, {1,1,0,0}, {0,0,0,0}, {0,0,0,0} }  \/\/ O\r\n};\r\n\r\n\/\/ ================= GAME STATE ==================\r\nenum GameState { MENU, PLAYING, GAME_OVER };\r\nGameState state = MENU;\r\n\r\nenum Difficulty { EASY, MEDIUM, HARD };\r\nDifficulty diffSel = MEDIUM;\r\n\r\nint score=0, level=1;\r\nunsigned long dropInterval=600;\r\nunsigned long lastDrop=0;\r\n\r\n\r\n\/\/ALFIAN CENTER\r\n\/\/SUBSCRIBE\r\n\/\/ ================= PIECE CONTROL ==================\r\nint curPiece&#91;4]&#91;4];\r\nint curX, curY;\r\nint nextPieceIdx;\r\nint lastPieceIdx=-1, repeatCount=0;\r\n\r\n\/\/ ================= UTILS ==================\r\nvoid beep(int f, int d){ tone(BUZZER,f,d); }\r\n\r\nvoid playDrop(){ beep(1000,50); }\r\nvoid playRotate(){ beep(1500,50); }\r\nvoid playGameOver(){ beep(300,500); }\r\n\r\nvoid copyPieceByte(const byte src&#91;4]&#91;4], int dest&#91;4]&#91;4]){\r\n  for(int y=0;y&lt;4;y++) for(int x=0;x&lt;4;x++) dest&#91;y]&#91;x]=src&#91;y]&#91;x];\r\n}\r\nvoid copyPieceInt(int src&#91;4]&#91;4], int dest&#91;4]&#91;4]){\r\n  for(int y=0;y&lt;4;y++) for(int x=0;x&lt;4;x++) dest&#91;y]&#91;x]=src&#91;y]&#91;x];\r\n}\r\n\r\nvoid rotatePiece(int m&#91;4]&#91;4]){\r\n  int tmp&#91;4]&#91;4];\r\n  for(int y=0;y&lt;4;y++) for(int x=0;x&lt;4;x++) tmp&#91;y]&#91;x]=m&#91;y]&#91;x];\r\n  for(int y=0;y&lt;4;y++) for(int x=0;x&lt;4;x++) m&#91;x]&#91;3-y]=tmp&#91;y]&#91;x];\r\n}\r\n\r\n\r\n\/\/ALFIAN CENTER\r\n\/\/SUBSCRIBE\r\nbool collision(int x,int y,int shape&#91;4]&#91;4]){\r\n  for(int py=0;py&lt;4;py++)\r\n    for(int px=0;px&lt;4;px++)\r\n      if(shape&#91;py]&#91;px]){\r\n        int nx=x+px, ny=y+py;\r\n        if(nx&lt;0||nx>=COLS||ny&lt;0||ny>=ROWS) return true;\r\n        if(board&#91;ny]&#91;nx]) return true;\r\n      }\r\n  return false;\r\n}\r\n\r\nvoid placePiece(){\r\n  for(int y=0;y&lt;4;y++)\r\n    for(int x=0;x&lt;4;x++)\r\n      if(curPiece&#91;y]&#91;x]) board&#91;curY+y]&#91;curX+x]=1;\r\n  playDrop();\r\n}\r\n\r\nvoid clearLines(){\r\n  int lines=0;\r\n  for(int y=ROWS-1;y>=0;y--){\r\n    bool full=true;\r\n    for(int x=0;x&lt;COLS;x++) if(!board&#91;y]&#91;x]){ full=false; break; }\r\n    if(full){\r\n      for(int ty=y;ty>0;ty--)\r\n        for(int x=0;x&lt;COLS;x++) board&#91;ty]&#91;x]=board&#91;ty-1]&#91;x];\r\n      for(int x=0;x&lt;COLS;x++) board&#91;0]&#91;x]=0;\r\n      lines++;\r\n      y++;\r\n    }\r\n  }\r\n  if(lines>0){\r\n    if(lines==1) score+=100;\r\n    else if(lines==2) score+=300;\r\n    else if(lines==3) score+=500;\r\n    else if(lines==4) score+=800;  \/\/ Tetris!\r\n  }\r\n}\r\n\r\n\r\n\/\/ALFIAN CENTER\r\n\/\/SUBSCRIBE\r\nvoid spawnPiece(){\r\n  int idx=random(7);\r\n  if(idx==lastPieceIdx){\r\n    repeatCount++;\r\n    if(repeatCount>=3){ \r\n      while(idx==lastPieceIdx) idx=random(7);\r\n      repeatCount=0;\r\n    }\r\n  } else repeatCount=0;\r\n  lastPieceIdx=idx;\r\n\r\n  copyPieceByte(tetrominoes&#91;idx],curPiece);\r\n  curX=COLS\/2-2; curY=0;\r\n  if(collision(curX,curY,curPiece)) state=GAME_OVER;\r\n\r\n  nextPieceIdx=random(7);\r\n}\r\n\r\nvoid updateSpeed(){\r\n  switch(diffSel){\r\n    case EASY: dropInterval=700-(level-1)*50; break;\r\n    case MEDIUM: dropInterval=500-(level-1)*40; break;\r\n    case HARD: dropInterval=300-(level-1)*30; break;\r\n  }\r\n  if(dropInterval&lt;100) dropInterval=100;\r\n}\r\n\r\n\/\/ ================= RENDER ==================\r\nvoid drawBoard(){\r\n  u8g2.clearBuffer();\r\n  \/\/ draw grid\r\n  for(int y=0;y&lt;ROWS;y++)\r\n    for(int x=0;x&lt;COLS;x++)\r\n      if(board&#91;y]&#91;x]) u8g2.drawBox(x*4,y*4,4,4);\r\n\r\n  \/\/ draw current piece\r\n  for(int y=0;y&lt;4;y++)\r\n    for(int x=0;x&lt;4;x++)\r\n      if(curPiece&#91;y]&#91;x]) u8g2.drawBox((curX+x)*4,(curY+y)*4,4,4);\r\n\r\n  \/\/ draw next piece\r\n  u8g2.setFont(u8g2_font_5x7_tr);\r\n  u8g2.setCursor(65,7); u8g2.print(\"Next:\");\r\n  for(int y=0;y&lt;4;y++)\r\n    for(int x=0;x&lt;4;x++)\r\n      if(tetrominoes&#91;nextPieceIdx]&#91;y]&#91;x])\r\n        u8g2.drawBox(80+x*4,10+y*4,4,4);\r\n\r\n  u8g2.setCursor(65,35); u8g2.print(\"Score:\"); u8g2.print(score);\r\n  u8g2.setCursor(65,45); u8g2.print(\"Lvl:\"); u8g2.print(level);\r\n\r\n  u8g2.sendBuffer();\r\n}\r\n\r\nvoid drawMenu(){\r\n  u8g2.clearBuffer();\r\n  u8g2.setFont(u8g2_font_6x12_tr);\r\n  u8g2.setCursor(20,15); u8g2.print(\"TETRIS MINI\");\r\n  u8g2.setCursor(10,35); u8g2.print(\"Diff: \");\r\n  if(diffSel==EASY) u8g2.print(\"Easy\");\r\n  else if(diffSel==MEDIUM) u8g2.print(\"Medium\");\r\n  else u8g2.print(\"Hard\");\r\n  u8g2.setCursor(10,50); u8g2.print(\"Press Button=Start\");\r\n  u8g2.sendBuffer();\r\n}\r\n\r\nvoid drawGameOver(){\r\n  u8g2.clearBuffer();\r\n  u8g2.setFont(u8g2_font_6x12_tr);\r\n  u8g2.setCursor(20,20); u8g2.print(\"GAME OVER!\");\r\n  u8g2.setCursor(20,40); u8g2.print(\"Score:\"); u8g2.print(score);\r\n  u8g2.setCursor(5,55); u8g2.print(\"Btn=Menu  JoyDown=Retry\");\r\n  u8g2.sendBuffer();\r\n}\r\n\r\n\/\/ ================= GAME ==================\r\nvoid startGame(){\r\n  for(int y=0;y&lt;ROWS;y++) for(int x=0;x&lt;COLS;x++) board&#91;y]&#91;x]=0;\r\n  score=0; level=1;\r\n  updateSpeed();\r\n  spawnPiece();\r\n  state=PLAYING;\r\n  playDrop();\r\n}\r\n\r\nvoid setup(){\r\n  pinMode(BTN_ROT,INPUT_PULLUP);\r\n  pinMode(BUZZER,OUTPUT);\r\n  u8g2.begin();\r\n  randomSeed(analogRead(A2));\r\n  drawMenu();\r\n}\r\n\r\nvoid loop(){\r\n  if(state==MENU){\r\n    if(digitalRead(BTN_ROT)==LOW){\r\n      startGame();\r\n      delay(200);\r\n    }\r\n    int joyX=analogRead(JOY_X);\r\n    if(joyX&lt;300){ diffSel=(Difficulty)((diffSel+2)%3); drawMenu(); delay(200);}\r\n    if(joyX>700){ diffSel=(Difficulty)((diffSel+1)%3); drawMenu(); delay(200);}\r\n    return;\r\n  }\r\n\r\n  if(state==PLAYING){\r\n    int joyX=analogRead(JOY_X);\r\n    int joyY=analogRead(JOY_Y);\r\n    if(joyX&lt;300 &amp;&amp; !collision(curX-1,curY,curPiece)){ curX--; delay(150);}\r\n    if(joyX>700 &amp;&amp; !collision(curX+1,curY,curPiece)){ curX++; delay(150);}\r\n    if(joyY>700 &amp;&amp; !collision(curX,curY+1,curPiece)){ curY++; } \/\/ turun cepat\r\n\r\n    if(digitalRead(BTN_ROT)==LOW){\r\n      int tmp&#91;4]&#91;4]; copyPieceInt(curPiece,tmp);\r\n      rotatePiece(tmp);\r\n      if(!collision(curX,curY,tmp)) copyPieceInt(tmp,curPiece);\r\n      playRotate();\r\n      delay(200);\r\n    }\r\n\r\n    unsigned long now=millis();\r\n    if(now-lastDrop>=dropInterval){\r\n      lastDrop=now;\r\n      if(!collision(curX,curY+1,curPiece)){\r\n        curY++;\r\n      } else {\r\n        placePiece();\r\n        clearLines();\r\n        if(score\/500+1>level){ level++; updateSpeed(); }\r\n        spawnPiece();\r\n      }\r\n    }\r\n    drawBoard();\r\n    return;\r\n  }\r\n\r\n  if(state==GAME_OVER){\r\n    drawGameOver();\r\n    if(digitalRead(BTN_ROT)==LOW){ state=MENU; drawMenu(); delay(200); }\r\n    int joyY=analogRead(JOY_Y);\r\n    if(joyY>700){ startGame(); delay(200); }\r\n  }\r\n}\r\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/youtu.be\/ROd6Rh7evUw?si=5LsUCBafL4Fjf6ke\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"576\" src=\"https:\/\/kuliahelektro.org\/wp-content\/uploads\/2026\/09\/image-12-1024x576.png\" alt=\"\" class=\"wp-image-428\" srcset=\"https:\/\/kuliahelektro.org\/wp-content\/uploads\/2026\/09\/image-12-1024x576.png 1024w, https:\/\/kuliahelektro.org\/wp-content\/uploads\/2026\/09\/image-12-300x169.png 300w, https:\/\/kuliahelektro.org\/wp-content\/uploads\/2026\/09\/image-12-768x432.png 768w, https:\/\/kuliahelektro.org\/wp-content\/uploads\/2026\/09\/image-12-1536x864.png 1536w, https:\/\/kuliahelektro.org\/wp-content\/uploads\/2026\/09\/image-12.png 1919w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><strong>Video 1. Video tutorial pembuatan simulasi di WOKWI<\/strong><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">TAG:<\/h1>\n\n\n\n<p>game tetris arduino, arduino tetris game, tetris arduino wokwi, tutorial game arduino, arduino oled display, ssd1306 arduino, arduino joystick game, game legend arduino, simulator wokwi arduino, belajar arduino game, proyek game arduino, arduino uno tetris, cara membuat game di arduino, coding game tetris arduino, game retro arduino, game klasik arduino, tutorial wokwi indonesia, ide proyek arduino, simulasi arduino online, wokwi simulator tutorial, joystick module arduino, oled display ssd1306, pemrograman C++ arduino, arduino display i2c, game tetris oled, membuat game dengan oled display, arduino project for beginners, proyek mikrokontroler game, tutorial arduino uno lengkap, skematik game tetris arduino, game dev arduino, membuat game 8bit arduino, logika game tetris arduino, game tetris sederhana arduino, sinyal analog joystick arduino, fungsi millis arduino game, library ssd1306 arduino, library gfx adafruit, game console sederhana arduino, diy game console arduino, porting game tetris arduino, tutorial elektronika dasar, praktikum mikrokontroler arduino, tugas akhir arduino game, media pembelajaran arduino, kodingan game tetris, koding game arduino uno, game tetris oled 0.96, display oled i2c arduino, kontroler joystick arduino, membuat stik game arduino, simulasi wokwi game, arduino tutorial indonesia, tutorial iot dan elektro, proyek mekatronika sederhana, proyek teknik elektro, koding arduino wokwi, game tetris wokwi online, belajar mekatronika dasar, tutorial simulasi wokwi, game tetris tanpa hardware, simulasi komponen elektronik, game tetris arduino uno r3, display 128&#215;64 oled arduino, adafruit ssd1306 tutorial, game tetris arduino code, source code game tetris arduino, program game tetris arduino, game tetris gratis arduino, proyek coding siswa arduino, game arcade arduino, retro gaming arduino, mini game console arduino, game tetris berbasis mikrokontroler, aplikasi game arduino, membuat game simulator wokwi, sensor joystick arduino, sumbu x y joystick arduino, pin analog arduino joystick, push button joystick arduino, render grafis oled arduino, animasi bitmap oled arduino, scoring system game arduino, game over logic arduino, matrix game tetris arduino, array 2d game tetris arduino, algoritma game tetris, tutorial arduino dasar sampai mahir, proyek kreatif arduino, karya siswa elektro arduino, portofolio mikrokontroler, latihan koding arduino, game dev mikrokontroler, proyek iot dan game, lab mikrokontroler arduino, proyek arduino seru, kreasi arduino uno, game tetris legenda arduino, game vintage arduino<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Tutorial ESP32: Game LEGEND ini bisa dibikin pake Arduino (Tetris) Oled Display + Joystick di WOKWI #game #tetris Pada bagian ini akan dibahas pembuatan proyek game legendaris Tetris berbasis mikrokontroler Arduino UNO, layar OLED Display SSD1306 0.96 inci (I2C), dan analog joystick sebagai pengontrol pergerakan blok, serta software simulasi WOKWI. Skematik rangkaian ditunjukkan pada Gambar 1, program Arduino pada Kode&#8230;<\/p>\n","protected":false},"author":3,"featured_media":429,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"_links":{"self":[{"href":"https:\/\/kuliahelektro.org\/index.php?rest_route=\/wp\/v2\/posts\/426"}],"collection":[{"href":"https:\/\/kuliahelektro.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kuliahelektro.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kuliahelektro.org\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/kuliahelektro.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=426"}],"version-history":[{"count":1,"href":"https:\/\/kuliahelektro.org\/index.php?rest_route=\/wp\/v2\/posts\/426\/revisions"}],"predecessor-version":[{"id":430,"href":"https:\/\/kuliahelektro.org\/index.php?rest_route=\/wp\/v2\/posts\/426\/revisions\/430"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kuliahelektro.org\/index.php?rest_route=\/wp\/v2\/media\/429"}],"wp:attachment":[{"href":"https:\/\/kuliahelektro.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kuliahelektro.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=426"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kuliahelektro.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}