使 canvas 图像重复向上滚动

make canvas image repeat scrolling upwards

所以我有一个 600x2400 的图像,我试图向上滚动(角色将在屏幕上自动运行)并重复。我有滚动,但没有重复。我的问题是,如何从顶部开始重新绘制图像并在结束时继续绘制?到目前为止,当代码到达图像的末尾时,我只是交错地重复了第一个实例滚动的底部部分。

JS

let canvas;
let context;
let secondsPassed;
let oldTimeStamp;
let fps;
let map = new Image();
let roadMovement = 0;
let increment = 2;


window.onload = init;

function init() {
    canvas = document.getElementById('gameCanvas');
    context = canvas.getContext('2d');


    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    window.requestAnimationFrame(gameLoop);
}

function draw() {
    map.src = "map.png";

}


function gameLoop(timeStamp) {
    secondsPassed = (timeStamp - oldTimeStamp) / 1000;
    oldTimeStamp = timeStamp;
    fps = Math.round(1 / secondsPassed);



    roadMovement += increment;

    map.onload = function () {
        context.drawImage(map, 0, roadMovement, 600, 600, 0, 0, canvas.width, canvas.height);
        
    };

    draw();
    window.requestAnimationFrame(gameLoop);
}

CSS

body{
    position: absolute;
    width:100vw;
    height:100vh;
    margin:0;
    padding:0;
    display: flex;
    justify-content: center;
    align-items: center;
}

#gameCanvas{
    position: relative;
    left:0;
    top:0;
    margin:0;
    padding:0;
}

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <link rel="stylesheet" href="style.css">
    <script src="jquery-3.6.0.min.js"></script>
</head>
<body>
    <canvas id="gameCanvas">
    </canvas>

    <script src="script.js"></script>
</body>
</html>

已编辑 为增量值添加了 let,以便可以更改自动滚动速度。

在CSS中直接将图片作为页面背景怎么样?

试试这个:

   body{
        position: absolute;
        width:100vw;
        height:1000vh;
        margin:0;
        padding:0;
        display: flex;
        justify-content: center;
        align-items: center; 
        
        background-image: url('./map.png'); 
        background-repeat: repeat;       
        background-size: 100%;  /*scale the image at 100% of the page width*/
    }

您可以绘制两次地图图像,并在它大于图像高度时随时重置 roadMovement。那时你知道整个图像在 canvas 视图之外。

从技术上讲,您只需要在 imageHeight - roadMovement < canvasHeight 时绘制第二张图像,但可能不值得优化。

let canvas;
let context;
let secondsPassed;
let oldTimeStamp;
let fps;
let map = new Image(600, 600);
map.onload = init;
map.src = "http://www.secretdoors.com/playit/resources/chessboard.gif";

let roadMovement = 0;
let increment = 2;

function init() {
    canvas = document.getElementById('gameCanvas');
    context = canvas.getContext('2d');
    canvas.width = 150;
    canvas.height = 150;
    window.requestAnimationFrame(gameLoop);
}


function gameLoop(timeStamp) {
    secondsPassed = (timeStamp - oldTimeStamp) / 1000;
    oldTimeStamp = timeStamp;
    fps = Math.round(1 / secondsPassed);

    roadMovement += increment;
    roadMovement %= map.naturalHeight;
    
    const y1 = roadMovement;
    const y2 = y1 - map.naturalHeight;

    context.clearRect(0, 0, 600, 600);

    context.drawImage(
      map,
      0, y1, map.naturalWidth, map.naturalHeight
    );
    
    context.drawImage(
      map,
      0, y2, map.naturalWidth, map.naturalHeight
    );
    
    window.requestAnimationFrame(gameLoop);
}
#gameCanvas{
  width: 150px;
  height: 150px;
  border: 1px solid red;
}
<canvas id="gameCanvas">
</canvas>