zoukankan      html  css  js  c++  java
  • html5 乒乓球(碰撞检测)

    演示地址

    http://koking.8u.hanmandarin.com/html5/1.html

    简单介绍

    小球可以在方框内部自由运动

    可以通过方向键控制黑色砖块上下左右移动去与小球发生碰撞

    代码实现

    <!--
    To change this template, choose Tools | Templates
    and open the template in the editor.
    -->
    <!DOCTYPE html>
    <html>
        <head>
            <title>乒乓球游戏</title>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
            <script>
                var ctx;
    			var canvas;
    			
    			var ball_x=10;
    			var ball_y=10;
    			var ball_radius=10;
    			var ball_vx=10;
    			var ball_vy=8;
    			
    			var wall_x=30;
    			var wall_y=40;
    			var wall_width=30;
    			var wall_height=60;
    			
    			var box_x=0;
    			var box_y=0;
    			var box_width=300;
    			var box_height=300;
    			
    			var bound_left=box_x+ball_radius;
    			var bound_right=box_x+box_width-ball_radius;
    			var bound_top=box_y+ball_radius;
    			var bound_bottom=box_y+box_height-ball_radius;
    			
    			var unit=10;
                            
                            function intersect(sx, sy, fx, fy, cx, cy, rad)
                            {
                                var dx;
                                var dy;
                                var t;
                                var rt;
                                dx = fx - sx;
                                dy = fy - sy;
                                t = 0.0 - (((sx - cx) * dx + (sy - cy) * dy) / (dx * dx + dy * dy));
                                if (t < 0.0)
                                {
                                    t = 0.0;
                                }
                                else if (t > 1.0)
                                    t = 1.0;
                                var dx1 = (sx + t * dx) - cx;
                                var dy1 = (sy + t * dy) - cy;
                                var rt = dx1 * dx1 + dy1 * dy1;
                                if (rt < rad * rad)
                                    return true;
                                else
                                    return false;
                            }
    			function move_ball()
    			{
    				ball_x=ball_x+ball_vx;
    				ball_y=ball_y+ball_vy;
    				if(ball_x<bound_left)
    				{
    					ball_x=bound_left;
    					ball_vx=-ball_vx;
    				}
    				if(ball_x>bound_right)
    				{
    					ball_x=bound_right;
    					ball_vx=-ball_vx;
    				}
    				if(ball_y<bound_top)
    				{
    					ball_y=bound_top;
    					ball_vy=-ball_vy;
    				}
    				if(ball_y>bound_bottom)
    				{
    					ball_y=bound_bottom;
    					ball_vy=-ball_vy;
    				}
                                    //撞到上边
                                    if(intersect(wall_x,wall_y,wall_x+wall_width,wall_y+wall_height,ball_x,ball_y,ball_radius))
                                    {
                                        ball_y=wall_y-ball_radius;
                                        ball_vy=-ball_vy;
                                    }
                                    //撞到左边
                                     if(intersect(wall_x,wall_y,wall_x,wall_y+wall_height,ball_x,ball_y,ball_radius))
                                    {
                                        ball_x=wall_x-ball_radius;
                                        ball_vx=-ball_vx;
                                    }
                                    //撞到右边
                                     if(intersect(wall_x+wall_width,wall_y,wall_x+wall_width,wall_y+wall_height,ball_x,ball_y,ball_radius))
                                    {
                                        ball_x=wall_x+wall_width+ball_radius;
                                        ball_vx=-ball_vx;
                                    }
                                    //撞到下边
                                     if(intersect(wall_x,wall_y+wall_height,wall_x+wall_width,wall_y+wall_height,ball_x,ball_y,ball_radius))
                                    {
                                        ball_y=wall_y+wall_height+ball_radius;
                                        ball_vy=-ball_vy;
                                    }
    			}
    			function move_wall(ev)
    			{
    				var keyCode;
    				if(event==null)
    				{
    					keyCode=window.event.keyCode;
    					window.event.preventDefault();
    				}
    				else
    				{
    					keyCode=event.keyCode;
    					event.preventDefault();
    				}
    				switch(keyCode)
    				{
    					case 37://left;
    					wall_x-=unit;
                                            if(wall_x<bound_left)
                                                wall_x=bound_left;
    					break;
    					case 38://up
    					wall_y-=unit;
                                            if(wall_y<bound_top)
                                                wall_y=bound_top;
    					break;
    					case 39://right
    					wall_x+=unit;
                                            if(wall_x+wall_width>bound_right)
                                                wall_x=bound_right-wall_width;
    					break;
    					case 40://down
    					wall_y+=unit;
                                            if(wall_y+wall_height>bound_bottom)
                                                wall_y=bound_bottom-wall_height;
    					break;
    					default:
    					break;
    				}
    			}
    			function draw_all()
    			{
                                ctx.beginPath();
    				ctx.clearRect(box_x,box_y,box_width,box_height);
    				
    				ctx.fillStyle="rgb(255,0,0)";
    				//ctx.lineWidth=ball_radius;
    				ctx.arc(ball_x,ball_y,ball_radius,0,Math.PI*2,true);
    				ctx.fill();//note
    				ctx.fillStyle="rgb(0,0,0)";
    				ctx.fillRect(wall_x,wall_y,wall_width,wall_height);
    				
    				ctx.strokeRect(box_x,box_y,box_width,box_height);
    			}
    			function init()
    			{
    				canvas=document.getElementById('canvas');
    				ctx=canvas.getContext('2d');
    				draw_all();
    				setInterval(draw_all,100);
                                    setInterval(move_ball,50);
    				window.addEventListener('keydown',move_wall,false);//note
    			}
             </script>
        </head>
        <body onLoad="init();">
            <canvas id="canvas" width="300" height="300"></canvas>
        </body>
    </html>
    


    难点

    小球和砖块的碰撞检测以及碰撞处理

    将砖块分解为4条线段

    分别对小球和每条线段进行碰撞检测。

    小球和线段的碰撞检测在另一篇文章

    http://blog.csdn.net/foreverkoking/article/details/9453831

    中有介绍。

  • 相关阅读:
    document.getElementById("mytxt").style.left=""style.left在IE的FF中注意
    asp.net 用户控件中 使用相对路径的解决方法 图片路径问题(用户控件、图片路径) ,ResolveUrl
    探索 Block (一) (手把手讲解Block 底层实现原理)
    iOS 多线程开发 (概念与API简介)
    iOS 性能小点
    iOS runtime (二)(runtime学习之AutoCoding源码分析)
    探索 NSRunLoop (二)(NSRunLoop 自己动手实现SimpleRunLoop)
    iOS NSNotificationCenter (自己实现一个通知中心XMCNotificationCenter)
    iOS runtime (三)(runtime学习之YYModel源码分析)
    iOS runtime(一)(runtime 分析理解)
  • 原文地址:https://www.cnblogs.com/java20130725/p/3215816.html
Copyright © 2011-2022 走看看