Игры для ESPspectrum
С момента выхода первой версии прошло достаточно времени и устройство получило уже достаточно доработок. Вчера закончил работу над новой игрой про математику для проекта. В этой статье я постараюсь подробно рассказать как сделать свою собственную игру для ESPspectrum.
Все игры хранятся в папке со скетчем в папке games. Игра имеет формат .h
создание игры
#ifndef MathGame_h //любое название игры
#define MathGame_h
#include
// ниже код игровой библиотеки
В начале нашей игры надо создать все необходимые переменные, изменить шрифт и выполнить другие необходимые действия.
void math_game()
{
const int resx = 315; //разрешение монитора
const int resy = 235;
int fps = 50;
int fpsdel = 1000 / fps; //обновление монитора
String pr = " "; //для игры
int answ = 0;
int trueAnsw = 0;
int score = 0;
int ex = 0; //чтобы выйти
Дальше будет бесконечный цикл, но перед ним можно выполнить обратный отсчет и запустить секундомер.
vga.clear(0);
vga.setCursor(resx/2,resy/2);
vga.print("5"); delay(1000); vga.clear(0);
vga.setCursor(resx/2,resy/2);
vga.print("4"); delay(1000); vga.clear(0);
vga.setCursor(resx/2,resy/2);
vga.print("3"); delay(1000); vga.clear(0);
vga.setCursor(resx/2,resy/2);
vga.print("2"); delay(1000); vga.clear(0);
vga.setCursor(resx/2,resy/2);
vga.print("1"); delay(1000); vga.clear(0);
unsigned long Time = millis(); //время игры
int a;
int b;
int r;
В while находится основная часть игры: текст, примеры, решение, правильный ответ, ввод ответа с клавиатуры.
while(1){
String str = "";
//игровое поле
vga.rect( 0, 0, resx, resy, vga.RGB(255, 255, 255) );
vga.setCursor(5, 10);
vga.print("Score ");
vga.println(score);
/*========================================================== */
if(trueAnsw == 0){ //генерация случаного примера
r = random(1,4);
// 1 +
// 2 -
// 3 *
if(r == 1){
a = random(5,299);
b = random(5,299);
trueAnsw = a + b;
}
if(r == 2){
a = random(5,399);
b = random(4,299);
trueAnsw = a - b;
}
if(r == 3){
a = random(5,220);
b = random(2,30);
trueAnsw = a * b;
}
}
if(trueAnsw != 0){
vga.setCursor(resx/2 - 20, resy/2);
if(r == 1){ vga.print(a); vga.print(" + "); vga.print(b); }
if(r == 2){ vga.print(a); vga.print(" - "); vga.print(b); }
if(r == 3){ vga.print(a); vga.print(" * "); vga.print(b); }
}
/*==========================================================*/
vga.setCursor(resx/2, resy/2 + resy/4);
while(answ == 0){
int scanval = 0;
for(int i = 0; i<11; i++)
{
while(digitalRead(CLOCK));
scanval |= digitalRead(DATA) << i;
while(!digitalRead(CLOCK));
}
scanval >>= 1;
scanval &= 0xFF;
Serial.println(scanval, HEX);
if(lastscan != 0xF0 && scanval != 0xF0)
{
if(scanval != 0x5A and scanval != 0xE0)
{
str = str + keymap[scanval];
Serial.println(keymap[scanval]);
vga.print(keymap[scanval]);
}
if(scanval == 0x5A){
vga.setCursor(0, 0);
vga.clear(vga.RGB(0,0,0));
answ = str.toInt();
str = "";
}
if(scanval == 0xE0){vga.clear(vga.RGB(0,0,0)); vga.setCursor(0, 0); str = ""; ex = 1; answ = 1;}
}
lastscan = scanval;
}
/*========================================================== */
if(ex == 1){delay(100); vga.setCursor(resx/2 - 10, resy/2); vga.print(millis() - Time);
vga.print(" ms "); delay(2000); vga.clear(0); vga.setCursor(0,0); return;}
if(answ != 0){
if(answ == trueAnsw){score += 1; answ = 0; trueAnsw = 0;} //правильность ответа
else{answ = 0; trueAnsw = 0; if(score>0){score -= 1;}}
}
if(score<0){score = 0;} //если каким то чудом < 0 то делаем равным 0
delay(fpsdel);
vga.clear(0);
vga.setCursor(0,0);
}
}
#endif //конец
На данном этапе опрос клавиатуры останавливает все остальные процессы. Это надо как то исправлять.
По такому же принципу сделана и змейка.
Как подключить созданную игру
1. Открываем скетч
2. Переходим во вкладку game_menu
3. подключаем игру и добавляем в меню выбора
#include "games/SnakeGame.h"
#include "games/MathGame.h" //подключаем игру которую мы сделали
void game_menu()
{
int gamemode = 0; //переменная отвечает за игры
while(true){
vga.setCursor(2, 2);
vga.println("1 - Snake");
vga.println("2 - Math"); //Вписываем для отображения в меню игр
vga.println("3 - Add");
int scanval = 0;
for(int i = 0; i<11; i++)
{
while(digitalRead(CLOCK));
scanval |= digitalRead(DATA) << i;
while(!digitalRead(CLOCK));
}
scanval >>= 1;
scanval &= 0xFF;
if(lastscan != 0xF0 && scanval != 0xF0)
{
if(scanval != 0x5A and scanval != 0xE0){ txt_keys = txt_keys + keymap[scanval]; Serial.println(keymap[scanval]);}
//системные клавиши
if(scanval == 0x76){vga.clear(vga.RGB(0,0,0)); vga.setCursor(0, 0);}
if(scanval == 0x5A){vga.clear(vga.RGB(0,0,0)); gamemode = 0;}
if(scanval == 0xE0){vga.clear(vga.RGB(0,0,0)); menu = 0; return;}
if(scanval == 0x16){gamemode = 1;}
if(scanval == 0x1E){gamemode = 2;} // наша игра по номером 2
if(scanval == 0x26){gamemode = 3;}
if(scanval == 0x25){gamemode = 4;}
if(scanval == 0x2E){gamemode = 5;}
}
lastscan = scanval;
if(gamemode == 1){ txt_keys = ""; vga.clear(vga.RGB(0,0,0)); vga.setCursor(0, 0); snake_game(); }
if(gamemode == 2){ txt_keys = ""; vga.clear(vga.RGB(0,0,0)); vga.setCursor(0, 0); math_game(); } //запускаем игру
//можно игры записать в любом порядке
Serial.print("gamemode = ");Serial.println(gamemode);
}
}
4. Можно проверять.
СЕРВЕР: вопросы, помощь проекту и по проекту: https://discord.gg/nd6K7sbR
Прошлые статьи