[Из песочницы] Создание логической игры для игровой платформы17.09.2018 19:02
#include
#include
#include
#include "slotgag_assets.h"
#define TAG_BUTTON_LEFT 201
#define TAG_BUTTON_RIGHT 202
#define TAG_BUTTON_ROT 203
#define TAG_BUTTON_DROP 204
#define X_BUTTON_LEFT 50
#define Y_BUTTON_LEFT 222
#define X_BUTTON_RIGHT 430
#define Y_BUTTON_RIGHT 222
#define X_BUTTON_ROT 430
#define Y_BUTTON_ROT 50
#define X_BUTTON_DROP 50
#define Y_BUTTON_DROP 50
// Color definitions
#define BLACK 0x000000
#define RED 0xFF0000
#define GREEN 0x00FF00
#define BLUE 0x0000FF
#define YELLOW 0xFFFF00
#define MAGENTA 0xFF00FF
#define CYAN 0x00FFFF
#define WHITE 0xFFFFFF
#define DISPLAY_MAX_X 480
#define DISPLAY_MAX_Y 272
#define MaxX 8
#define MaxY 17
#define SmeX 3
#define SmeY 3
#define razmer 18
#define NumCol 6
#define MaxLevel 8
#define NextLevel 80
#define DISP_LEFT ((DISPLAY_MAX_X - MaxX*razmer)/2 - 2)
#define DISP_RIGHT ((DISPLAY_MAX_X + MaxX*razmer)/2 + 2)
#define DISP_TOP ((DISPLAY_MAX_Y - (MaxY-4)*razmer)/2 - 2)
#define DISP_BOT ((DISPLAY_MAX_Y + (MaxY-4)*razmer)/2 + 2)
uint8_t MasSt[MaxX][MaxY], MasTmp[MaxX][MaxY], fignext[3];
uint8_t Level=1, dx, dy, tr, flfirst=1;
uint32_t MasCol[]={WHITE, BLACK, RED, BLUE, GREEN, YELLOW, MAGENTA, CYAN};
unsigned long Counter, Score=0, TScore=0, Record=0, myrecord;
uint16_t tempspeed = 1000;
bool fl, Demo=true, Arbeiten=false, FlZ=false;
int8_t x,y;
int8_t mmm [4][2]={{-1,0},{0,-1},{1,0},{0,1}};
uint16_t MasSpeed[MaxLevel]={500,450,400,350,300,250,200,100};
uint8_t state_game = 0;
unsigned long time_count;
byte prevkey;
uint32_t btn_color = 0xff0000;
/****************************************************************************************************************/
void setup(void)
{
Serial.begin(1000000);
Serial.println("Columns");
GD.begin();
LOAD_ASSETS();
GD.BitmapHandle(BACKGROUND_HANDLE);
GD.BitmapSize(NEAREST, REPEAT, REPEAT, 480, 272);
randomSeed(analogRead(5));
myrecord = eeprom_read_byte((unsigned char *)1);
time_count = millis() + 1000;
}
static struct {
byte t, note;
} pacman[] = {
{ 0, 71 },
{ 2, 83 },
{ 4, 78 },
{ 6, 75 },
{ 8, 83 },
{ 9, 78 },
{ 12, 75 },
{ 16, 72 },
{ 18, 84 },
{ 20, 79 },
{ 22, 76 },
{ 24, 84 },
{ 25, 79 },
{ 28, 76 },
{ 32, 71 },
{ 34, 83 },
{ 36, 78 },
{ 38, 75 },
{ 40, 83 },
{ 41, 78 },
{ 44, 75 },
{ 48, 75 },
{ 49, 76 },
{ 50, 77 },
{ 52, 77 },
{ 53, 78 },
{ 54, 79 },
{ 56, 79 },
{ 57, 80 },
{ 58, 81 },
{ 60, 83 },
{ 255, 255 }
};
//==================================================
void loop(void)
{
GD.get_inputs();
byte key = GD.inputs.tag;
int8_t VAL = 0;
if (prevkey == 0x00)
{
switch (key) {
case TAG_BUTTON_LEFT:
VAL = -1;
break;
case TAG_BUTTON_RIGHT:
VAL = 1;
break;
case TAG_BUTTON_ROT:
if (!FlZ)
{
GD.play(HIHAT);
byte aa=MasSt[x][y];
MasSt[x][y]=MasSt[x][y+2];
MasSt[x][y+2]=MasSt[x][y+1];
MasSt[x][y+1]=aa;
}
break;
case TAG_BUTTON_DROP:
if (Arbeiten) {
if (!FlZ) {
tempspeed=50;
GD.play(NOTCH);
}
} else {
GD.play(CLICK);
Demo=false;
NewGame();
}
break;
}
}
prevkey = key;
if (VAL!=0 && fig_shift(VAL) && !FlZ) {
for (byte i=0;i<3;i++) {
MasSt[x+VAL][y+i]=MasSt[x][y+i];
MasSt[x][y+i]=0;
}
x=x+VAL;
}
ProcGame();
ViewStacan();
GD.swap();
}
//==================================================
// redraw one square
void ViewQuad(byte i,byte j,byte mycolor)
{
if (j<3) return;
uint16_t wy=DISP_TOP + SmeY+(j-3)*razmer-j;
uint16_t wx=DISP_LEFT + SmeX+i*razmer-i;
if (mycolor!=0) {
GD.LineWidth(16*1);
GD.ColorRGB(WHITE);
GD.Begin(LINE_STRIP);
GD.Vertex2ii(wx,wy);
GD.Vertex2ii(wx + razmer-1,wy);
GD.Vertex2ii(wx + razmer-1,wy + razmer-1);
GD.Vertex2ii(wx,wy + razmer-1);
GD.Vertex2ii(wx,wy);
GD.Begin(RECTS);
GD.ColorRGB(MasCol[mycolor]);
GD.Vertex2ii(wx+1, wy+1); GD.Vertex2ii(wx+1 + razmer-2 - 1, wy+1 + razmer-2 - 1);
} else {
}
}
//==================================================
void ViewStacan(void)
{
char myStr2[5];
// Draw background fone
GD.Clear();
GD.ColorMask(1, 1, 1, 0);
GD.Begin(BITMAPS);
GD.BitmapHandle(BACKGROUND_HANDLE);
GD.BitmapSize(NEAREST, REPEAT, REPEAT, 480, 272);
GD.Vertex2ii(0, 0, BACKGROUND_HANDLE);
// Print text
GD.ColorRGB(WHITE);
GD.cmd_text(DISP_LEFT - 30, DISP_TOP + 3, 27, OPT_CENTER, "LEVEL");
GD.cmd_text(DISP_RIGHT + 30, DISP_TOP + 3, 27, OPT_CENTER, "NEXT");
GD.cmd_text(DISP_RIGHT + 30, DISP_TOP + 100, 27, OPT_CENTER, "SCORE");
GD.cmd_text(DISP_LEFT - 30, DISP_TOP + 100, 27, OPT_CENTER, "TOP");
// Print digit Score
GD.ColorRGB(RED);
sprintf(myStr2,"%05d",Score );
GD.cmd_text(DISP_RIGHT + 30, DISP_TOP + 130, 27, OPT_CENTER, myStr2);
// Print digit Top
sprintf(myStr2,"%05d",myrecord );
GD.cmd_text(DISP_LEFT - 30, DISP_TOP + 130, 27, OPT_CENTER, myStr2);
// Print digit Level
sprintf(myStr2,"%02d",Level );
GD.cmd_text(DISP_LEFT - 30, DISP_TOP + 40, 31, OPT_CENTER, myStr2);
// Draw color squares
for (byte j=3;j=0 && ny>=0 && nx1 || MasTmp[i][j]>2 )) {
MasTmp[nx][ny]=3;
MasTmp[i][j]=3;
} else {
if (mode==3 && MasTmp[nx][ny]==3) {
if (MasTmp[i][j]!=3) {
MasTmp[i][j]=3;
fl=true;
}
}
}
}
}
//==================================================
void Sos(int i,int j, byte mode)
{
for (byte k=0;k<4;k++)
Sosed(i,j,mmm[k][0],mmm[k][1],mode);
}
//==================================================
// create next figure
void GetNext(void)
{
x=3; y=0;
for (byte i=0;i<3;i++) {
if (!Demo) MasSt[x][i]=fignext[i];
fignext[i]=random(NumCol)+2;
}
if (!Demo) {
Counter++;
if (Counter==NextLevel) {
Counter=0;
Level++;
if (Level>MaxLevel) Level=MaxLevel;
}
tempspeed=MasSpeed[Level-1];
}
}
//==================================================
// find onecolor elements
bool FindFull(void)
{
byte i,j,k; bool res;
res=false;
for (byte k=2;k<8;k++) { // by every color
ClearMas(MasTmp);
for (j=3;j1) Sos(i,j,2);
do {
fl=false;
for (j=3;j0) Sos(i,j,3);
} while (fl);
for (j=3;j0 && !FlZ) {
if (y+dy+2>MaxY-1 || MasSt[x+dx][y+dy+2]>0) {
if (y<3) {
gameover();
} else {
return true;
}
} else {
if (y+dy+dy+2>MaxY-1 || MasSt[x+dx][y+dy+dy+2]>0) {
GD.play(COWBELL);
}
for (byte i=0;i<3;i++) MasSt[x][y+2-i+dy]=MasSt[x][y+2-i];
MasSt[x][y]=0;
y=y+dy;
}
}
return(false);
}
//================================================
// move figure left/right (shift)
bool fig_shift(int dx)
{
if (x+dx<0 || x+dx>MaxX-1) {
GD.play(COWBELL);
return(false);
}
if (dx!=0) {
if (MasSt[x+dx][y+dy+2]==0) {
if (x+dx+dx<0 || x+dx+dx>MaxX-1)
GD.play(COWBELL);
else
GD.play(CHACK);
return(true);
} else {
GD.play(COWBELL);
return(false);
}
}
return(false);
}
//==================================================
// State-machine
void ProcGame(void)
{
byte i,j,k; bool res = false;
if (time_count < millis()) {
if (Arbeiten)
time_count = millis() + tempspeed;
else
time_count = millis() + 1000;
switch (state_game) {
// Demo
case 0:
Score=0;
GetNext();
for (byte j=3;j0)
{
FlZ=true;
time_count = millis() + 500;
}
state_game = 2;
break;
case 2:
for (j=0;j7) Score=Score+TScore+(TScore-8)*2;
else Score=Score+TScore;
state_game = 1;
} else {
state_game = 0;
}
break;
// Arbeiten
case 3:
if (fig_drop(1))
{
tempspeed=MasSpeed[Level-1];
TScore=0;
FindFull();
if (TScore>0)
{
GD.play(KICKDRUM);
FlZ=true;
state_game = 4;
} else {
FlZ=false;
GetNext();
}
}
break;
case 4:
for (j=0;j7) Score=Score+TScore+(TScore-8)*2;
else Score=Score+TScore;
state_game = 5;
FlZ=true;
GD.play(CLACK);
} else {
state_game = 3;
FlZ=false;
time_count = millis() + 100;
}
break;
case 5:
state_game = 3;
FlZ=false;
break;
default:
break;
}
}
}
//================================================
// start new game
void NewGame()
{
Score = 0;
FlZ = false;
ClearMas(MasSt);
Arbeiten = true;
GetNext();
Counter = 0;
Level = 1;
tempspeed = MasSpeed[0];
Record = myrecord;
state_game = 3;
}
//================================================
// draw "GAME OVER"
void gameover()
{
if (Arbeiten==true) {
GD.play(SWITCH);
Arbeiten=false;
if (Score>myrecord) {
myrecord=Score;
eeprom_write_byte((unsigned char *) 1, myrecord);
}
}
}
© Habrahabr.ru