如何在画布中将图像更改为另一个图像一段时间后再更改回来

时间:2017-04-24 00:01:51

标签: javascript html5 canvas

我是游戏开发的新手,我正在开发一个简单的游戏,当我开车撞到怪物时,我可以得到一个点。所以现在我想改变汽车的颜色(如果是红色然后是蓝色,反之亦然)当我击中怪物一段时间(5秒)然后切换回原始颜色。我试过

var myObj = {
    imgs: ["http://res.cloudinary.com/dfhppjli0/image/upload/c_scale,w_2048/v1492045665/road_dwsmux.png", "http://res.cloudinary.com/dfhppjli0/image/upload/c_scale,w_32/v1491958999/car_p1k2hw.png","http://res.cloudinary.com/dfhppjli0/image/upload/v1491958478/monster_rsm0po.png","http://res.cloudinary.com/dfhppjli0/image/upload/v1492579967/car_03_ilt08o.png"], 
    currentImg: 0, 
    draw: function(){
        ctx.drawImage(this.imgs[this.currentImg], this.x, this.y)
    }, 
    changeImg: function(index){
        this.currentImg = index
    }
}

然后用

画画
images.__createImage("background","img[0]");

但它不起作用。

我的工作:pen

感谢任何帮助

1 个答案:

答案 0 :(得分:2)

您已经加载了前后更改外观所需的图像,这样就可以了,您不需要将url数组保留在您的英雄(汽车)对象中,并在需要时再次加载。

我已将changeImage属性添加到你的heroDefault(car)中,因此我可以标记需要检查图像是否需要更改的对象,并且我还将changeImageTime添加到heroDefault其中我必须在完成更改后存储时间,所以当汽车撞到怪物时,我会检查changeImagetrue并将changeImageTime设置为Date.now() + 5000,这意味着我存储当前时间再加上5秒(5000毫秒):

if (monster.isTouching(this)) {
    monster.reset();
    monstersCaught += 1;

    this.changeImage = true;
    this.changeImageTime = Date.now() + 5000; //5 sec from now.
    this.image = (this.image === images.hero)? images.hero_other : images.hero;
}

然后在你的heroDefault更新函数中,我检查是否需要更改图像,如果时间已经过去,如果是,我将图像更改回来并标记对象,以便不再通过设置{{1来比较时间错误。

changeImage

if(this.changeImage){
    if(Date.now() > this.changeImageTime){
        this.changeImage = false;
        this.image = (this.image === images.hero)? images.hero_other : images.hero;
    }
}
// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 2048;
canvas.height = 1024;
document.body.appendChild(canvas);
var monstersCaught = 0;
var lastFrameTime;
var frameTime = 0; // in seconds used to control hero speed

// The main game loop
function main(time) {
  if (lastFrameTime !== undefined) {
    frameTime = (time - lastFrameTime) / 1000; // in seconds
  }
  lastFrameTime = time
  updateObjects();
  render();
  requestAnimationFrame(main);
};

// this is called when all the images have loaded
function start() {
  monstersCaught = 0;
  resetObjs();
  requestAnimationFrame(main);
}

function displayStatus(message) {
  ctx.setTransform(1, 0, 0, 1, 0, 0); // set default transform
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = "black";
  ctx.font = "24px Helvetica";
  ctx.textAlign = "center";
  ctx.textBaseline = "center";
  ctx.fillText(message, canvas.width / 2, canvas.height / 2);
}
// reset objects
function resetObjs() {
  monsters.array.forEach(monster => monster.reset());
  heros.array.forEach(hero => hero.reset());
}

// Update game objects
function updateObjects(modifier) {

  monsters.array.forEach(monster => monster.update());
  heros.array[0].update('random');
  heros.array[1].update('random');
  heros.array[2].update('random');
  heros.array[3].update('random');
  heros.array[4].update('random');
  heros.array[5].update('random');
  heros.array[6].update('random');
  heros.array[7].update('random');


}

function drawObjects(modifier) {
  monsters.array.forEach(monster => monster.draw());
  heros.array.forEach(hero => hero.draw());

}

// Draw everything
function render() {
  ctx.setTransform(1, 0, 0, 1, 0, 0); // set default transform
  ctx.drawImage(images.background, 0, 0);
  drawObjects();

  // Score
  ctx.setTransform(1, 0, 0, 1, 0, 0); // set default transform
  ctx.fillStyle = "rgb(250, 250, 250)";
  ctx.font = "24px Helvetica";
  ctx.textAlign = "left";
  ctx.textBaseline = "top";
  ctx.fillText("points : " + monstersCaught, 32, 32);
}

// hold all the images in one object.
const images = { // double underscore __ is to prevent adding images that replace these functions
  __status: {
    count: 0,
    ready: false,
    error: false,
  },
  __onready: null,
  __createImage(name, src) {
    var image = new Image();
    image.src = src;
    images.__status.count += 1;
    image.onerror = function() {
      images.__status.error = true;
      displayStatus("Error loading image : '" + name + "'");
    }
    image.onload = function() {
      images.__status.count -= 1;
      if (images.__status.count === 0) {
        images.__status.ready = true;
        images.__onready();
      }
      if (!images.__status.error) {
        displayStatus("Images remaing : " + images.__status.count);
      }
    }
    images[name] = image;
    return image;
  }
}

// Handle all key input
const keys = { // key input object
  ArrowLeft: false, // only add key names you want to listen to
  ArrowRight: false,
  ArrowDown: false,
  ArrowUp: false,
  keyEvent(event) {
    if (keys[event.code] !== undefined) { // are we interested in this key
      keys[event.code] = event.type === "keydown";
      event.preventDefault();
    }
  }
}

// default setting for objects
const objectDefault = {
  x: 0,
  y: 0,
  dir: 0, // the image rotation
  isTouching(obj) { // returns true if object is touching box x,y,w,h
    return !(this.x > obj.x + obj.w || this.y > obj.y + obj.h || this.x + this.w < obj.x || this.y + this.h < obj.y);
  },
  draw() {
    ctx.setTransform(1, 0, 0, 1, this.x + this.w / 2, this.y + this.h / 2);
    ctx.rotate(this.dir);
    ctx.drawImage(this.image, -this.image.width / 2, -this.image.height / 2);
  },
  reset() {},
  update() {},
}

// default setting for monster object
const monsterDefault = {
  w: 32, // width 
  h: 32, // height
  reset() {
    this.x = this.w + (Math.random() * (canvas.width - this.w * 2));
    this.y = this.h + (Math.random() * (canvas.height - this.h * 2));
  },
}

// default settings for hero
const heroDefault = {
  w: 32, // width 
  h: 32, // height
  speed: 256,
  spawnPos: 1.5,
  distanceTraveledInOneDirection: 0,
  autoDirection: 'right',
  changeImage: false, // If true, will check if changeImageTime passed and image needs to be changed
  changeImageTime: 0, // Time after image will be changed
  reset() {
    this.x = canvas.width / this.spawnPos;
    this.y = canvas.height / this.spawnPos;
    this.autoDirection = 'right';
    this.distanceTraveledInOneDirection = 0;
  },
  auto() {
    this.y -= this.speed * frameTime;
  },
  update(dir) {
    this.distanceTraveledInOneDirection += this.speed * frameTime;
    if (dir === 'random') {
      dir = this.autoDirection; //set new direction
      if (this.distanceTraveledInOneDirection > 300) { //make this random or use a timestamp instead of distance if you want
        this.autoDirection = ['up', 'down', 'right', 'left','right','down','left','up'][Math.floor(Math.random() * 4)]; //we have traveled in one direction long enough, time to roll dice and change direction.
        dir = this.autoDirection; //set new direction
        this.distanceTraveledInOneDirection = 0;
      }
    }
    if (!dir) {
      if (keys.ArrowUp) dir = 'up'
      if (keys.ArrowDown) dir = 'down'
      if (keys.ArrowLeft) dir = 'left'
      if (keys.ArrowRight) dir = 'right'
    }
    if (dir === 'up') { // Player holding up
      this.y -= this.speed * frameTime;

      this.dir = Math.PI * 0; // set direction
    }
    if (dir === 'down') { // Player holding down
      this.y += this.speed * frameTime;
      this.dir = Math.PI * 1; // set direction
    }
    if (dir === 'left') { // Player holding left
      this.x -= this.speed * frameTime;
      this.dir = Math.PI * 1.5; // set direction
    }
    if (dir === 'right') { // Player holding right
      this.x += this.speed * frameTime;
      this.dir = Math.PI * 0.5; // set direction
    }
    if (Math.sign(this.speed) === -1) { // filp directio of second car
      this.dir += Math.PI; // set direction
    }

    monsters.array.forEach(monster => {
      if (monster.isTouching(this)) {
        monster.reset();
        monstersCaught += 1;
        this.changeImage = true;
        this.changeImageTime = Date.now() + 5000; //5 sec from now.
        this.image = (this.image === images.hero)? images.hero_other : images.hero;
      }
    });
    if (this.x >= canvas.width || this.y >= canvas.height || this.y < 0 || this.x < 0) {
      this.reset();
    }
    
    if(this.changeImage){
      if(Date.now() > this.changeImageTime){
        this.changeImage = false;
        this.image = (this.image === images.hero)? images.hero_other : images.hero;
      }
    }
  }
}

// objects to hold monsters and heros
const monsters = { // dont call a monster "array"
  array: [], // copy of monsters as array    
};

const heros = { // dont call a monster "array"
  array: [], // copy of heros as array
};

// add monster 
function createMonster(name, settings = {}) {
  monsters[name] = Object.assign({}, objectDefault, monsterDefault, settings, {
    name
  });
  //monsters[name] = {...objectDefault, ...monsterDefault, ...settings, name};
  monsters[name].reset();
  monsters.array.push(monsters[name]);
  return monsters[name];
}

// add hero to heros object
function createHero(name, settings) {

  heros[name] = Object.assign({}, objectDefault, heroDefault, settings, {
    name
  });
  //heros[name] = {...objectDefault, ...heroDefault, ...settings, name};
  heros[name].reset();
  heros.array.push(heros[name]);
  return heros[name];
}

// set function to call when all images have loaded
images.__onready = start;

// load all the images
images.__createImage("background", "http://res.cloudinary.com/dfhppjli0/image/upload/c_scale,w_2048/v1492045665/road_dwsmux.png");
images.__createImage("hero", "http://res.cloudinary.com/dfhppjli0/image/upload/c_scale,w_32/v1491958999/car_p1k2hw.png");
images.__createImage("monster", "http://res.cloudinary.com/dfhppjli0/image/upload/v1491958478/monster_rsm0po.png");
images.__createImage("hero_other", "http://res.cloudinary.com/dfhppjli0/image/upload/v1492579967/car_03_ilt08o.png");

// create all objects
createHero("hero", {
  image: images.hero,
  spawnPos: 1.5
});

createHero("hero3", {
  image: images.hero,
  spawnPos: 2
});
createHero("hero9", {
  image: images.hero_other,
  spawnPos: 2.6
});
createHero("hero12", {
  image: images.hero,
  spawnPos: 1.75
});
createHero("hero15", {
  image: images.hero,
  spawnPos: 1.8
});
createHero("hero18", {
  image: images.hero,
  spawnPos: 2.4
});
createHero("hero21", {
  image: images.hero_other,
  spawnPos: 2.8
});
createHero("hero24", {
  image: images.hero,
  spawnPos: 1.9
});

createMonster("monster", {
  image: images.monster,
});
createMonster("monster3", {
  image: images.monster
});
createMonster("monster9", {
  image: images.monster
});
createMonster("monster12", {
  image: images.monster
});
createMonster("monster15", {
  image: images.monster
});
createMonster("monster18", {
  image: images.monster
});

// add key listeners
document.addEventListener("keydown", keys.keyEvent);
document.addEventListener("keyup", keys.keyEvent);
canvas.addEventListener('click', function(event) {
    createMonster("monster24", {
  image: images.monster
});

}, false);