I. Design Ideas
A background array and a square array. When placing the square array into the background array, a coordinate is required for positioning, that is, there is a ing relationship between the two coordinate systems.
Ii. form code
Erluosiclass elsclass = new erluosiclass ();/* game start button event */private void button#click (Object sender, eventargs e) {elsclass. cellwidthcount = 12; elsclass. cellheightcount = 16; elsclass. initerluosi (); elsclass. winhandle = elspanel. handle; elspanel. width = elsclass. width; elspanel. height = elsclass. height; elsclass. erluosidraw (); button1.enabled = false; // the current block elsclass is randomly generated. getinitblockdata ();// Timer start timer1.enabled = true;}/* */private void elspanel_paint (Object sender, painteventargs e) {If (elsclass. elsstartflag) elsclass. erluosidraw ();}/* keyboard operation */private void form1_keydown (Object sender, keyeventargs e) {If (E. keycode = keys. down) {// first determine whether you can move down if (elsclass. candown () elsclass. currentx ++; // move down} else if (E. keycode = keys. left) {// first judge whether it is possible to move left if (elsclass. canleft () elsclas S. currenty --; // left shift} else if (E. keycode = keys. right) {// first determine whether the right shift if (elsclass. canright () elsclass. currenty ++; // shift right} else if (E. keycode = keys. up) {// first determine whether the IF (elsclass. canchange () elsclass. changeblock (); // transformation} else if (E. keycode = keys. space) {// Space key pause, start if (timer1.enabled) timer1.enabled = false; else timer1.enabled = true;} // redraw here also redraw on the interface to reflect the speed of elsclass. erluosidraw (); elspanel. focus ();}/* Timer event */private void timereffectick (Object sender, eventargs e) {If (elsclass. candown () {elsclass. currentx ++;} else // if it cannot be moved again {// put the value in the block into the background array elsclass. setdata (); // check and delete the row elsclass. checkanddeletelines (); // check whether it reaches the top if (elsclass. checktotop () {timer1.enabled = false; MessageBox. show ("to the top! ");} // Reset the Starting Status of elsclass. currentx =-4; elsclass. currenty = 5; // randomly generate a new block elsclass. getinitblockdata ();} // redraw elsclass. erluosidraw ();}
Iii. Core Control
Public class erluosiclass {# region parameter public system. intptr winhandle; // game switch flag public bool elsstartflag = false; // The default array of the game canvas is 0 public int [,] rushdata; # the status of the region small pattern, seven types for the time being, each of which uses four variations (7*4) * 4*4 Public int [,] blocks = {// counter-clockwise rotation # Four statuses of the region horizontal bar }}, {,}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {, 0}, {, 0}, {, 0 }, {,}, {, 0, 0}, {,}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0 }}, # endregion # Four statuses in the region box: {,}, {,}, {0, 0}, {0, 0}, {0, 0, 0, 0}, {, 0, 0}, {0, 0, 0}, {0, 0, 0}, {, 0}, {, 0}, {, 0}, {0, 0, 0, 0}, {0, 0, 0}, {, 0}, {, 0}, {0, 0}, {0, 0, 0}, {0, 0 }}, # endregion # Four statuses of region T: {,}, {,}, {0, 0}, {0, 0}, {0, 0, 0, 0}, {, 0, 0}, {, 0, 0}, {0, 0, 0}, {0, 0, 0}, {,}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}, # endregion # Four statuses of Region 7, }, {, 0, 0}, {0, 0, 0}, {0, 0, 0}, {, 0}, {, 0}, {, 0, 0, 0}, {0, 0, 0}, {0, 0}, {1, 1, 0}, {0, 0}, {0, 0}, {0, 0 }}, # endregion # Four statuses of Region Anti-7 characters: {,}, {, 0}, {, 0}, {, 0}, {0, 0 }}, {,}, {,}, {0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0 }, {,}, {0, 0, 0}, {,}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0, 0 }}, # endregion # Four statuses of Region z: {,}, {,}, {0, 0}, {0, 0}, {0, 0}, {0, 0, 0, 0}, {, 0, 0}, {, 0, 0}, {0, 0, 0}, {, 0, 0}, {,}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}, # endregion # Region Anti-Z characters in four states: {0, 1, 0}, {, 0}, {0, 0}, {0, 0}, {0, 0 }}, {,}, {,}, {0,}, {0, 0}, {0, 0, 0}, {0,}, {, 0 }, {0, 0, 0}, {0, 0, 0}, {, 0}, {, 0}, {, 0}, {0, 0, 0}, {0, 0, 0 }}, # endregion };# endregion/* internal structure of the block in the current operation */Public int [,] currentblock = new int [4, 4]; // The starting point of the block in the current operation is in the entire array. The starting point is in the upper left corner of the public int currentx =-4; Public int currenty = 5; // The number of current squares and the number of State squares public int cellnum = 0; Public int cellstate = 0; // the size of a grid public int cellsize = 15; // number of cells in the width and height directions public int cellwidthcount; Public int cellheightcount; // area width and height public int width; Public int height; # endregion/* initialization */Public void initerluosi () {rushdata = new int [cellheightcount, cellwidthcount]; width = cellwidthcount * (cellsize + 1) + 1; height = cellheightcount * (cellsize + 1) + 1; elsstartflag = true; // set the game status to start}/* draw a Game Image */Public void erluosidraw () {image myimage = new Bitmap (width, height); graphics G = graphics. fromimage (myimage); G. fillrectangle (New solidbrush (color. gray), 0, 0, width, height); // draw a vertical line for (INT I = 0; I <= cellwidthcount; I ++) {G. drawline (new pen (color. black), (cellsize + 1) * I, 0, (cellsize + 1) * I, height);} // The height direction goes up, draw a horizontal line for (INT I = 0; I <= cellheightcount; I ++) {G. drawline (new pen (color. black), 0, (cellsize + 1) * I, width, (cellsize + 1) * I);} solidbrush brush = new solidbrush (color. gray); // default gray background painter fontfamily = new fontfamily ("Arial"); font = new font (fontfamily, 12, fontstyle. regular, graphicsunit. pixel); string strtemp = ""; // The default text to be written: int fontleft = cellsize/5; // draw all squares for (INT I = 0; I <cellheightcount; I ++) {for (Int J = 0; j <cellwidthcount; j ++) {brush = new solidbrush (color. gray); // gray background paint brush if (rushdata [I, j] = 1) Brush = new solidbrush (color. gold); // strtemp = rushdata [I, j]. tostring (); G. fillrectangle (brush, (cellsize + 1) * j + 1, (cellsize + 1) * I + 1, cellsize, cellsize); G. drawstring (strtemp, Font, new solidbrush (color. black), (cellsize + 1) * j + fontleft, (cellsize + 1) * I + fontleft) ;}// draw the currently moving square for (INT I = 0; I <4; I ++) {for (Int J = 0; j <4; j ++) {If (currentx + I <0) continue; brush = new solidbrush (color. gray); // default gray background paint brush strtemp = currentblock [I, j]. tostring (); If (currentblock [I, j] = 1) {brush = new solidbrush (color. gold ); // golden background painter} If (currentx + I> = 0 & currentx + I <= cellheightcount-1 & currenty + j> = 0 & currenty + j <= cellwidthcount -1 & rushdata [currentx + I, currenty + J] = 1) {brush = new solidbrush (color. gold); // strtemp = "1";} G. fillrectangle (brush, (cellsize + 1) * (currenty + J) + 1, (cellsize + 1) * (currentx + I) + 1, cellsize, cellsize); G. drawstring (strtemp, Font, new solidbrush (color. black), (cellsize + 1) * (currenty + J) + fontleft, (cellsize + 1) * (currentx + I) + fontleft);} graphics Gg = graphics. fromhwnd (winhandle); GG. drawimage (myimage, 0, 0);}/* randomly generate the current block */Public void getinitblockdata () {random ran = new random (); cellnum = ran. next (0, 6); cellstate = ran. next (0, 4); For (INT I = 0; I <4; I ++) {for (Int J = 0; j <4; j ++) {currentblock [I, j] = blocks [cellnum * 4 + cellstate, I, j] ;}}/* Can I move down */Public bool candown () {for (INT I = 3; I> = 0; I --) {for (Int J = 0; j <4; j ++) {// If the square is 1, you need to determine whether it is possible to go down if (currentblock [I, j] = 1) {If (currentx + I + 1> = cellheightcount) {return false; // cannot move down} else if (currentx + I + 1> = 0 & currentx + I + 1 <cellheightcount & currenty + j> = 0 & currenty + J <cellwidthcount & rushdata [currentx + I + 1, currenty + J] = 1) {return false; // cannot move down }}} return true;}/* Can I move to the left */Public bool canleft () {for (INT I = 0; I <4; I ++) {for (Int J = 0; j <4; j ++) {If (currentblock [I, j] = 1) {If (currenty + J-1 <0) {return false; // cannot move down} else if (currentx + I> = 0 & currentx + I <cellheightcount & currenty + J-1> = 0 & currenty + J-1 <cellwidthcount & rushdata [currentx + I, currenty + J-1] = 1) {return false; // cannot move down }}} return true ;} /* Can I move to the right? */Public bool canright () {for (INT I = 0; I <4; I ++) {for (Int J = 0; j <4; j ++) {If (currentblock [I, j] = 1) {If (currenty + J + 1> = cellwidthcount) {return false; // cannot move down} else if (currentx + I> = 0 & currentx + I <cellheightcount & currenty + J + 1> = 0 & currenty + J + 1 <cellwidthcount & rushdata [currentx + I, currenty + J + 1] = 1) {return false; // cannot move down }}} return true;}/* can rotate */Public bool canchange () {cellstate = (cellstate + 1) % 4; for (INT I = 0; I <4; I ++) {for (Int J = 0; j <4; j ++) {// check whether the position after the square is rotated as 1 conflicts. If (blocks [cellnum * 4 + cellstate, I, j] = 1) {// if the value is in the range if (currentx + I> = 0 & currentx + I <cellwidthcount & currenty + j> = 0 & currenty + j <cellheightcount) {If (rushdata [I, j] = 1) return false;} // If the else {return false ;}}} is not in the range, return true ;} /* rotate the current square */Public void changeblock () {for (INT I = 0; I <4; I ++) {for (Int J = 0; j <4; j ++) {currentblock [I, j] = blocks [cellnum * 4 + cellstate, I, j] ;}}/ * sets the array: put the value of a block that cannot be moved into the background array */Public void setdata () {for (INT I = 0; I <4; I ++) {for (Int J = 0; j <4; j ++) {If (currentblock [I, j] = 1) {If (currentx + I> = 0 & currentx + I <cellheightcount & currenty + j> = 0 & currenty + j <cellwidthcount) rushdata [currentx + I, currenty + J] = 1 ;}}}/* check that the row is full and destroy the row and score */Public void checkanddeletelines () {int lines = 0; // The number of rows used for scoring int [] linesflag = new int [cellheightcount]; // record whether each row is filled up // find the full row for (INT I = CellHeightCount-1; I> = 0; I --) {int COUNT = 0; // the full number of rows for (Int J = CellWidthCount-1; j> = 0; j --) {If (rushdata [I, j] = 1) {count ++;} If (COUNT = cellwidthcount) {linesflag [I] = 1; lines ++ ;}} // move the row for (INT I = 0; I <cellheightcount; I ++) {// If the row is full if (linesflag [I] = 1) {// move the for (Int J = I; j> 0; j --) {for (int K = 0; k <cellwidthcount; k ++) {rushdata [j, k] = rushdata [J-1, K] ;}}for (int K = 0; k <cellwidthcount; k ++) {rushdata [0, k] = 0 ;}}}// check whether public bool checktotop () {// column loop for (Int J = 0; j <cellwidthcount; j ++) is reached) {If (rushdata [0, J] = 1 & currentx <0) return true; // to the top} return false ;}}