//+------------------------------------------------------------------+ //| Base.mqh | //| Copyright 2025, Niquel Mendoza. | //| https://www.mql5.com/es/users/nique_372/news | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Niquel Mendoza." #property link "https://www.mql5.com/es/users/nique_372/news" #property strict //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include "..\\..\\..\\GrapichsByLeo\\General\\Canvas.mqh" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_TETRIS_FIGURA_TYPE { TETRIS_FIGURA_CUADRADO, TETRIS_FIGURA_L, TETRIS_FIGURA_BARRA, TETRIS_FIGURA_ESCALERA, }; enum ENUM_TETRIS_FIGURA_POSITION { TETRIS_FIG_POS_INICIAL = 0, TETRIS_FIG_POS_90 = 90, TETRIS_FIG_POS_180 = 180, TETRIS_FIG_POS_270 = 270 }; enum ENUM_TETRIS_DIR { TETRIS_DIR_ARRIBA = 0, TETRIS_DIR_ABAJO = 1, TETRIS_DIR_DERECHA = 2, TETRIS_DIR_IZQUIERDA = 3 }; enum EMUM_TETRIS_DIR_SENT_Y { TETRIS_DIR_Y_ARRIBA = 0, TETRIS_DIR_Y_ABAJO = 1, }; enum EMUM_TETRIS_DIR_SENT_X { TETRIS_DIR_X_IZQUIERDA = 0, TETRIS_DIR_X_DERECHA = 1, }; #define TETRIS_FLAG_COLISION_END 1 #define TETRIS_FLAG_COLISION_INIT 2 /* x1 x2 y1 y1 y2 y2 x1 x2 */ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CTetrisFigura { protected: bool m_init; CCanvasCustom* m_canvas; int m_width; uint m_clr_clean; uint m_color; ENUM_TETRIS_FIGURA_POSITION m_position; int m_x1; int m_y1; int m_x2; int m_y2; uint8_t m_flags_seccion; //--- virtual void Draw() = 0; public: CTetrisFigura(void); // ~CTetrisFigura(void); //--- void Init(int x1, int y1, int x2, int y2, CCanvasCustom* c, uint clr_clean, uint clr); //--- General virtual void CleanPixles() = 0; //--- Cordenadas void Move(int x1, int y1, int x2, int y2); void ChangeY2(int new_y2); void ChangeY(int new_y1); void ChangeX(int new_x1); inline int X1() const { return m_x1; } inline int Y1() const { return m_y1; } inline int X2() const { return m_x2; } inline int Y2() const { return m_y2; } //--- aqui a tener en cuneta que seria -1, osea no el alto como tal... no el espacio en peixles si no la distanica __forceinline int DistY() const { return fabs(m_y2 - m_y1); } __forceinline int DistX() const { return fabs(m_x2 - m_x1); } //--- Color __forceinline uint Color() const { return m_color; } void Color(uint new_clr); //--- Tipo virtual inline ENUM_TETRIS_FIGURA_TYPE Type() const = 0; //--- Rotacion // Rota a la siguiente posicion ENUM_TETRIS_FIGURA_POSITION NextRotate(); // Rotacion custom virtual void Rotate(ENUM_TETRIS_FIGURA_POSITION pos) = 0; //--- Colision bool Colisiona(int x, int y); virtual bool Colisiona(ENUM_TETRIS_DIR direcicon_preferida, int x, int y) = 0; //--- Pixeles ocupaods virtual void GetOcupatePixels(int& pixels_pos[]) = 0; virtual void GetOcupatePixels(ENUM_TETRIS_DIR direcicon, int& pixels_pos[]) = 0; virtual void GetOcupatePixels(int y1, EMUM_TETRIS_DIR_SENT_Y y_direccion, int& pixels_pos[]) = 0; virtual void GetOcupatePixels(int x1, EMUM_TETRIS_DIR_SENT_X x_direccion, int& pixels_pos[]) = 0; //--- virtual int CalculateMinPixelsInYAbajo(int y, int& out_x) const = 0; virtual int CalculateMinPixelsInYAbajo(int& out_x) const = 0; //--- Colision ext void FlagColisionEndAdd() { m_flags_seccion |= TETRIS_FLAG_COLISION_END; } void FlagColisionEndRemove() { m_flags_seccion &= ~TETRIS_FLAG_COLISION_END; } bool IsActiveColisionEnd() const { return (m_flags_seccion & TETRIS_FLAG_COLISION_END) != 0; } void FlagColisionInitAdd() { m_flags_seccion |= TETRIS_FLAG_COLISION_INIT; } void FlagColisionInitRemove() { m_flags_seccion &= ~TETRIS_FLAG_COLISION_INIT; } bool IsActiveColisionInit() const { return (m_flags_seccion & TETRIS_FLAG_COLISION_INIT) != 0; } }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CTetrisFigura::CTetrisFigura(void) : m_canvas(NULL), m_init(false), m_flags_seccion(0) { } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CTetrisFigura::Init(int x1, int y1, int x2, int y2, CCanvasCustom *c, uint clr_clean, uint clr) { if(m_init) return; m_x1 = x1; m_x2 = x2; m_y1 = y1; m_y2 = y2; m_canvas = c; m_width = c.Width(); m_clr_clean = clr_clean; m_color = clr; m_init = true; //--- Draw(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CTetrisFigura::Move(int x1, int y1, int x2, int y2) { CleanPixles(); m_x1 = x1; m_x2 = x2; m_y1 = y1; m_y2 = y2; Draw(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CTetrisFigura::ChangeY2(int new_y2) { CleanPixles(); m_y2 = new_y2; Draw(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CTetrisFigura::ChangeY(int new_y1) { CleanPixles(); const int y_size = fabs(m_y2 - m_y1); m_y1 = new_y1; m_y2 = m_y1 + y_size; Draw(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CTetrisFigura::ChangeX(int new_x1) { CleanPixles(); const int x_size = fabs(m_x2 - m_x1); m_x1 = new_x1; m_x2 = m_x1 + x_size; Draw(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CTetrisFigura::Color(uint new_clr) { CleanPixles(); m_color = new_clr; Draw(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ ENUM_TETRIS_FIGURA_POSITION CTetrisFigura::NextRotate(void) { const int new_pos = m_position + 90; // Siguyiente posicion m_position = ENUM_TETRIS_FIGURA_POSITION(new_pos % 360); // Modulo de 360, 0-90-180-270 Rotate(m_position); return m_position; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CTetrisFigura::Colisiona(int x, int y) { for(int i = 0; i < 4; i++) if(Colisiona(ENUM_TETRIS_DIR(i), x, y)) return true; return false; } //+------------------------------------------------------------------+