const { ccclass, property } = cc._decorator;

type Option = "平均" | "正态";
const options: Array<Option> = ["平均", "正态"];
let currOption: Option;
let optionIndex: number = -1;

const g = -1;

@ccclass
export default class Test extends cc.Component {

    @property(cc.Prefab)
    private dot_prefab: cc.Prefab = null;

    private container: cc.Node;
    private label: cc.Label;

    private dots: Array<Dot>;
    private nums: Array<number>;

    protected start(): void {
        this.container = this.node.getChildByName("container");
        this.label = this.node.getChildByName("label").getComponent(cc.Label);
        this.label.node.on(cc.Node.EventType.TOUCH_START, () => {
            this.nextOption();
        });
        this.nextOption();
    }

    private nextOption(): void {
        this.dots = [];
        this.nums = [];
        this.container.destroyAllChildren();
        if (++optionIndex >= options.length) {
            optionIndex = 0;
        }
        currOption = options[optionIndex];
        this.label.string = currOption + "（点击切换）";
    }

    protected update(): void {
        for (let i: number = 0; i < 20; i++) {
            const dot = new Dot(cc.instantiate(this.dot_prefab));
            this.container.addChild(dot.node);
            this.dots.push(dot);
        }
        let i: number = this.dots.length;
        while (i--) {
            const dot = this.dots[i];
            dot.node.x += dot.vx;
            dot.node.y += dot.vy;
            dot.vy += g;
            if (dot.node.y < -500) {
                this.dots.splice(i, 1);
                const x = Math.round(dot.node.x);
                if (this.nums[x] > 0) {
                    this.nums[x] += 4;
                } else {
                    this.nums[x] = 4;
                }
                dot.node.y = -500 + this.nums[x];
            }
        }
    }

}

class Dot {

    public node: cc.Node;

    public vx: number;
    public vy: number;

    public constructor(node: cc.Node) {
        this.node = node;
        switch (currOption) {
            case "平均":
                this.vx = (Math.random() - 0.5) * 20;
                break;
            case "正态":
                this.vx = Math.sqrt(-2 * Math.log(Math.random())) * Math.cos(Math.PI * 2 * Math.random()) * 5;
                break;
        }
        this.vy = 0;
    }

}
