在上一篇中我介绍了使用React Native开发的跨平台俄罗斯方块小游戏,截图和代码都在上一篇中。本篇记录的是如何来实现这个小游戏的框架。如果你还不了解React Native,可以参考React Native中文网
游戏整体框架介绍
这个俄罗斯方块小游戏的源码目录层次如下图所示:
最主要的是src
目录和index.js
、App.js
文件,需要注意的是,在低版本的React Native中,新创建的项目里是包含index.android.js
和index.ios.js
两个文件的,在高版本的React Native中,这两个文件整合成一个index.js
文件。下面分别说下src
目录,index.js
和App.js
.
index.js文件
该文件是项目的入口文件,源码如下:
import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('RNTetris', () => App);
其实就是注册了一个App
组件,引用了App.js
。
App.js文件
该文件代码也不多,主要是根据一个游戏状态值gameState
来切换不同的游戏界面,比如从准备界面切换到正在游戏界面,从正在游戏界面切换到游戏结束界面,App.js代码如下:
import React, { Component } from 'react';
import GameOverView from './src/view/GameOverView';
import GameNotStartView from './src/view/GameNotStartView';
import GamePauseView from './src/view/GamePauseView';
import GamePlayingView from './src/view/GamePlayingView';
import {
GAME_STATE_NOT_START,
GAME_STATE_PLAYING,
GAME_STATE_PAUSE,
GAME_STATE_OVER
} from './src/utils/Constants';
// 正式环境中去掉所有的log
if (!__DEV__) {
global.console = {
info: () => {},
log: () => {},
warn: () => {},
debug: () => {},
error: () => {},
};
}
export default class App extends Component<{}> {
constructor(props) {
super(props);
this.state = {
// 表示游戏状态,根据这个值来切换游戏界面(开始、进行中、游戏结束)
gameState: GAME_STATE_NOT_START
};
}
render() {
switch (this.state.gameState) {
case GAME_STATE_NOT_START:
// 游戏待开始界面
return <GameNotStartView changeGameState={this.changeGameState} />;
break;
case GAME_STATE_PLAYING:
// 游戏正在进行中界面
return <GamePlayingView changeGameState={this.changeGameState} />;
break;
case GAME_STATE_PAUSE:
// 暂停页面在这个项目中未实现
return <GamePauseView changeGameState={this.changeGameState} />;
break;
case GAME_STATE_OVER:
// 游戏结束界面
return <GameOverView changeGameState={this.changeGameState} />;
break;
}
}
// 该方法作为参数,传给每个页面去调用
changeGameState = (state)=>{
this.setState({
gameState: state
});
}
}
这里我们定义了一个state状态值,名为gameState
,gameState
的可取值定义在/src/utils/Constants
中,然后定义了一个changeGameState
方法,该方法用于改变gameState的值,从而达到切换游戏界面的目的。gameState的取值有如下4个:
1. GAME_STATE_NOT_START(对应src/view/GameNotStartView)
2. GAME_STATE_PLAYING(对应src/view/GamePlayingView)
3. GAME_STATE_PAUSE
4. GAME_STATE_OVER(对应src/view/GameOverView)
其中GAME_STATE_PAUSE这个暂停界面,在本游戏中未实现,本游戏中一共就3个界面,游戏待开始、游戏进行中、游戏结束。
src目录
该目录分为3个包:entity
、utils
、view
entity包
该包存放游戏的实体类,实体类主要是Shape
类、Ground
类和ShapeFactory
类,下面分别说明:
Shape
类
Shape
代表一个方块,方块可以左右移动,可以下落,还可以变形。Ground
类
Ground
代表游戏面板,即方块可以自由移动的区域。Ground
可以吃掉一个Shape
,即方块下落到跟Ground
接触后,转化为Ground
的一部分。Ground
还需要在每次吃掉Shape
后,检查是否有满行,如果有满行,则需要将满行给删除。ShapeFactory
类
ShapeFactory
主要用于生产不同形状的方块,比如长条形、正方形、直角形等等。ShapeFactory
提供一个getRandomShapeData
方法,用于随机生产一种形状的方块。
utils包
该包存放游戏的工具类,主要是游戏常量Constants.js
和调试打印的工具Utils.js
view包
该包存放游戏的不同界面,主要是GameNotStartView
、GamePlayingView
、GamePauseView
、GameOverView
四个界面,其中GamePauseView
在该项目中未实现。
关于游戏绘图
在俄罗斯方块游戏中,由于需要不断的重绘游戏界面,所以需要采用React Native提供的ART API,关于ART的使用,可以自行搜索或者参考这篇文章。
后续
最主要的逻辑都在src
包中,后面一篇我会详细记录如何实现俄罗斯方块的逻辑,包括方块的移动,变形,被Ground
吃掉,Ground
满行消除等等。