티스토리 뷰
728x90
본 체험 제품은 element14 의 후원을 받아 아이씨뱅큐㈜ 에서 진행하는 무상 체험단 활동으로 작성한 것입니다.
출처 : Arduino Pong Game - OLED Display: 5 Steps (with Pictures)
micro:bit - Pong Game
Arduino로 SSD1331이용해서 만들어진 간단한 PONG 게임을 micro:bit에서 구동 되도록 만들어 보았습니다. micro:bit에 내장된 좌우 버튼으로 좌버튼을 누르면 올라가고, 우버튼을 누르면 내려가도록 했습니다.
main.cpp - pong_game_source_2.7z
#include "MicroBit.h" #include "ssd1331.h" // Color definitions #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF #define LOW 0 const unsigned long PADDLE_RATE = 33; const unsigned long BALL_RATE = 20; const uint8_t PADDLE_HEIGHT = 24; int MAX_SCORE = 3; int CPU_SCORE = 0; int PLAYER_SCORE = 0; // You can use any (4 or) 5 pins #define sclk 13 #define mosi 11 #define cs 10 #define rst 9 #define dc 8 // MOSI is Data pin on display breakout // ssd1331(PinName cs_pin, PinName rst_pin, PinName a0_pin, PinName mosi_pin, PinName miso_pin, PinName sclk_pin); ssd1331 display(P0_16, P0_18, P0_10, P0_21, P0_22, P0_23); // cs, res, dc, miso(nc), sck (KL25z) void drawCourt(); void gameOver(); void loop(); void showScore(); uint8_t ball_x = 64, ball_y = 32; uint8_t ball_dir_x = 1, ball_dir_y = 1; bool gameIsRunning = true; bool resetBall = false; static const unsigned char pong [] = { 0xff,0xe0,0x0,0x3f,0x80,0x7,0xe0,0x7,0xc0,0x3,0xfc,0x0, 0xff,0xf8,0x1,0xff,0xe0,0x7,0xf0,0x7,0xc0,0x1f,0xff,0x0, 0xff,0xfc,0x3,0xff,0xf0,0x7,0xf0,0x7,0xc0,0x3f,0xff,0x0, 0xff,0xfe,0x7,0xff,0xf8,0x7,0xf8,0x7,0xc0,0xff,0xff,0x0, 0xf8,0x7f,0xf,0xff,0xfc,0x7,0xfc,0x7,0xc0,0xff,0xff,0x0, 0xf8,0x3f,0xf,0xe0,0xfe,0x7,0xfc,0x7,0xc1,0xfc,0x7,0x0, 0xf8,0x1f,0x1f,0x80,0x7e,0x7,0xfe,0x7,0xc3,0xf8,0x1,0x0, 0xf8,0x1f,0x1f,0x0,0x3e,0x7,0xfe,0x7,0xc3,0xf0,0x0,0x0, 0xf8,0x1f,0x3f,0x0,0x3f,0x7,0xdf,0x7,0xc7,0xe0,0x0,0x0, 0xf8,0x1f,0x3e,0x0,0x1f,0x7,0xdf,0x87,0xc7,0xc0,0x0,0x0, 0xf8,0x3f,0x3e,0x0,0x1f,0x7,0xcf,0x87,0xc7,0xc1,0xff,0x80, 0xf8,0x7e,0x3e,0x0,0x1f,0x7,0xc7,0xc7,0xc7,0xc1,0xff,0x80, 0xff,0xfe,0x3e,0x0,0x1f,0x7,0xc7,0xe7,0xc7,0xc1,0xff,0x80, 0xff,0xfc,0x3e,0x0,0x1f,0x7,0xc3,0xe7,0xc7,0xc1,0xff,0x80, 0xff,0xf8,0x3e,0x0,0x1f,0x7,0xc1,0xf7,0xc7,0xc0,0xf,0x80, 0xff,0xe0,0x3f,0x0,0x3f,0x7,0xc1,0xf7,0xc7,0xe0,0xf,0x80, 0xf8,0x0,0x1f,0x0,0x3e,0x7,0xc0,0xff,0xc3,0xe0,0xf,0x80, 0xf8,0x0,0x1f,0x80,0x7e,0x7,0xc0,0x7f,0xc3,0xf0,0xf,0x80, 0xf8,0x0,0x1f,0xc0,0xfc,0x7,0xc0,0x7f,0xc3,0xfc,0xf,0x80, 0xf8,0x0,0xf,0xff,0xfc,0x7,0xc0,0x3f,0xc1,0xff,0xff,0x80, 0xf8,0x0,0x7,0xff,0xf8,0x7,0xc0,0x3f,0xc0,0xff,0xff,0x80, 0xf8,0x0,0x3,0xff,0xf0,0x7,0xc0,0x1f,0xc0,0x7f,0xff,0x80, 0xf8,0x0,0x1,0xff,0xe0,0x7,0xc0,0xf,0xc0,0x3f,0xff,0x0, 0xf8,0x0,0x0,0x7f,0x0,0x7,0xc0,0xf,0xc0,0x7,0xf8,0x0 }; static const unsigned char game [] ={ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xff,0x80, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc3,0xff,0x80, 0x0,0x0,0x0,0x0,0x0,0x0,0xf,0xc3,0xff,0x80, 0x0,0x0,0x0,0x0,0x3,0xe0,0xf,0xc3,0xe0,0x0, 0x0,0x0,0x0,0x0,0x7,0xf0,0x1f,0xc1,0xe0,0x0, 0x0,0x0,0x0,0xf8,0x7,0xf0,0x1f,0xc1,0xe0,0x0, 0x0,0xfc,0x1,0xfc,0x7,0xf8,0x1f,0xc1,0xe0,0x0, 0x7,0xfc,0x1,0xfc,0x3,0xf8,0x1f,0xe1,0xff,0x80, 0x1f,0xfc,0x1,0xde,0x3,0xbc,0x3d,0xe1,0xff,0x80, 0x3f,0xfe,0x1,0xde,0x3,0xbc,0x39,0xe1,0xff,0x80, 0x7e,0x0,0x3,0xdf,0x3,0xde,0x39,0xe1,0xfc,0x0, 0x7c,0x0,0x3,0xcf,0x3,0xde,0x39,0xe1,0xe0,0x0, 0xf8,0x0,0x3,0xcf,0x3,0xcf,0x39,0xe1,0xf0,0x0, 0xf8,0x0,0x3,0x87,0x83,0xcf,0x79,0xe0,0xf0,0x0, 0xf0,0x7f,0x7,0x87,0x83,0xc7,0xf1,0xe0,0xf0,0xe0, 0xf0,0xff,0x7,0x83,0xc3,0xc7,0xf1,0xe0,0xff,0xe0, 0xf0,0xff,0x7,0xff,0xc1,0xc3,0xf1,0xf0,0xff,0xe0, 0xf0,0xff,0x7,0xff,0xe1,0xc3,0xf0,0xf0,0xff,0xe0, 0xf8,0xf,0xf,0xff,0xe1,0xc1,0xe0,0xf0,0xe0,0x0, 0xf8,0xf,0x8f,0x1,0xf1,0xe1,0xe0,0xf0,0x0,0x0, 0x7c,0xf,0x8f,0x0,0xf1,0xe1,0xe0,0x0,0x0,0x0, 0x7f,0x1f,0x8f,0x0,0xf9,0xc0,0x0,0x0,0x0,0x0, 0x3f,0xff,0x9f,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x1f,0xff,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x7,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 }; unsigned long ball_update; unsigned long paddle_update; const uint8_t CPU_X = 12; uint8_t cpu_y = 16; const uint8_t PLAYER_X = 85; uint8_t player_y = 16; uint64_t millis() { return us_ticker_read() / 1000; } void delay(uint32_t delay) { wait_ms(delay); } uint8_t random(uint8_t min, uint8_t max) { return (rand() % (max - min + 1) ) + 1; } DigitalIn UP_BUTTON(MICROBIT_PIN_BUTTON_A); DigitalIn DOWN_BUTTON(MICROBIT_PIN_BUTTON_B); int main() { display.cls(); // clear screen to black display.drawBitmap(3,0,pong,89,24,GREEN); display.drawBitmap(10,30,game,75,26,RED); while(UP_BUTTON && DOWN_BUTTON) { wait_ms(100); } unsigned long start = millis(); display.fillScreen(BLACK); drawCourt(); while(millis() - start < 2000); ball_update = millis(); paddle_update = ball_update; ball_x = random(25,65); ball_y = random(3,63); while(1) { loop(); } release_fiber(); } void loop() { unsigned long time = millis(); static bool up_state = false; static bool down_state = false; up_state |= (UP_BUTTON == LOW); down_state |= (DOWN_BUTTON == LOW); if(resetBall) { ball_x = random(25,70); ball_y = random(3,63); /* do { ball_dir_x = random(-1,2); }while(ball_dir_x==0); do { ball_dir_y = random(-1,2); }while(ball_dir_y==0); */ ball_dir_x = 1; ball_dir_y = 1; resetBall=false; } if(time > ball_update && gameIsRunning) { uint8_t new_x = ball_x + ball_dir_x; uint8_t new_y = ball_y + ball_dir_y; // Check if we hit the vertical walls if(new_x == 0) //Player Gets a Point { PLAYER_SCORE++; if(PLAYER_SCORE==MAX_SCORE) { gameOver(); }else { showScore(); } } // Check if we hit the vertical walls if(new_x == 95) //CPU Gets a Point { CPU_SCORE++; if(CPU_SCORE==MAX_SCORE) { gameOver(); }else { showScore(); } } // Check if we hit the horizontal walls. if(new_y == 0 || new_y == 63) { ball_dir_y = -ball_dir_y; new_y += ball_dir_y + ball_dir_y; } // Check if we hit the CPU paddle if(new_x == CPU_X && new_y >= cpu_y && new_y <= cpu_y + PADDLE_HEIGHT) { ball_dir_x = -ball_dir_x; new_x += ball_dir_x + ball_dir_x; } // Check if we hit the player paddle if(new_x == PLAYER_X && new_y >= player_y && new_y <= player_y + PADDLE_HEIGHT) { ball_dir_x = -ball_dir_x; new_x += ball_dir_x + ball_dir_x; } display.drawPixel(ball_x, ball_y, BLACK); display.drawPixel(new_x, new_y, WHITE); ball_x = new_x; ball_y = new_y; ball_update += BALL_RATE; } if(time > paddle_update && gameIsRunning) { paddle_update += PADDLE_RATE; // CPU paddle display.drawFastVLine(CPU_X, cpu_y,PADDLE_HEIGHT, BLACK); const uint8_t half_paddle = PADDLE_HEIGHT >> 1; if(cpu_y + half_paddle > ball_y) { cpu_y -= 1; } if(cpu_y + half_paddle < ball_y) { cpu_y += 1; } if(cpu_y < 1) cpu_y = 1; if(cpu_y + PADDLE_HEIGHT > 63) cpu_y = 63 - PADDLE_HEIGHT; display.drawFastVLine(CPU_X, cpu_y, PADDLE_HEIGHT, RED); // Player paddle display.drawFastVLine(PLAYER_X, player_y,PADDLE_HEIGHT, BLACK); if(up_state) { player_y -= 1; } if(down_state) { player_y += 1; } up_state = down_state = false; if(player_y < 1) player_y = 1; if(player_y + PADDLE_HEIGHT > 63) player_y = 63 - PADDLE_HEIGHT; display.drawFastVLine(PLAYER_X, player_y, PADDLE_HEIGHT, GREEN); } } void drawCourt() { display.drawRect(0, 0, 96, 64, WHITE); } void gameOver() { gameIsRunning = false; display.fillScreen(BLACK); drawCourt(); if(PLAYER_SCORE>CPU_SCORE) { display.setCursor(5,4); display.setTextColor(WHITE); display.setTextSize(2); display.printf("You Won"); }else { display.setCursor(5,4); display.setTextColor(WHITE); display.setTextSize(2); display.printf("CPU WON"); } display.setCursor(20,30); display.setTextColor(RED); display.setTextSize(3); display.printf("%d", CPU_SCORE); display.setCursor(60,30); display.setTextColor(GREEN); display.setTextSize(3); display.printf("%d",PLAYER_SCORE); delay(2000); while(UP_BUTTON && DOWN_BUTTON) { delay(100); } gameIsRunning = true; CPU_SCORE = PLAYER_SCORE = 0; unsigned long start = millis(); display.Scrollstop(); // stop scroll delay(100); display.fillScreen(BLACK); drawCourt(); while(millis() - start < 2000); ball_update = millis(); paddle_update = ball_update; gameIsRunning = true; resetBall=true; display.Scrollstop(); // stop scroll wait(1); } void showScore() { gameIsRunning = false; display.fillScreen(BLACK); drawCourt(); display.setCursor(15,4); display.setTextColor(WHITE); display.setTextSize(2); display.printf("Score"); display.setCursor(20,30); display.setTextColor(RED); display.setTextSize(3); display.printf("%d",CPU_SCORE); display.setCursor(60,30); display.setTextColor(GREEN); display.setTextSize(3); display.printf("%d",PLAYER_SCORE); delay(2000); unsigned long start = millis(); display.Scrollstop(); // stop scroll delay(100); display.fillScreen(BLACK); drawCourt(); while(millis() - start < 2000); ball_update = millis(); paddle_update = ball_update; gameIsRunning = true; resetBall=true; }
실행 - pulse-combined.hex
마이크로비트 공식 구입처 : 아이씨뱅큐 http://www.icbanq.com/
엘리먼트14의 특장점 - 글로벌 전자부품 유통회사, 6만원 이상 무료배송, 60만가지 재고 보유, MOQ 없음, 한글 웹사이트, 국내서비스센터 운영 (http://kr.element14.com/?CMP=DSP-ODB-KR-JAN2018-BLOG-ICBanQ1-HOMEPAGE)
마이크로비트 공식 카페 : http://cafe.naver.com/bbcmicro
아이씨뱅큐 공식 블로그 : http://blog.naver.com/icbanq
댓글
300x250
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- sas2009
- KOBA
- JavaScript
- Spring
- flex
- Delphi
- Java
- Delphi Tip
- 지스타2007
- 서울오토살롱
- oracle
- SAS
- BPI-M4
- Mac
- 전예희
- ubuntu
- 송주경
- NDK
- android
- ble
- 튜닝쇼 2008
- MySQL
- 레이싱모델 익스트림 포토 페스티벌
- Linux
- Xcode
- Spring MVC
- 일본여행
- koba2010
- ffmpeg
- 동경
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함