Back to posts Edit this post
Copy content

13 Oct 09:10

#include "platform.h" #include "xil_printf.h" #include "displayport.h" #include "vtc.h" #include "tpg.h" #include "xparameters.h" #include "./../../../hw/sdt/drivers/myip_v1_0/src/myip.h" #include <stdint.h> #include "xil_types.h" #include "xil_io.h" extern char inbyte(void); #define BOARD_WIDTH 20 #define BOARD_HEIGHT 15 #define MAX_SNAKE_LEN 100 // Typy obiektów renderowanych na monitorze #define OBJ_CLEAR 0 // Puste pole / tło #define OBJ_SNAKE 1 // Segment węża #define OBJ_APPLE 2 // Jabłko typedef enum { UP, DOWN, LEFT, RIGHT } Direction; typedef struct { int8_t x; int8_t y; } Point; // Funkcja pakująca współrzędne, typ obiektu i kolor Hue w jeden rejestr 32-bitowy // Bit 31-28: Typ obiektu (0=czyszczenie, 1=wąż, 2=jabłko) // Bit 27-20: Współrzędna X (0-255) // Bit 19-12: Współrzędna Y (0-255) // Bit 11-0 : Wartość Hue (0-360) void draw_object(u8 obj_type, u8 x, u8 y, u16 hue) { u32 packed_data = ((u32)(obj_type & 0x0F) << 28) | ((u32)x << 20) | ((u32)y << 12) | (hue & 0x0FFF); MYIP_mWriteReg(XPAR_MYIP_0_BASEADDR, MYIP_S00_AXI_SLV_REG0_OFFSET, packed_data); } void simple_delay(u32 cycles) { volatile u32 i; for (i = 0; i < cycles; i++) { __asm__("nop"); } } int main() { init_platform(); xil_printf("\n\n\n\n\n--- SNAKE MONITOR RENDERER ---\r\n"); displayport_init(); displayport_setup_interrupts(); vtc_init(); tpg_init(); // Definiowanie kolorów w Hue (0-360) u16 HUE_SNAKE = 120; // Zielony wąż u16 HUE_APPLE = 0; // Czerwone jabłko // Stan gry Point snake[MAX_SNAKE_LEN]; u8 snake_len = 3; Direction dir = RIGHT; Point apple = {12, 7}; Point tail_end = {0, 0}; // Przechowuje stary ogon do wyczyszczenia z monitora u8 game_over = 0; u32 score = 0; u32 rand_counter = 0; // Pozycja startowa snake[0].x = 10; snake[0].y = 7; snake[1].x = 9; snake[1].y = 7; snake[2].x = 8; snake[2].y = 7; // Wyrysowanie początkowego stanu na monitorze for(int i = 0; i < snake_len; i++) { draw_object(OBJ_SNAKE, snake[i].x, snake[i].y, HUE_SNAKE); } draw_object(OBJ_APPLE, apple.x, apple.y, HUE_APPLE); while (1) { rand_counter++; // 1. OBSŁUGA STEROWANIA UART char c = inbyte(); if (c == 0x1B) { c = inbyte(); if (c == 0x5B) { c = inbyte(); switch (c) { case 0x41: if (dir != DOWN) dir = UP; break; case 0x42: if (dir != UP) dir = DOWN; break; case 0x43: if (dir != LEFT) dir = RIGHT; break; case 0x44: if (dir != RIGHT) dir = LEFT; break; } } } if (game_over) { xil_printf("\rGAME OVER! Resetowanie planszy..."); // Czyszczenie całego ekranu monitora (kafelek po kafelku) for(u8 x = 0; x < BOARD_WIDTH; x++) { for(u8 y = 0; y < BOARD_HEIGHT; y++) { draw_object(OBJ_CLEAR, x, y, 0); } } // Reset zmiennych snake_len = 3; dir = RIGHT; snake[0].x = 10; snake[0].y = 7; snake[1].x = 9; snake[1].y = 7; snake[2].x = 8; snake[2].y = 7; apple.x = 12; apple.y = 7; score = 0; game_over = 0; // Ponowne narysowanie stanu startowego for(int i = 0; i < snake_len; i++) { draw_object(OBJ_SNAKE, snake[i].x, snake[i].y, HUE_SNAKE); } draw_object(OBJ_APPLE, apple.x, apple.y, HUE_APPLE); continue; } // Zapamiętanie ostatniego segmentu ogona przed ruchem (żeby go potem zgasić) tail_end = snake[snake_len - 1]; // 2. LOGIKA RUCHU WĘŻA for (int i = snake_len - 1; i > 0; i--) { snake[i] = snake[i - 1]; } switch (dir) { case UP: snake[0].y--; break; case DOWN: snake[0].y++; break; case LEFT: snake[0].x--; break; case RIGHT: snake[0].x++; break; } // 3. KOLIZJE if (snake[0].x < 0 || snake[0].x >= BOARD_WIDTH || snake[0].y < 0 || snake[0].y >= BOARD_HEIGHT) { game_over = 1; continue; } for (int i = 1; i < snake_len; i++) { if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) { game_over = 1; } } // 4. ZJADANIE JABŁKA if (snake[0].x == apple.x && snake[0].y == apple.y) { score += 10; if (snake_len < MAX_SNAKE_LEN) { snake_len++; } // Nowa pozycja jabłka apple.x = (rand_counter % (BOARD_WIDTH - 2)) + 1; apple.y = (rand_counter / 3 % (BOARD_HEIGHT - 2)) + 1; // Narysowanie nowego jabłka na monitorze draw_object(OBJ_APPLE, apple.x, apple.y, HUE_APPLE); } else { // Jeśli nie zjadł jabłka, stary ogon musi zniknąć z monitora draw_object(OBJ_CLEAR, tail_end.x, tail_end.y, 0); } // 5. AKTUALIZACJA MONITORA // Rysujemy tylko nową pozycję głowy (reszta ciała podąża za nią, a ogon czyścimy wyżej) draw_object(OBJ_SNAKE, snake[0].x, snake[0].y, HUE_SNAKE); xil_printf("\rScore: %d | Snake Head: [%d,%d]", score, snake[0].x, snake[0].y); simple_delay(2000000); } cleanup_platform(); return 0; }

No files