弹跳小球Look

一、 框架

1、标题用h1。

2、计数器用p。

3、小球和环都用canvas绘制。


二、功能

1、小球相互碰撞会变颜色。

2、通过键盘改变环的位置。

3、小球碰到环会消失,计数器数量减少。

4、小球会一直移动,碰到边缘会弹回。

三、知识点

1、用面向对象的思想,创建Shape对象,并由他派生出Ball球和Eaters环对象。

        // 定义Shape构造器
        function Shape(x, y, velX, velY, exists) {
            this.x = x;
            this.y = y;
            this.velX = velX;
            this.velY = velY;
            // 用来标记球是否存在于程序中 (没有被恶魔圈吃掉)
            this.exists = exists;
        }

        // 定义Ball构造器,继承自Shape
        function Ball(x, y, velX, velY, exists, color, size) {
            Shape.call(this, x, y, velX, velY, exists);

            this.color = color;
            this.size = size;
        }
        // 给构造器 Ball() 的prototype 和 constructor 属性设置适当的值
        Ball.prototype = Object.create(Shape.prototype);
        Ball.prototype.constructor = Ball;


        // 定义Ball绘制函数:重点研究一下这个写法
        Ball.prototype.draw = function () {
            ctx.beginPath();
            ctx.fillStyle = this.color; // why?
            ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
            ctx.fill();
        };


        // 实例化对象Ball,并传入参数
        let ball = new Ball(
            // 为避免绘制错误,球至少离画布边缘球本甚一倍宽度的距离
            random(0 + size, width - size),
            random(0 + size, height - size),
            random(-7, 7),
            random(-7, 7),
            true,
            randomColor(),
            size
        );

2、监听键盘事件,并判断方向

        // 定义大胃王控制设置方法
        Eaters.prototype.setControls = function () {
            window.onkeydown = e => {
                switch (e.key) {
                    case 'a':
                    case 'A':
                    case 'ArrowLeft':
                        this.x -= this.velX;
                        break;
                    case 'd':
                    case 'D':
                    case 'ArrowRight':
                        this.x += this.velX;
                        break;
                    case 'w':
                    case 'W':
                    case 'ArrowUp':
                        this.y -= this.velY;
                        break;
                    case 's':
                    case 'S':
                    case 'ArrowDown':
                        this.y += this.velY;
                        break;
                }
            };
        };

3、随机数函数、随机颜色函数的编写

        // 生成随机数
        function random(min, max) {
            return Math.floor(Math.random() * (max - min) + min);
        }

        // 生成随机颜色值
        function randomColor() {
            return 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) + ')';
        }

4、边界判断

        // 定义彩球边界测试函数,若球超出边界,更新 velX/velY
        Ball.prototype.update = function () {
            if ((this.x + this.size) >= width) {
                this.velX = -(this.velX);
            }
            if ((this.x - this.size) <= 0) {
                this.velX = -(this.velX);
            }
            if ((this.y + this.size) >= height) {
                this.velY = -(this.velY);
            }
            if ((this.y - this.size) <= 0) {
                this.velY = -(this.velY);
            }

            this.x += this.velX;
            this.y += this.velY;
        };



        // 定义大胃王的边缘检测方法,若超出边界,我们通过增加或减去环的size,来改变x,y的值
        Eaters.prototype.checkBounds = function () {
            if ((this.x + this.size) >= width) {
                this.x -= this.size;
            }
            if ((this.x - this.size) <= 0) {
                this.x += this.size;
            }
            if ((this.y + this.size) >= height) {
                this.y -= this.size;
            }
            if ((this.y - this.size) <= 0) {
                this.y += this.size;
            }
        };

5、canvas绘制

        // 设置画布:通过获取要绘制的 <canvas> 元素,然后调用它的HTMLCanvasElement.getContext()方法
        const canvas = document.querySelector('canvas');
        const ctx = canvas.getContext('2d');

        const width = canvas.width = window.innerWidth;
        const height = canvas.height = window.innerHeight;

            // 背景设为黑色,
            //  strokeStyle和stroke(0是设置图形轮廓(边框)的颜色,fillStyle 和 fill() 是设置图形填充(边框以内)的颜色
            ctx.fillStyle = 'rgba(0,0,0,0.25)';
            ctx.fillRect(0, 0, width, height);
            // canvas.toDataURL('image/jpeg');

        // 定义彩球绘制函数:重点研究一下这个写法
        Ball.prototype.draw = function () {
            ctx.beginPath();
            ctx.fillStyle = this.color; // why?
            ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
            ctx.fill();
        };

6、动画--计时器

requestAnimationFrame的用法与settimeout很相似,只是不需要设置时间间隔而已。requestAnimationFrame使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。它返回一个整数,表示定时器的编号,这个值可以传递给cancelAnimationFrame用于取消这个函数的执行。

应用
  现在分别使用setInterval、setTimeout和requestAnimationFrame这三个方法制作一个简单的进制度效果

1 setInterval
<div id="myDiv" style="background-color: lightblue;width: 0;height: 20px;line-height: 20px;">0%</div>
<button id="btn">run</button>
<script>
var timer;
btn.onclick = function(){
    clearInterval(timer);
    myDiv.style.width = '0';
    timer = setInterval(function(){
        if(parseInt(myDiv.style.width) < 500){
            myDiv.style.width = parseInt(myDiv.style.width) + 5 + 'px';
            myDiv.innerHTML =     parseInt(myDiv.style.width)/5 + '%';    
        }else{
            clearInterval(timer);
        }        
    },16);
}
</script>


2 setTimeout
<div id="myDiv" style="background-color: lightblue;width: 0;height: 20px;line-height: 20px;">0%</div>
<button id="btn">run</button>
<script>
var timer;
btn.onclick = function(){
    clearTimeout(timer);
    myDiv.style.width = '0';
    timer = setTimeout(function fn(){
        if(parseInt(myDiv.style.width) < 500){
            myDiv.style.width = parseInt(myDiv.style.width) + 5 + 'px';
            myDiv.innerHTML =     parseInt(myDiv.style.width)/5 + '%';
            timer = setTimeout(fn,16);
        }else{
            clearTimeout(timer);
        }    
    },16);
}
</script>


3 requestAnimationFrame
<div id="myDiv" style="background-color: lightblue;width: 0;height: 20px;line-height: 20px;">0%</div>
<button id="btn">run</button>
<script>
var timer;
btn.onclick = function(){
    myDiv.style.width = '0';
    cancelAnimationFrame(timer);
    timer = requestAnimationFrame(function fn(){
        if(parseInt(myDiv.style.width) < 500){
            myDiv.style.width = parseInt(myDiv.style.width) + 5 + 'px';
            myDiv.innerHTML =     parseInt(myDiv.style.width)/5 + '%';
            timer = requestAnimationFrame(fn);
        }else{
            cancelAnimationFrame(timer);
        }    
    });
}
</script>

7、碰撞

        // 定义碰撞检测函数
        Ball.prototype.collisionDetect = function () {
            for (var j = 0; j < balls.length; j++) {
                //检验循环到的小球是否是当前 collisionDetect() 小球,不是的话就让当前小球和其他小球依次计算直线距离,距离小于两个球的半径和就碰在一起了
                if (this != balls[j]) {
                    const dx = this.x - balls[j].x;
                    const dy = this.y - balls[j].y;
                    const distance = Math.sqrt(dx * dx + dy * dy);

                    if (distance < this.size + balls[j].size && balls[j].exists) {
                        // 碰一起后小球颜色发生改变
                        balls[j].color = this.color = randomColor();
                    }
                }
            }
        };


        // 定义大胃王与小球碰撞的函数,要检查小球是不是存在,如果小球不存在,说明它已经被恶魔圈吃掉了,那么就不需要再检测它是否与恶魔圈碰撞了。
        Eaters.prototype.collisionDetect = function () {
            for (let j = 0; j < balls.length; j++) {
                if (balls[j].exists) {
                    const dx = this.x - balls[j].x;
                    const dy = this.y - balls[j].y;
                    const distance = Math.sqrt(dx * dx + dy * dy);

                    if (distance < this.size + balls[j].size) {
                        balls[j].exists = false;
                        count--;
                        para.textContent = '剩余彩球数:' + count;
                    }
                }
            }
        };

遇到的问题:

1. 如何改变canvas的背景颜色?

因为canvas整个画布相当于一张图片,所以就是如何改变图片的颜色。

ctx.fillStyle = '#000';
ctx.fillRect(0, 0, width, height);

2. vsCode的 live server插件失效了

百度的解决方法是:若失效则换用Preview on Web Server插件为同样效果。

几分钟后不知道为什么又可以用了,推测是网络问题。

3. notepad 如何对比两个文件

插件》compare安装》重启后点插件》compare》compare即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python弹跳小球是一个简单的游戏,通过使用Python编程语言来模拟小球在不同条件下的弹跳行为。在这个游戏中,你可以控制小球的起始位置、速度和重力等参数,然后观察小球在屏幕上的弹跳运动。 要实现Python弹跳小球,你可以使用Pygame库来创建游戏窗口和处理游戏逻辑。以下是一个简单的实现步骤: 1. 导入Pygame库并初始化游戏: ```python import pygame pygame.init() ``` 2. 设置游戏窗口的大小和标题: ```python width = 800 height = 600 window = pygame.display.set_mode((width, height)) pygame.display.set_caption("Python弹跳小球") ``` 3. 定义小球的属性和初始状态: ```python ball_radius = 20 ball_color = (255, 0, 0) ball_x = width // 2 ball_y = height // 2 ball_speed_x = 5 ball_speed_y = 0 gravity = 0.5 ``` 4. 创建游戏主循环,处理事件和更新小球位置: ```python running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False ball_speed_y += gravity ball_x += ball_speed_x ball_y += ball_speed_y if ball_y + ball_radius > height: ball_speed_y = -ball_speed_y * 0.8 ball_y = height - ball_radius window.fill((255, 255, 255)) pygame.draw.circle(window, ball_color, (ball_x, ball_y), ball_radius) pygame.display.flip() ``` 5. 游戏结束后,退出Pygame: ```python pygame.quit() ``` 这只是一个简单的示例,你可以根据自己的需求和想法来扩展和改进这个游戏。希望对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值