试图在画布上画一个精灵,但我遗漏了一些东西

时间:2017-11-18 00:15:53

标签: javascript html canvas



window.onload = function(){
  theVideo();
  playVideo();
  Move();
  Draw();
};
let objectInfo = {
    canvas: null,
    context: null,
    // Number of sprites
    numberOfFrames: 16,        
    image: null,
    imageWidth: 128,
    imageHeight: 192,
    frameIndex: 0,
    frameWidth: 0,
    // Animation interval (ms)
    msInterval: 1000,        
    x: 10,
    y: 10,
};
const imageFile = "shaggy.png";
 function Draw(){
  objectInfo.context.drawImage(myImage, shift, 0, frameWidth, frameHeight, 120, 25, frameWidth, frameHeight);
 }
//image setup
window.onload= function () {

    // Canvas setup
    objectInfo.canvas = document.querySelector("#myCanvas");
    objectInfo.context = objectInfo.canvas.getContext("2d");

    // Image setup
    objectInfo.image = new Image();
    objectInfo.image.onload = function() {

        // The this object refers to image because within image onload event handler
        objectInfo.imageWidth = this.width;
        objectInfo.imageHeight = this.height;

        // Calculate framewidth (size of each sprite)
        objectInfo.frameWidth = objectInfo.imageWidth / objectInfo.numberOfFrames;
    };
    // Load image
    objectInfo.image.src = imageFile;

};

var xPos = 0;
var yPos = 0;

//move image
function Move(e){
  //right
  if(e.keyCode==39){
      xPos+=5;
  }
  //left
  if(e.keyCode==37){
      xPos-=5;
  }
  //up
   if(e.keyCode==38){
      yPos-=5;
   }
   //down
    if(e.keyCode==40){
      yPos+=5;
    }
}

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Sprite</title>
    <meta charset="utf-8">
    <meta name="author" content="Peyton">
    <meta name="description" content="115">
    <link rel= 'stylesheet' href="p4.css">
    <script src="p4.js"> </script>
      <style>canvas { border: 1px solid black; }</style>  
<body>
    <canvas width= "1300" height= "600" id= "myCanvas">

    <video id="video" controls >       
        <source src="ScoobyDooV.mp4"/>
        <source src="ScoobyDooV.ogv"/>
    </video>

    </canvas>
    </body>
  
    </html>
    <nav>
    </nav>
    <main id="#wrapper"><br>
    
    </main>
</body>
</html>
&#13;
&#13;
&#13;

我对编码很陌生,不知道我错过了什么来调用我的精灵并将第一张图片绘制到画布上。我后来不得不调用我的精灵的每个测量并分配给一个函数keydown事件,使它看起来像每个方向走,所以如果我能得到任何指导,那将是伟大的。

enter image description here

3 个答案:

答案 0 :(得分:0)

在加载图片之前,您似乎正在调用Draw。尝试在image.onload方法中放置Draw()调用。

答案 1 :(得分:0)

您要定义window.onload两次,两个回调中只有一个会被执行

答案 2 :(得分:0)

您的代码完全不适合您正在尝试的任务。动画需要定期渲染。您的示例中有大量缺少的代码,因此我可以直接解决任何问题。

所以我想我会举例说明如何加载,动画和渲染精灵表。

精灵表

有许多方法可以处理精灵表,但我发现对所有精灵表使用标准方法可以简化生活。

一些精灵表有一个规则的布局,均匀间隔的精灵,其他精灵表,已经打包在一起,以节省像素和内存。

每个精灵在工作表上都有一个位置,左上角和大小为宽度和高度。

您可以将这些位置的数组附加到图像

例如,下一个函数为常规布局创建精灵(如问题中的图像)

function createSprites(width, height, columns, rows, image) {
  const sprites = [];
  var w = width / columns;
  var h = height / rows;
  var ix, iy;
  for (iy = 0; iy < rows; iy++) {
    for (ix = 0; ix < columns; ix++) {
      const x = ix * w;
      const y = iy * h;
      sprites.push({ x, y, w, h });
    }
  }
  image.sprites = sprites;
}

数组已添加到img中,因此您无需添加其他管理

然后,您可以通过创建自定义绘图功能来绘制精灵。

function drawSprite(img, sprIndex, x, y) {
  const spr = img.sprites[sprIndex];
  ctx.drawImage(img,
    spr.x, spr.y, spr.w, spr.h, // location on sprite sheet
    x , y  ,       // location on canvas
    spr.w, spr.h, // size on canvas;
  );

}

你传递了精灵表图像,精灵数组中的精灵索引以及你想要绘制精灵的位置。

轻松

因为您可能知道精灵表的大小以及精灵的位置,所以您不必等待加载图像以附加精灵数据。

&#13;
&#13;
const ctx = canvas.getContext("2d");
const spriteSheet = new Image;
spriteSheet.src = "https://i.stack.imgur.com/hOrC1.png";
// The image size is known so you dont have to wait for it to load
createSprites(128, 192, 4, 4, spriteSheet); // add a array of sprite locations


// It is important that the sprite sizes are integers
// width must be divisible by columns and height by rows
function createSprites(width, height, columns, rows, image) {
  const sprites = [];
  var w = width / columns;
  var h = height / rows;
  var ix, iy;
  for (iy = 0; iy < rows; iy++) {
    for (ix = 0; ix < columns; ix++) {
      const x = ix * w;
      const y = iy * h;
      sprites.push({ x, y, w, h });
    }
  }
  image.sprites = sprites;
}


function drawSprite(img, sprIndex, x, y) {
  const spr = img.sprites[sprIndex];
  ctx.drawImage(img,
    spr.x, spr.y, spr.w, spr.h, // location on sprite sheet
    x , y , // location on canvas
    spr.w, spr.h, // size on canvas;
  );

}

const walkerInfo = {
  framesPerDir: 4,
  movements: [{x: 0,y: 3 },{ x: -5, y: 0 }, { x: 5, y: 0 }, { x: 0, y: -3 } ],
}
const walker = {
  dir: 0, // 0,1,2,3 
  time: 0, // time in Frames 
  rate: 0, // steps per frame
  x: 0, // position
  y: 0, // 
  update() {
    this.time += 1;
    // only move when sprite frame changes
    if ((this.time % this.rate) === 0) {
      this.x += walkerInfo.movements[this.dir].x;
      this.y += walkerInfo.movements[this.dir].y;
      if(this.x < -128 || this.x > canvas.width ||
         this.y < -192 || this.y > canvas.height) {
         this.x = randI(canvas.width);
         this.y = randI(canvas.height);
         this.dir = randI(4)
         this.rate = randI(6, 12)         
         
      }
    }
    if(randI(1000) === 0){
          this.dir = (this.dir + (randI(2) ? 2 : 1)) % 4;
          this.rate = randI(6, 12)   
    }

    
  },
  draw() {
    var index = this.dir * walkerInfo.framesPerDir;
    index += (this.time / this.rate | 0) % walkerInfo.framesPerDir;
    drawSprite(
      spriteSheet, index,
      this.x, this.y
    );
  }

}

function createWalker(x = randI(w), y = randI(h), dir = randI(4), rate = randI(6, 18)) {
  return { ...walker, x, y, dir, rate, time: randI(100) };
}
const walkers = [];


// main update function
function update(timer) {
  globalTime = timer;
  ctx.setTransform(1, 0, 0, 1, 0, 0); // reset transform
  ctx.globalAlpha = 1; // reset alpha
  if (w !== innerWidth || h !== innerHeight) {
    cw = (w = canvas.width = innerWidth) / 2;
    ch = (h = canvas.height = innerHeight) / 2;
  } else {
    ctx.clearRect(0, 0, w, h);
  }
  
  
  if (spriteSheet.complete) { // has the image loaded
    if (randI(walkers.length) === 0) { // odd 1/100 to create a walker
      walkers.push(createWalker());
    }
    walkers.sort((a,b)=>a.y - b.y);
    eachOf(walkers, walk => walk.update());
    eachOf(walkers, walk => walk.draw());

  }
  requestAnimationFrame(update);
}
requestAnimationFrame(update);



















var w = canvas.width;
var h = canvas.height;
var cw = w / 2; // center 
var ch = h / 2;
var globalTime;


const randI = (min, max = min + (min = 0)) => (Math.random() * (max - min) + min) | 0;
const rand = (min = 1, max = min + (min = 0)) => Math.random() * (max - min) + min;
const eachOf = (array, cb) => {
  var i = 0;
  const len = array.length;
  while (i < len && cb(array[i], i++, len) !== true);
};
&#13;
canvas {
  position: absolute;
  top: 0px;
  left: 0px;
}
&#13;
<canvas id="canvas"></canvas>
&#13;
&#13;
&#13;