JavaScript写的台球小游戏
二十一点小游戏(HTML游戏使用JavaScript开发)

二十一点小游戏(HTML游戏使用JavaScript开发)HTML游戏使用JavaScript开发已经成为一种流行的趋势,其中二十一点小游戏是一种简单而有趣的游戏。
在这个小游戏中,玩家需要通过抽取数字卡片的方式来接近或者达到21点的总和。
以下是对这款游戏的简要介绍,包括游戏规则、开发过程和功能设计。
一、游戏规则1. 玩家可以选择抽取一张数字卡片或者停止抽取。
2. 玩家根据手中卡片的总和来判断是否获胜。
3. 如果玩家手中卡片的总和超过21点,则游戏失败。
4. 如果玩家手中卡片的总和等于21点,则游戏胜利。
5. 在游戏中,A的点数可以是1或者11,J、Q、K的点数均为10。
二、开发过程在开发二十一点小游戏时,我们需要使用HTML、CSS和JavaScript来实现游戏的界面和逻辑。
1. HTML部分首先,我们需要设计出游戏的界面。
可以使用HTML5的语义化标签来构建游戏画面的各个部分,例如头部、主体和底部。
并且使用CSS来设置样式,使得游戏界面看起来更加美观。
2. JavaScript部分在实现游戏逻辑时,我们需要使用JavaScript来处理用户的交互和计算卡片的点数总和。
2.1 定义卡片对象使用JavaScript定义一个卡片对象,包含点数和花色两个属性。
每次抽卡时,可以从预先定义好的一组卡片中随机抽取一张。
2.2 玩家抽取卡片当玩家点击抽取按钮时,JavaScript会随机抽取一张卡片,并根据抽取的结果更新玩家的手牌。
2.3 计算点数总和通过遍历玩家的手牌数组,计算出玩家手中所有卡片的点数总和。
需要注意A的处理,根据手中的其他卡片决定A是1还是11。
2.4 判断胜负根据点数总和判断玩家是胜利、失败还是继续游戏。
如果点数总和超过21点,游戏失败。
如果点数总和等于21点,游戏胜利。
三、功能设计为了增加游戏的趣味性和可玩性,可以在二十一点小游戏中添加以下功能:1. 游戏计分记录玩家的胜利次数和失败次数,并在界面上显示。
打台球小游戏

打台球小游戏
打台球是一种受欢迎的桌上运动,它需要精准的击球技巧和战略思维。
游戏的目标是使用球杆将球击入袋中,同时遵循一定的规则和技巧。
游戏规则:
1. 台球桌上有15个编号的球,其中包括一组红色球和一组彩色球(黑、粉、蓝、棕、绿、黄)以及一颗白色的白球。
2. 游戏开始时,玩家需要用白球击打红球,将红球依次击入袋中。
3. 当红球全部被击入袋中后,玩家可以开始击打彩色球。
在击打彩色球时,玩家需要先将彩色球击入袋中,然后再击打红球。
4. 游戏的最终目标是将所有球都击入袋中,最后击打黑球并赢得比赛。
玩法:
1. 玩家可以选择不同的击球力度和角度,以达到最佳的球路。
2. 在击球时,玩家需要考虑球杆的位置、手部动作和击球力度,以确保准确击打目标球。
3. 玩家可以利用反弹和旋转来控制球的方向和速度,以获得更好的击球效果。
4. 玩家需要在击球前仔细规划每一杆的击球路线,以确保能够连续击打多个球。
术语和技巧:
1. 击球力度:玩家需要掌握不同力度的击球技巧,以适应不同的球路和距离。
2. 角度控制:玩家需要学会调整球杆的角度,以确保球的击打方向准确无误。
3. 球道规划:玩家需要在击球前规划好球道,以确保能够连续击打多个球,最大限度地提高得分。
通过掌握这些规则、玩法和技巧,玩家可以享受到打台球小游戏
带来的挑战和乐趣,同时也能提高自己的击球技巧和战略思维能力。
愿你在游戏中尽情享受!。
打台球小游戏

打台球小游戏
目标:打台球小游戏的目标是使用球杆将球击入球袋,根据规则得分并赢得比赛。
规则: 1. 游戏通常由两名玩家进行,每人轮流击球。
2. 可以选择红色球或黄色球作为比赛的目标球。
3. 每个玩家轮流击球,先将目标球击入球袋,然后再将彩球击入球袋。
4. 如果玩家在一杆中将目标球和彩球都击入球袋,则可以继续击打,直到没有球被击入球袋。
5. 如果玩家在一杆中未能将目标球或彩球击入球袋,轮到对方击打。
6. 游戏直到所有的球都被击入球袋,得分最高的玩家获胜。
玩法: 1. 准备:将15个红色球和6个彩球摆成三角形,球杆放在球桌的一端。
2. 击球:玩家可以在球桌上自由移动球杆,用球杆击打白球,以使目标球和彩球进入球袋。
3. 技巧:击球时需要注意击球的力度和方向,以确保球能够准确进入球袋。
此外,需要考虑球杆的姿势和击球的角度,以避免犯规或者使对手获得优势。
术语和技巧: 1. 击球力度:根据球的位置和击球的目标,需要掌握不同的击球力度,以确保球能够准确进入球袋。
2. 击球角度:需要根据球的位置和球杆的姿势选择合适的击球角度,以避免
犯规或者使对手获得优势。
3. 犯规:击球过程中需要遵守规则,避免犯规,否则对手将获得额外的机会。
通过掌握击球力度和角度,以及遵守规则,玩家可以在打台球小游戏中取得成功,并享受游戏的乐趣。
同时,尝试不同的策略和方法也可以使游戏更具挑战性和乐趣。
打台球小游戏

打台球小游戏
打台球是一种受欢迎的桌上运动,玩家使用球杆击打球,目标是将球打入球袋。
台球游戏通常使用15个编号球和一只白球,玩家需要使用球杆击打白球,以便将编号球击入球袋。
游戏的目标是使用球杆将所有的编号球按照规定的顺序依次打入球袋,最后再将黑八球击入指定的球袋。
玩家需要在不犯规的情况下,先将自己的编号球全部打入球袋,然后再将黑八球打入指定的球袋,才能获胜。
游戏的规则包括: 1. 开局时,玩家需要使用球杆击打白球,让白球撞击编号球,使编号球依次进袋。
2. 如果在一杆中将自己的编号球和黑八球同时打入球袋,或者将黑八球先打入球袋,都会导致犯规。
3. 如果玩家在一杆中没有将球击入球袋,或者将对方的编号球击入球袋,也会被视为犯规。
4. 犯规的玩家将失去击打的机会,并且对手可以将白球放置在台面上的任意位置。
玩家需要掌握一些技巧和术语,以便在游戏中取得优势。
例如,玩家需要掌握击球的力度和角度,以确保球能够准确进袋。
另外,了解如何使用反弹和旋转等技巧,也能帮助玩家在游戏中取得更好的表现。
为了增加游戏的挑战性和乐趣,玩家可以尝试不同的策略和方法,例如选择不同的击球顺序,或者利用球杆的特殊技巧来达到更好的效果。
此外,玩家还可以尝试使用一些花式击球的技巧,来展示自己的球技水平。
总的来说,打台球小游戏是一种充满挑战和乐趣的桌上运动,玩家需要掌握一定的技巧和策略,才能在游戏中取得好成绩。
通过不断练习和尝试,玩家可以不断提高自己的球技水平,享受游戏带来的乐趣。
弹球小游戏编程实现

弹球小游戏编程实现在当代科技发展快速的背景下,电子游戏已经成为人们娱乐生活中不可或缺的一部分。
弹球小游戏作为其中的经典之作,引领了一代又一代游戏爱好者的热情。
在本文中,将介绍弹球小游戏的编程实现过程,以帮助读者进一步了解游戏制作的原理和技术。
一、项目介绍弹球小游戏是一种经典的街机游戏,在游戏中玩家需要操控一个球拍,通过反弹球拍,将球击打到上方的砖块,从而消除砖块并得分。
游戏难度会逐渐增加,随着砖块的消除,球的速度也会加快,给玩家带来挑战。
二、编程环境准备在实现弹球小游戏之前,需要准备一些编程环境。
首先,选择合适的编程语言和开发工具,如Python语言和Pygame库。
接着,安装相关的软件和依赖项,并配置开发环境,确保编程平台正常运行。
三、游戏场景设计在编程实现过程中,首先需要设计游戏场景。
弹球小游戏通常包含一个球拍、一个球和若干砖块。
可以利用开发工具提供的绘图函数绘制这些元素,并设置它们在屏幕上的位置和大小。
四、游戏物理效果模拟为了使游戏更具真实感,需要模拟球的运动轨迹和球拍的反弹效果。
通过计算球的速度和方向,并结合碰撞检测算法,可以实现球与边界、球拍和砖块的交互作用。
当球和物体发生碰撞时,根据不同的碰撞情况调整球的运动方式,以及砖块的消除与得分。
五、用户交互设计游戏的交互性是吸引玩家的重要因素之一。
通过监听用户的键盘或鼠标操作,可以实现球拍的移动控制和游戏的开始、暂停等功能。
此外,可以添加音效和动画效果,提升游戏的娱乐性和视觉效果。
六、游戏逻辑设计在实现游戏逻辑时,需要确定游戏的基本规则和条件。
如何判断球与砖块的碰撞、游戏胜利和失败的条件、分数的计算等,都需要根据具体的游戏设计进行编程实现。
此外,还需要考虑游戏难度的逐渐增加以及关卡的设计等方面。
七、测试与优化在完成游戏的编程实现后,需要进行测试和优化。
通过不断调试和测试,发现和修复程序中的错误,并对性能进行优化,以提高游戏的稳定性和流畅度。
通过以上的步骤,我们可以顺利地完成弹球小游戏的编程实现。
弹球游戏(HTML游戏使用JavaScript开发)

弹球游戏(HTML游戏使用JavaScript开发)HTML游戏已经成为人们在网络上娱乐和消遣的热门选择。
其中,弹球游戏是一种简单而令人上瘾的游戏类型。
通过使用JavaScript开发,我们可以创建一个动态、互动性强的弹球游戏。
本文将介绍如何使用HTML和JavaScript开发一个简单但有趣的弹球游戏。
1. 准备工作在开始编写游戏代码之前,我们需要准备一些基本的文件和资源。
首先,创建一个HTML文件,并在文件中引入JavaScript代码。
其次,我们需要为游戏设计必要的图形资源,如球、挡板和背景图片。
确保这些资源文件被正确引入到HTML文件中。
2. 创建游戏画布游戏画布是显示游戏内容的区域,在HTML中通过<canvas>标签创建。
为<canvas>标签添加一个唯一的id属性,并在JavaScript代码中使用该id获取对画布的引用。
3. 绘制游戏元素在游戏画布上绘制游戏元素,如球和挡板,以及游戏背景。
使用JavaScript的Canvas API,我们可以通过指定坐标和尺寸来定位和绘制这些元素。
4. 定义游戏动画为了使游戏元素能够在画布中运动,我们需要实现一个动画循环。
通过使用JavaScript的requestAnimationFrame函数,在每一帧更新游戏元素的位置,并重新绘制它们,以模拟动画效果。
5. 处理用户输入游戏需要对用户的输入做出相应。
在弹球游戏中,用户通常通过移动挡板来控制球的移动方向。
为了实现这一功能,我们可以通过监听键盘事件或鼠标事件来获取用户输入,并相应地更新挡板的位置。
6. 碰撞检测在弹球游戏中,球与边界或挡板的碰撞是非常重要的。
通过编写碰撞检测函数,我们可以检测球与游戏边界或挡板之间的碰撞,并进行相应的处理,如改变球的移动方向或增加得分。
7. 游戏结束当球与底部边界发生碰撞或达到一定得分时,游戏将结束。
在结束游戏时,我们可以显示得分信息,并提供重新开始游戏的选项。
打台球小游戏

打台球小游戏
1. 开始游戏时,球桌上会放置15个彩色球和一个白球。
彩色球分为红色和彩色两种,红色球每个值1分,彩色球分别为黄色(2分)、绿色(3分)、棕色(4分)、蓝色(5分)、粉红色(6分)和黑色(7分)。
2. 玩家轮流使用球杆击打白球,目标是先将红色球打入袋中,然后再依次打入彩色球。
在打入红色球后,玩家可以选择继续打入红色球或者彩色球,直到所有红色球都被打入袋中。
3. 一旦所有红色球都被打入袋中,玩家需要按照球的分值顺序依次打入彩色球。
游戏直到所有球都被打入袋中或者某一玩家先达到规定的分数为止。
4. 在击球时,玩家需要注意击球的力度和角度,以确保能够准确打入目标球,并且使得白球停在有利的位置上,以便下一杆的击球。
5. 在游戏中,还有一些特殊的规则和技巧,例如犯规、使用花式击球等,这些都可以增加游戏的趣味性和挑战性。
打台球小游戏需要玩家具备一定的眼力、手眼协调能力和战术思维,同时也可以通过不同的击球技巧和策略来增加游戏的趣味性。
希望以上的介绍能够让读者对打台球小游戏有一个清晰的认识,并且能够尝试不同的方法来提高自己的技能和战术水平。
JAVASCRIPT写的台球小游戏

guideBall = table.appendChild(guideBallDiv); } function initBall() { //添加母球 cueBall = new Ball("cue",170,H/2); balls.push(cueBall); //添加目标球 for(var i = 0; i < 5; i++) { for(var j = 0; j <= i; j++) { var ball = new Ball("target",520 + i*2*R, H/2 - R*i + j*2*R); balls.push(ball); } } } function initShootPos() { var wrap = $("shootPos"), handler = $("dot"), arrowR = 18; addEventHandler(wrap,"mousedown",selectDot); function selectDot(e) { e = e || event; var pos = getElemPos(wrap), x = e.clientX - pos[0] - handler.offsetWidth/2, y = e.clientY - pos[1] - handler.offsetHeight/2; if(Math.sqrt((x-22)*(x-22) + (y-22)*(y-22)) > arrowR) { var angle = Math.atan2(x-22,y-22); x = arrowR*Math.sin(angle) + 22; y = arrowR*Math.cos(angle) + 22; } setPos(handler,x,y); } } function getElemPos(target,reference) { reference = reference || document; var left = 0,top = 0; return getPos(target); function getPos(target) { if(target != reference) { left += target.offsetLeft; top += target.offsetTop; return getPos(target.parentNode); } else { return [left,top]; }
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>台球by CNwander</title><style type="text/css">* {margin:0; padding:0}body {background:black; text-align:center; font-size:12px}h1 {font-size:12px; color:gray; font-weight:normal; line-height:200%}h1 .sub {vertical-align:super; color:red; font-size:9px; }.info {position:absolute; right:0; color:gray}#table {position:relative; width:800px; margin:20px auto 10px; height:544px; background:url(/articleimg/2009/10/7086/table.jpg) no-repeat}.ball {position:absolute; width:30px; height:30px}#dotWrap {position:absolute; z-index:2; left:32px; top:32px; width:736px; height:480px}.guide {z-index:3; background-image:url(/articleimg/2009/10/7086/dashed_ball.png);_background:none; _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true', sizingMethod='scale', src="/articleimg/2009/10/7086/dashed_ball.png");background-repeat:no-repeat}.target {left:500px; top:250px; background-image:url(/articleimg/2009/10/7086/yellow_ball.png);_background:none; _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true', sizingMethod='scale', src="/articleimg/2009/10/7086/yellow_ball.png");background-repeat:no-repeat}.cue {background-image:url(/articleimg/2009/10/7086/white_ball.png); _background:none; _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true', sizingMethod='scale', src="/articleimg/2009/10/7086/white_ball.png");background-repeat:no-repeat}.bot {position:relative; width:800px; margin:10px auto 10px; height:70px}.ctrl {position:absolute; top:0; right:0; width:200px; height:80px; background:url(/articleimg/2009/10/7086/bg_controler.png) no-repeat} #force {position:absolute; left:0; top:18px; width:75px; height:20px; background:url(/articleimg/2009/10/7086/force_conver.png) no-repeat} #shootPos {position:absolute; top:0; right:14px; width:52px; height:52px}#dot {position:absolute; top:22px; left:22px; width:8px; height:8px; background:url(/articleimg/2009/10/7086/bule_dot.png) no-repeat; font-size:1px}#scoreBoard {position:absolute; z-index:3; top:230px; left:346px; font-size:50px; color:white; filter:alpha(opacity=0); -moz-opacity:0; opacity:0}#tips {padding:15px 0 0 20px; text-align:left; color:red; font-size:12px} </style><script type="text/javascript">// commonfunction $(str) {return document.getElementById(str);}function $tag(str,target) {target = target || document;return target.getElementsByTagName(str);}function addEventHandler(obj,eType,fuc){if(obj.addEventListener){obj.addEventListener(eType,fuc,false);}else if(obj.attachEvent){obj.attachEvent("on" + eType,fuc);}else{obj["on" + eType] = fuc;}}function removeEventHandler(obj,eType,fuc){if(obj.removeEventListener){obj.removeEventListener(eType,fuc,false);}else if(obj.attachEvent){obj.detachEvent("on" + eType,fuc);}}function randowNum(start,end) {return Math.floor(Math.random()*(end - start)) + start;}Array.prototype.remove=function(dx) {if(isNaN(dx)||dx>this.length){return false;}for(var i=0,n=0;i<this.length;i++){if(this[i]!=this[dx]){this[n++]=this[i]}}this.length-=1}//constvar TOTALR = 15, //球的半径(包括阴影)R = 12, //球真实半径POKER = 20,W = 736, //案宽H = 480, //案高THICKNESS = 32, //边缘厚度RA TE = 100, //刷新频率F = 0.01, //摩擦力LOSS = 0.2, // 碰撞速度损失TIPS = ["Tip1: 参考球,目标球,目标袋,三点一线,这是最基本的进球方法","Tip2: 右下角蓝条代表击球力度,小的力度更便于控制母球位置","Tip3: 右下角白球上的蓝点控制击球点,高杆,低杆,加塞都由它控制,高手与菜鸟的区别往往在此","Tip4: 桌球,其实打的不是目标球,是母球"];var table, //案子cueBall, //母球guideBall, //参考球dotWrap, //参考线speed = 12,rollUp = 0,rollRight = 0,timer,forceTimer,balls = [],movingBalls = [],pokes = [[0,0],[W/2,-5],[W,0],[0,H],[W/2,H+5],[W,H]],hasShot = false;shots = 0; //连击次数window.onload = function() {initTable();initShootPos();showTips();startGame();}function startGame() {initBall();addEventHandler(table,"mousemove",dragCueBall);addEventHandler(table,"mouseup",setCueBall);}function initTable() {table = $("table");var dotWrapDiv = document.createElement("div"),guideBallDiv = document.createElement("div");dotWrapDiv.id = "dotWrap";guideBallDiv.className = "guide ball";setStyle(guideBallDiv,"display","none");dotWrap = table.appendChild(dotWrapDiv);guideBall = table.appendChild(guideBallDiv);}function initBall() {//添加母球cueBall = new Ball("cue",170,H/2);balls.push(cueBall);//添加目标球for(var i = 0; i < 5; i++) {for(var j = 0; j <= i; j++) {var ball = new Ball("target",520 + i*2*R, H/2 - R*i + j*2*R); balls.push(ball);}}}function initShootPos() {var wrap = $("shootPos"),handler = $("dot"),arrowR = 18;addEventHandler(wrap,"mousedown",selectDot);function selectDot(e) {e = e || event;var pos = getElemPos(wrap),x = e.clientX - pos[0] - handler.offsetWidth/2,y = e.clientY - pos[1] - handler.offsetHeight/2;if(Math.sqrt((x-22)*(x-22) + (y-22)*(y-22)) > arrowR) {var angle = Math.atan2(x-22,y-22);x = arrowR*Math.sin(angle) + 22;y = arrowR*Math.cos(angle) + 22;}setPos(handler,x,y);}}function getElemPos(target,reference) {reference = reference || document;var left = 0,top = 0;return getPos(target);function getPos(target) {if(target != reference) {left += target.offsetLeft;top += target.offsetTop;return getPos(target.parentNode);} else {return [left,top];}}}// ball classfunction Ball(type,x,y) {var div = document.createElement("div");div.className = type + " ball";this.elem = table.appendChild(div);this.type = type;this.x = x; //位置this.y = y;this.angle = 0; //角度this.v = 0; //速度(不包含方向)setBallPos(this.elem,x,y);return this;}function setCueBall() {removeEventHandler(table,"mousemove",dragCueBall); removeEventHandler(table,"mouseup",setCueBall); startShot();}function startShot() {show(cueBall.elem);addEventHandler(table,"mousemove",showGuide); addEventHandler(table,"mousedown",updateForce); addEventHandler(table,"mouseup",shotCueBall);}function dragCueBall(e) {var toX,toY;e = e || event;toX = e.clientX - table.offsetLeft - THICKNESS,toY = e.clientY - table.offsetTop - THICKNESS;toX = toX >= R ? toX : R;toX = toX <= 170 ? toX : 170;toY = toY >= R ? toY : R;toY = toY <= H - R ? toY : H - R;setBallPos(cueBall,toX,toY);}function shotCueBall() {removeEventHandler(table,"mousemove",showGuide); removeEventHandler(table,"mousedown",updateForce); removeEventHandler(table,"mouseup",shotCueBall); window.clearInterval(forceTimer);speed = $("force").offsetWidth * 0.15;var dotDisX = $("dot").offsetLeft-22,dotDisY = $("dot").offsetTop-22,dotDis = Math.sqrt(dotDisX*dotDisX + dotDisY*dotDisY), dotAngle = Math.atan2(dotDisX,dotDisY);rollRight = Math.round(dotDis*Math.sin(dotAngle))/5;rollUp = -Math.round(dotDis*Math.cos(dotAngle))/5;var formPos = getBallPos(cueBall.elem),toPos = getBallPos(guideBall),angle = Math.atan2(toPos[0] - formPos[0],toPos[1] - formPos[1]); hide(dotWrap);hide(guideBall);cueBall.v = speed;cueBall.angle = angle;movingBalls.push(cueBall);timer = window.setInterval(roll,1000 / RATE);}function showGuide(e) {var fromX,fromY,toX,toY;e = e || event;toX = e.clientX - table.offsetLeft - THICKNESS,toY = e.clientY - table.offsetTop - THICKNESS;setBallPos(guideBall,toX,toY);show(dotWrap);show(guideBall);drawLine();//参考线function drawLine() {var dotNum = 16,pos = getBallPos(cueBall.elem);dotWrap.innerHTML = "";fromX = pos[0];fromY = pos[1];var partX = (toX - fromX) / dotNum,partY = (toY - fromY) / dotNum;for(var i = 1; i < dotNum; i++) {var x = fromX + partX * i,y = fromY + partY * i;drawDot(dotWrap, x, y);}}}function roll() {if(movingBalls.length <= 0) {if(!hasShot) shots = 0;else shots ++; //累计连击hasShot = false;setStyle($("force"),"width",80+"px"); setPos($("dot"),22,22);window.clearInterval(timer);if(shots > 1) showScore(shots); //显示连击数startShot();}for(var i = 0; i < movingBalls.length; i++) { var ball = movingBalls[i],sin = Math.sin(ball.angle),cos = Math.cos(ball.angle);ball.v -= F;//移除静止的小球if(Math.round(ball.v) == 0) {ball.v = 0;movingBalls.remove(i);continue;}var vx = ball.v * sin,vy = ball.v * cos;ball.x += vx;ball.y += vy;//入袋if(isPocket(ball.x,ball.y)) {hide(ball.elem);if(ball.type == "cue") {if(!hasShot) shots = 0;hasShot = false;window.setTimeout(function(){ball.v = 0;setBallPos(ball,170,250);},500);}else {//移除入袋小球hasShot = true;ball.v = 0;for(var k = 0, l =0; k < balls.length; k++) { if(balls[k] != ball) {balls[l++] = balls[k];}}balls.length -= 1;}return;}//边缘碰撞if(ball.x < R || ball.x > W - R) {ball.angle *= -1;ball.angle %= Math.PI;ball.v = ball.v * (1 - LOSS);vx = ball.v*Math.sin(ball.angle);vy = ball.v*Math.cos(ball.angle);if(ball.x < R) ball.x = R;if(ball.x > W - R) ball.x = W - R;//母球加塞if(ball.type == "cue") {if(ball.angle > 0) vy -= rollRight;else vy += rollRight;vx += rollUp;rollUp *= 0.2;rollRight *= 0.2;ball.v = Math.sqrt(vx*vx + vy*vy);ball.angle = Math.atan2(vx,vy);}}if(ball.y < R || ball.y > H - R) {ball.angle = ball.angle > 0 ? Math.PI - ball.angle : - Math.PI - ball.angle ; ball.angle %= Math.PI;ball.v = ball.v * (1 - LOSS);vx = ball.v*Math.sin(ball.angle);vy = ball.v*Math.cos(ball.angle);if(ball.y < R) ball.y = R;if(ball.y > H - R) ball.y = H - R;//母球加塞if(ball.type == "cue") {if(Math.abs(ball.angle) < Math.PI/2) vx += rollRight;else vx -= rollRight;vy += rollUp;rollUp *= 0.2;rollRight *= 0.2;ball.v = Math.sqrt(vx*vx + vy*vy);ball.angle = Math.atan2(vx,vy);}}//小球碰撞for(var j = 0; j < balls.length; j++) {var obj = balls[j];if(obj == ball) continue;var disX = obj.x - ball.x,disY = obj.y - ball.y,gap = 2 * R;if(disX <= gap && disY <= gap) {var dis = Math.sqrt(Math.pow(disX,2)+Math.pow(disY,2));if(dis <= gap) {//如果是静止的,则添加到数组movingBallsif(Math.round(obj.v) == 0)movingBalls.push(obj);//将坐标旋转到x轴进行碰撞计算// 计算角度和正余弦值- 精确值//var c = (obj.x*ball.y - obj.y*ball.x)/(2*R),// d = Math.sqrt(ball.x*ball.x + ball.y*ball.y),// angle = Math.asin(ball.y/d) - Math.asin(c/d) - ball.angle%(Math.PI/2), //angle = Math.asin(oy / (2 * R)),//还原两球相切状态- 近似值ball.x -= (gap - dis)*sin;ball.y -= (gap - dis)*cos;disX = obj.x - ball.x;disY = obj.y - ball.y;// 计算角度和正余弦值var angle = Math.atan2(disY, disX),hitsin = Math.sin(angle),hitcos = Math.cos(angle),objVx = obj.v * Math.sin(obj.angle),objVy = obj.v * Math.cos(obj.angle);//trace(angle*180/Math.PI);// 旋转坐标var x1 = 0,y1 = 0,x2 = disX * hitcos + disY * hitsin,y2 = disY * hitcos - disX * hitsin,vx1 = vx * hitcos + vy * hitsin,vy1 = vy * hitcos - vx * hitsin,vx2 = objVx * hitcos + objVy * hitsin,vy2 = objVy * hitcos - objVx * hitsin;// 碰撞后的速度和位置var plusVx = vx1 - vx2;vx1 = vx2;vx2 = plusVx + vx1;//母球加塞if(ball.type == "cue") {vx1 += rollUp;rollUp *= 0.2;}x1 += vx1;x2 += vx2;// 将位置旋转回来var x1Final = x1 * hitcos - y1 * hitsin,y1Final = y1 * hitcos + x1 * hitsin,x2Final = x2 * hitcos - y2 * hitsin,y2Final = y2 * hitcos + x2 * hitsin;obj.x = ball.x + x2Final;obj.y = ball.y + y2Final;ball.x = ball.x + x1Final;ball.y = ball.y + y1Final;// 将速度旋转回来vx = vx1 * hitcos - vy1 * hitsin;vy = vy1 * hitcos + vx1 * hitsin;objVx = vx2 * hitcos - vy2 * hitsin;objVy = vy2 * hitcos + vx2 * hitsin;//最终速度ball.v = Math.sqrt(vx*vx + vy*vy) * (1 - 0);obj.v = Math.sqrt(objVx*objVx + objVy*objVy) * (1 - 0);// 计算角度ball.angle = Math.atan2(vx , vy);obj.angle = Math.atan2(objVx , objVy);//break;}}}setBallPos(ball,ball.x,ball.y);}}function isPocket(x,y) {if(y < POKER) return check(0,2);else if (y > H - POKER) return check(3,5);else return false;function check(m,n) {for(var i=m; i<=n; i++) {if(x >= pokes[i][0] - POKER && x <= pokes[i][0] + POKER) {var dis = Math.sqrt(Math.pow(x - pokes[i][0],2) + Math.pow(y - pokes[i][1],2)); if(dis <= POKER) return true;else return false;}}}}function getBallPos(obj) {var pos = [];pos.push(obj.offsetLeft - THICKNESS + TOTALR);pos.push(obj.offsetTop - THICKNESS + TOTALR);return pos;}function setPos(obj,x,y) {obj.style.left = x + "px";obj.style.top = y + "px";}function setBallPos(ball,x,y) {if(ball.constructor == Ball) {ball.x = x;ball.y = y;ball = ball.elem;}setPos(ball,x + THICKNESS - TOTALR,y + THICKNESS - TOTALR); }function drawDot(wrap,x,y) {var elem = document.createElement("div");setStyle(elem,{position: "absolute",width: "1px",height: "1px",fontSize: "1px",background: "white"});setPos(elem,x,y);wrap.appendChild(elem);}function updateForce() {var obj = $("force"),len = 80,up = true;forceTimer = window.setInterval(update,10);function update() {if(up) setStyle(obj,"width",len+++"px");else setStyle(obj,"width",len--+"px");if(len > 136) up = false;if(len <= 0) up = true;}}function setStyle() {if(arguments.length == 2 && typeof arguments[1] == "object") {for(var key in arguments[1]) {arguments[0].style[key] = arguments[1][key];}} else if (arguments.length > 2) {arguments[0].style[arguments[1]] = arguments[2];}}function hide(obj) {setStyle(obj,"display","none");}function show(obj) {setStyle(obj,"display","block");}//输出信息function trace(sth,who) {who = who || $("tips");if(document.all) who.innerText = sth;else who.textContent = sth;return who;}function showScore(n) {var wrap = $("scoreBoard");trace(n+"连杆",wrap);fadeIn(wrap);}function fadeIn(obj){var fromY = 230,posStep = [8,14,19,23,26,28,29,29,30,30,30], opaStep = [0,0.05,0.1,0.15,0.2,0.25,0.3,0.4,0.5,0.6,0.8], fromOpa = 0,t = 0,step = posStep.length,inTimer = window.setInterval(showIn,20), outTimer;function showIn() {setOpacity(obj,opaStep[t]);obj.style.top = fromY + posStep[t] + "px";t++;if(t>=step) {window.clearInterval(inTimer);outTimer = window.setInterval(fadeOut,50);}}function fadeOut() {t--;setOpacity(obj,opaStep[t]);obj.style.top = fromY + posStep[t] + "px";if(t <= 0) {window.clearInterval(outTimer);hide(obj);}}}function setOpacity(obj,n) {obj.style.cssText = "filter:alpha(opacity="+ n*100 +"); -moz-opacity:"+ n +"; opacity:"+ n;}function showTips() {var i = 0;tip();window.setInterval(tip,3000);function tip() {trace(TIPS[i++]);if(i >= TIPS.length) i = 0;}}</script></head><body><div class="info">探讨:<a href="/thread-2951566-1-1.html">Blueidea</a> <a href="/blog/?p=11">Wander's space</a></div><h1>中国人民烎起来!<span class="sub">60周年</span></h1><div id="table"><div id="scoreBoard"></div></div><div class="bot"><div id="tips"></div><div class = "ctrl"><div id="force"></div><div id="shootPos"><div id="dot"></div></div></div></div></body></html>。