看萧井陌b站直播第一集的收获,附代码

通过观看萧井陌的JavaScript游戏开发直播录播,作者回顾了自己的编程学习历程,并分享了关于编程思维转变的心得体会,包括从记流水账式的编程到重构的重要性,以及如何将面向对象编程与实际项目结合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看了萧井陌在b站直播的录播第一集,收获颇大,遂记录一下;


直播中使用的语言是JavaScript,我之前学web后台的时候,对js有一个简单的了解,因为学过C++和Java,所以看录播的时候虽然有些语法不太习惯,但也能够理解;
收获主要集中在两个方面:一是写代码的方式,主要是一个思维过程;二是重构;
我最近两年才学的C++和Java,并没有写过实际的项目,感触也不多;大学的时候,自学Delphi,写过一些小程序;虽然Delphi的知识已经忘完了,但是写代码时的感觉还记得,当时写代码,就好像是记流水账,写的时候非常的畅快,和该录播的前25分钟差不多,因为当时的写的小程序代码量不大,只有数百行,心里也没有什么高内聚,低耦合,可复用之类的概念,除了debug的时候痛苦了一点,也感受不到啥缺点;学习Java的时候,慢慢的接触了面向对象的思想(虽然学习Delphi的时候,也有这个思想,但是那个时候,最大的感觉是面向控件,估计是当时学艺不精),知道了写代码不仅仅是当时能够运行就行了,还要考虑可复用,可移植,可扩展等等,但是毕竟没有经过大量代码的洗礼,还不能够深刻理解这些;
说实话,我现在也不清楚写代码的顺序,是像视频中萧老师那样,先记流水账,在重构呢,还是先抽象,再具体,比如面向接口编程;很多人推崇面向接口编程,我也尝试过,然后发现作为一个初学者,我没有把对象抽象出来的能力,前几天用Java写了一个爬虫,我开始的时候想先把框架搭出来,把对象都抽象出来,发现做不到,后来还是边写边重构;等下次再写爬虫的时候,应该就能先搭架子了;或许别人说的面向接口编程,也是说给有一定编程经验的人听的,我考虑的有些提前了,等多重构几次,或许就习惯了;
以前我写流水账就是流水账,后来学Java就是直接的面向对象,萧老师的直播帮我把这两者联系起来了,这便是我看了第一集最大的收获;
写的比较啰嗦,因为是初学者,也想顺便总结一下自己的学习历程;


直播中,萧老师有说会把代码上传的,但是我没找到,我把我看视频时跟着写的代码贴在下边,供后来者参考:
//25min时的,之后的就开始封装重构了,和这时的代码完全变样了;

<!DOCTYPE html>

<html>
    <head>
        <meta charset="utf-8">
        <title>game 1</title>
        <style media="screen">
            canvas {
                border:1px black solid;
            }
        </style>    
    </head>

    <body>
        <canvas id="id-canvas" width="800" height="600"></canvas>
        <script>
            var log = console.log.bind(console)
            var canvas = document.querySelector('#id-canvas')
            var context = canvas.getContext('2d')

            var x = 100
            var y = 100
            var speed = 5
            var img = new Image()
            img.src = 'paddle.png'
            log(img)
            img.onload = function(){
                context.drawImage(img, x, y)
            }

            var leftDown = false
            var rightDown = false

            // events
            window.addEventListener('keyup',function(event){
                log('keyup')
                var k = event.key
                log(k)
                if(k == 'a') {
                    leftDown = false
                } else if (k == 'd') {
                    rightDown = false
                }
            })
            window.addEventListener('keydown',function(event){
                var k = event.key
                log(k)
                if(k == 'a') {
                    leftDown = true
                } else if (k == 'd') {
                    rightDown = true
                }
            })

            //设置每秒刷新次数,即fps
            setInterval(function(){
            //update x
                if (leftDown) {
                    x -= speed
                } else if (rightDown) {
                    x += speed
                }

            //可以在这个地方加个限制,把图片移动的范围限制在画面中;
            //dray
                context.clearRect(0, 0, canvas.width, canvas.height)
                context.drawImage(img, x, y)

            },1000/30)
        </script>
    </body>
</html>

//以下是第一集的最终代码

<!DOCTYPE html>
<!--
这个注释中的东西是我看视频时的总结、记录
重构:
    1.定义一个入口;
    2.把所有的代码都放在入口中;

目的:高内聚,低耦合

命名规范之函数命名:
    如果这个函数表达的是一个动作,那么以动词开头,不要用介词,比如to
-->
<html>
    <head>
        <meta charset="utf-8">
        <title>game 1</title>
        <style media="screen">
            canvas {
                border:1px black solid;
            }
        </style>
    </head>

    <body>
        <canvas id="id-canvas" width="800" height="600"></canvas>

        <script>
            var log = console.log.bind(console)
            var imageFromPath = function(path) {
                var img = new Image()
                img.src = path
                return img
            }

            var Paddle = function() {
                var image = imageFromPath('paddle.png') 
                //这个形式有点像C++中的struct
                var o = {
                    image: image,
                    x: 100,
                    y: 500,
                    speed:15,
                    //此处最后一定要加个逗号(,),为了一致性;以后增删都简单;据说ie6会报错
                }
                o.moveLeft = function() {
                    o.x -= o.speed
                }
                o.moveRight = function() {
                    o.x += o.speed              
                }
                //函数参数之前不加参数类型,真的好不习惯
                o.collide = function(ball) {
                    if(ball.y + ball.image.height > o.y) {
                        if(ball.x > o.x && ball.x < o.x + o.image.width) {
                            log('相撞')
                            return true 
                        }   
                    }
                    return false    
                }
                return o
            }

            var Ball = function() {
                var image = imageFromPath('ball.png')
                var o = {
                    image: image,
                    x: 100,
                    y: 200,
                    speedX:10,
                    speedY:10,
                    fired: false,
                    //此处最后一定要加个逗号(,),为了一致性;以后增删都简单;据说ie6会报错
                }
                o.move = function() {
                    if (o.fired) {
                        log('move')
                        if (o.x < 0 || o.x > 800) {
                            o.speedX = -o.speedX
                        }

                        if (o.y < 0 || o.y > 600) {
                            o.speedY = -o.speedY
                        }
                        //move
                        o.x += o.speedX
                        o.y += o.speedY
                    }
                }
                o.fire = function() {
                    o.fired = true
                }
                return o
            }

            var GuaGame = function() {
                var g = {
                    actions: {},
                    keydowns: {},
                }
                var canvas = document.querySelector('#id-canvas')
                var context = canvas.getContext('2d')

                g.canvas = canvas
                g.context = context
                //draw
                g.drawImage = function(guaImage) {
                    g.context.drawImage(guaImage.image, guaImage.x, guaImage.y)
                }

                //events
                window.addEventListener('keydown',function(event){
                    log('keydown')
                    g.keydowns[event.key] = true
                })
                window.addEventListener('keyup',function(event){
                    g.keydowns[event.key] = false
                })

                //
                g.registerAction = function(key, callback) {
                    g.actions[key] = callback
                }

                //timer:设置每秒刷新次数,即fps
                setInterval(function(){
                    //events
                    var actions = Object.keys(g.actions)
                    for (var i = 0;i < actions.length; i++) {
                        var key = actions[i]
                        if(g.keydowns[key]) {
                            //如果按键被按下,调用注册的action
                            g.actions[key]()
                        }
                    }
                //update
                g.update()
                //clear
                context.clearRect(0, 0, canvas.width, canvas.height)
                //draw
                g.draw()
                },1000/30)
                return g
            }

            var __main = function() {
                var game = GuaGame()    
                var paddle = Paddle()
                var ball = Ball()

                game.registerAction('a',function(){
                    paddle.moveLeft()
                })

                game.registerAction('d',function(){
                    paddle.moveRight()
                })

                game.registerAction('f',function(){
                    ball.fire()
                })

                game.update = function() {
                    ball.move()
                    //判断相撞
                    if(paddle.collide(ball)) {
                        //这里应该调用一个ball.反弹()来实现;
                        ball.speedY *= -1
                    }
                }

                game.draw = function() {
                    //draw
                    game.drawImage(paddle)
                    game.drawImage(ball)
                }
            }

            __main()
        </script>
    </body>
</html>
------------------------课程介绍------------------------ 第1章 HTML、CSS、布局 第2章 JavaScript 介绍 第3章 作业讲解、编程的选择结构和函数返回值和库、css初步、函数参数 第4章 数组和字符串、作业讲解、debug大法 第5章 作业讲解、如何方便地用测试写代码、break&continue;语句、object、读文档、递归 第6章 网页中引入JavaScript代码、DOM、事件 第7章 数据类型、多行字符串和转义符号、高阶函数、匿名函数 第8章 事件委托、时间操作、标签的可编辑属性、(本地存储) 和 JSON 格式 第9章 作业选讲、抽象化, 如何封装功能, 如何组织代码结构、变量命名的方法 第10章 HTTP 协议 和 AJAX、DOM 事件机制, 事件冒泡和事件捕获 第11章 面向对象、ajax、作业和代码思路 第12章 找工作基础、ajax作业、api封装 第13章 jQuery 常见用法、课程重点、常用组件例如弹窗的制作 第14章 作业讲解 第15章 log的要素、git和github、js的一些高级内容 bind apply call、前端CSS框架Bootstrap和Pure 第16章 JS的历史现状和未来、什么是ES6有什么新东西、CSS最基础的套路 第17章 前端工程师 第1章 网址组成、端口、HTTP协议、web服务器 第2章 作业讲解、服务器框架、html和getpost传递参数 第3章 基本框架、框架解释、model解释 第4章 cookie讲解、session讲解、作业讲解和调试技巧 第5章 todo程序、todo的更新和删除、带用户功能的todo程序 第6章 jinja模板套路、类和其他、作业讲解 第7章 摘要算法、加盐保护密码-数据库索引原理、微博程序 第8章 传统数据库、sql注入和mongo安装使用、mongo日常使用 第9章 前端基础、dom和事件、js todo 第10章 ajax 第11章 css 第12章 linux基础 第13章 flask框架 第14章 使用sshkey连接linux服务器、rsa原理和git软件使用、使用git软件同步本地和服务器代码 第15章 flask的session和cookie、flask留言板&web;后端栈、flask博客套路 第16章 抓包&爬虫基础、爬虫精讲、编码&API; 第17章 数据结构基础和算法分析原理、链表队列栈和四大结构、平衡二叉搜索树和哈希表 第18章 bbs基础、bbs标题和回复、bbs其他 第19章 web安全和应对、服务器的配置文件处理、开发论坛的板块功能 第20章 论坛收尾、迁移mongo、性能 第21章 操作系统、python高级 第22章 python高级技巧、rpc实现和vagrant 第23章 架构、分布式、性能、聊天室项目 第24章 简历和工作、工作后的计划、学习的计划
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值