Reputation: 687
I am new to game development and I am developing a simple game where I can get a point when I hit the monster by car. So now I want to change the color of the car (if red then blue and vice versa ) when I hit the monster for a while (5 seconds) and then switch back to the original color. I tried with
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
}
}
and then draw with
images.__createImage("background","img[0]");
But it did not work.
My working :pen
Any help is appreciated
Upvotes: 0
Views: 672
Reputation: 618
You were already loading images you need for changing appearance forth and back so that was ok, you don't need to keep url array inside your hero (car) object and loading it again when it is needed.
I have added changeImage
property to your heroDefault (car) so I can mark the object that it needs to check if the image need to be changed back, and I also added changeImageTime
to heroDefault where I store time after the change has to be done, so when car hits a monster I check changeImage
to true
and I set changeImageTime
to Date.now() + 5000
which means I store current time plus 5 seconds (5000ms):
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;
}
Then inside your heroDefault update function I check if there is need to change image back and if the time has passed, if so I change image back and mark the object so it won't compare time no more by setting changeImage
to false.
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);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Simple Canvas Game</title>
</head>
<body>
<script src="game.js"></script>
</body>
</html>
Upvotes: 2