按下左或右键时,仅在画布中旋转特定图像

时间:2017-04-12 01:50:50

标签: javascript html5 canvas

我是画布并开发一款汽车直行的游戏,现在我想旋转汽车的图像,只有在按下左键时逆时针旋转,按下右键时顺时针旋转。

目前我正在尝试

var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");



var heroReady = false;
var heroImage = new Image();
heroImage.onload = function () {
    heroReady = true;
};
heroImage.src = "images/car.png";
  if (37 in keysDown) { // Player holding left
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.save();
    ctx.translate(canvas.width,canvas.height);
    ctx.rotate(90*Math.PI/180);
    ctx.drawImage(heroImage,hero.x,hero.y);    
}

但是这会旋转整个屏幕。我只想要旋转heroImage而不是屏幕。任何帮助都表示赞赏。 我的源代码:working pen

1 个答案:

答案 0 :(得分:0)

获取键输入和旋转路径以及画布上没有的内容。



/** SimpleUpdate.js begin **/
// short cut vars 
var ctx = canvas.getContext("2d");
var w = canvas.width;
var h = canvas.height;
ctx.font = "18px arial";
var cw = w / 2;  // center 
var ch = h / 2;
var focused = false;
var rotated = false;
var angle = 0;

// Handle all key input
const keys = {  // key input object
    ArrowLeft : false,  // only add key names you want to listen to
    ArrowRight : false,
    keyEvent (event) {
        if (keys[event.code] !== undefined) {  // are we interested in this key
            keys[event.code] = event.type === "keydown";
            rotated = true; // to turn off help
        }
    }
}
// add key listeners
document.addEventListener("keydown", keys.keyEvent)
document.addEventListener("keyup", keys.keyEvent)

// check if focus click
canvas.addEventListener("click",()=>focused = true);

// main update function
function update (timer) {
    ctx.setTransform(1, 0, 0, 1, 0, 0);  // reset transform
    ctx.clearRect(0,0,w,h);      
    
    // draw outside box
    ctx.fillStyle = "red"
    ctx.fillRect(50, 50, w - 100, h - 100);
    
    // rotate if input
    angle += keys.ArrowLeft ? -0.1 : 0;
    angle += keys.ArrowRight ? 0.1 : 0;
    
    // set orgin to center of canvas
    ctx.setTransform(1, 0, 0, 1, cw, ch);
    
    // rotate
    ctx.rotate(angle);
    
    // draw rotated box
    ctx.fillStyle = "Black"
    ctx.fillRect(-50, -50, 100, 100);
    
    // set transform to center
    ctx.setTransform(1, 0, 0, 1, cw, ch);
    // rotate
    ctx.rotate(angle);
    // move to corner
    ctx.translate(50,50);
    // rotate once more, Doubles the rotation
    ctx.rotate(angle);
    
    ctx.fillStyle = "yellow"
    ctx.fillRect(-20, -20,40, 40);

    ctx.setTransform(1, 0, 0, 1, 0, 0);  // restore default
    
    // draw center box
    ctx.fillStyle = "white"
    ctx.fillRect(cw - 25, ch - 25, 50, 50);
    
    if(!focused){
        ctx.lineWidth = 3;
        ctx.strokeText("Click on canvas to get focus.",10,20);
        ctx.fillText("Click on canvas to get focus.",10,20);
    }else if(!rotated){
        ctx.lineWidth = 3;
        ctx.strokeText("Left right arrow to rotate.",10,20);
        ctx.fillText("Left right arrow to rotate.",10,20);
    }

    requestAnimationFrame(update);

}
requestAnimationFrame(update);


/** SimpleUpdate.js end **/

<canvas id = canvas></canvas>
&#13;
&#13;
&#13;

看着你的笔吼声是一个有用的功能。

以下函数将在画布上绘制缩放和旋转的精灵

// draws a image as sprite at x,y scaled and rotated around its center 
// image, the image to draw
// x,y position of the center of the image 
// scale the scale, 1 no scale, < 1 smaller, > 1 larger
// angle in radians
function drawSprite(image, x, y, scale = 1,angle = 0){
    ctx.setTransform(scale, 0, 0, scale, x, y); // set scale and center of sprite
    ctx.rotate(angle);
    ctx.drawImage(image,- image.width / 2, - image.height / 2);
    ctx.setTransform(1,0,0,1,0,0); // restore default transform
                                   // if you call this function many times
                                   // and dont do any other rendering between
                                   // move the restore default line
                                   // outside this function and after all the
                                   // sprites are drawn. 
}

确定更多信息。

你的代码到处都是,解决问题的唯一方法就是从头开始重写代码。

以下是我认为你想要你的笔做的事情。不是我压扁宽度以适应代码段窗口。

来自OP pen的代码并进行修改以提供我认为OP想要的内容。

&#13;
&#13;
// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 1024;
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.forEach(hero => hero.update());
}

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,
    reset(){
        this.x = canvas.width /  this.spawnPos;
        this.y = canvas.height / this.spawnPos;        
    }, 
    update(){
        if (keys.ArrowUp) { // Player holding up
            this.y -= this.speed * frameTime;
            this.dir = Math.PI * 0; // set direction
        }
        if (keys.ArrowDown) { // Player holding down
            this.y += this.speed * frameTime;
            this.dir = Math.PI * 1; // set direction
	      }
	      if (keys.ArrowLeft) { // Player holding left
            this.x -= this.speed * frameTime;
            this.dir = Math.PI * 1.5; // set direction
        }
        if (keys.ArrowRight) { // 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;
            }
        });
        if (this.x >= canvas.width || this.y >= canvas.height || this. y < 0 || this.x < 0) {
            this.reset();
        } 
    }
}

// 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] = {...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] = {...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/v1491958481/road_lrjihy.jpg");
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/v1491959220/m_n1rbem.png");

// create all objects
createHero("hero", {image : images.hero, spawnPos : 1.5});
createHero("hero3", {image : images.hero, spawnPos : 2, speed : -256});
createMonster("monster", {image : images.monster});
createMonster("monster3", {image : images.monster});
createMonster("monster9", {image : images.monster});
createMonster("monster12", {image : images.monster});

// add key listeners
document.addEventListener("keydown", keys.keyEvent);
document.addEventListener("keyup", keys.keyEvent);
&#13;
canvas {
   width : 100%;
   height : 100%;
}
&#13;
&#13;
&#13;