如何用 JS js实现赛车游戏 3D 赛车效果

7794人阅读
本文将分享如何用 JS 写出一个 3D 赛车,我之前曾在技术交流会上也讲过一次(),后来有同学反馈说讲得太深奥没听懂。其实 PPT 里说的更多的是三维图形的基础知识,实现原理体现的稍微少一些,那么本文将着重从实现原理这块做一些补充。
先看赛车的示例:,还是半成品状态,很多功能没有实现,不过目前也没有后续的开发计划。
准备工作:
1) 图片素材:图片素材是每一个网页游戏必不可少的,本游戏中素材涉及到、、、、、以及其它一些背景图片等。为了实现延伸,这里的白云及远山等图片素材一定要做成首尾相接看起来平滑的,中间不能出现交界痕迹,这样的图片可以从网上找到素材,再用
PhotoShop 进行处理。
2) 矢量绘图库:矢量绘画部分没有必要自己从头写起,我们应该将关注点放在游戏的业务逻辑部分,可以从网上找个自己用得顺手的基础库,比如&、&等,如果不考虑浏览器兼容的话,也可以使用
HTML5 提供的 &canvas& 标签。强力推荐&,Raphael 是一个全浏览器监容的绘画库,她提供大部分常用基本图形的绘制方法,以及支持通过 SVGPath 语法来描绘任意曲线,更甚的是,每一个图形单元都对应一个 Raphael 对象,可以类似 JQuery 那样的链式调用来对图形单元进行操作,Raphael
的图形渲染载体是浏览器提供的原生 vml 或 svg,IE 下使用 vml,其它浏览器使用 svg。
实现原理:
实际上赛车的实现过程中考虑了很多细节的问题,由于篇幅有限,这里只挑一些重点的来介绍。
1) 白云及远山:这两个都是 &div& 的背景实现的,通过控制 &div& 样式中的 backgroundPositionX 属性来达到移动的目的,注意两个特点:a、运动方向与小车行驶的方向相反(小车左拐时,云和山向右移,反之则相反);b、由于白云离观察者的距离比远山要远,所以白云运动的速度比山体要慢(本游戏用的速度是 1:4)。在 IE6 下,变更 backgroundPosition 相关属性的值会使背景图片重载,导致界面上看起来闪烁,所以这里要用 document.execCommand(“BackgroundImageCache”,
false, true) 命令强制背景图片缓存。
2) 路面:路面最重要的构成是两条,贝塞尔曲线有几个重要的参数——起点、控制点一、控制点二和终点,这样的四个点即构成一条贝赛尔曲线。SVGPath 里的 C 指令可以完成贝塞尔曲线的绘制。路面变换弯度是如何实现的呢?幸好 vml/svg 节点的 path 属性是允许动态改变的,可以通过改变它的
path 来完成弯度的变化,这点 Raphael 库提供了很大的便利。如果是 &canvas& 实现的话,需要不断的重绘路面来达到目的。
3) 树木:本游戏中树木是由 6 张图片随机产生的,它们由远及近地运动来向玩家表达车子向前跑的状态,运动是通过不断改变树木的坐标和大小实现的,这里的坐标由路沿的两条贝塞尔曲线来确定。树木的运动有三个特点:a、离观察者越远的树越小,所以运动使树木不断变大,同时也使相邻树木的间距变大;b、由于前面的过程,树木的 y 坐标(top 值)不一定在逐渐增大,有时反而在减小;c、离观察者近的树,层次要位于离得远的树之上。
4) 车子:车子是由一张集合了 13 个可能出现的方向的图片组合而成(见上述图片素材部分),你可能会奇怪这样的图片怎么制作,其实很简单,我是拿 3dsmax 软件做成的,从网上找了一个 3d 车子模型,用 3dsmax 软件改改样子,并导出不同方向的图片,最终用 PhotoShop 合成。在网页上,用这张图片做为一个 &div& 的背景,仍然是通过控制 &div& 样式的 backgroundPositionX 属性来达到车子变换方向的目的。本游戏中车子在改变方向或位置的时候,将受到以下参数的影响:当前车速、人为加减速、自然减速(速度自然衰减)、被迫减速(碰擦路沿时)、弯道系数、左右方向键累积系数、离心力大小等,这些参数复合运算后的结果将决定车子当前应该处于的
x 坐标位置和方向。由于实现在不同的模块中,这里就不详细说明这些运算了。
5) 时速表:时速表由表盘和表针组成,表盘是静止的,表针是可以转动的。转动的原理是改变表针的 rotate 属性,这点在 Raphael 库也有也对应的方法实现,参见 Raphael 文档中的 rotate 方法。为了更加逼真,指针加入了抖动策略,具体为:如果车子处于匀速状态下,指针将在当前速度附近抖动,你可以将车子开满 180km/h 看看效果。
6) 速度:这是本游戏中最重要的参数之一,本游戏中将速度量化为 0-1,1 为满速,0 为静止不动。速度参数将决定网页上很多物件的移动:除了车子上述复杂过程外,还有白云和远山的位移速度、路面改变弯道的快慢程度、树木运动的快慢、时速表指针旋转的角度等。
关于实现原理就介绍到这里,下面说说我原来的一些想法:
后续可以做的:
1) 小地图:使路况与小地图结合起来,模拟真实世界。
2) 起点和终点:这是一个赛车游戏必备的。
3) 耗油:起跑时,油箱是满的,在车子跑动过程中,结合速度、路况、玩家控制、阻力等因素来消耗汽油,在到达终点之前油用完就 Game Over,考验玩家的驾驶水平。
4) 敌车:路上不可能只有一个车子嘛。
5) 复杂路况:可以用草丛、沙地、小石头、水坑等物体来复杂化路况,增加游戏的难度和趣味性。
6) 路边风景:结合小地图,可以在路边实现一些河流、建筑物等,纯树木还是很单调的。
原文来自:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:375184次
积分:4307
积分:4307
排名:第5271名
原创:23篇
转载:65篇
评论:121条
(6)(15)(9)(12)(12)(8)(3)(2)(5)(5)(5)(6)12345678910
11-1811-1811-1711-1711-1611-1511-1511-1411-1411-14
京公网安备 86 京ICP证140355号 京网文【-109号
未成年人家长监护
注意:本游戏需安卓版与数据包一同下载才能进行游戏当前位置: &
用js实现的3D特效 - 网页特效代码演示 - 特效代码运行&
效果非常强悍的3D效果以下是HTML网页特效代码,点击运行按钮可查看效果:
&html xmlns:v="urn:schemas-microsoft-com:vml"&
&title&3dtest2&/title&
&script language="JavaScript"&&!--
var isNav, isIE, isNS6;
if(d.layers) {isNav = 1;}
else if(d.all) {isIE = 1;}
else if (d.getElementByID) {isNS6 = 1;}
if(!isIE) {
alert("this experiment requires IE, as it uses VML");
function mousemove(e) {
if (isIE) {
mx = window.event.clientX;
my = window.event.clientY;
mx = e.pageX;
my = e.pageY;
if (isNav) document.captureEvents(Event.MOUSEMOVE);
document.onmousemove =
// vertex definitions:
x,y,z,xp,yp
var b1 = new Array(-40,40,-40,0,0);
var b2 = new Array(-40,40,40,0,0);
var b3 = new Array(40,40,40,0,0);
var b4 = new Array(40,40,-40,0,0);
var b5 = new Array(-40,-40,-40,0,0);
var b6 = new Array(-40,-40,40,0,0);
var b7 = new Array(40,-40,40,0,0);
var b8 = new Array(40,-40,-40,0,0);
function project(vert, obj) {
vert[3] = Math.floor((vert[0] * dist) / (vert[2] + dist + 40));
vert[4] = Math.floor((vert[1] * dist) / (vert[2] + dist + 40));
function xrotate(vert, deg) {
cos1 = costable[deg];
sin1 = sintable[deg];
y = vert[1];
z = vert[2];
vert[1] = (cos1*y) - (sin1*z);
vert[2] = (sin1*y) + (cos1*z);
function yrotate(vert, deg) {
cos1 = costable[deg];
sin1 = sintable[deg];
x = vert[0];
z = vert[2];
vert[0] = (cos1*x) + (sin1*z);
vert[2] = (cos1*z) - (sin1*x);
function zrotate(vert, deg) {
cos1 = costable[deg];
sin1 = sintable[deg];
x = vert[0];
y = vert[1];
vert[0] = (cos1*x) - (sin1*y);
vert[1] = (sin1*x) + (cos1*y);
var dist = 90;
var mx = 100,my = 100;
var p1,p2,p3,p4,p5,p6,p7,p8;
var xcenter,
var sintable = new Array(360);
var costable = new Array(360);
function startup() {
for(i=-360;i&=360;i++) {
costable[i] = Math.cos(i*0.017454);
sintable[i] = Math.sin(i*0.017454);
function amod(vert, lyr, img, xr, yr, zr) {
project(vert);
xrotate(vert,yr);
yrotate(vert,xr);
//zrotate(vert,zr);
var v1path, v2path, v3path, v4
var scrtch = 0;
function swip() {
if(scrtch == "1") {
scrtch = 0;
c1.path = "m";
c2.path = "m";
c3.path = "m";
c4.path = "m";
scrtch = 1;
function main() {
if(scrtch == "1") {
c1.path = v1
c2.path = v2
c3.path = v3
c4.path = v4
xr = -Math.floor((mx-350)/80);
if(xr & 6) {xr = 6};
yr = Math.floor((my-250)/80);
if(yr & 6) {yr = 6};
for(i=1;i&=8;i++) {
eval("amod(b"+i+",p"+i+",'i"+i+"', xr, yr, zr)");
v1path = "m "+b1[3]+","+b1[4]+" l "+b2[3]+","+b2[4]+" "+b3[3]+","+b3[4]+" "+b4[3]+","+b4[4]+" x e";
v2path = "m "+b5[3]+","+b5[4]+" l "+b6[3]+","+b6[4]+" "+b7[3]+","+b7[4]+" "+b8[3]+","+b8[4]+" x e";
v3path = "m "+b1[3]+","+b1[4]+" l "+b2[3]+","+b2[4]+" "+b6[3]+","+b6[4]+" "+b5[3]+","+b5[4]+" x e";
v4path = "m "+b3[3]+","+b3[4]+" l "+b4[3]+","+b4[4]+" "+b8[3]+","+b8[4]+" "+b7[3]+","+b7[4]+" x e";
v1.path = v1
v2.path = v2
v3.path = v3
v4.path = v4
setTimeout('main()','20');
//--&&/script&
&style type="text/css"&
v\:*{behavior:url(#default#VML);}
body {font-family: verdana, font-size:10 color:}
input, select, .cb {background-color: #BB0000; padding:3font-family:verdana, helvetica, font-size:10 border: 0 border-color: #C0E0C0; color:#FFFFFF;}
a:link, a:visited, a:active {font-family: verdana, font-size:10 color:}
a:hover {font-family: verdana, font-size:10 color:}
&body onload="startup();" bgcolor="#000000"&
&v:shape id="c1" filled="false" strokecolor="#ff8888" style="visibility:position:left:300;top:400;width:200;height:200" coordorigin="0, 100" coordsize="100,100"&&v:path v="m 0,0 l x e"/&&/v:shape&
&v:shape id="c2" filled="false" strokecolor="#ff8888" style="visibility:position:left:300;top:400;width:200;height:200" coordorigin="0, 100" coordsize="100,100"&&v:path v="m 0,0 l x e"/&&/v:shape&
&v:shape id="c3" filled="false" strokecolor="#ff8888" style="visibility:position:left:300;top:400;width:200;height:200" coordorigin="0, 100" coordsize="100,100"&&v:path v="m 0,0 l x e"/&&/v:shape&
&v:shape id="c4" filled="false" strokecolor="#ff8888" style="visibility:position:left:300;top:400;width:200;height:200" coordorigin="0, 100" coordsize="100,100"&&v:path v="m 0,0 l x e"/&&/v:shape&
&v:shape id="v1" filled="false" strokecolor="white" style="visibility:position:left:300;top:400;width:200;height:200" coordorigin="0, 100" coordsize="100,100"&&v:path v="m 0,0 l 100,100 200,50 x e"/&&/v:shape&
&v:shape id="v2" filled="false" strokecolor="white" style="visibility:position:left:300;top:400;width:200;height:200" coordorigin="0, 100" coordsize="100,100"&&v:path v="m 0,0 l 100,100 200,50 x e"/&&/v:shape&
&v:shape id="v3" filled="false" strokecolor="white" style="visibility:position:left:300;top:400;width:200;height:200" coordorigin="0, 100" coordsize="100,100"&&v:path v="m 0,0 l 100,100 200,50 x e"/&&/v:shape&
&v:shape id="v4" filled="false" strokecolor="white" style="visibility:position:left:300;top:400;width:200;height:200" coordorigin="0, 100" coordsize="100,100"&&v:path v="m 0,0 l 100,100 200,50 x e"/&&/v:shape&
&div style="position: top:75 left:122 width:200;" align="justify"&
&select onchange="dist = Math.floor(this.value);"&
&option value="40"&super high&/option&
&option value="50"&high&/option&
&option value="90" selected&normal&/option&
&option value="200"&low&/option&
&option value="10000"&super low&/option&
[提示:可先修改代码再按运行]
刚被其它网友点击的网页特效&
特效标题预览特效点击运行特效
搜索查询面板&
本月特效排行&
本周特效排行&
本日特效排行&激情飞扬 彰显个性――建设JSI10-5(K8赛车版)试骑体验_论文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
您可以上传图片描述问题
联系电话:
请填写真实有效的信息,以便工作人员联系您,我们为您严格保密。
激情飞扬 彰显个性――建设JSI10-5(K8赛车版)试骑体验
||文档简介
中国最大最早的专业内容网站|
总评分0.0|
&&近​年​来​,​身​边​不​少​朋​友​都​骑​起​了​摩​托​车​.​对​于​一​直​钟​爱​摩​托​车​的​我​来​说​也​有​了​购​置​一​台​摩​托​车​的​念​头​,​除​了​上​下​班​代​步​外​,​还​可​以​与​摩​迷​们​一​起​兜​兜​风​,​享​受​旅​行​生​活​带​来​的​激​情​与​喜​悦​。​当​我​正​在​犹​豫​什​么​车​型​适​合​的​时​候​,​建​设​K的​一​场​试​骑​测​试​活​动​来​啦​,​除​了​性​能​测​试​外​,​还​有​个​长​达​数​天​的​体​验​机​会​:
试读已结束,如果需要继续阅读或下载,敬请购买
定制HR最喜欢的简历
你可能喜欢百度技术 的BLOG
用户名:百度技术
文章数:403
评论数:152
访问量:1052689
注册日期:
阅读量:5863
阅读量:12276
阅读量:355753
阅读量:1052870
51CTO推荐博文
本文将分享如何用 JS 写出一个 3D 赛车,我之前曾在技术交流会上也讲过一次(),后来有同学反馈说讲得太深奥没听懂。其实 PPT 里说的更多的是三维图形的基础知识,实现原理体现的稍微少一些,那么本文将着重从实现原理这块做一些补充。
先看赛车的示例:,还是半成品状态,很多功能没有实现,不过目前也没有后续的开发计划。
准备工作:
1) 图片素材:图片素材是每一个网页游戏必不可少的,本游戏中素材涉及到、、、、、以及其它一些背景图片等。为了实现延伸,这里的白云及远山等图片素材一定要做成首尾相接看起来平滑的,中间不能出现交界痕迹,这样的图片可以从网上找到素材,再用 PhotoShop 进行处理。
2) 矢量绘图库:矢量绘画部分没有必要自己从头写起,我们应该将关注点放在游戏的业务逻辑部分,可以从网上找个自己用得顺手的基础库,比如&、 等,如果不考虑浏览器兼容的话,也可以使用 HTML5 提供的 &canvas& 标签。强力推荐&,Raphael 是一个全浏览器监容的绘画库,她提供大部分常用基本图形的绘制方法,以及支持通过 SVGPath 语法来描绘任意曲线,更甚的是,每一个图形单元都对应一个 Raphael 对象,可以类似 JQuery 那样的链式调用来对图形单元进行操作,Raphael 的图形渲染载体是浏览器提供的原生 vml 或 svg,IE 下使用 vml,其它浏览器使用 svg。
实现原理:
实际上赛车的实现过程中考虑了很多细节的问题,由于篇幅有限,这里只挑一些重点的来介绍。
1) 白云及远山:这两个都是 &div& 的背景实现的,通过控制 &div& 样式中的 backgroundPositionX 属性来达到移动的目的,注意两个特点:a、运动方向与小车行驶的方向相反(小车左拐时,云和山向右移,反之则相反);b、由于白云离观察者的距离比远山要远,所以白云运动的速度比山体要慢(本游戏用的速度是 1:4)。在 IE6 下,变更 backgroundPosition 相关属性的值会使背景图片重载,导致界面上看起来闪烁,所以这里要用 document.execCommand(&BackgroundImageCache&, false, true) 命令强制背景图片缓存。
2) 路面:路面最重要的构成是两条,贝塞尔曲线有几个重要的参数&&起点、控制点一、控制点二和终点,这样的四个点即构成一条贝赛尔曲线。SVGPath 里的 C 指令可以完成贝塞尔曲线的绘制。路面变换弯度是如何实现的呢?幸好 vml/svg 节点的 path 属性是允许动态改变的,可以通过改变它的 path 来完成弯度的变化,这点 Raphael 库提供了很大的便利。如果是 &canvas& 实现的话,需要不断的重绘路面来达到目的。
3) 树木:本游戏中树木是由 6 张图片随机产生的,它们由远及近地运动来向玩家表达车子向前跑的状态,运动是通过不断改变树木的坐标和大小实现的,这里的坐标由路沿的两条贝塞尔曲线来确定。树木的运动有三个特点:a、离观察者越远的树越小,所以运动使树木不断变大,同时也使相邻树木的间距变大;b、由于前面的过程,树木的 y 坐标(top 值)不一定在逐渐增大,有时反而在减小;c、离观察者近的树,层次要位于离得远的树之上。
4) 车子:车子是由一张集合了 13 个可能出现的方向的图片组合而成(见上述图片素材部分),你可能会奇怪这样的图片怎么制作,其实很简单,我是拿 3dsmax 软件做成的,从网上找了一个 3d 车子模型,用 3dsmax 软件改改样子,并导出不同方向的图片,最终用 PhotoShop 合成。在网页上,用这张图片做为一个 &div& 的背景,仍然是通过控制 &div& 样式的 backgroundPositionX 属性来达到车子变换方向的目的。本游戏中车子在改变方向或位置的时候,将受到以下参数的影响:当前车速、人为加减速、自然减速(速度自然衰减)、被迫减速(碰擦路沿时)、弯道系数、左右方向键累积系数、离心力大小等,这些参数复合运算后的结果将决定车子当前应该处于的 x 坐标位置和方向。由于实现在不同的模块中,这里就不详细说明这些运算了。
5) 时速表:时速表由表盘和表针组成,表盘是静止的,表针是可以转动的。转动的原理是改变表针的 rotate 属性,这点在 Raphael 库也有也对应的方法实现,参见 Raphael 文档中的 rotate 方法。为了更加逼真,指针加入了抖动策略,具体为:如果车子处于匀速状态下,指针将在当前速度附近抖动,你可以将车子开满 180km/h 看看效果。
6) 速度:这是本游戏中最重要的参数之一,本游戏中将速度量化为 0-1,1 为满速,0 为静止不动。速度参数将决定网页上很多物件的移动:除了车子上述复杂过程外,还有白云和远山的位移速度、路面改变弯道的快慢程度、树木运动的快慢、时速表指针旋转的角度等。
关于实现原理就介绍到这里,下面说说我原来的一些想法:
后续可以做的:
1) 小地图:使路况与小地图结合起来,模拟真实世界。
2) 起点和终点:这是一个赛车游戏必备的。
3) 耗油:起跑时,油箱是满的,在车子跑动过程中,结合速度、路况、玩家控制、阻力等因素来消耗汽油,在到达终点之前油用完就 Game Over,考验玩家的驾驶水平。
4) 敌车:路上不可能只有一个车子嘛。
5) 复杂路况:可以用草丛、沙地、小石头、水坑等物体来复杂化路况,增加游戏的难度和趣味性。
6) 路边风景:结合小地图,可以在路边实现一些河流、建筑物等,纯树木还是很单调的。
by huangzhilong
【本文首发于:
【本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)

我要回帖

更多关于 js实现赛车游戏 的文章

 

随机推荐