如何用canvas画板实现一个简单的球在盒子内反弹运动

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用canvas画板实现一个简单的球在盒子内反弹运动相关的知识,希望对你有一定的参考价值。

参考技术A 1、创建Canvas画板
html5内声明一个Canvas画板很简单,只需要这样在HTML页面内加入一个canvas标签即可,需要定义其大小和id

view sourceprint?
1.<canvas id="myCanvas" width="400" height="400">
2.对不起,你的浏览器不支持Canvas标签!
3.</canvas>

2、实现方案整理
要实现这样一个球在固定盒子内随机移动我们需要做到以下几点:
1)、画板大小固定;
2)、球大小固定且圆心位置随机;
3)、需要考虑球不出边界;
4)、通过setInterval(function(),speed)方法实现时间间隔通过清空面板和重画模拟球的移动。
3、通过javascript操作画板
1)、初始化变量

view sourceprint?
1.//x和y为球的圆心坐标
2.//speed:表示球移动的速度 单位为毫秒
3.//radius:为球的半径
4.//width和height为盒子大小
5.var w, x,y, speed = 500, radius = 50, width = 400, height = 400;

2)、页面初始化绘制画板且设定时间间隔

view sourceprint?
01.//初始化
02.function init()
03.drawCanvas();
04.setInterval(moveWheel, speed);
05.
06.
07.//画盒子
08.function drawCanvas()
09.//创建Canvas对象
10.var c = document.getElementById("myCanvas");
11.var ctx = c.getContext("2d");
12.//在画布面板上面创建一个矩形
13.ctx.fillStyle = "#000000"; //设置填充颜色值
14.ctx.fillRect(0, 0, width, height);
15.ctx.fill();
16.
17.w = ctx;
18.

3)、随机移动球的实现

view sourceprint?
01.//随机移动球
02.function moveWheel()
03.clearCanvas();
04.drawCanvas();
05.
06.//获得随机坐标
07.x = getRandomNum();
08.y = getRandomNum();
09.
10.//在画布上渲染一个圆形
11.w.fillStyle = '#FFFFFF';
12.w.beginPath();
13.w.arc(x, y, radius, 0, Math.PI * 2, true);
14.w.closePath();
15.w.fill();
16.

4)、获取随机坐标数据

view sourceprint?
1.//获取随机数
2.function getRandomNum()
3.return Math.random() * (width - radius * 2) + radius;
4.

5)、清除画布

view sourceprint?
1.//清除画布
2.function clearCanvas()
3.if (typeof w != "undefined")
4.w.clearRect(0, 0, width, height);
5.
6.

完整示例代码如下所示:

view sourceprint?
01.<!doctype html>
02.<html>
03.<head>
04.<title>HTML5标签Canvas画布练习轮子滚动</title>
05.<meta charset="UTF-8" />
06.</head>
07.<body onload="init();">
08.<h1>Canvas 标签实现一个球限定在盒子内随机移动效果</h1>
09.<canvas id="myCanvas" width="400" height="400">
10.对不起,你的浏览器不支持Canvas标签!
11.</canvas>
12.<script type="text/javascript" language="javascript">
13.//x和y为球的圆心坐标
14.//speed:表示球移动的速度 单位为毫秒
15.//radius:为球的半径
16.//width和height为盒子大小
17.var w, x,y, speed = 500, radius = 50, width = 400, height = 400;
18.
19.//初始化
20.function init()
21.drawCanvas();
22.setInterval(moveWheel, speed);
23.
24.
25.//画盒子
26.function drawCanvas()
27.//创建Canvas对象
28.var c = document.getElementById("myCanvas");
29.var ctx = c.getContext("2d");
30.//在画布面板上面创建一个矩形
31.ctx.fillStyle = "#000000"; //设置填充颜色值
32.ctx.fillRect(0, 0, width, height);
33.ctx.fill();
34.
35.w = ctx;
36.
37.
38.//随机移动球
39.function moveWheel()
40.clearCanvas();
41.drawCanvas();
42.
43.//获得随机坐标
44.x = getRandomNum();
45.y = getRandomNum();
46.
47.//在画布上渲染一个圆形
48.w.fillStyle = '#FFFFFF';
49.w.beginPath();
50.w.arc(x, y, radius, 0, Math.PI * 2, true);
51.w.closePath();
52.w.fill();
53.
54.
55.//清除画布
56.function clearCanvas()
57.if (typeof w != "undefined")
58.w.clearRect(0, 0, width, height);
59.
60.
61.
62.//获取随机数
63.function getRandomNum()
64.return Math.random() * (width - radius * 2) + radius;
65.
66.</script>
67.</body>
68.</html>

过多的代码解释这里就不罗嗦了,核心代码段均有注释,实在有什么不明白的地方随时留言。本回答被提问者和网友采纳

一个在矩形内旋转的球,一个 QML 项目

【中文标题】一个在矩形内旋转的球,一个 QML 项目【英文标题】:A ball rotating inside a rectangle, a QML project 【发布时间】:2017-12-10 07:51:49 【问题描述】:

我在 QML 项目中的 Rectangle 内有一个球动画,如下所示,我希望当它碰到 Rectangle 的边界时,它会返回内部,直到碰到另一个边界,然后再返回,依此类推。

我为此编写了这段代码,但不知道使用什么代码让球在击中边界时返回! 你能帮帮我吗?

ma​​in.qml:

import QtQuick 2.6
import QtQuick.Window 2.2

 Window 
    visible: true
    width: 800
    height: 600
    title: qsTr("Ball_in_Room")

    Rectangle 
        id: root
        width: 700; height: 500
        border.width: 10
        border.color: "gray"
        color: "moccasin"
        property real xPos: root.width
        property real yPos: Math.random() * root.height

        Ball  id: ball 

        ParallelAnimation 
           id: anim
               NumberAnimation 
                        target: ball
                        properties: "x"
                        to: root.xPos
                        duration: 1000
                        easing.type: Easing.Linear
                    
               NumberAnimation 
                        target: ball
                        properties: "y"
                        to: root.yPos
                        duration: 1000
                        easing.type: Easing.Linear
                    
        

         MouseArea 
             anchors.fill: ball
             onClicked: anim.start()
         
       
     

Ball.qml:

import QtQuick 2.8

Rectangle 
    width: 20; height: 20
    x: 250; y: 250
    color: "blue"
    radius: width/2

【问题讨论】:

“返回”是什么意思?你想在这里实现反射效果吗?我认为这个问题与 QML 无关。我不只是计算,你只需要实现一些已知的算法来获得正确的方向和碰撞检测。顺便说一句,您为什么不直接获得一些 2D 引擎而不是自己实现呢?看看qml-box2d Box2D QML 插件。 谢谢。 (+1)。是的,我的意思是反思。考虑一下你在一个房间里,用你的脚射球。它朝房间的墙壁移动,然后反射回来并撞到房间的另一面墙壁,然后再次发生,直到球停止。我的意思是如何让球触到人墙并反弹等等。我想解决这个练习。 【参考方案1】:

弹跳球的非常简单的实现:

Rectangle 
    id: container
    anchors.fill: parent
    border.color: "orange"
    border.width: 3

    Rectangle 
        id: ball
        property double xincrement: Math.random() + 0.5
        property double yincrement: Math.random() + 0.5
        width: 50
        height: width
        radius: width / 2
        color: "lightgreen"
        x: 300
        y: 300

        Timer 
            interval: 1
            repeat: true
            running: true
            onTriggered: 
                ball.x = ball.x + (ball.xincrement * 2.0);
                ball.y = ball.y + (ball.yincrement * 2.0);
                if(ball.x <= 0 || ball.x + ball.width >= container.width)
                    ball.xincrement *= (-1);
                if(ball.y <= 0 || ball.y + ball.height >= container.height)
                    ball.yincrement *= (-1);
            
        

    

【讨论】:

感谢您的回答。我可能有更多问题要问您,如果可能,请继续指导我。 我的问题是关于 timer 正文中的最后一个 if 。当 ball.y 时,表示球正在接触容器的顶部,因此我们将 ball.yincrement 乘以 -1 使其为负数。那是减少球的y坐标。但是为什么在这种情况下球仍然向下移动(“增加” y 坐标)!? 正如我所说,这是非常简单的实现,可能会忽略一些特定情况。如果您的目标当然不是​​自己发明,我仍然建议您使用一些 2D 引擎。 我需要这样完成这个游戏。我不了解 2D 游戏引擎,但这个简单的游戏对我来说就像是一个练习。如果可能,请告诉我为什么当 ball.y 为零时,减小其 y 坐标会使其向下移动!?它应该使它在逻辑上向上移动。 好吧,我猜你做到了。无论如何,您可以使用调试器对其进行检查。对我来说,这段代码运行良好,也许你的用例不同。

以上是关于如何用canvas画板实现一个简单的球在盒子内反弹运动的主要内容,如果未能解决你的问题,请参考以下文章

canvas画布实现一个动态效果小demo(滚动圆)

canvas画布实现一个动态效果小demo(滚动圆)

canvas画布实现一个动态效果小demo(滚动圆)

canvas绘画板效果 html+css+js

canvas绘画板效果 html+css+js

球在全息镜头中穿过地面,但在统一时效果很好。空间映射