Tetris mit wxWidgets
-
Hallo Community,
ich habe ein simples Tetris geschreiben. Ich programmiere noch nicht so lange in C++ und mit wxWidgets und würde gerne Eure Meinung zum Aufbau, Umsetzung usw. hören. :pHeader :
Variables.h
#ifndef VARIABLES_H_ #define VARIABLES_H_ enum tDir{Left,Right}; const int BlockX=20; const int BlockY=20; const int FieldX=10; const int FieldY=30; #endif
Tiles.h
#ifndef TILE_H_ #define TILE_H_ #include "Variables.h" class tTile { static bool Tile[7][4][5][5]; static int TileStartPos[7][4][2]; int Rotation; int NrTile; int x,y; public: tTile(){ x=0; y=0; Rotation=0; } void setTile(); bool rotate(int Dir); void draw(wxDC &dc); bool isPlaced(); void save(); void move(int Dir); void fallDown(); }; #endif
Field.h
#ifndef FIELD_H_ #define FIELD_H_ #include "Variables.h" enum tState{Empty,Full}; class tField { bool GameOver; tState Field[FieldX][FieldY]; tField(){} static tField* instance; public: static tField* getInstance(); void init(); void set(int x,int y,tState s); void deleteRow(int r); void clear(); bool fullRow(int r); tState get(int x,int y); void draw(wxDC& dc); bool isGameOver(); }; #endif
TetrisFrame.h
#ifndef TETRISFRAME_H_ #define TETRISFRAME_H_ class MyApp : public wxApp { public: virtual bool OnInit(); }; class TetrisFrame : public wxFrame { wxTimer timer; public: TetrisFrame(const wxString& title, const wxPoint &pos, const wxSize& size); void OnPaint(wxPaintEvent& event); void OnTimer(wxTimerEvent& event); void OnKeyDown(wxKeyEvent& event); void OnEraseBackground(wxEraseEvent& event); void OnAbout(wxCommandEvent& event); void neuesSpiel(); }; #endif
und jezt die Implementierungsdateien...
Tile.cpp
#include "Tile.h" #include "Field.h" bool tTile::Tile[7][4][5][5]= { {//I { {0,0,1,0,0}, {0,0,1,0,0}, {0,0,1,0,0}, {0,0,1,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,0,0,0}, {1,1,1,1,0}, {0,0,0,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,1,0,0}, {0,0,1,0,0}, {0,0,1,0,0}, {0,0,1,0,0} }, { {0,0,0,0,0}, {0,0,0,0,0}, {0,1,1,1,1}, {0,0,0,0,0}, {0,0,0,0,0} }, }, {//T { {0,0,0,0,0}, {0,1,1,1,0}, {0,0,1,0,0}, {0,0,0,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,1,0,0}, {0,1,1,0,0}, {0,0,1,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,1,0,0}, {0,1,1,1,0}, {0,0,0,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,1,0,0}, {0,0,1,1,0}, {0,0,1,0,0}, {0,0,0,0,0} }, }, {//Z { {0,0,0,0,0}, {0,0,0,0,0}, {0,1,1,0,0}, {0,0,1,1,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,1,0,0}, {0,1,1,0,0}, {0,1,0,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,0,0,0}, {0,1,1,0,0}, {0,0,1,1,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,1,0,0}, {0,1,1,0,0}, {0,1,0,0,0}, {0,0,0,0,0} }, }, {//Z gespiegelt { {0,0,0,0,0}, {0,0,0,0,0}, {0,0,1,1,0}, {0,1,1,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,1,0,0,0}, {0,1,1,0,0}, {0,0,1,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,1,1,0}, {0,1,1,0,0}, {0,0,0,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,1,0,0}, {0,0,1,1,0}, {0,0,0,1,0}, {0,0,0,0,0} }, }, {//L { {0,0,1,0,0}, {0,0,1,0,0}, {0,0,1,0,0}, {0,0,1,1,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,0,0,0}, {0,1,1,1,1}, {0,1,0,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,1,1,0,0}, {0,0,1,0,0}, {0,0,1,0,0}, {0,0,1,0,0} }, { {0,0,0,0,0}, {0,0,0,1,0}, {1,1,1,1,0}, {0,0,0,0,0}, {0,0,0,0,0} }, }, {//L gespiegelt { {0,0,1,0,0}, {0,0,1,0,0}, {0,0,1,0,0}, {0,1,1,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,1,0,0,0}, {0,1,1,1,1}, {0,0,0,0,0}, {0,0,0,0,0} }, { {0,0,1,1,0}, {0,0,1,0,0}, {0,0,1,0,0}, {0,0,1,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,0,0,0}, {0,1,1,1,1}, {0,0,0,0,1}, {0,0,0,0,0} }, }, {//Block { {0,0,0,0,0}, {0,0,1,1,0}, {0,0,1,1,0}, {0,0,0,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,1,1,0}, {0,0,1,1,0}, {0,0,0,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,1,1,0}, {0,0,1,1,0}, {0,0,0,0,0}, {0,0,0,0,0} }, { {0,0,0,0,0}, {0,0,1,1,0}, {0,0,1,1,0}, {0,0,0,0,0}, {0,0,0,0,0} }, }, }; int tTile::TileStartPos[7][4][2/*1.x 2.y*/]= { {// I { { 2,//x }, { 0,//y }, }, { { 2,//x }, { -2,//y }, }, { { 2,//x }, { -1,//y }, }, { { 1,//x }, { -2,//y }, }, }, { // T { { 2,//x }, { -1,//y }, }, { { 2,//x }, { -1,//y }, }, { { 2,//x }, { -1,//y }, }, { { 2,//x }, { -1,//y }, }, }, {//Z { { 2,//x }, { -2,//y }, }, { { 2,//x }, { -1,//y }, }, { { 2,//x }, { -2,//y }, }, { { 2,//x }, { -1,//y }, }, }, {//Z gespiegelt { { 2,//x }, { -2,//y }, }, { { 2,//x }, { -1,//y }, }, { { 2,//x }, { -1,//y }, }, { { 2,//x }, { -1,//y }, }, }, {//L { { 2,//x }, { 0,//y }, }, { { 2,//x }, { -2,//y }, }, { { 2,//x }, { -1,//y }, }, { { 2,//x }, { -1,//y }, }, }, {//L gespiegelt { { 2,//x }, { 0,//y }, }, { { 2,//x }, { -1,//y }, }, { { 2,//x }, { 0,//y }, }, { { 2,//x }, { -2,//y }, }, }, {//Block { { 2,//x }, { -1,//y }, }, { { 2,//x }, { -1,//y }, }, { { 2,//x }, { -1,//y }, }, { { 2,//x }, { -1,//y }, }, }, }; void tTile::setTile() { NrTile=rand()%7; Rotation=rand()%4; x=TileStartPos[NrTile][Rotation][0]; y=TileStartPos[NrTile][Rotation][1]; } void tTile::draw(wxDC &dc) { dc.SetBrush(wxColour(0,0,255)); for(int py=0;py<5;py++){ for(int px=0;px<5;px++){ if(Tile[NrTile][Rotation][py][px]){ dc.DrawRectangle((x+px)*BlockX,(y+py)*BlockY,BlockX,BlockY); } } } } bool tTile::isPlaced() { tField *Field=tField::getInstance(); for(int px=0;px<5;px++){ for(int py=0;py<5;py++){ if(Tile[NrTile][Rotation][py][px]){ if(py+y==FieldY)return true; if(Field->get(px+x,py+y)==Full)return true; } } } return false; } void tTile::save() { tField *Field=tField::getInstance(); for(int px=0;px<5;px++){ for(int py=0;py<5;py++){ if(Tile[NrTile][Rotation][py][px]) Field->set(px+x,py+y-1,Full); } } } bool tTile::rotate(int Dir) { tField *Field=tField::getInstance(); int OldRot=Rotation; switch(Dir) { case Left: if(Rotation-->0); else Rotation=3; break; case Right: if(Rotation++<3); else Rotation=0; break; } for(int px=0;px<5;px++){ for(int py=0;py<5;py++){ if(Tile[NrTile][Rotation][py][px]){ if(px+x<0 || px+x>=FieldX || py+y<0 || py+y>=FieldY || Field->get(px+x,py+y)==Full){ Rotation=OldRot; return false; } } } } return true; } void tTile::move(int Dir) { tField *Field=tField::getInstance(); int oldx,oldy; oldx=x; oldy=y; switch(Dir) { case Left: x--; break; case Right: x++; break; } for(int px=0;px<5;px++){ for(int py=0;py<5;py++){ if(Tile[NrTile][Rotation][py][px]){ if(px+x<0 || px+x>=FieldX || Field->get(px+x,py+y)==Full){ x=oldx; y=oldy; } } } } } void tTile::fallDown() { y++; }
Field.cpp
#include "Field.h" tField *tField::instance=0; tField* tField::getInstance() { if(!instance) instance=new tField(); return instance; } void tField::init() { GameOver=false; clear(); } void tField::set(int x,int y,tState s) { if(y<=0)GameOver=true; Field[x][y]=s; } void tField::deleteRow(int r) { if(r<1)return; for(int i=0;i<FieldX;i++){ Field[i][r]=Field[i][r-1]; Field[i][r-1]=Empty; } deleteRow(r-1); } void tField::clear() { for(int x=0;x<FieldX;x++){ for(int y=0;y<FieldY;y++){ Field[x][y]=Empty; } } } bool tField::fullRow(int r) { for(int i=0;i<FieldX;i++) if(Field[i][r]==Empty) return false; return true; } tState tField::get(int x,int y) { return Field[x][y]; } void tField::draw(wxDC &dc) { dc.SetBrush(wxColour(255,255,255)); dc.DrawRectangle(0,0,FieldX*BlockX,FieldY*BlockY); dc.SetBrush(wxColour(255,0,0)); for(int x=0;x<FieldX;x++){ for(int y=0;y<FieldY;y++){ if(Field[x][y]==Full){ dc.DrawRectangle(x*BlockX,y*BlockY,BlockX,BlockY); } } } } bool tField::isGameOver() { return GameOver; }
TetrisFrame.cpp
#include <wx/wx.h> #include <ctime> #include "TetrisFrame.h" #include "Field.h" #include "Tile.h" enum tGame{Paused,Running}Game; const int About_ID=12; tTile Tile; IMPLEMENT_APP( MyApp ); bool MyApp::OnInit() { TetrisFrame* frame = new TetrisFrame(wxT("Tetris"), wxDefaultPosition,wxSize(220,690)); frame->SetIcon( wxICON( amain ) ); frame->Show(); return true; } TetrisFrame::TetrisFrame(const wxString& title,const wxPoint &pos, const wxSize& size) : wxFrame((wxFrame*) NULL,-1,title,pos,size),timer(this) { srand((unsigned int)time(0)); wxMenu* menu=new wxMenu; menu->Append(About_ID,wxT("Über")); wxMenuBar *menuBar=new wxMenuBar; menuBar->Append(menu,wxT("Datei")); SetMenuBar(menuBar); CreateStatusBar(); Connect(wxEVT_COMMAND_MENU_SELECTED,wxCommandEventHandler(TetrisFrame::OnAbout)); Connect(wxEVT_PAINT,wxPaintEventHandler(TetrisFrame::OnPaint)); Connect(wxEVT_TIMER,wxTimerEventHandler(TetrisFrame::OnTimer)); Connect(wxEVT_KEY_DOWN,wxKeyEventHandler(TetrisFrame::OnKeyDown)); Connect(wxEVT_ERASE_BACKGROUND,wxEraseEventHandler(TetrisFrame::OnEraseBackground)); Game=Running; neuesSpiel(); } void TetrisFrame::OnAbout(wxCommandEvent &event) { wxMessageBox(wxT("2011 by Daniel S."),wxT("Tetris")); } void TetrisFrame::neuesSpiel() { tField* Field=tField::getInstance(); Field->init(); Tile.setTile(); timer.Start(150); } #include <wx/dcbuffer.h> void TetrisFrame::OnPaint(wxPaintEvent &event) { tField* Field=tField::getInstance(); wxBufferedPaintDC dc(this); Field->draw(dc); Tile.draw(dc); } void TetrisFrame::OnTimer(wxTimerEvent& event) { if(Game==Running){ tField* Field=tField::getInstance(); Tile.fallDown(); if(Field->isGameOver()){ timer.Stop(); wxMessageBox(wxT("Game Over !")); neuesSpiel(); } if(Tile.isPlaced()){ Tile.save(); Tile.setTile(); } for(int i=0;i<FieldY;i++) if(Field->fullRow(i)){ Field->deleteRow(i); } Refresh(); SetStatusText(wxT("Tetris")); } else SetStatusText(wxT("Pausiert ...")); } void TetrisFrame::OnKeyDown(wxKeyEvent &event) { int key=event.GetKeyCode(); if(key=='P') if(Game==Running){ Game=Paused; } else Game=Running; if(Game==Paused)return; switch(key) { case WXK_DOWN : Tile.rotate(Left); break; case WXK_UP : Tile.rotate(Right); break; case WXK_LEFT : Tile.move(Left); break; case WXK_RIGHT : Tile.move(Right); break; } } void TetrisFrame::OnEraseBackground(wxEraseEvent &event) { }
-
Hier die Dateien:
http://www3.zippyshare.com/v/60213284/file.html
-
Den Script habe ich mir noch nicht ganz durchgelesen, aber beim Spielen habe ich gesehen dass du die L förmigen steine zu lang gemacht hast.
deine Steine:
XX
X
X
XOriginal:
XX
X
Xansonsten gute Arbeit!
-
hi danke für den Beitrag,
das mit dem L kann man in dem Array Tile[7][4][5][5] ändern