-
Notifications
You must be signed in to change notification settings - Fork 0
/
gameStart.c
211 lines (190 loc) · 5.6 KB
/
gameStart.c
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#include "headers.h"
#include "Board_GLCD.h"
#include "GLCD_Config.h"
#include "stm32f7xx.h"
#include <stdlib.h>
#include <stdio.h>
#define BLOCK_SIZE 10
#define BLOCK_NUM_X 24
#define BLOCK_NUM_Y 24
#define BLOCK_PAD 5
#define BOX_X 15
#define BOX_Y 10
extern int STATE;
extern int uuid;
extern int currentGameId;
extern struct Snake* currentSnake;
extern struct Food* currentFood;
extern struct TouchArea snakeBTAUp;
extern struct TouchArea snakeBTADown;
extern struct TouchArea snakeBTALeft;
extern struct TouchArea snakeBTARight;
extern struct TouchArea snakeBTAPause;
extern struct GameRecord* gameRecords;
extern volatile unsigned int tickPSC;
void drawSnakeBox (unsigned int lineColor)
{
GLCD_SetForegroundColor(lineColor);
unsigned int edgeLenX = BLOCK_SIZE * BLOCK_NUM_X + 2 * BLOCK_PAD;
unsigned int edgeLenY = BLOCK_SIZE * BLOCK_NUM_Y + 2 * BLOCK_PAD;
GLCD_DrawHLine(BOX_X, BOX_Y, edgeLenX);
GLCD_DrawVLine(BOX_X, BOX_Y, edgeLenY);
GLCD_DrawHLine(BOX_X, BOX_Y + edgeLenY, edgeLenX);
GLCD_DrawVLine(BOX_X + edgeLenX, BOX_Y, edgeLenY);
}
void drawSnakeBlock (unsigned int x, unsigned int y, unsigned int fillColor)
{
if (x >= BLOCK_NUM_X || y >= BLOCK_NUM_Y)
{
return;
}
GLCD_SetForegroundColor(fillColor);
unsigned int startX = BOX_X + BLOCK_PAD + x * BLOCK_SIZE;
unsigned int startY = BOX_Y + BLOCK_PAD + y * BLOCK_SIZE;
for (unsigned int i = 0; i < BLOCK_SIZE; i++)
{
GLCD_DrawHLine(startX, startY + i, BLOCK_SIZE);
}
}
void drawSnakeButton (unsigned int centerX, unsigned int centerY, unsigned int size, unsigned int spread, unsigned int color)
{
GLCD_SetForegroundColor(color);
unsigned int textMarginX = size / 2 - 16;
unsigned int textMarginY = size / 2 - 12;
// up
snakeBTAUp.startX = centerX - size / 2;
snakeBTAUp.startY = centerY - spread - size / 2;
snakeBTAUp.sizeX = size;
snakeBTAUp.sizeY = size;
GLCD_DrawRectangle(snakeBTAUp.startX, snakeBTAUp.startY, snakeBTAUp.sizeX, snakeBTAUp.sizeY);
GLCD_DrawString(snakeBTAUp.startX + textMarginX, snakeBTAUp.startY + textMarginY, "UP");
// down
snakeBTADown.startX = centerX - size / 2;
snakeBTADown.startY = centerY + spread - size / 2;
snakeBTADown.sizeX = size;
snakeBTADown.sizeY = size;
GLCD_DrawRectangle(snakeBTADown.startX, snakeBTADown.startY, snakeBTADown.sizeX, snakeBTADown.sizeY);
GLCD_DrawString(snakeBTADown.startX + textMarginX, snakeBTADown.startY + textMarginY, "DN");
// left
snakeBTALeft.startX = centerX - spread - size / 2;
snakeBTALeft.startY = centerY - size / 2;
snakeBTALeft.sizeX = size;
snakeBTALeft.sizeY = size;
GLCD_DrawRectangle(snakeBTALeft.startX, snakeBTALeft.startY, snakeBTALeft.sizeX, snakeBTALeft.sizeY);
GLCD_DrawString(snakeBTALeft.startX + textMarginX, snakeBTALeft.startY + textMarginY, "LT");
// right
snakeBTARight.startX = centerX + spread - size / 2;
snakeBTARight.startY = centerY - size / 2;
snakeBTARight.sizeX = size;
snakeBTARight.sizeY = size;
GLCD_DrawRectangle(snakeBTARight.startX, snakeBTARight.startY, snakeBTARight.sizeX, snakeBTARight.sizeY);
GLCD_DrawString(snakeBTARight.startX + textMarginX, snakeBTARight.startY + textMarginY, "RT");
// pause
GLCD_SetForegroundColor(GLCD_COLOR_WHITE);
snakeBTAPause.startX = 390;
snakeBTAPause.startY = 1;
snakeBTAPause.sizeX = 88;
snakeBTAPause.sizeY = 30;
GLCD_DrawRectangle(snakeBTAPause.startX, snakeBTAPause.startY, snakeBTAPause.sizeX, snakeBTAPause.sizeY);
GLCD_DrawString(snakeBTAPause.startX + 5, snakeBTAPause.startY + 6, "PAUSE");
}
void gameStartPageInitialize(void){
while (!(RNG->SR & (1 << 0)));
srand(RNG->DR);
//No record is loaded, start new game
if (currentSnake == 0){
currentGameId = uuid;
uuid++;
currentSnake = getNewSnake();
currentFood = getNewFood(currentSnake);
}
drawSnakeBox(GLCD_COLOR_YELLOW);
drawSnakeButton(370, 136, 45, 45, GLCD_COLOR_RED);
startTimer();
}
void drawSnakeAndFood(void){
drawSnakeBlock(currentFood->coor.x, currentFood->coor.y,GLCD_COLOR_RED);
drawSnakeBlock(currentSnake->boxToClear.x, currentSnake->boxToClear.y,GLCD_COLOR_BLACK);
for (int i = 0; i < currentSnake->length-1; i++) {
drawSnakeBlock(currentSnake->coor[i].x, currentSnake->coor[i].y,GLCD_COLOR_WHITE);
}
}
void gameRender(void){
changeDir(currentSnake);
move(currentSnake);
if (checkDead(currentSnake)){
stopTimer();
updateHistoryScore();
STATE = GAME_END;
renderPage();
deleteRecord(currentGameId);
currentGameId = 0;
return; // avoid new food generation after death
}
checkFood(currentSnake,currentFood);
if (currentFood->eaten){
free(currentFood);
currentFood = getNewFood(currentSnake);
}
drawSnakeAndFood();
// draw score
char buffer[12];
sprintf(buffer, "SCORE: %04d", currentSnake->length - 3);
GLCD_DrawString(285, 38, buffer);
// update speed
if (currentSnake->length < 8)
{
tickPSC = 8;
}
else if (currentSnake->length < 13)
{
tickPSC = 7;
}
else if (currentSnake->length < 18)
{
tickPSC = 6;
}
else if (currentSnake->length < 23)
{
tickPSC = 5;
}
else if (currentSnake->length < 28)
{
tickPSC = 4;
}
else if (currentSnake->length < 33)
{
tickPSC = 3;
}
}
void deleteRecord(int recordId){
struct GameRecord* p = gameRecords;
if (p == NULL){
free(currentSnake->coor);
free(currentSnake);
free(currentFood);
currentSnake = NULL;
currentFood = NULL;
return;
}
if (p->recordId == recordId){
struct GameRecord* tmp = p->nextRecord;
free(gameRecords);
gameRecords = tmp;
return;
}
struct GameRecord* PREV = p;
p = p->nextRecord;
while (p){
if (p->recordId == recordId){
struct GameRecord* tmp = p->nextRecord;
PREV->nextRecord = tmp;
free(p);
return;
}
p = p->nextRecord;
PREV = PREV->nextRecord;
}
currentSnake = NULL;
currentFood = NULL;
}