Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/450.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 利用transformapi实现三维错觉效果_Javascript_Animation_Math_Canvas_Formula - Fatal编程技术网

Javascript 利用transformapi实现三维错觉效果

Javascript 利用transformapi实现三维错觉效果,javascript,animation,math,canvas,formula,Javascript,Animation,Math,Canvas,Formula,我正在制作一个简单的宇宙飞船2d游戏,我想通过使用变换来创建好看的3d错觉效果。通过实验,我最终调整了a(水平缩放)和d(垂直缩放) 因此,默认情况下(无转换),我们可以使用ctx.transform(1,0,0,1,0,0) 我当前的设置是这个ctx.transform(1.72,0,0,0.65,0,0) 在这种背景下,船看起来不错,但只有在某些角度下。我在想,是否有一种方法可以使用适当的数学来应用公式来动态调整这些值(可能是基于船舶旋转的角度)。不幸的是,我的数学知识很差,所以我请更有经验

我正在制作一个简单的宇宙飞船2d游戏,我想通过使用
变换
来创建好看的3d错觉效果。通过实验,我最终调整了
a
(水平缩放)和
d
(垂直缩放)

因此,默认情况下(无转换),我们可以使用
ctx.transform(1,0,0,1,0,0)

我当前的设置是这个
ctx.transform(1.72,0,0,0.65,0,0)

在这种背景下,船看起来不错,但只有在某些角度下。我在想,是否有一种方法可以使用适当的数学来应用公式来动态调整这些值(可能是基于船舶旋转的角度)。不幸的是,我的数学知识很差,所以我请更有经验的会员帮我弄清楚

以下是小型原型(通过单击单选按钮,您可以在默认值和我的硬编码值之间切换):

var mode=“3d”;
var切换=功能(ev,项目){
mode=item.value;
};
var工具=新函数(){
this.rad=a=>(Math.PI/180)*a;
this.deg=rad=>(rad*180)/Math.PI;
这个距离=p=>
数学sqrt((p.x-p.dx)*(p.x-p.dx)+(p.y-p.dy)*(p.y-p.dy));
this.rftv=p=>Math.atan2(p.dy-p.y,p.dx-p.x);
this.pfa=函数(l,x,y,a){
返回{
x:Math.cos(this.rad(a))*l+x,
y:Math.sin(this.rad(a))*l+y
};
};
}();
让设计={
c:[
{尺寸:0.716667,度:-90},
{尺寸:0.5060742150229658,度:-107.24145939893998},
{尺寸:0.42196629670573876,度:-99.0902769208223},
{尺寸:0.08975274678557507,度:-158.19859051364818},
{尺寸:0.08975274678557507,度:-21.80140948635181},
{尺寸:0.42196629670573876,度:-80.90972307917767},
{尺寸:0.5060742150229658,度:-72.75854060106003}
],
l1:[
{尺寸:0.4552166761249221,度:-113.74949449286676},
{尺寸:0.390156636906542,度:-109.98310652189998},
{尺寸:0.184089350286435,度:-174.8055710922652},
{大小:0.6324555320336759,度:161.565051770778}
],
r1:[
{尺寸:0.390156636906542,度:-70.01689347810003},
{尺寸:0.4552166761249221,度:-66.25050550713325},
{大小:0.6324555320336759,度:18.43494882292201},
{尺寸:0.184089350286435,度:-5.194428907734806}
],
l2:[
{尺寸:0.2608745973749754,度:153.434948822922},
{尺寸:0.6262764742685312,度:154.79887635452494},
{尺寸:0.6616477747093069,度:130.91438322002512}
],
r2:[
{尺寸:0.2608745973749754,度:26.565051770707799},
{尺寸:0.6262764742685312,度:25.20112364547507},
{尺寸:0.6616477747093069,度:49.08561677997487}
]
};
设圆=(x,y,r,fs,ss)=>{
ctx.save();
ctx.beginPath();
弧(x,y,r,0,Math.PI*2);
如果(fs!==false){
ctx.fillStyle=fs;
ctx.fill();
}
如果(ss!==false){
ctx.lineWidth=1;
ctx.strokeStyle=ss;
ctx.stroke();
}
ctx.restore();
};
var变换=函数(Z轴、倾斜、缩放、x、y){
var cs=Math.cos(zAxis),sn=Math.sin(zAxis);
var h=数学cos(倾斜);
变量a=标度*cs,b=标度*sn,c=x;
变量d=h*标度*sn,e=h*标度*cs,f=y;
返回{a,d,b,e,c,f};
};
让ship=(x,y,size,a,fs)=>{
ctx.save();
ctx.beginPath();
ctx.translate(x,y);
如果(模式==“2d”){
变换(1,0,0,1,0,0);
}
如果(模式==“3d”){
var{a,d,b,e,c,f}=变换(tools.rad(a),45,1,x,y);
设置转换(a,d,b,e,c,f);
}
ctx.translate(-x,-y);
用于(let输入设计){
for(设i=0;i0){
设c=设计[类型][0],
p=工具pfa(尺寸*c.尺寸,x,y,c.度+a+90);
ctx.lineTo(p.x,p.y);
}
}
ctx.fillStyle=fs;
ctx.fill();
ctx.restore();
圆圈(x,y,尺寸,假,“蓝色”);
};
让cvs=document.createElement(“画布”),
ctx=cvs.getContext(“2d”),
w=(CV.width=400),
h=(cvs.height=400),
cx=w/2,
cy=h/2;
设点=[
{x:cx-40,y:3},
{x:cx+40,y:h-3},
{x:3,y:cy+40},
{x:w-3,y:cy-40}
];
让shipData={
x:cx,
y:cy,
r:40,
答:0,,
c:0,
dx:点[0].x,
dy:点[0].y,
运行:函数(){
设d=工具距离(此);
if(d<1){
这是c+=1;
if(this.c>points.length-1){
这个c=0;
}
this.dx=点[this.c].x;
this.dy=点[this.c].y;
}
设rad=tools.rftv(this);
该.a=工具度(rad);
这个.x+=Math.cos(rad);
this.y+=Math.sin(rad);
}
};
让渲染=()=>{
ctx.clearRect(0,0,w,h);
ctx.fillStyle=“#ccc”;
ctx.fillRect(0,0,w,h);
/*调试*/圆(点[0].x,点[0].y,3,“红色”,假);
/*调试*/圆(点[1].x,点[1].y,3,“红色”,假);
/*调试*/圆(点[2].x,点[2].y,3,“红色”,假);
/*调试*/圆(点[3].x,点[3].y,3,“红色”,假);
ship(shipData.x、shipData.y、shipData.r、shipData.a,“蓝色”);
shipData.run();
请求动画帧(渲染);
};
文件.正文.附件(cvs);
render()

二维
三维

您可以使用画布轻松渲染ismoetric(非透视)图形,同样的转换也可以用于CSS。矩阵系数取决于倾斜角度(通常在等距游戏中固定)和围绕Z(高度)轴的旋转


对于完整的公式,您可以看到以下答案:

hmmm我试图应用在该主题链接下找到的公式(那些计算
a,d,b,e,c,f
并应用
ctx.setTransform(a,d,b,e,c,f);
但对我的代码无效。首先,有两个角度变量
angle1,angle2