|
|
@@ -0,0 +1,571 @@
|
|
|
+#include <stdio.h>
|
|
|
+#include <furi.h>
|
|
|
+
|
|
|
+#include <gui/gui.h>
|
|
|
+#include <input/input.h>
|
|
|
+#include <notification/notification.h>
|
|
|
+#include <notification/notification_messages.h>
|
|
|
+#include <gui/canvas_i.h>
|
|
|
+#include "bomberduck_icons.h"
|
|
|
+
|
|
|
+int max(int a, int b) {
|
|
|
+ return (a > b) ? a : b;
|
|
|
+}
|
|
|
+
|
|
|
+int min(int a, int b) {
|
|
|
+ return (a < b) ? a : b;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+FuriMutex* mutex;
|
|
|
+#define WorldSizeX 12
|
|
|
+#define WorldSizeY 6
|
|
|
+#define BombTime 4
|
|
|
+#define BombRange 1
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ int row;
|
|
|
+ int col;
|
|
|
+} Cell;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ Cell cells[WorldSizeY * WorldSizeX];
|
|
|
+ int front;
|
|
|
+ int rear;
|
|
|
+} Queue;
|
|
|
+
|
|
|
+void enqueue(Queue* q, Cell c) {
|
|
|
+ q->cells[q->rear] = c;
|
|
|
+ q->rear++;
|
|
|
+}
|
|
|
+
|
|
|
+Cell dequeue(Queue* q) {
|
|
|
+ Cell c = q->cells[q->front];
|
|
|
+ q->front++;
|
|
|
+
|
|
|
+ return c;
|
|
|
+}
|
|
|
+
|
|
|
+bool is_empty(Queue* q) {
|
|
|
+ return q->front == q->rear;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ int x;
|
|
|
+ int y;
|
|
|
+ int planted;
|
|
|
+} Bomb;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ int x;
|
|
|
+ int y;
|
|
|
+ bool side;
|
|
|
+} Player;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ int x;
|
|
|
+ int y;
|
|
|
+ int last;
|
|
|
+ bool side;
|
|
|
+ int level;
|
|
|
+} Enemy;
|
|
|
+
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ int matrix[WorldSizeY][WorldSizeX];
|
|
|
+ Player* player;
|
|
|
+ bool running;
|
|
|
+ int level;
|
|
|
+
|
|
|
+ Enemy enemies[10];
|
|
|
+ int enemies_count;
|
|
|
+
|
|
|
+ Bomb bombs[100];
|
|
|
+ int bombs_count;
|
|
|
+
|
|
|
+ int endx;
|
|
|
+ int endy;
|
|
|
+} World;
|
|
|
+
|
|
|
+Player player = {0, 0, 1};
|
|
|
+World world = {{{0}}, &player, 1, 0, {}, 0, {}, 0, 0, 0};
|
|
|
+
|
|
|
+void init(){
|
|
|
+ player.x = 1;
|
|
|
+ player.y = 1;
|
|
|
+
|
|
|
+ world.endx = 3 + rand()%8;
|
|
|
+ world.endy = rand()%6;
|
|
|
+ for (int i = 0; i < WorldSizeY; i++) {
|
|
|
+ for (int j = 0; j < WorldSizeX; j++) {
|
|
|
+ world.matrix[i][j] = rand() % 3;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ world.running = 1;
|
|
|
+
|
|
|
+ for(int j = max(0, player.y-BombRange); j < min(WorldSizeY, player.y+BombRange+1); j++){
|
|
|
+ world.matrix[j][player.x] = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ for(int j = max(0, player.x-BombRange); j < min(WorldSizeX, player.x+BombRange+1); j++){
|
|
|
+ world.matrix[player.y][j] = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ world.enemies_count=0;
|
|
|
+ for(int j = 0; j < rand()%2 + world.level/5; j++){
|
|
|
+ Enemy enemy;
|
|
|
+ enemy.x = 3 + rand()%8;
|
|
|
+ enemy.y = rand()%6;
|
|
|
+ enemy.last = 0;
|
|
|
+ enemy.side = 1;
|
|
|
+ enemy.level = 0;
|
|
|
+
|
|
|
+ world.enemies[j] = enemy;
|
|
|
+ world.enemies_count++;
|
|
|
+
|
|
|
+ for(int m = max(0, world.enemies[j].y-BombRange); m < min(WorldSizeY, world.enemies[j].y+BombRange+1); m++){
|
|
|
+ world.matrix[m][world.enemies[j].x] = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ for(int m = max(0, world.enemies[j].x-BombRange); m < min(WorldSizeX, world.enemies[j].x+BombRange+1); m++){
|
|
|
+ world.matrix[world.enemies[j].y][m] = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ world.matrix[world.endy][world.endx] = 1;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+const NotificationSequence end = {
|
|
|
+ &message_vibro_on,
|
|
|
+
|
|
|
+ &message_note_ds4,
|
|
|
+ &message_delay_10,
|
|
|
+ &message_sound_off,
|
|
|
+ &message_delay_10,
|
|
|
+
|
|
|
+ &message_note_ds4,
|
|
|
+ &message_delay_10,
|
|
|
+ &message_sound_off,
|
|
|
+ &message_delay_10,
|
|
|
+
|
|
|
+ &message_note_ds4,
|
|
|
+ &message_delay_10,
|
|
|
+ &message_sound_off,
|
|
|
+ &message_delay_10,
|
|
|
+
|
|
|
+ &message_vibro_off,
|
|
|
+ NULL,
|
|
|
+};
|
|
|
+
|
|
|
+void intToStr(int num, char* str) {
|
|
|
+ int i = 0, sign = 0;
|
|
|
+
|
|
|
+ if (num < 0) {
|
|
|
+ num = -num;
|
|
|
+ sign = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ do {
|
|
|
+ str[i++] = num % 10 + '0';
|
|
|
+ num /= 10;
|
|
|
+ } while (num > 0);
|
|
|
+
|
|
|
+ if (sign) {
|
|
|
+ str[i++] = '-';
|
|
|
+ }
|
|
|
+
|
|
|
+ str[i] = '\0';
|
|
|
+
|
|
|
+ // Reverse the string
|
|
|
+ int j, len = i;
|
|
|
+ char temp;
|
|
|
+ for (j = 0; j < len / 2; j++) {
|
|
|
+ temp = str[j];
|
|
|
+ str[j] = str[len - j - 1];
|
|
|
+ str[len - j - 1] = temp;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool BFS() {
|
|
|
+ // Initialize visited array and queue
|
|
|
+ int visited[WorldSizeY][WorldSizeX] = {0};
|
|
|
+ Queue q = {.front = 0, .rear = 0};
|
|
|
+ // Mark the starting cell as visited and enqueue it
|
|
|
+ visited[world.player->y][world.player->x] = 1;
|
|
|
+ Cell startCell = {.row = world.player->y, .col = world.player->x};
|
|
|
+ enqueue(&q, startCell);
|
|
|
+ // Traverse the field
|
|
|
+ while (!is_empty(&q)) {
|
|
|
+ // Dequeue a cell from the queue
|
|
|
+ Cell currentCell = dequeue(&q);
|
|
|
+ // Check if the current cell is the destination cell
|
|
|
+ if (currentCell.row == world.endy && currentCell.col == world.endx) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ // Check the neighboring cells
|
|
|
+ for (int rowOffset = -1; rowOffset <= 1; rowOffset++) {
|
|
|
+ for (int colOffset = -1; colOffset <= 1; colOffset++) {
|
|
|
+ // Skip diagonals and the current cell
|
|
|
+ if (rowOffset == 0 && colOffset == 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (rowOffset != 0 && colOffset != 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // Calculate the row and column of the neighboring cell
|
|
|
+ int neighborRow = currentCell.row + rowOffset;
|
|
|
+ int neighborCol = currentCell.col + colOffset;
|
|
|
+ // Skip out-of-bounds cells and already visited cells
|
|
|
+ if (neighborRow < 0 || neighborRow >= WorldSizeY ||
|
|
|
+ neighborCol < 0 || neighborCol >= WorldSizeX) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (visited[neighborRow][neighborCol]) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // Mark the neighboring cell as visited and enqueue it
|
|
|
+ if (world.matrix[neighborRow][neighborCol] != 2){
|
|
|
+ visited[neighborRow][neighborCol] = 1;
|
|
|
+ Cell neighborCell = {.row = neighborRow, .col = neighborCol};
|
|
|
+ enqueue(&q, neighborCell);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static void draw_callback(Canvas* canvas, void* ctx) {
|
|
|
+ UNUSED(ctx);
|
|
|
+
|
|
|
+ furi_mutex_acquire(mutex, FuriWaitForever);
|
|
|
+ if(!BFS()){
|
|
|
+ init();
|
|
|
+ }
|
|
|
+ canvas_clear(canvas);
|
|
|
+
|
|
|
+ canvas_draw_icon(canvas, world.endx*10+4, world.endy*10+2, &I_end);
|
|
|
+
|
|
|
+ if(world.running){
|
|
|
+ for (size_t i = 0; i < WorldSizeY; i++)
|
|
|
+ {
|
|
|
+ for (size_t j = 0; j < WorldSizeX; j++)
|
|
|
+ {
|
|
|
+ switch (world.matrix[i][j])
|
|
|
+ {
|
|
|
+ case 0:
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ canvas_draw_icon(canvas, j*10+4, i*10+2, &I_box);
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ canvas_draw_icon(canvas, j*10+4, i*10+2, &I_unbreakbox);
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ canvas_draw_icon(canvas, j*10+4, i*10+2, &I_bomb0);
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ canvas_draw_icon(canvas, j*10+4, i*10+2, &I_bomb1);
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ canvas_draw_icon(canvas, j*10+4, i*10+2, &I_bomb2);
|
|
|
+ break;
|
|
|
+ case 6:
|
|
|
+ canvas_draw_icon(canvas, j*10+4, i*10+2, &I_explore);
|
|
|
+ world.matrix[i][j] = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(world.player->side){
|
|
|
+ canvas_draw_icon(canvas, world.player->x*10+4, world.player->y*10+2, &I_playerright);
|
|
|
+ }else{
|
|
|
+ canvas_draw_icon(canvas, world.player->x*10+4, world.player->y*10+2, &I_playerleft);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < world.enemies_count; i++)
|
|
|
+ {
|
|
|
+ if(world.enemies[i].level>0){
|
|
|
+ canvas_draw_icon(canvas, world.enemies[i].x*10+4, world.enemies[i].y*10+2, &I_enemy1);
|
|
|
+ } else {
|
|
|
+ if(world.enemies[i].side){
|
|
|
+ canvas_draw_icon(canvas, world.enemies[i].x*10+4, world.enemies[i].y*10+2, &I_enemyright);
|
|
|
+ }else{
|
|
|
+ canvas_draw_icon(canvas, world.enemies[i].x*10+4, world.enemies[i].y*10+2, &I_enemyleft);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ canvas_set_font(canvas, FontPrimary);
|
|
|
+ if(world.player->x == world.endx && world.player->y == world.endy){
|
|
|
+ if(world.level == 20){
|
|
|
+ canvas_draw_str(canvas, 30, 35, "You win!");
|
|
|
+ }
|
|
|
+ canvas_draw_str(canvas, 30, 35, "Next level!");
|
|
|
+ char str[20];
|
|
|
+ intToStr(world.level, str);
|
|
|
+ canvas_draw_str(canvas, 90, 35, str);
|
|
|
+
|
|
|
+ } else {
|
|
|
+ canvas_draw_str(canvas, 30, 35, "Game over!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ furi_mutex_release(mutex);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+static void input_callback(InputEvent* input_event, void* ctx) {
|
|
|
+ // Проверяем, что контекст не нулевой
|
|
|
+ furi_assert(ctx);
|
|
|
+ FuriMessageQueue* event_queue = ctx;
|
|
|
+
|
|
|
+ furi_message_queue_put(event_queue, input_event, FuriWaitForever);
|
|
|
+}
|
|
|
+
|
|
|
+int32_t bomberduck_app(void* p) {
|
|
|
+ UNUSED(p);
|
|
|
+
|
|
|
+ // Текущее событие типа InputEvent
|
|
|
+ InputEvent event;
|
|
|
+ // Очередь событий на 8 элементов размера InputEvent
|
|
|
+ FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
|
|
|
+
|
|
|
+ // Создаем новый view port
|
|
|
+ ViewPort* view_port = view_port_alloc();
|
|
|
+ // Создаем callback отрисовки, без контекста
|
|
|
+ view_port_draw_callback_set(view_port, draw_callback, NULL);
|
|
|
+ // Создаем callback нажатий на клавиши, в качестве контекста передаем
|
|
|
+ // нашу очередь сообщений, чтоб запихивать в неё эти события
|
|
|
+ view_port_input_callback_set(view_port, input_callback, event_queue);
|
|
|
+
|
|
|
+ mutex = furi_mutex_alloc(FuriMutexTypeNormal);//
|
|
|
+
|
|
|
+ // Создаем GUI приложения
|
|
|
+ Gui* gui = furi_record_open(RECORD_GUI);
|
|
|
+ // Подключаем view port к GUI в полноэкранном режиме
|
|
|
+ gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
|
|
+ NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
|
|
|
+ notification_message_block(notification, &sequence_display_backlight_enforce_on);
|
|
|
+ init();
|
|
|
+
|
|
|
+ // Бесконечный цикл обработки очереди событий
|
|
|
+ while(1) {
|
|
|
+ if (furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk){
|
|
|
+ furi_mutex_acquire(mutex, FuriWaitForever);
|
|
|
+ // Если нажата кнопка "назад", то выходим из цикла, а следовательно и из приложения
|
|
|
+
|
|
|
+ if(event.type == InputTypePress) {
|
|
|
+ if(event.key == InputKeyOk) {
|
|
|
+ if(world.running){
|
|
|
+ if (world.matrix[world.player->y][world.player->x]==0 && world.bombs_count<2)
|
|
|
+ {
|
|
|
+ world.matrix[world.player->y][world.player->x] = 3;
|
|
|
+ Bomb bomb = {world.player->x, world.player->y, furi_get_tick()};
|
|
|
+ world.bombs[world.bombs_count] = bomb;
|
|
|
+ world.bombs_count++;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ init();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(event.key == InputKeyUp) {
|
|
|
+ if (world.player->y >0 && world.matrix[world.player->y-1][world.player->x]==0)
|
|
|
+ world.player->y--;
|
|
|
+ }
|
|
|
+ if(event.key == InputKeyDown) {
|
|
|
+ if (world.player->y < WorldSizeY-1 && world.matrix[world.player->y+1][world.player->x]==0)
|
|
|
+ world.player->y++;
|
|
|
+ }
|
|
|
+ if(event.key == InputKeyLeft) {
|
|
|
+ world.player->side=0;
|
|
|
+ if (world.player->x > 0 && world.matrix[world.player->y][world.player->x-1]==0)
|
|
|
+ world.player->x--;
|
|
|
+ }
|
|
|
+ if(event.key == InputKeyRight) {
|
|
|
+ world.player->side=1;
|
|
|
+ if (world.player->x < WorldSizeX-1 && world.matrix[world.player->y][world.player->x+1]==0)
|
|
|
+ world.player->x++;
|
|
|
+ }
|
|
|
+ if(event.key == InputKeyBack) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(world.running){
|
|
|
+ if(world.player->x == world.endx && world.player->y == world.endy){
|
|
|
+ notification_message(notification, &end);
|
|
|
+ world.running=0;
|
|
|
+ world.level+=1;
|
|
|
+ }
|
|
|
+ for (int i = 0; i < world.bombs_count; i++)
|
|
|
+ {
|
|
|
+ if(furi_get_tick() - world.bombs[i].planted > 3000){
|
|
|
+ world.matrix[world.bombs[i].y][world.bombs[i].x] = 6;
|
|
|
+
|
|
|
+ for(int j = max(0, world.bombs[i].y-BombRange); j < min(WorldSizeY, world.bombs[i].y+BombRange+1); j++){
|
|
|
+ if(world.matrix[j][world.bombs[i].x]!=2){
|
|
|
+ world.matrix[j][world.bombs[i].x] = 6;
|
|
|
+ if (j==world.player->y && world.bombs[i].x == world.player->x){
|
|
|
+ notification_message(notification, &end);
|
|
|
+ world.running=0;
|
|
|
+ }
|
|
|
+ for (int e = 0; e < world.enemies_count; e++)
|
|
|
+ {
|
|
|
+ if (j==world.enemies[e].y && world.bombs[i].x == world.enemies[e].x){
|
|
|
+ for (int l = e; l < world.enemies_count - 1; l++) {
|
|
|
+ world.enemies[l] = world.enemies[l + 1];
|
|
|
+ }
|
|
|
+ world.enemies_count--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for(int j = max(0, world.bombs[i].x-BombRange); j < min(WorldSizeX, world.bombs[i].x+BombRange+1); j++){
|
|
|
+ if(world.matrix[world.bombs[i].y][j]!=2){
|
|
|
+ world.matrix[world.bombs[i].y][j] = 6;
|
|
|
+ if (world.bombs[i].y ==world.player->y && j == world.player->x){
|
|
|
+ notification_message(notification, &end);
|
|
|
+ world.running=0;
|
|
|
+
|
|
|
+ }
|
|
|
+ for (int e = 0; e < world.enemies_count; e++)
|
|
|
+ {
|
|
|
+ if (world.bombs[i].y == world.enemies[e].y && j == world.enemies[e].x){
|
|
|
+ for (int l = e; l < world.enemies_count - 1; l++) {
|
|
|
+ world.enemies[l] = world.enemies[l + 1];
|
|
|
+ }
|
|
|
+ world.enemies_count--;
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ for (int j = i; j < world.bombs_count - 1; j++) {
|
|
|
+ world.bombs[j] = world.bombs[j + 1];
|
|
|
+ }
|
|
|
+ world.bombs_count--;
|
|
|
+ }else if (furi_get_tick() - world.bombs[i].planted > 2000)
|
|
|
+ {
|
|
|
+ world.matrix[world.bombs[i].y][world.bombs[i].x] = 5;
|
|
|
+
|
|
|
+ }else if (furi_get_tick() - world.bombs[i].planted > 1000)
|
|
|
+ {
|
|
|
+ world.matrix[world.bombs[i].y][world.bombs[i].x] = 4;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (int e = 0; e < world.enemies_count; e++)
|
|
|
+ {
|
|
|
+ if (world.player->y==world.enemies[e].y && world.player->x == world.enemies[e].x){
|
|
|
+ notification_message(notification, &end);
|
|
|
+ world.running=0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int e = 0; e < world.enemies_count; e++)
|
|
|
+ {
|
|
|
+ if(world.enemies[e].level>0){
|
|
|
+ if (furi_get_tick() - world.enemies[e].last > (unsigned long)(2000 - world.level*100)){
|
|
|
+ world.enemies[e].last = furi_get_tick();
|
|
|
+ int move = rand()%4;
|
|
|
+ switch (move)
|
|
|
+ {
|
|
|
+ case 0:
|
|
|
+ if (world.enemies[e].y >0 && world.matrix[world.enemies[e].y-1][world.enemies[e].x]!=2)
|
|
|
+ world.enemies[e].y--;
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ if (world.enemies[e].y < WorldSizeY-1 && world.matrix[world.enemies[e].y+1][world.enemies[e].x]!=2)
|
|
|
+ world.enemies[e].y++;
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ world.enemies[e].side=0;
|
|
|
+ if (world.enemies[e].x > 0 && world.matrix[world.enemies[e].y][world.enemies[e].x-1]!=2)
|
|
|
+ world.enemies[e].x--;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ world.enemies[e].side=1;
|
|
|
+ if (world.enemies[e].x < WorldSizeX-1 && world.matrix[world.enemies[e].y][world.enemies[e].x+1]!=2)
|
|
|
+ world.enemies[e].x++;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (furi_get_tick() - world.enemies[e].last > (unsigned long)(1000 - world.level*50)){
|
|
|
+ world.enemies[e].last = furi_get_tick();
|
|
|
+ int move = rand()%4;
|
|
|
+ switch (move)
|
|
|
+ {
|
|
|
+ case 0:
|
|
|
+ if (world.enemies[e].y >0 && world.matrix[world.enemies[e].y-1][world.enemies[e].x]==0)
|
|
|
+ world.enemies[e].y--;
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ if (world.enemies[e].y < WorldSizeY-1 && world.matrix[world.enemies[e].y+1][world.enemies[e].x]==0)
|
|
|
+ world.enemies[e].y++;
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ world.enemies[e].side=0;
|
|
|
+ if (world.enemies[e].x > 0 && world.matrix[world.enemies[e].y][world.enemies[e].x-1]==0)
|
|
|
+ world.enemies[e].x--;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ world.enemies[e].side=1;
|
|
|
+ if (world.enemies[e].x < WorldSizeX-1 && world.matrix[world.enemies[e].y][world.enemies[e].x+1]==0)
|
|
|
+ world.enemies[e].x++;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (int e = 0; e < world.enemies_count; e++)
|
|
|
+ {
|
|
|
+ for (int h = e + 1; h < world.enemies_count; h++)
|
|
|
+ {
|
|
|
+ if(world.enemies[e].y == world.enemies[h].y && world.enemies[e].x==world.enemies[h].x){
|
|
|
+ world.enemies[h].level++;
|
|
|
+ for (int l = e; l < world.enemies_count - 1; l++) {
|
|
|
+ world.enemies[l] = world.enemies[l + 1];
|
|
|
+ }
|
|
|
+ world.enemies_count--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ view_port_update(view_port);
|
|
|
+ furi_mutex_release(mutex);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Специальная очистка памяти, занимаемой очередью
|
|
|
+ furi_message_queue_free(event_queue);
|
|
|
+
|
|
|
+ // Чистим созданные объекты, связанные с интерфейсом
|
|
|
+ gui_remove_view_port(gui, view_port);
|
|
|
+ view_port_free(view_port); furi_message_queue_free(event_queue);
|
|
|
+
|
|
|
+ // Чистим созданные объекты, связанные с интерфейсом
|
|
|
+ gui_remove_view_port(gui, view_port);
|
|
|
+ view_port_free(view_port);
|
|
|
+ furi_mutex_free(mutex);
|
|
|
+ furi_record_close(RECORD_GUI);
|
|
|
+ furi_mutex_free(mutex);
|
|
|
+ furi_record_close(RECORD_GUI);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|