React-native数独游戏(二)界面实现

上篇已经生成了数独题目,这篇是关于react-native界面实现的部分,说实在的,react-native对于复杂界面的实现还是有点困难,当然这个还不算太复杂,可能是因为本身与安卓原生的设计思路是有很大的不同,然后个人不习惯吧
github源码地址
这里写图片描述

这里写图片描述
界面比较简单,进去就是三个菜单,分别对应不同的难度,其实就是扣掉不同数量的数字,达到难度的划分。扣掉的数字,填上0。另外关于数独题目的问题,其实这个出题是不科学的,因为随机扣掉数字,并不能保证出的题目一定有唯一解,甚至不一定有解,本身需要倒退去完成这道数独,验证之后才能是完成,这个太复杂,市面上的数独游戏其实都是有题库的,不可能在手机上出题的,题外话。
先看react-native实现的网格布局,用来填充数独的题目。

_renderBoard(id, position, num, ViewId) {
        if (num.type != 0) {
            return (
                <View style={[Styles.Board, position]} key={id}>
                    <Text style={Styles.Text}>
                        {this._showNum(num.num)}
                    </Text>
                </View>
            )
        } else {
            return (
                <View style={[Styles.Board, position, this._chosen(ViewId)]} key={id}>
                    <Text style={[Styles.Text, {color: 'green'}]}
                          onPress={()=>this._click(ViewId)}>
                        {this._showNum(num.num)}
                    </Text>
                </View>
            )
        }
    }

先画好单个格子,比较简单,每个控件需要有一个key,这个地方满坑的,其实这个key没用到,但是如果不传,就会报错,传重复的也会报错。我直接i++传进去的。num会有两个值type是用来判断这个值是不是需要填写的,题目里的数字是不能填写的,就用这个来判断。

//获取数独题目
export function _getSudoku(hard) {
    let Sudoku = _calculateData();
    for (let x = 0; x < 9; x++) {
        for (let y = 0; y < 9; y++) {
            Sudoku[x][y] = {num: Sudoku[x][y], type: 1}
        }
    }
    for (let i = 0; i < hard; i++) {
        let x = Math.floor(Math.random() * 9);
        let y = Math.floor(Math.random() * 9);
        if (Sudoku[x][y].type == 0) {
            i--
        } else {
            Sudoku[x][y] = {num: 0, type: 0};
        }
    }
    console.log(Sudoku);
    return Sudoku;
}

position就是用来排列的位置,这个不多说了,看我的源码吧。

 //循环添加每个格子
    _renderAll() {
        let result = [];
        let i = 0;
        for (let row = 0; row < SIZE; row++) {
            for (let col = 0; col < SIZE; col++) {
                // 位置
                let position = {
                    left: col * BOARDSIZE,
                    top: row * BOARDSIZE,
                }
                position = this._boardBGC(row, col, position)
                let ViewId = [row, col]
                let num = this.state.Sudoku[row][col]
                result.push(this._renderBoard(i++, position, num, ViewId));
                // console.log("position=>>>(" + position.left + "," + position.top + ")")
            }
        }
        return result;
    }

然后绘制下面的键盘,如法炮制,一个是格子,不同的是它有间隔。
键盘点击会有一个动画,这边我觉得react-native的动画用起来不是很舒服,不太好理解。
先在state里初始化10个动画,就是对应十个键

constructor(props) {
        super(props);
        let animated = new Array(10);
        for (var i = 0; i < animated.length; i++) {
            animated[i] = new Animated.Value(0);
        }
        this.state = {animated};
    }

用Animated.View带上动画效果

//数字及取消
    _renderKey(id, position, num) {
        return (
            <Animated.View
                key={id}
                style={[Styles.Key, position]}
                onStartShouldSetResponder={() => this._clickNum(id, num)}>
                <Text style={Styles.Num}>{num}</Text>
            </Animated.View>
        )
    }

然后按键点击后播放动画,就是start

    //点击数字键
    _clickNum(id, num) {
        let animated = this.state.animated[id];
        animated.setValue(1.5);
        Animated.spring(
            animated,
            {
                toValue: 1,
                friction: 3,
            }
        ).start();
        this.props.Num(num);
    }

其他关于逻辑上的处理没有什么难度了,一些样式处理之类。
虽然东西不多,但是界面还是花了差不多一整天时间,如果用原生开发根本用不了这么多时间,而且效果也会更好,当然主要还是对react-native不是很熟悉,写多了可能会好一点。
毕竟拥抱新技术嘛,虽然坑还是不少。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值