gpt4 book ai didi

javascript - 如何使视口(viewport)跟随此 javascript 代码中的矩形?

转载 作者:行者123 更新时间:2023-11-28 03:23:22 25 4
gpt4 key购买 nike

我已经创建了一些 Javascript 代码,可以在屏幕上绘制一个正方形并使其永久向上动画。我想要的是让正方形保持在屏幕中央,而它周围的世界( Canvas )向下移动,给人一种正方形无限向上移动的错觉。问题是,我不知道该怎么做,任何帮助将不胜感激!

我的代码

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);
* { padding: 0; margin: 0; }
canvas { background: #eee; display: block; margin: 0 auto; }
<!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>

最佳答案

您只需要绘制设计的背景,并按照您想要的速度平移背景的 y 位置。

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

您还需要确保您的背景(图像、颜色、图案)在视口(viewport)中始终可见。

我会给你一个我为用 typescript 编写的测试游戏引擎制作的示例相机来转换坐标。

/**
* 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;
}

此函数返回一个新点,供背景图像或图 block 在跟随实体(在您的例子中为正方形)时绘制。

如果对您有帮助,请告诉我!

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

    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

关于javascript - 如何使视口(viewport)跟随此 javascript 代码中的矩形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45114651/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com