Realization of the Reactnative Tetris game based on the 3--of the shape in the game _react

Source: Internet
Author: User
Tags border color transparent color

In the previous article, I recorded the framework of the game based on the react native Tetris games, which is a record of how to achieve the shape,shape of Tetris to represent a moving and falling figure. Art Drawing Basics

To complete the shape of Tetris, you must first understand the drawing base in the lower react native. React native built a gallery of art for drawing purposes, the following is a simple way to record the use of the art library. The following code is used to draw a square with a side length of 100 pixels in the center of the phone's screen:

 import react, {Component} from ' react '; import {StyleSheet, View, ART, Dimensions} from ' react-native ';
Type Props = {}; Export default class App extends Component<props> {render () {Const PATH = ART.
    Path ();
    Path.moveto (0, 0);
    Path.lineto (100, 0);
    Path.lineto (100, 100);
    Path.lineto (0, 100);
    Path.lineto (0, 0);
    Path.close (); Return (<view style={styles.container}> <art. Surface width={100} height={100}> <art. Shape D={path} fill= "#6699FF" stroke= "#FF0000" strokewidth={2}/> </art.
  Surface> </View>); } Const STYLES = Stylesheet.create ({container: {flex:1, justifycontent: ' Center ', Alignitems: ' Center '
,
  },
}); 

The effect of the code running is as follows:

The steps for drawing a square are as follows:
1. Import Art Package: import {ART} from ' react-native ';
2. Create the Path object and determine the contour of the graph with the path object, as follows:
Const PATH = ART. Path ();
Path.moveto (0, 0);
Path.lineto (100, 0);
Path.lineto (100, 100);
Path.lineto (0, 100);
Path.lineto (0, 0);
Path.close ();
3. Use <art. Surface> and <art. Shape> Draw the graph. What needs to be noted here is the <art. Shape> components must be wrapped in <art. Surface> assembly, by giving <art. The shape> setting D={path} property determines the shape of the graphic, and the Fill property specifies the fill color of the shape, the border color of the shape specified by the Stroke property, and the border width of the graphic specified by the strokewidth. Design and implementation of shape class

With the drawing foundation of art, we can finish the design and implementation of the Shape class. Design of Shape class

A shape class represents a shape that can be moved around, can be deformed and dropped, and in the game there are many different shapes, such as strips, squares, bends, and so on. We use a 4x4 two-dimensional array to represent the structure of a graph, with 0 and one in the array representing the hollow and solid, where the shape class is designed by using art drawing in a solid place, without drawing anything in the hollow, in order to complete the design of the shapes, as in the following two-dimensional array:

[1, 1, 1, 0],
[0, 1, 0, 0], [0, 0, 0
, 0],
[0, 0, 0, 0]

It means a T-shaped square. Code implementation of Shape class

After designing the shape class, you need to encode this class, shape has some properties such as: start coordinates, shape two-dimensional array data, shape and some other methods such as: Left, right, deformation, automatic whereabouts, shape touch to ground after processing. Deformation of shape

First, consider the shape deformation, taking the T-shape as an example, a T-shape can be deformed to a inverted T-shaped or partial t-shape, in order to handle the shape's distortion, we use an array to hold all the possible shapes of a shape, which becomes a three-dimensional array, as follows:

Let shapedata = [[[
  1, 0, 0, 0],
  [1, 1, 0, 0], [1, 0, 0,
  0],
  [0, 0, 0, 0]], [[1, 1,
1,
  0],
  [  0, 1, 0, 0],
  [0, 0, 0, 0],
  [0, 0, 0, 0]
], [
  [0, 0, 1, 0],
  [0, 1, 1, 0],
  [0, 0, 1, 0],
  [0, 0, 0, 0]
], [
  [0, 0, 0, 0], [0, 1, 0, 0
  ],
  [1, 1, 1, 0],
  [0, 0, 0, 0]
]]

In the initial case, the graph is the above shapedata[0] data, when the graph needs to deform, becomes the shapedata[1 "the data, then needs to deform, becomes shapedata[2] The data, in turn loops." The left and right movements and whereabouts of shape

The left and right movement of shape is simpler, changing the coordinates of the shape, where we set a starting point (POSX, posy) for shape, stored in state, and when we change this coordinate in state, shape is automatically redrawn to achieve the effect of movement, The code for Shape movement is as follows:

  MoveLeft () {
    this.setstate ({posx:this.state.posx-1});
  }
  MoveRight () {
    this.setstate ({PosX:this.state.posX + 1});
  }
  MoveDown () {
    this.setstate ({PosY:this.state.posY + 1});
  }
Automatic whereabouts of shape

When we do not do anything, a graphic will automatically fall, where we need to use a timed task to allow the graphics to automatically fall, but every drop needs to be judged, if the shape touched the ground, think that the shape of death, was ground eaten, At this time to turn off the timing of the automatic drop of shape, and also to determine whether the game is over, if the game is not over, you need to produce new shape and automatic whereabouts, the logic here is slightly more complex, to judge the conditions are more, first put the shape automatically falling code:

Automovedown () {//Auto drop
  This.movefun = () =>{//This is a timed execution method used to drive the graphics auto Drop
    if (This.props.canShapeMoveDown && Amp This.props.canShapeMoveDown ()) {//If the graphic can fall, drop
      this.setstate ({
        PosX:this.state.posX,
        posy:1 + This.state.posY
      });
    else {
      //cannot fall, clear timed task
      this._clearinterval ();
      Triggering a graphical death callback
      This.props.onShapeDieListener && This.props.onShapeDieListener (This.state.posX, This.state.posY, Shapearrdata[shapeindex]);
      To determine if the game is over, the end condition is that the posy coordinates are the same as the original posy coordinates when the shape is eaten
      (This.state.posY = = this.inity) {
        //end
        of game This.props.onGameOverListener && This.props.onGameOverListener ();
      } else {
        //game not ended
        This._reset ();
      }
      return;
    }
  This.intervalid = SetInterval (This.movefun);
}

The above code involves some of the methods in the <GamePlayingView> component, such as a way to determine whether a graph can fall or not, Canshapemovedown The graph is onshapedielistener by the callback method of death after ground is eaten, which will be recorded in subsequent space. Drawing of shape

In react native, we need to implement the component's Render method to complete the rendering of the component, where we render a shape shape. Since shape's data is a two-dimensional array of integers, we can iterate through the array in a loop, draw the color of the value 1 in the array, and draw a transparent color where the value is 0, thus forming a complete graph. Drawing is mainly the following two methods:

Generates a small square (a lattice in a 4x4), based on fill to determine whether to fill the color Generatecell (POSX, Posy, Indexx, indexy, fill) {Const PATH = ART.
  Path ();
  Path.moveto ((posx + indexx) * width, (posy + indexy) * width);
  Path.lineto ((posx + Indexx + 1) * width, (posy + indexy) * width);
  Path.lineto ((posx + Indexx + 1) * width, (posy + indexy + 1) * width);
  Path.lineto ((posx + indexx) * width, (posy + indexy + 1) * width);
  Path.lineto ((posx + indexx) * width, (posy + indexy) * width);
  Path.close (); Processing return <art with the IF (fill) {//value of 1. Shape D={path} fill= "#33CC99" stroke= "#6699CC" Strokewidth={divider_width}/>} else {//value 0 of processing return < ART.
  Shape D={path} fill= "#00000000"/>}//Generate a shape (entire shape of 4x4) Generateshape (Shapearr) {Let shape = []; Iterate through the two-dimensional array, saving all the small squares for (let row = 0; row < 4; row++) {for (let col = 0; col < 4; col++) {Shape.push (
    This.generatecell (This.state.posX, This.state.posY, col, Row, Shapearr[row][col]);
} return shape; }

Finally our render method, we just need to call the above Generateshape method on the line. The complete code for the shape class is placed below:

Import react, {Component} from ' react ';
Import {ART, View} from ' react-native ';
Import shapefactory from './shapefactory '; Import {cell_hor_count, WIDTH, divider_width} from ' ...

/utils/constants ';
Let Shapeindex = 0;
Const Shapefactory = new Shapefactory ();

Let Shapearrdata = Shapefactory.getrandomshapedata ();
    Export default class Shape extends Component {constructor (props) {super (props);
    THIS.INITX = parseint (CELL_HOR_COUNT/2)-2;
    this.inity = 5; This.state = {//initial coordinates PosX:this.initX, PosY:this.initY}} getPosition () {//Return shape's current coordinates retu
  RN {PosX:this.state.posX, PosY:this.state.posY};
  GetData () {//Returns the shape's two-dimensional array data return SHAPEARRDATA[SHAPEINDEX];
  Getnextshapedata () {//returns the two-dimensional array data for the next shape of shape return shapearrdata[(Shapeindex + 1)% 4];
    _reset () {//Be ground eaten and reset Shapearrdata = Shapefactory.getrandomshapedata ();
    Shapeindex = 0; This.setstate ({PosX:this.initX, posY:this.inity}, () =>{this.automovedown ();
  }); } Generatecell (Posx, Posy, Indexx, indexy, fill) {//Generate a small square, based on fill to determine whether to fill the color const PATH = ART.
    Path ();
    Path.moveto ((posx + indexx) * width, (posy + indexy) * width);
    Path.lineto ((posx + Indexx + 1) * width, (posy + indexy) * width);
    Path.lineto ((posx + Indexx + 1) * width, (posy + indexy + 1) * width);
    Path.lineto ((posx + indexx) * width, (posy + indexy + 1) * width);
    Path.lineto ((posx + indexx) * width, (posy + indexy) * width);
    Path.close (); if (fill) {return <art. Shape D={path} fill= "#33CC99" stroke= "#6699CC" Strokewidth={divider_width}/>} else {return <art.
    Shape D={path} fill= "#00000000"/>}} generateshape (Shapearr) {//Generate a shape let shape = []; for (let row = 0; row < 4; row++) {for (let col = 0; col < 4; col++) {Shape.push (t
      His.state.posX, This.state.posY, col, Row, Shapearr[row][col]); }
    return shape; Automovedown () {//Auto drop This.movefun = () =>{if (This.props.canShapeMoveDown && this.props.canSh
      Apemovedown ()) {this.setstate ({PosX:this.state.posX, posy:1 + This.state.posY});
        else {//Cannot drop this._clearinterval (); This.props.onShapeDieListener && This.props.onShapeDieListener (This.state.posX, This.state.posY,
        Shapearrdata[shapeindex]); To determine if the game is over, the end condition is that the posy coordinates are the same as the original posy coordinates when the shape is eaten (This.state.posY = = this.inity) {//game end this
        . Props.ongameoverlistener && This.props.onGameOverListener ();
        else {//game not finished This._reset ();
      } return;
  } this.intervalid = SetInterval (This.movefun, 600);
  Componentwillmount () {//When the component is about to be mounted, the timing task is turned on to allow shape to fall automatically this.automovedown (); } render () {//Render shape return This.generateshape (shapearrdata[shapeindex% 4]);
  Transform () {//Graphics variant Shapeindex = (++shapeindex)% 4;
  } moveLeft () {this.setstate ({posx:this.state.posx-1});
  } moveright () {this.setstate ({PosX:this.state.posX + 1});
  } movedown () {this.setstate ({PosY:this.state.posY + 1});
  _clearinterval () {//Purge timed Tasks this.intervalid && clearinterval (this.intervalid);
  Componentwillunmount () {//component is about to uninstall, stop Timing Task this._clearinterval ();
 }
}
Subsequent

The next article will record the ground class design and coding implementation. Source

Click to view project Source-github
Click to view project Source-code Cloud

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.