初识react之打字小游戏

106 阅读2分钟

前言

在初学react时查看官方教程时跟着教程学习了敲一个井字棋游戏,由于是边学边看边敲,感觉掌握的不熟练,为了加深react的基础用法,如state、props等的使用,想着写一个简易的demo。后来发现自己打字速度越来越慢,就想着做一个打字小游戏。

代码过程

1. 先把字符列表定义好
const WordList = ["q","w","e","r","t","y","u","i","o","p","a","s","d","f","g","h","j","k","l","z","x","c","v","b","n","m","Q","W","E","R","T","Y","U","I","O","P","A","S","D","F","G","H","J","K","L","Z","X","C","V","B","N","M",];
2. 将显示字符的每一个方格定义好
class Square extends React.Component {
  constructor(props) {
    super(props);
      this.state = {};
    }
    render() {
      return <div className="square">{this.props.value}</div>;
    }
}
3. 将棋盘定义好
class Board extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  // 渲染棋盘列表
  list = () => {
    const x = this.props.size.x;
    const y = this.props.size.y;
    return Array(y)
      .fill("")
      .map((item, index) => {
        let row = Array(x)
        .fill("")
        .map((ite, ind) => {
          const now = ind + index * x + 1;
          let location = "";
          this.props.showList.forEach((choose) => {
            if (choose.index === now) {
              location = choose;
              return;
	     }
	   });
           return <Square key={ind} value={location.value}></Square>;
	});
        return (
          <div className="row" key={index}>
            {row}
          </div>
        );
      });
  };
  render() {
    return <div className="board">{this.list()}</div>;
  }
}
4. 定义操作面板和显示分数
class Settings extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      start: false,
    };
  }
  start = () => {
    this.setState(
      {
        start: !this.state.start,
      },
      () => {
        this.props.begin(this.state.start);
      }
    );
  };
  end = () => {
    this.props.end();
    this.setState({ start: false });
  };
  render() {
    return (
      <div className="settings">
        <div>设置</div>
        <div>
          <span>行数:{this.props.size.x}</span>
          <span>列数:{this.props.size.y}</span>
        </div>
        <div>速度:1个/{this.props.speed}ms</div>
        <div>
          <span>得分:{this.props.score}</span>
          <span>错失:{this.props.error}</span>
        </div>
        <button className="btn" onClick={this.start}>
          {this.state.start ? "暂停" : "开始"}
        </button>
        <button className="btn" onClick={this.end}>
          停止
        </button>
      </div>
    );
  }
}
5. 定义游戏基本类
export default class Game extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      size: {
        x: 10,
        y: 10,
      },
      showList: [],
      start: false,
      speed: 1000,
      score: 0,
      error: 0,
    };
  }
  componentDidMount() {
    document.addEventListener("keydown", this.onKeyDown);
  }
  // 开始暂停游戏
  begin = (start) => {
    this.setState({
      start: start,
    });
    if (start) {
      this.creatNewOne();
      this.startTimer = setInterval(() => {
        this.creatNewOne();
      }, this.state.speed);
    } else {
      clearInterval(this.startTimer);
    }
  };
  // 新增一个
  creatNewOne = () => {
    const value = Math.floor(Math.random() * WordList.length);
    const index = Math.floor(Math.random() * this.state.size.x * this.state.size.y);
    const newOne = {
      value: WordList[value],
      index: index,
    };
    let showList = this.state.showList;
    let error = this.state.error;
    showList.forEach((item) => {
      if (item.index === newOne.index) {
        error += 1;
      }
    });
    showList.push(newOne);
    this.setState({
      showList,
      error,
    });
  };
  // 停止游戏
  end = () => {
    clearInterval(this.startTimer);
    this.setState({
      start: false,
      showList: [],
      score: 0,
      error: 0,
    });
  };
  // 监听键盘事件
  onKeyDown = (e) => {
    let index = null;
    let showList = this.state.showList;
    showList.forEach((item, i) => {
      if (e.key === item.value) {
        index = i;
        return;
      }
    });
    if (index !== null) {
      showList.splice(index, 1);
      this.setState({
        showList,
        score: this.state.score + 1,
      });
    }
  };
  render() {
    return (
      <div className="game">
        <Board size={this.state.size} showList={this.state.showList}></Board>
        <Settings
          speed={this.state.speed}
          size={this.state.size}
          score={this.state.score}
          error={this.state.error}
          begin={this.begin.bind(this)}
          end={this.end.bind(this)}
        ></Settings>
      </div>
    );
  }
}

6. css样式
.game {
  margin: 0 auto;
  position: relative;
  text-align: center;

  .board {
    .row {
      width: auto;
      font-size: 0;
    }
  }

  .square {
    height: 40px;
    width: 40px;
    font-size: 14px;
    background: rgba(170, 204, 0, 0.5);
    box-sizing: border-box;
    border: 1px solid rgba(170, 204, 0, 0.2);
    display: inline-block;
    text-align: center;
    line-height: 40px;
    vertical-align: middle;
  }

  .settings {
    display: inline-block;
    padding: 10px 20px;
    margin-top: 10px;
    border: 1px solid #666;
    border-radius: 20px;
    text-align: left;

    button {
      margin: 5px 10px 0;
    }
  }
}

总结

这是3年多前初学react时写的代码,记录一下。当时学习react感觉还是比vue难,因为先会的jq,再学vue,然后用react就不顺手,后来学ts也是不顺手,但是写多了就熟悉了,学了java之后,ts用着也是简简单单。