改变定时器的速度

时间:2017-12-29 12:18:28

标签: angular typescript canvas timer

我有一个正常运行的代码。此代码在屏幕上绘制带有随机坐标的圆圈。代码如下所示:

.TS

import { Component, NgZone, HostListener, OnInit } from '@angular/core';
import { DomSanitizationService } from '@angular/platform-browser';
import { bootstrap } from '@angular/platform-browser-dynamic';
import {SimpleTimer} from 'ng2-simple-timer';

@Component({
selector: 'canvas_game_component',
templateUrl: 'WebSite/Components/CanvasGameComponent/CanvasGame.html',
styleUrls: ['WebSite/Components/CanvasGameComponent/CanvasGame.css']
})

export class CanvasGameComponent {
public ComponentShapes: Shapes.Shape[] = [];
public Score: number = 0;
public TimeOfRefreshCanvasShapes;
public TimeOfAddShapesToComponentShape;
public TimeOfDecreaseXCoordinateOfShapes;

constructor() {

}
public Start() {
    this.TimeOfAddShapesToComponentShape = setInterval(() => {
        this.AddShapesToComponentShape();
    }, 350);
    this.TimeOfRefreshCanvasShapes = setInterval(() => {
        this.RefreshCanvasShapes();
    }, 50);
}

public AddShapesToComponentShape() {
    var yCordinateOfCircle: number = Math.floor((Math.random() * 140) + 5);
    var xCordinateOfCircle: number = Math.floor((Math.random() * 200) + 5);
    var circle: Shapes.Circle = new Shapes.Circle(xCordinateOfCircle, yCordinateOfCircle, 10);
    this.ComponentShapes.push(circle);
}

public RefreshCanvasShapes() {
    var canvas: HTMLCanvasElement = document.getElementById("shape_canvas") as HTMLCanvasElement;
    var context: CanvasRenderingContext2D = canvas.getContext("2d") as CanvasRenderingContext2D;
    context.clearRect(0, 0, 1000, 500);
    var i: number;
    this.Score++;
    for (i = 1; i < this.ComponentShapes.length; i++) {
        var probability: number = Math.floor((Math.random() * 100) + 1);
        this.ComponentShapes[i].Draw(context);
    }
}
}

module Shapes {
export class Shape {
    public XCoordinate: number = 0;
    public YCoordinate: number = 0;

    constructor(xCoordinate: number, yCoordinate: number) {
        this.XCoordinate = xCoordinate;
        this.YCoordinate = yCoordinate;
    }

    public Draw(context: CanvasRenderingContext2D) {

    }
}

export class Circle extends Shape {
    private Size: number = 0;

    constructor(xCoordinate: number, yCoordinate: number, size: number) {
        super(xCoordinate, yCoordinate);
        this.Size = size;
    }

    public Draw(context: CanvasRenderingContext2D) {
        context.beginPath();
        context.fillStyle = "white";
        context.strokeStyle = "white";
        context.arc(this.XCoordinate, this.YCoordinate, this.Size / 2, 0, 2 * Math.PI);
        context.closePath();
        context.fill();
        context.lineWidth = this.Size / 14;
        context.stroke();
    }
}
}

html的

<div id="canvas_component" class="canvas_component_class">
<div class="menu_side_class">
    <button (click)="Start()">
        click
    </button>
    <a>{{Score}}</a>
</div>
<canvas id="shape_canvas" class="shape_canvas_class"></canvas>
</div>

的CSS

.canvas_game_component {
width: 100%;
height: 100%;
}

.menu_side_class {
width: 100%;
height: 50px;
background-color: green;
}

.shape_canvas_class {

background-color: black;
width: 100%;
height: calc(100% - 50px)
}

我想在分数为200和400和600时更改定时器的速度。我已为此更新了代码。

import { Component, NgZone, HostListener, OnInit } from '@angular/core';  
import { DomSanitizationService } from '@angular/platform-browser';
import { bootstrap } from '@angular/platform-browser-dynamic';
import {SimpleTimer} from 'ng2-simple-timer';

@Component({
selector: 'canvas_game_component',
templateUrl: 'WebSite/Components/CanvasGameComponent/CanvasGame.html',
styleUrls: ['WebSite/Components/CanvasGameComponent/CanvasGame.css']
})

export class CanvasGameComponent {
public ComponentShapes: Shapes.Shape[] = [];
public Score: number = 0;
public TimeOfRefreshCanvasShapes;
public TimeOfAddShapesToComponentShape;
public TimeOfDecreaseXCoordinateOfShapes;

constructor() {

}
public Start() {
    this.TimeOfAddShapesToComponentShape = setInterval(() => {
        this.AddShapesToComponentShape();
    }, 350);
    this.TimeOfRefreshCanvasShapes = setInterval(() => {
        this.RefreshCanvasShapes();
    }, 50);
}

public AddShapesToComponentShape() {
    var yCordinateOfCircle: number = Math.floor((Math.random() * 140) + 5);
    var xCordinateOfCircle: number = Math.floor((Math.random() * 200) + 5);
    var circle: Shapes.Circle = new Shapes.Circle(xCordinateOfCircle, yCordinateOfCircle, 10);
    this.ComponentShapes.push(circle);
}

public IncreaseSpeed() {
    if (this.Score > 200 && this.Score < 300) {
        clearInterval(this.TimeOfAddShapesToComponentShape);
        clearInterval(this.TimeOfRefreshCanvasShapes);
        this.TimeOfAddShapesToComponentShape = setInterval(() => {
            this.AddShapesToComponentShape();
        }, 300);
        this.TimeOfRefreshCanvasShapes = setInterval(() => {
            this.RefreshCanvasShapes();
        }, 40);
    }
    else if (this.Score > 300 && this.Score < 400) {
        clearInterval(this.TimeOfAddShapesToComponentShape);
        clearInterval(this.TimeOfRefreshCanvasShapes);
        this.TimeOfAddShapesToComponentShape = setInterval(() => {
            this.AddShapesToComponentShape();
        }, 200);
        this.TimeOfRefreshCanvasShapes = setInterval(() => {
            this.RefreshCanvasShapes();
        }, 30);
    }
    else if (this.Score > 400 && this.Score < 500) {
        clearInterval(this.TimeOfAddShapesToComponentShape);
        clearInterval(this.TimeOfRefreshCanvasShapes);
        this.TimeOfAddShapesToComponentShape = setInterval(() => {
            this.AddShapesToComponentShape();
        }, 100);
        this.TimeOfRefreshCanvasShapes = setInterval(() => {
            this.RefreshCanvasShapes();
        }, 20);
    }
}

public RefreshCanvasShapes() {
    var canvas: HTMLCanvasElement = document.getElementById("shape_canvas") as HTMLCanvasElement;
    var context: CanvasRenderingContext2D = canvas.getContext("2d") as CanvasRenderingContext2D;
    context.clearRect(0, 0, 1000, 500);
    var i: number;
    this.Score++;    
    this.IncreaseSpeed();  
    for (i = 1; i < this.ComponentShapes.length; i++) {
            var probability: number = Math.floor((Math.random() * 100) + 1);
            this.ComponentShapes[i].Draw(context);
    }
}
}

module Shapes {
export class Shape {
    public XCoordinate: number = 0;
    public YCoordinate: number = 0;

    constructor(xCoordinate: number, yCoordinate: number) {
        this.XCoordinate = xCoordinate;
        this.YCoordinate = yCoordinate;
    }

    public Draw(context: CanvasRenderingContext2D) {

    }
}

export class Circle extends Shape {
    private Size: number = 0;

    constructor(xCoordinate: number, yCoordinate: number, size: number) {
        super(xCoordinate, yCoordinate);
        this.Size = size;
    }

    public Draw(context: CanvasRenderingContext2D) {
        context.beginPath();
            context.fillStyle = "white";
            context.strokeStyle = "white";
        context.arc(this.XCoordinate, this.YCoordinate, this.Size / 2, 0, 2 * Math.PI);
        context.closePath();
        context.fill();
        context.lineWidth = this.Size / 14;
        context.stroke();
    }
}
}

但是当分数为200时,程序将停止绘制圆圈。但是当分数超过500时,它会再次开始绘制圆圈。我停止调用AddShapesToComponentShape()函数的计时器。我改变了计时器的时间并再次启动它。但它并没有增加圈子。我做错了什么?或者我怎么能做我想做的事情?谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

没有看到任何内容的原因是因为在添加新形状之前关闭了计时器。当分数超过500时,您不再清除计时器,并且添加形状函数被称为

从您的代码中

resources.myhost.com

我无法修复您的代码,因为您正在执行的操作始终存在各种问题。您需要使用requestAnimationFrame使用单个动画循环,该动作循环在1/60秒触发。

从那个循环中你渲染并照顾任何产卵。该示例每300ms产生一次。任何定时误差都不会累积,只要你没有设置速度快于17ms就会保持平均产卵率

public IncreaseSpeed() {
    if (this.Score > 200 && this.Score < 300) {
        // clears both timers not giving add shape timer a chance to be called.
        clearInterval(this.TimeOfAddShapesToComponentShape);
        clearInterval(this.TimeOfRefreshCanvasShapes);

        // This will be called every 300 ms 
        this.TimeOfAddShapesToComponentShape = setInterval(() => {
            this.AddShapesToComponentShape();
        }, 300);  // << 300ms will happen after the 40ms 

        // this will be called in 40 ms
        // when it does the function RefreshCanvasShapes calls
        // IncreaseSpeed (this function) which clears the 
        // timer TimeOfAddShapesToComponentShape
        this.TimeOfRefreshCanvasShapes = setInterval(() => {
            this.RefreshCanvasShapes();
        }, 40);
    }