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



我是画布和开发汽车直线移动游戏的新手,现在我想旋转汽车的图像,只在按下左键时逆时针旋转,在按下右键时顺时针旋转。

目前我正在尝试

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);    
}

但这 旋转整个屏幕 .我只希望英雄图像旋转而不是屏幕。任何帮助,不胜感激。我的源代码:工作笔

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

/** 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>

看着你的笔波纹管是一个会有所帮助的功能。

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

// 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 笔的代码并进行了修改以提供我认为 OP 想要的内容。

// 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);
canvas {
   width : 100%;
   height : 100%;
}

最新更新