简体   繁体   English

HTML5 Canvas:在画布的边缘周围绘制形状

[英]HTML5 Canvas: Drawing shapes around edges of the canvas

I'm creating a basic game that draws squares at random positions on a canvas, but sometimes the shape gets cut off because it's outside of the canvas' boundaries. 我正在创建一个基本游戏,该游戏在画布上的任意位置绘制正方形,但是有时形状会被切除,因为它在画布的边界之外。 Can any one explain how I could go about getting the square to be drawn on the other side of the canvas (similar to how it's done in asteroids )? 谁能解释一下如何在画布的另一侧绘制正方形(类似于在小行星中的绘制方法)? The searches I've come up with haven't been helpful. 我提出的搜索没有帮助。 Any help is appreciated. 任何帮助表示赞赏。

OK I think I've solved this one. 好的,我想我已经解决了这一问题。 Basically this code only draws the square whilst it is inside the canvas, if it leaves the canvas it checks which boundaries it is leaving and updates the position. 基本上,此代码仅在正方形在画布内部时才绘制正方形,如果它离开画布,则会检查其离开的边界并更新位置。 The looped variable is needed because otherwise the square will be always leaving the canvas. 需要使用循环变量,因为否则正方形将始终离开画布。

var canvas = document.getElementById('bg');
var ctx = canvas.getContext('2d');

var squares = [];
squares[squares.length] = new Square(200, 200, 20, 'red', 0.785398164);

function Square(x, y, size, colour, angle)
{
    this.x = x;
    this.y = y;
    this.size = size;
    this.colour = colour;
    this.speed = 5;
    this.angle = angle;
    this.looped = false;
}

Square.prototype.update = function()
{
    this.x += (Math.cos(this.angle) * this.speed);
    this.y += (Math.sin(this.angle) * this.speed);
    if (this.x < canvas.width && this.x + this.size > 0 &&
        this.y < canvas.height && this.y + this.size > 0)
    {
        this.draw();
        this.looped = false;
    }
    else
    {
        if (this.x > canvas.width && !this.looped)
        {
            this.x = -this.size;
        }
        if (this.x + this.size < 0 && !this.looped)
        {
            this.x = this.size + canvas.width;
        }
        if (this.y > canvas.height && !this.looped)
        {
            this.y = -this.size;
        }
        if (this.y + this.size < 0 && !this.looped)
        {
            this.y = this.size + canvas.height;
        }
        this.looped = true;
    }
}

Square.prototype.draw = function()
{
    ctx.fillStyle = this.colour;
    ctx.fillRect(this.x, this.y, this.size, this.size);
}

function gameLoop()
{
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    for (var i = 0; i < squares.length; i++)
    {
        squares[i].update();
    }
    requestAnimationFrame(gameLoop);
}

gameLoop();

(function()
{
    // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x)
    {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element)
    {
        var currTime = new Date().getTime();
        var timeToCall = Math.max(0, 16 - (currTime - lastTime));
        var id = window.setTimeout(function()
        {
            callback(currTime + timeToCall);
        }, timeToCall);
        lastTime = currTime + timeToCall;
        return id;
    };

    if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id)
    {
        clearTimeout(id);
    };
}());

I'd do a JSFiddle but requestAnimationFrame doesn't play nice with it. 我会做一个JSFiddle,但是requestAnimationFrame不能很好地使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM