Смена угла движения через стрелочки и движение в эту сторону Canvas
Есть полный код того, что сейчас есть. Там реализовано движение ракеты за мышкой. Но сейчас нужно сделать так, чтобы кораблик всегда двигался вперед туда, куда он развернут, а уже стрелочками по чуть-чуть менялся угол его направления.
https://jsfiddle.net/8qgLxw5p/
(function() {
const cnv = document.getElementById("myCanvas");
const ctx = cnv.getContext("2d");
let mouse = new Vec2();
let distanceVec = new Vec2();
let myImg = new ImgSceneObject(
new Image(),
'http://www.java-forums.org/attachments/java-2d/1449d1319003532t-tank-game-help-please-tankeast.jpg',
30, 30,
new Vec2(200, 200)
);
let meteor = new ImgSceneObject(
new Image(),
'meteor.png',
50, 50
);
let angle = 0;
let translationVec = new Vec2(myImg.pos.x, myImg.pos.y);
let direction = new Vec2();
let translationSpeed = 8;
function initApp() {
cnv.width = window.innerWidth;
cnv.height = window.innerHeight;
document.onmousemove = mousemove;
}
function Vec2(x=0, y=0) {
this.x = x; this.y = y;
this.add = function(v) {
this.x += v.x;
this.y += v.y;
return this;
};
this.sub = function(v) {
this.x -= v.x;
this.y -= v.y;
return this;
};
this.multScalar = function(s) {
this.x *= s; this.y *= s;
return this;
};
this.dot = function(v) {
return this.x*v.x + this.y*v.y;
};
this.rotate = function(angle) {
this.x = this.x*Math.cos(angle) - y*Math.sin(angle);
this.y = this.x*Math.sin(angle) + y*Math.cos(angle);
return this;
};
this.translate = function(v) {
this.add(v);
return this;
};
this.length = function() {
return Math.sqrt(this.x*this.x + this.y*this.y);
};
this.normalize = function() {
const invLength = 1.0/this.length();
this.x *= invLength;
this.y *= invLength;
return this;
};
}
function ImgSceneObject(img, src, w, h, imageCenter) {
loaded = false;
img.onload = function() { loaded = true; }
img.src = src;
this.pos = imageCenter;
this.w = w;
this.h = h;
this.update = function(angle, v) {
ctx.save();
ctx.translate(this.pos.x, this.pos.y);
ctx.rotate(angle);
this.pos.x = v.x;
this.pos.y = v.y;
if (loaded) {
ctx.drawImage(img, -this.w/2, -this.h/2, this.w, this.h);
}
ctx.restore();
};
}
function updateScene() {
myImg.update(angle, translationVec);
distanceVec.x = mouse.x - myImg.pos.x;
distanceVec.y = mouse.y - myImg.pos.y;
if (distanceVec.length() > 10) {
translationVec.add(direction);
}
}
function gameloop() {
ctx.clearRect(0, 0, cnv.width, cnv.height);
updateScene();
id = requestAnimationFrame(gameloop);
}
function mousemove(e) {
mouse.x = e.clientX;
mouse.y = e.clientY;
direction.x = mouse.x;
direction.y = mouse.y;
angle = Math.atan2(mouse.y-myImg.pos.y, mouse.x-myImg.pos.x);
direction.sub(myImg.pos).normalize().multScalar(translationSpeed);
};
initApp();
gameloop();
}());
Ответы (1 шт):
Автор решения: Leonid
→ Ссылка
Самому проще написать, а потом усложнять если надо. Управление D и A. Можно добавить изменение скорости таким же образом для W и S для свойства speed только.
const canvas = document.getElementById('myCanvas');
playGame();
window.onresize = playGame;
function playGame(){
let ctx = canvas.getContext('2d');
let w = canvas.width = window.innerWidth - 20;
let h = canvas.height = window.innerHeight - 20;
let x = 50;
let y = 50;
let angle = 0;
let speed = 1;
let rotateSpeed = 2;
const image = new Image();
image.src = 'http://www.java-forums.org/attachments/java-2d/1449d1319003532t-tank-game-help-please-tankeast.jpg';
image.onload = render;
document.onkeypress = changeAngle;
function changeAngle(e){
let sign = 0;
if(e.key == 'd' || e.key == 'в'){
sign = 1;
} else if(e.key == 'a' || e.key == 'ф'){
sign = -1;
}
angle += sign * rotateSpeed;
}
function render(){
ctx.clearRect(0,0,w,h);
ctx.save();
ctx.translate(x, y);
ctx.rotate(Math.PI/180*angle);
ctx.drawImage(image, -20, -20, 40, 40);
ctx.restore();
}
function move(){
x += Math.cos(Math.PI/180*angle) * speed;
y += Math.sin(Math.PI/180*angle) * speed;
render();
requestAnimationFrame(move);
}
requestAnimationFrame(move);
}
<canvas id="myCanvas" style="background: #eee"></canvas>
Это с добавлением некоторых опций:
const canvas = document.getElementById('myCanvas');
playGame();
window.onresize = playGame;
function playGame(){
let ctx = canvas.getContext('2d');
let w = canvas.width = window.innerWidth - 20;
let h = canvas.height = window.innerHeight - 20;
let x = 50;
let y = 50;
let angle = 0;
let speed = 1;
let rotateSpeed = 2;
let acceleration = 0.1;
let started = false;
const image = new Image();
image.src = 'http://www.java-forums.org/attachments/java-2d/1449d1319003532t-tank-game-help-please-tankeast.jpg';
image.onload = render;
document.onkeypress = changeMotion;
function changeMotion(e){
let angleSign = 0;
let speedSign = 0;
if(e.key == 'd' || e.key == 'в'){
angleSign = 1;
} else if(e.key == 'a' || e.key == 'ф'){
angleSign = -1;
} else if(e.key == 'w' || e.key == 'ц'){
speedSign = 1;
if(speed == 0){
started = true;
}
} else if(e.key == 's' || e.key == 'ы'){
speedSign = -1;
}
angle += angleSign * rotateSpeed;
speed += speedSign * acceleration;
}
function render(){
ctx.clearRect(0,0,w, h);
ctx.save();
ctx.translate(x, y);
ctx.rotate(Math.PI/180*angle);
ctx.drawImage(image, -20, -20, 40, 40);
ctx.restore();
}
function move(){
pushX = 0;
pushY = 0;
if(x <= 20 || x >= w - 20 || y <= 20 || y >= h - 20){
speed = 0;
if(started){
pushX = x > w/2 ? -1 : 1;
pushY = y > h/2 ? -1 : 1;
}
started = false;
}
x += Math.cos(Math.PI/180*angle) * speed + pushX;
y += Math.sin(Math.PI/180*angle) * speed + pushY;
render();
requestAnimationFrame(move);
}
requestAnimationFrame(move);
}
<canvas id="myCanvas" style="background: #eee"></canvas>