Неизвестное имя типа «Shape1» в C ++ Builder - PullRequest
0 голосов
/ 26 ноября 2018

Я пытаюсь сделать клон тетриса в C ++ Builder.Я начал с 2 классов.Я записал их в файл .h и включил в свой файл .cpp:

class Stage
{
protected:
    int Width;
    int Height;
public:

    Stage()
    {
        Width=300;
        Height=733;
    }

    Stage(int Width0,int Height0)
    {
        Width=Width0;
        Height=Height0;
    }
};

Это мой первый класс, этап.Я не знаю наверняка, что должен содержать этот класс, поэтому, если у вас есть какие-либо предложения относительно того, что я должен включить в него, я рад их услышать.

class Tetromino : public Stage
{
protected:
    Tshape *Shape1;
public:
    Tetromino(Tshape *Shape1)
    {
        TetrisGame->Shape1->Width=33;
        TetrisGame->Shape1->Height=33;
        TetrisGame->Shape1->Brush->Color=clBlack;
        TetrisGame->Shape1->Left=10;
        TetrisGame->Shape1->Top=200;
    }

    void mLeft()
    {
        if(TetrisGame->Shape1->Left<=Widht)
            TetrisGame->Shape1->Left=TetrisGame->Shape1->Left+33;
    }

    void mRight()
    {
        if(TetrisGame->Shape1->Left>=Width)
            TetrisGame->Shape1->Left=TetrisGame->Shape1->Left-33;
    }

    void free_fall()
    {
        TetrisGame->PieceFallTime->Enabled=true;
    }
};

Это мой второй класс,класс для фигур.

Я знаю, что это не так, как это должно работать.Я должен сделать матрицу, например, скажем:

piece[4][4]=
    {(0,0,0,0),
     (0,0,0,0),
     (0,1,0,0),
     (1,1,1,0)}

, но я до сих пор не знаю, как мне ее использовать.Я думаю, что я должен поставить форму там, где есть 1, и она должна создать мою фигуру, но я не знаю, как это сделать.

Сейчас я пытаюсь выяснить, как сделать формуупасть и переместить его вправо или влево с помощью клавиатуры.Я делал это раньше, но без занятий.Это немного сложнее с использованием классов, и я не понимаю.

Я пытался инициализировать объект Tetromino x(Shape1) (код в form.cpp), имеющий Shape1 в моей форме.Я думаю, что это должно заставить Shape1 в моей Форме использовать методы, которые я написал в своем классе, верно?

Но я получаю эту ошибку:

[ошибка bcc32c] StartGame.cpp (110): неизвестное имя типа 'Shape1'

1 Ответ

0 голосов
/ 28 ноября 2018

Вы забыли использовать new для растрового изображения в конструкторе, поэтому вы загружаете файл bmp в растровые объекты, которые еще не созданы, следовательно, нарушение прав доступа.Вы можете использовать прозрачность для растровых изображений tetrominos ... вам просто нужно активировать их на целевом холсте (например, Form1 ... в его свойствах).Однако я хотел бы визуализировать мои tetrominos непосредственно в растровое изображение вместо использования файлов ... Вы можете использовать растровое изображение в качестве экранного буфера ...

Здесь простой BDS2006 C ++ / VCL Tetris пример, который я кодировал смои студенты во время одной лекции несколько лет назад, когда они хотели написать код игры и проголосовали за тетрис ... (уродливо, но работает ...)

preview

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "win_main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

// window
TForm1 *Form1;
// keyboard map
enum{
    _key_left =0,
    _key_right,
    _key_rot  ,
    _key_drop ,
    _keys
    };
int keys      [_keys];  // is key pressed ?
WORD keys_code[_keys];  // scan code

// back/double buffer
Graphics::TBitmap *bmp = new Graphics::TBitmap;
//  scoore,  position of falling tetromino,next shape
int score=0,px=0,py=0,novy_dielik=0;
// actual tetromino map
BYTE pm[4][4]=
    {
    0,0,1,0,
    0,1,1,0,
    0,0,1,0,
    0,0,1,0
    };

// game board size
const int map_xs=10;
const int map_ys=20;
BYTE map[map_xs][map_ys];
// tetrominos
BYTE shp[7*16]=
    {
    0,1,0,0,
    0,1,0,0,
    0,1,0,0,
    0,1,0,0,

    0,1,0,0,
    0,1,0,0,
    0,1,1,0,
    0,0,0,0,

    0,0,1,0,
    0,0,1,0,
    0,1,1,0,
    0,0,0,0,

    0,1,0,0,
    0,1,1,0,
    0,0,1,0,
    0,0,0,0,

    0,0,1,0,
    0,1,1,0,
    0,1,0,0,
    0,0,0,0,

    0,0,0,0,
    0,0,1,0,
    0,1,1,1,
    0,0,0,0,

    0,0,0,0,
    0,1,1,0,
    0,1,1,0,
    0,0,0,0
    };
//---------------------------------------------------------------------------
// tetromino colision test
//---------------------------------------------------------------------------
int step()
    {
    int i,j,x,y;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      if (pm[i][j]!=0)
        {
        x=px+j;
        y=py+i;
        if (x<0)          return 1;
        if (x>=map_xs)    return 1;
        if (y<0)          return 1;
        if (y>=map_ys)    return 1;
        if (map[x][y]!=0) return 1;
        }
    return 0;
    }
//---------------------------------------------------------------------------
// render game
//---------------------------------------------------------------------------
void draw()
    {
    // clear screen
    bmp->Canvas->Brush->Color=clBlack;
    bmp->Canvas->FillRect(TRect(0,0,bmp->Width,bmp->Height));

    // [game board]
    int x,y,a,i,j,adr;
    x=bmp->Width/(map_xs+4+3);
    y=bmp->Height/(map_ys+2);
    if (x<y) a=x; else a=y;

    // border
    x=a; y=a;
    bmp->Canvas->Pen->Color=clBlue;
    bmp->Canvas->Pen->Width=a>>1;
    bmp->Canvas->Rectangle(x,y,x+(map_xs*a),y+(map_ys*a));
    bmp->Canvas->Pen->Width=1;

    // game board
    for (j=0;j<map_ys;j++)
        {
        for (i=0;i<map_xs;i++)
            {
            // set color from map
            if (map[i][j]==0) bmp->Canvas->Brush->Color=clBlack;
            else              bmp->Canvas->Brush->Color=clAqua;
            // grid cell
            bmp->Canvas->FillRect(TRect(x,y,x+a,y+a));
            x+=a;       // posun sa o policko vpravo
            }
        x-=map_xs*a;    // vrat sa vlavo
        y+=a;           // posun sa o policko dole
        }
    y-=map_ys*a;        // vrat sa hore

    // falling tetromino
    x+=px*a;
    y+=py*a;
    for (j=0;j<4;j++)
        {
        for (i=0;i<4;i++)
            {
            // cell
            if (pm[j][i]!=0)
                {
                bmp->Canvas->Brush->Color=clGreen;
                bmp->Canvas->FillRect(TRect(x,y,x+a,y+a));
                }
            x+=a;       // posun sa o policko vpravo
            }
        x-=4*a;         // vrat sa vlavo
        y+=a;           // posun sa o policko dole
        }
    y-=4*a;             // vrat sa hore
    x-=px*a;
    y-=py*a;

    x+=(map_xs+1)*a;    // posun sa na pravy stlpec

    // score:
    bmp->Canvas->Font->Color=clWhite;
    bmp->Canvas->Brush->Color=clBlack;
    bmp->Canvas->TextOutA(x,y,AnsiString().sprintf("Score: %i",score));
    y+=a+a;

    // border
    bmp->Canvas->Pen->Color=clBlue;
    bmp->Canvas->Pen->Width=a>>1;
    bmp->Canvas->Rectangle(x,y,x+(4*a),y+(4*a));
    bmp->Canvas->Pen->Width=1;

    adr=16*novy_dielik;
    for (j=0;j<4;j++)
        {
        for (i=0;i<4;i++)
            {
            // set color from map
            if (shp[adr]==0) bmp->Canvas->Brush->Color=clBlack;
            else             bmp->Canvas->Brush->Color=clAqua;
            // nakresli stvorcek
            bmp->Canvas->FillRect(TRect(x,y,x+a,y+a));
            x+=a;       // go right
            adr++;
            }
        x-=4*a;         // return left
        y+=a;           // go down
        }
    y-=4*a;             // return up

    Form1->Canvas->Draw(0,0,bmp);
    }
//--- konstruktor okna ------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    {
    keys_code[_key_left ]='O';
    keys_code[_key_right]='P';
    keys_code[_key_rot  ]='Q';
    keys_code[_key_drop ]='A';

    // new game
    novy_dielik=rand()%7;       // new tetromino
    px=(map_xs>>1)-2;           // position top/middle
    py=0;
    int adr=16*novy_dielik;
    for (int j=0;j<4;j++)       // copy it to pm
     for (int i=0;i<4;i++)
        {
        pm[j][i]=shp[adr];
        adr++;
        }
    for (int j=0;j<map_ys;j++)  // clear map
     for (int i=0;i<map_xs;i++)
      map[i][j]=0;
    novy_dielik=rand()%7;
    }
//--- resize event ----------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
    {
    bmp->Width=ClientWidth;
    bmp->Height=ClientHeight;
    draw(); // force redraw
    }
//--- redraw event ----------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
    {
    draw();
    }
//--- falling timer ---------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
    py++;
    if (step()) // tetromino hit the ground?
        {
        py--;
        int i,j,x,y,adr,e;      // copy it to map
        for (j=0;j<4;j++)
         for (i=0;i<4;i++)
          if (pm[j][i])
            {
            x=px+i;
            y=py+j;
            map[x][y]=1;
            }
        px=(map_xs>>1)-2;       // new tetromino top/middle position
        py=0;
        adr=16*novy_dielik;
        for (j=0;j<4;j++)       // copy it to pm
         for (i=0;i<4;i++)
            {
            pm[j][i]=shp[adr];
            adr++;
            }

         // map full line test
        int dscore=0;
        for (j=map_ys-1;j>=0;j--)
            {
            e=1;
            for (i=0;i<map_xs;i++)
             if (map[i][j]==0)
                {
                e=0;
                break;
                }
            if (e)
                {
                dscore<<=1;
                dscore+=100;
                e=j;
                for (j=e-1;j>=0;j--)
                 for (i=0;i<map_xs;i++)
                  map[i][j+1]=map[i][j];
                j=e+1;
                draw();
                Sleep(200);
                }
            }
        score+=dscore;

        if (step()) // end game? (no new tetromino)
            {
            int q;
            q=bmp->Canvas->Font->Height;
            bmp->Canvas->Font->Height=40;
            bmp->Canvas->Font->Color=clRed;
            bmp->Canvas->Brush->Style=bsClear;
            AnsiString s="Game over";
            bmp->Canvas->TextOutA(
                (bmp->Width-bmp->Canvas->TextWidth(s))>>1,
                (bmp->Height-bmp->Canvas->TextHeight(s))>>1,s);
            bmp->Canvas->Brush->Style=bsSolid;
            bmp->Canvas->Font->Height=q;
            Form1->Canvas->Draw(0,0,bmp);
            Sleep(1000);

            // new game
            novy_dielik=rand()%7;       // new tetromino
            px=(map_xs>>1)-2;           // top/middle
            py=0;
            int adr=16*novy_dielik;
            for (int j=0;j<4;j++)       // copy it to pm
             for (int i=0;i<4;i++)
                {
                pm[j][i]=shp[adr];
                adr++;
                }
            for (int j=0;j<map_ys;j++)  // clear board
             for (int i=0;i<map_xs;i++)
              map[i][j]=0;
            novy_dielik=rand()%7;
            }
        novy_dielik=rand()%7;           // random next tetromino 0-6
        }
    draw();
    }
//--- keyboard timer --------------------------------------------------------
void __fastcall TForm1::Timer2Timer(TObject *Sender)
    {
    int e=0;
    if (keys[_key_left ]!=0)
        {
        px--; if (step()) px++; else e=1;
        }
    if (keys[_key_right]!=0)
        {
        px++; if (step()) px--; else e=1;
        }
    if (keys[_key_rot  ]!=0)
        {
        int i,j;
        BYTE ori[4][4];
        for (j=0;j<4;j++) for (i=0;i<4;i++) ori[i][j]=pm[i][j];
        for (j=0;j<4;j++) for (i=0;i<4;i++) pm[3-j][i]=ori[i][j];
        if (step()) for (j=0;j<4;j++) for (i=0;i<4;i++) pm[i][j]=ori[i][j];
        else e=1;
        }
    if (keys[_key_drop ]!=0)
        {
        py++; if (step()) py--; else e=1;
        }
    if (e) draw();
    }
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
    {
    Caption=Key;
    for (int i=0;i<_keys;i++)   // test all keys
     if (Key==keys_code[i])     // if match
      keys[i]=1;                // set it as pressed
    }
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift)
    {
    for (int i=0;i<_keys;i++)   // test all keys
     if (Key==keys_code[i])     // if match
      keys[i]=0;                // set it as released
    }
//---------------------------------------------------------------------------
void __fastcall TForm1::FormActivate(TObject *Sender)
    {
    for (int i=0;i<_keys;i++)   // set all keys
      keys[i]=0;                // as released
    }
//---------------------------------------------------------------------------
---------------------------------------

Это одно приложение формы с 2 таймерами на нем

Form


Timer1 равно 250 мс
Timer2 - это80ms

Если вы хотите использовать мой, вы должны:

  1. создать пустую форму приложения
  2. установить 2 таймера и установить интервалы
  3. создавать все события, которые использует мой код
  4. копировать коды событий и игр в правильные места

Но вы должны использовать это скорее как подсказку, как может выглядеть архитектура игры.Я знаю, что это безобразно и без уроков (те ученики, у которых еще нет возможности ООП , и мы вместе закодировали игру, так что был достигнут некоторый консенсус по всем частям, чтобы сделать это простым ...)

Таким образом, bmp походит на экранный буфер (чтобы избежать мерцания), управление осуществляется клавишами O P Q A.Один таймер управляет падающей анимацией / симуляцией, а другой управляет клавиатурой.Рендеринг выполняется с использованием VCL инкапсулированных GDI и bmp ...

для получения дополнительной информации см .:

...