如何使视口遵循此javascript代码中的rect?

时间:2017-07-15 04:57:19

标签: javascript html css animation canvas

我创建了一些Javascript代码,可以在屏幕上绘制一个正方形并永久地向上设置动画。我想要的是广场留在屏幕的中心,而它周围的世界(画布)向下移动,给人一种幻觉,即广场无限向上移动。问题是,我不知道如何做到这一点,任何帮助将不胜感激!

我的代码



var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var rectWidth = 50;
var rectHeight = 50;
var rectRad = 25;
var x = (canvas.width/2)-rectRad;
var y = canvas.height-rectHeight;
var dx = 2;
var dy = 4;
var ch = canvas.height;

function rect() {
	ctx.beginPath();
	ctx.rect(x, y, rectWidth, rectHeight);
	ctx.fillStyle = "#0095DD";
	ctx.fill();
	ctx.closePath();
}

function draw() {
	ctx.clearRect(0, 0, canvas.width, canvas.height);
	rect();

	if(y + dy < 0) {
		ch += 4;
	}

	if(y + dy > canvas.height-rectHeight) {
		dy = -dy;
	}

	y += dy;
}
setInterval(draw, 10);
&#13;
* { padding: 0; margin: 0; }
		canvas { background: #eee; display: block; margin: 0 auto; }
&#13;
<!DOCTYPE html>

<html>

<head>
	<meta charset="utf-8" />
	<title>Game</title>
	
	<style>
		* { padding: 0; margin: 0; }
		canvas { background: #eee; display: block; margin: 0 auto; }
	</style>

</head>
<body>

<canvas id="myCanvas" width="480" height="320"></canvas>

<script src="gameJS.js"></script>

</body>

</html>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

您只需绘制所需的背景并按照您想要的速度转换背景y位置。

这通常被称为相机。当方形(或播放器实体)位于屏幕中间时,相机处理x和y位置的平移。

您还需要确保视口始终可见背景(图像,颜色,图案)。

我会给你一个示例相机,我用一个用打字稿编写的测试游戏引擎来翻译坐标。

/**
 * calculates the position offset for camera following
 */
private static calculatePositionOffsetForCameraFollow(originalPosition: Vector2D, camera: Camera): Vector2D {

    // first check if there is any following
    let entity = camera.getFollowingEntity();

    // if no following is active, return the original position
    if (!entity) return originalPosition;

    // calculate the offset. the entity should be in the center of the screen
    let canvasDim = CameraOffsetCalculator.getCanvasDimension();

    // calculate the center position for the entity and shift the other
    // vectors.
    let tmpVector = originalPosition.substract(entity.getPosition()).add(
        canvasDim.divide(new Vector2D(2, 2))
    );

    // now check if the camera has world bounds
    let worldBounds = camera.getWorldBounds();
    if (!worldBounds) return tmpVector;

    // check if the original vector is smaller than the shifted vector
    // this will bound the left and top world bounds
    if (originalPosition.x < tmpVector.x) {

        // reset the x axis to fix the camera
        tmpVector.x = originalPosition.x;
    }

    if (originalPosition.y < tmpVector.y) {

        // reset the y axis to fix the camera
        tmpVector.y = originalPosition.y;
    }

    // now the left and bottom bounds
    // we need the world dimension to check if the camera reaches
    // the end of the world in the visible area
    let entityPosition = entity.getPosition();
    let worldBoundCanvas = worldBounds.substract(canvasDim.half());

    if (entityPosition.x > worldBoundCanvas.x) {

        // get the original position and substract
        // the distance from world bounds and canvas dim
        tmpVector.x = originalPosition.x - (worldBounds.x - canvasDim.x);
    }

    if (entityPosition.y > worldBoundCanvas.y) {

        // get the original position and substract
        // the distance from world bounds and canvas dim
        tmpVector.y = originalPosition.y - (worldBounds.y - canvasDim.y);
    }

    // return the corrected position vector
    return tmpVector;
}

此函数返回背景图像或图块的新点,以便在跟随实体(在您的情况下为正方形)时绘制。

请告诉我这是否对您有帮助!

以下是使用非常简化的相机在代码中集成的错觉:

    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d");
    var rectWidth = 50;
    var rectHeight = 50;
    var rectRad = 25;
    var x = (canvas.width / 2) - rectRad;
    var y = (canvas.height / 2) - rectHeight;
    //var dx = 2;
    //var dy = 4;
    var ch = canvas.height;

    // should be lower than bgHeight
    var scrollSpeed = .0475;

    // a boolean to make the background shifts differently at
    // y position to make the user think the player entity is moving
    // forwards
    var scroller = 0;

    // the repeating background
    var bg = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAQCAMAAAA7+k+nAAAAKlBMVEXx8fH7+/v8/Pz5+fn29vb39/f19fXz8/P4+Pj6+vr09PTy8vL////o6OgghGlxAAAAk0lEQVR42nWPSQ7DMAwDZWujxPj/363dS1qk1YkCwQFG1p+Tdd33mXcxIppoSa4r0R6ZAHfR1kUwI9ZVLBpnu8p+nEGWY67LfXZijDyLgHmd2UEd7Hu2Czc4kE7d2MyATqk6qMgaraq984SWear99/g2uLMEaOTTRmSMgD1tRNsQ82kjnuX6w0ZazeSHjdAsE0+bFzAoDXEZIyZUAAAAAElFTkSuQmCC";
    var bgBitmap = createImageBitmap(b64ToBlob(bg, "image/png"));

    function rect() {
        ctx.beginPath();
        ctx.rect(x, y, rectWidth, rectHeight);
        ctx.fillStyle = "#0095DD";
        ctx.fill();
        ctx.closePath();
    }

    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        // first draw the background
        drawBackground();

        // and now the rectangle
        rect();
    }

    function drawBackground() {

        var bgWidth = 14, bgHeight = 14;

        // draw the full visible screen and on each edge, draw another tile
        // to make a smooth scrolling
        for (var x = -1; x < canvas.width / bgWidth; x++) {
            for (var y = -1; y < canvas.height / bgHeight; y++) {

                var yCorrectedCoordinate = y + (scroller * scrollSpeed);

                // draw!
                ctx.drawImage(
                    bgBitmap, x * bgWidth, yCorrectedCoordinate * bgHeight,
                    bgWidth, bgHeight
                );
            }
        }

        // change the scroller offset
        scroller++;
        if (scroller > 20)
            scroller = 0;
    }

    /**
    * converts a base64 string to a blob image capable for using in canvas environment
    * @see https://stackoverflow.com/questions/16245767/creating-a-blob-from-a-base64-string-in-javascript
    */
    function b64ToBlob(b64Data, contentType, sliceSize) {

        contentType = contentType || '';
        sliceSize = sliceSize || 512;

        var byteCharacters = atob(b64Data.split(',')[1]);
        var byteArrays = [];

        for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
            var slice = byteCharacters.slice(offset, offset + sliceSize);

            var byteNumbers = new Array(slice.length);
            for (var i = 0; i < slice.length; i++) {
                byteNumbers[i] = slice.charCodeAt(i);
            }

            var byteArray = new Uint8Array(byteNumbers);

            byteArrays.push(byteArray);
        }

        var blob = new Blob(byteArrays, { type: contentType });
        return blob;
    }

    // start the game loop after the image has beed loaded
    bgBitmap.then(function (bg) {

        bgBitmap = bg;
        setInterval(draw, 10);
    });

    // i would recommend to use window.requestAnimationFrame() instead

如果还有其他关于游戏开发的问题,请访问我的存储库:qhun-engine at Github.com