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

    中有介绍。

  • 相关阅读:
    Basic4android v3.20 发布
    KbmMW 4.40.00 正式版发布
    Devexpress VCL Build v2013 vol 13.2.2 发布
    KbmMW 4.40.00 测试发布
    kbmMWtable for XE5 接近尾声
    使用delphi 开发多层应用(二十一)使用XE5 RESTClient 直接访问kbmmw 数据库
    为什么有些东西,反反复复总是学不会
    心灵沟通
    <转>离婚前夜悟出的三件事
    c++ socket 客户端库 socks5 客户端 RudeSocket™ Open Source C++ Socket Library
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3215074.html
Copyright © 2011-2022 走看看