프로그래밍은 항상 재미 있었고 Arduino와 같은 개발 플랫폼으로 훨씬 더 좋아졌습니다. 여기에있는 거의 모든 프로그래머는 그들이 배우고 연습하는 언어를 사용하여 어떤 종류의 게임을 개발하려고 노력했을 것입니다. 이를 통해 재미 있으면서도 생산적인 방식으로 프로그래밍 기술을 조정할 수 있습니다. 저는 Arduino를 처음 접한 이래로 Arduino의 열렬한 팬이었으며 항상 멋진 것을 시도해보고 싶었습니다. Arduino와 함께 Nokia 5110과 같은 그래픽 LCD로 얼마나 멋진 지 알게되었을 때 게임 개발에 대한 제 생각입니다. 몇 가지 프로그래밍 기술을 조정하고 동시에 재미있게 즐길 수있는 흥미로운 방법 이었지만, 여러분도 게임 개발에 관심이있을 수 있습니다. 따라서이 튜토리얼에서는 Arduino 및 그래픽 LCD를 사용하여 Decent Game을 만드는 방법을 배웁니다.
우리는 이미 Arduino를 사용하여 구식 Snake 게임을 만들었으므로 이번에는 새로운 것을 시도하고 있으며이 게임 을 조이스틱을 사용하여 적의 선박으로부터 안전하게 유지해야하는 Space Race Game 으로 명명했습니다.
전략:
시작하기 전에 게임이 실제로 어떻게 작동할지 계획하는 것이 매우 중요합니다. 하드웨어 선택을 위해 Nokia5110 그래픽 LCD 및 조이스틱을 사용했습니다. 이 튜토리얼에서는 당신도 같은 것을 선택했다고 가정합니다. Nokia 5110은 공간이 많지 않기 때문에 전체 게임을 디스플레이의 84 * 48 픽셀 해상도로 계획했습니다. 우리는 이미 Nokia 5110 LCD를 Arduino와 인터페이스하고 Joystick을 Arduino와 인터페이스하는 방법에 대한 자습서를 만들었습니다.
이 공간 내에서 우리는 게임 영역과 점수 및 물건과 같은 것을 표시 할 점수 판 영역에 꼭 맞아야합니다. 픽셀 위치를 추적하고 화면에서 업데이트하려면 물건을 놓는 위치의 픽셀 위치를 아는 것이 매우 중요합니다.
게임 화면 모양이 결정되면 게임에서 캐릭터를 결정해야합니다. 제 게임에는 우주선 인 플레이어 캐릭터와 외계인 우주선처럼 보이는 적 캐릭터 만 있습니다. Nokia LCD는 비트 맵 이미지를 표시 할 수 있으므로이 옵션을 사용하여 우주선과 적을 표시하기로 결정했습니다.
그래서 우리는 외계인 우주선을 통해 경주하는 우주선을 갖게 될 것입니다.이 우주선은 외계인과의 충돌을 피하기 위해 3 개의 차선을 변경할 것입니다. 외계인은 항상 두 개의 트랙 만 차지할 수 있으며 플레이어는 자유 트랙을 통과 할 수 있어야합니다. 이러한 아이디어가 완료되면 하드웨어와 프로그래밍을 진행할 수 있습니다.
회로도:
이 Arduino 게임 의 회로 는 매우 간단합니다. Nokia 5110 LCD 모듈과 Joystick을 Arduino와 연결하기 만하면됩니다. 전체 회로도가 아래에 나와 있습니다.
Nokia 5110 LCD는 3.3V에서 작동하고 Joystick 모듈은 5V에서 작동하므로 5V로 인해 LCD가 영구적으로 손상 될 수 있으므로 3.3V로만 LCD를 연결해야합니다. LCD는 SPI 프로토콜을 통해 Arduino와 통신하고 조이스틱은 전압 변화를 읽기 위해 ADC 만 읽습니다. 연결 설정은 다음과 같습니다.
전제 조건:
프로그래밍 부분으로 들어가기 전에 사람들이 디스플레이 모듈과 조이스틱을 편리하게 사용하는 것이 중요하므로 다음 자습서를 사용하여 자세한 내용을 알 수 있으며 여기로 돌아와서 작업이 제대로 작동하는지 확인할 수 있습니다. 필요합니다!
- Arduino와 인터페이스하는 Nokia 5110 LCD
- Arduino와 인터페이스하는 조이스틱 모듈
우주 경주 게임을위한 Arduino 프로그래밍:
게임 의 전체 프로그램 은이 페이지 끝에서 찾을 수 있습니다. Arduino IDE에서 직접 사용하고 Board에 업로드 할 수 있습니다. 그러나 실제로 코드 내에서 어떤 일이 발생하는지 알고 싶다면 더 읽어보십시오.
항상 그렇듯이 라이브러리 헤더 파일 을 추가하여 프로그램을 시작 합니다.이 프로젝트에는 기본적으로 SPI 라이브러리가 IDE에 추가되는 세 개의 라이브러리가 필요합니다. 다른 두 라이브러리는 Adafruit Github 페이지에서 다운로드해야합니다. 라이브러리를 추가하는 방법을 잘 모르는 경우 전제 조건 섹션에 언급 된 LCD 인터페이스 자습서를 따르십시오.
#포함
튜토리얼을 따라했다면 LCD에 비트 맵 이미지 를 표시 할 수 있음을 알아야합니다. 따라서 튜토리얼에서 언급 한 소프트웨어를 사용하여 필요한 이미지를 비트 맵 코드 로 변환해야합니다. 인터넷에서 이미지를 선택하여 비트 맵 코드로 변환하여 사용할 수 있습니다. 이미지가 LCD 화면에 표시 될 수있을만큼 단순한 지 확인하고 실제로 LCD 화면에서 시도하기 전에 미리보기를 확인하십시오. 우리 프로그램에서 우리는 두 개의 비트 맵 문자를 사용했습니다. 하나는 우주선이고 다른 하나는 적함입니다. 둘 다에 대한 비트 맵 코드는 아래와 같이 코드에 추가되었습니다.
// SpaceShip static const unsigned char PROGMEM ship = { B00000000, B00000000, B00000001, B00000000, B00000011, B10000000, B00000010, B10000000, B00000010, B11000000, B00000111, B11000000, B00001101, B11100000, B00011111, B11110000, B00111111, B11111000, B01111111, B11111100, B01111111, B11111100, B01111111, B11111100, B00011111, B11110000, B00000111, B11100000, B00000000, B00000000, }; // 적함의 비트 맵 데이터 static const unsigned char PROGMEMenemy = { B00000101, B11000000, B00001011, B11100000, B00000011, B11100000, B00110011, B11111000, B01111111, B11111100, B10111111, B11111010, B01110111, B11011100, B01111110, B11111100, B00111111, B11111100, B11101111, B11101110, B11000001, B00000110, B10000001, B00000010, B10000000, B00000010, B00000000, B00000000, };
Nokia LCD 5110 디스플레이 가 연결 되는 핀 을 지정해야합니다. 디스플레이는 SPI 통신을 사용하여 통신합니다. 위의 회로도를 따랐다면 LCD를 초기화하는 코드는 다음과 같습니다. 변경할 필요가 없습니다.
Adafruit_PCD8544 디스플레이 = Adafruit_PCD8544 (7, 6, 5, 4, 3); // 로 명시 액정가 연결된 핀
설정 기능 내에서 직렬 모니터를 9600 전송 속도로 시작하여 디버깅 한 다음 LCD 디스플레이를 초기화 할 수 있습니다. 또한 LCD 디스플레이의 대비 를 설정 해야합니다. 각 디스플레이는 서로 다른 대비 수준에서 가장 잘 작동하므로 값을 사용하여 가장 적합한 것을 확인하십시오. 마지막으로 디스플레이 화면을 지워 새로 시작합니다.
void setup () { Serial.begin (9600); // 디버깅을위한 직렬 모니터 display.begin (); // LCD 통신 시작 display.setContrast (30); // 디스플레이의 대비를 설정합니다 . display.clearDisplay (); // 화면을 지우고 새로 시작 }
화면이 지워지면 루프 기능으로 이동 하여 게임 화면이 표시 됩니다. 게임 화면은 점수 및 속도 수준과 함께 게임의 기본 골격을 표시합니다. 우리는 선 기능을 사용하여 테두리로 3 개의 선을 그리고 오른쪽에는 오래된 레트로 휴대용 게임기처럼 텍스트 점수와 속도를 표시합니다.
void gamescreen () { // 화면 테두리 그리기 display.drawLine (0, 0, 0, 47, BLACK); display.drawLine (50, 0, 50, 47, BLACK); display.drawLine (0, 47, 50, 47, BLACK); // 기본 텍스트 입력 display.setTextSize (1); display.setTextColor (BLACK); display.setCursor (52,2); display.println ("속도"); display.setCursor (54,12); display.println (game_speed); display.setCursor (52,25); display.println ("점수"); display.setCursor (54,35); display.println (score); }
다음 으로 사용자가 우주선을 제어 할 수 있도록 사용자로부터 입력 을 받아야합니다. 입력은 핀 A1에 연결된 조이스틱 모듈에서 수신됩니다. 센서의 아날로그 값은 이동하지 않으면 512가되고 X 축을 따라 이동하면 증가하거나 감소합니다. 이 값을 사용하여 사용자가 왼쪽 또는 오른쪽으로 이동할 것인지 결정합니다. 아래 프로그램을 이해하기 어렵다면 전제 조건에 언급 된 Arduino와 인터페이스하는 Joystick 튜토리얼을 읽어야합니다.
// 사용자로부터 입력 받기 Joy_X = analogRead (A1); // 조이스틱에서 X 값 읽기 if (Joy_X <312 && POS! = 1 && control == true) // 조이스틱이 오른쪽으로 움직이면 {POS--; control = false;} // 우주선 위치 감소 else if (Joy_X> 712 && POS! = 3 && control == true) // 조이스틱이 오른쪽으로 움직이면 {POS ++; control = false;} // 우주선 위치 증가 else if (Joy_X> 502 && Joy_X <522) // 조이스틱이 초기 위치로 돌아 가면 control = true; // 다음 이동을 위해 준비 // 사용자 입력
사용자로부터 우주선의 위치를 얻은 후 우리는 그 특정 장소에 우주선을 배치해야 합니다. 아래 함수를 사용하고 위치 값을 매개 변수로 전달한 다음 우주선이 해당 트랙에 배치 된 위치를 기반으로합니다.
void player_car (char pos) // 사용자가 선택한 위치에 따라 우주선 배치 { if (pos == 1) display.drawBitmap (2, 32, ship, 15, 15, BLACK); if (pos == 2) display.drawBitmap (18, 32, ship, 15, 15, BLACK); if (pos == 3) display.drawBitmap (34, 32, ship, 15, 15, BLACK); }
이제 우주선이 화면에 배치되고 경주 할 준비가되었으므로 플레이어와 함께 경쟁 할 적 군함을 소개해야합니다. 적 군함이 화면을 넘을 때마다 우리는 그가 죽었다고 가정하고 그가 죽었 을 때 우리는 새로운 우주선을 만들어야합니다. 아래의 기능은 동일합니다. 적 군함 2 척에 대한 새로운 위치를 생성하여 화면 상단에 배치합니다.
if (enemy_dead) // 적 군함이 죽었는지 확인 {// 죽었 으면 적 군함 이 죽었 는지 적함 _0_pos = POS; // 우주선 위에 첫 번째 적을 만듭니다. 적군 _1_pos = random (0,4); // 다른 임의의 장소에 secound 적을 만듭니다. 적군 _phase = 0; // 상단에서 적을 가져 오십시오. 적군 _dead = false; // 적은 더 이상 죽지 않도록 생성됩니다. }
적 군함을 화면 상단에 배치 한 후 플레이어가 위로 경주하는 것처럼 창을 띄도록 아래로 내려야합니다. 이렇게하려면 위상 (이미지가 표시되는 위치)을 증가시켜야합니다. 천천히 내려옵니다. 아래 그림과 같이 두 적군함에 대해 동일하게 적용됩니다.
적함 (enemy_0_pos, enemy_phase); 적 _ 단계 ++; // 첫 번째 적을 화면에 배치하고 적 군함을 몰아 내십시오 (enemy_1_pos, enemy_phase); 적 _ 단계 ++; // 화면에 두 번째 적을 배치하고 그를 추락시킵니다.
다음에 적 군함 함수 가 표시되어 있습니다. 플레이어 자동차 함수와 매우 유사하지만 여기에는 두 개의 매개 변수가 있습니다. 하나는 적을 트랙에 배치하는 것이고 다른 하나는 적을 바닥으로 이동시키는 것입니다.
voidenemy_ship (int place, int phase) // 적 군함을 새로운 장소와 단계에 배치 { if (place == 1) display.drawBitmap (2, phase, 적, 15, 15, BLACK); if (place == 2) display.drawBitmap (18, phase, 적, 15, 15, BLACK); if (place == 3) display.drawBitmap (34, phase, 적, 15, 15, BLACK); }
다음 코드는 우주선이 적 군함을 피했는지 확인해야합니다. 이를 확인하려면 적 군함의 위치와 플레이어의 우주선을 알아야합니다. 우리는 모든 것을 알고 있으므로 우주선 위치가 적함과 같은지 확인해야합니다. 적 군함이 우주선 근처에 도달 한 경우에만이를 확인합니다. 플레이어가 적을 피하지 않았다면 게임 오버를 의미합니다.
if (enemy_phase> 22 && ((enemy_0_pos == POS)-(enemy_1_pos == POS))) // 우주선이 적 중 하나에 닿으면 game_over (); // 게임 오버 표시
플레이어가 적을 성공적으로 피했다면 적을 죽이고 플레이어에게 점수를 주어야합니다. 이렇게하려면 적이 화면 하단에 도달했는지 확인하고, 도달하면 아래 코드를 사용하여 죽입니다.
if (enemy_phase> 40) // 우주선이 적을 탈출하면 {enemy_dead = true; score ++;} // 점수를 높이고 적을 처치하십시오
우리가 높은 점수를받을 때 게임의 난이도를 높이 지 않는다면 얼마나 재미 있을까요? 그래서 우리 는 플레이어의 점수 를 모니터링하고 점수에 따라 게임의 속도를 증가시키는 또 다른 기능을 사용 합니다. 속도는 실제로 지연 기능을 사용하여 제어됩니다. 이것은 게임의 새로 고침 간격을 제어하여 속도를 빠르게 또는 느리게 만듭니다.
void Level_Controller () // 점수에 따라 게임 속도를 높입니다. { if (score> = 0 && score <= 10) // 점수가 0-10 인 경우 { game_speed = 0; 지연 (80); // 게임을 80ms 느리게 } if (score> 10 && score <= 20) // If score 10-40 { game_speed = 1; 지연 (70); // 게임을 70ms 느리게합니다. } if (score> 20 && score <= 30) // 점수가 20-40 인 경우 { game_speed = 2; 지연 (60); // 게임을 60ms 느리게 } if (score> 30 && score <= 40) // If 점수 30-40 { game_speed = 3; 지연 (50); // 게임을 50ms 느리게 } }
Arduino Space Racer 게임 작동:
하드웨어와 프로그램이 이해되었는지 확인한 후 회로를 구축하고 코드를 Arduino 보드에 업로드하면됩니다. 아래와 같이 게임이 시작되는 것을 확인할 수 있습니다.
조이스틱을 사용하여 왼쪽이나 오른쪽으로 이동하여 적함을 탈출하세요. 각 적을 피하면 점수가 1 씩 증가합니다. 점수가 높아지면 게임 속도도 빨라집니다. 즉, 10 점을 얻을 때마다 속도가 10ms 씩 증가합니다. 계속해서이 게임을 기반으로 새로운 레벨을 도입하거나 가속도계를 사용하여 모션을 통해 제어하기 위해 하드웨어를 변경할 수 있습니다. 창의성은 유일한 한계입니다. 참고로 여기에서 Arduino와 함께 가속도계를 사용하는 방법을 배웁니다.
당신이 프로젝트를 이해하고 그것을 만드는 것을 즐겼기를 바랍니다. 이 작업을 수행하는 데 문제가있는 경우 아래 댓글 섹션에 문제를 게시하거나 기술 지원을 위해 포럼을 사용하십시오. 즐거운 게임 !!
아래 의 전체 코드와 데모 비디오를 확인하십시오.