`

[转]小黑之天地培训学习手记——第三、四周

阅读更多
http://bbs.9ria.com/viewthread.php?tid=79563&extra=page%3D1%26amp%3Borderby%3Ddateline%26amp%3Bfilter%3D2592000

最近忙得很……在干一些不为人知的事。。=。 =。菜头帮的兄弟都叫我快点更新贴子,并喷得我体无完肤……其实我也想发,现在好了,终于可以写到了。
          这次要写2周的东西。嘛,中途放了清明节,所以课程也不会很多。而且主要讲的是OOP思想神马的,所以不会很多实际上的知识。(想问各位愚人节过得怎么样。)
         上周再上周4是由黑羽大叔……大哥亲自上阵……教我们殿堂之路之失落的60页。
          黑羽讲的课基本是没有写什么代码的,都是OOP思想的一些法则,为了使我们这些新手少走弯路。这是内功啊~
       编程有4条法则,新手们最好按照这个来做。
                             1、        宁用复合不用继承。
                             2、        200行代码需警惕,500行有问题
                              3、        继承不过5层
          我擦,忘记了1条……对此我表示淡定。
           对应的法则我来解说一下:
        1、        新手用继承可能会产生混乱,例如一台电脑,它需要刻录东西的时候,就需要刻录功能了,于是继承了刻录机,就有了刻录功能。但换一种方式思考,我电脑继承刻录机……电脑是刻录机的儿子……好吧,这感觉不太爽,电脑会抗议的。这是新手容易犯的错误。虽然这样做可以达到目的,但这样就太委屈电脑了吧。
再看复合,我电脑缺少刻录功能,于是把刻录机拿过来集成在里面。这下爽了,下次内存不足的时候也直接拿一条好了。

         2、        新手写程序时,类不要分得太多,也不要把所有东西放在一个类中。因为这很容易牵一发动全身的。而且代码不能重用。最主要的是读那代码会很辛苦的。
这让我想起以前到现在都在研究的一个飞机游戏。单单类文档就580行,而且很少注释。看着它我感到很茫然,作为一个新手的我感到鸭梨很大……

         3、        如果真的要用继承的话,新手们,不要超过3层了,否则逻辑很容易混乱的,黑羽说,6层以上的是架构师们的事了。除非你是爱因斯坦吧(貌似现在英国有个13岁的小女孩智商比爱因斯坦还高?)。

             最近菜头帮上老在讨论着设计模式。其实嘛,作为新手就对这个不需要太过于执着,但也不太过于冷淡。设计模式在我们写代码过程中就很自然地形成的。这时cobersky就来句惊人发言了:让你写一辈子的HelloWorld也写不出一个windows。

      (我……我什么时候才能写出一个HelloWorld啊T^T……)

      好吧,但先让我们新手写好这个HelloWorld好么?
         要学设计模式就去看秋神的贴子吧。
          http://bbs.9ria.com/thread-77927-1-1.html

        另外黑羽要求我们去看看这些
OO五大原则(1.SRP 单一职责原则) 
OO五大原则(2.OCP——开闭原则)
OO五大原则(3.LSP——里氏替换原则)
“依赖倒转”原则(DIP)
OOD的设计原则--接口隔离原则


好吧,这星期讲了一下二维数组。
所谓二维数组。也只是
Var ary1:array = new array();
Var ary2:array = new array();
Var ary:array = new array();
ary.push(ary1);
ary.push(ary2);
这样而已。
把一个数组放到另一个数组。
(坑爹啊。大学时的老师有木有这样说!!!!!!!纯洁的计算机学生你伤不起啊!!!!!!!!!!)
                二维矩形使用实例如附件,不解说了。无力啊……囧~
array.rar (1018 Bytes)

                 第二个实例,永恒的打砖头游戏……
               前面已经放过一个大砖头的代码了,但那个只写在时间轴上。这次我们分开类来写。
                首先,我们需要砖头(Brick),小球(Ball),挡板(Bar),文档类(BlickBreak)
               我们让他们做自己的东西,然后在文档类结合起来。
        1、        砖头,砖头什么都不用做,纯粹的小受,那也太无聊了,我们就给个HP给他。
                     private var HP:int = 4*Math.random();
                     这个设置成私有,否则就对砖头太不负责任了,那么文档类怎么获得他呢?
                    用setter和getter吧。
                    写好setter和getter后就够了。
package
{
        import flash.display.Graphics;
        import flash.display.Sprite;
        public class Brick extends Sprite
        {
                private var HP:int = 4*Math.random();
                
                public function Brick()
                {
                        drawBrick();
                }
                //画画
                private function drawBrick():void
                {
                        var g:Graphics = this.graphics;
                        g.beginFill(0x000000);
                        g.drawRect(0,0,50,20);
                        g.endFill();
                }
                //我们只需要知道HP是否为0
                public function get getHP():Boolean
                {
                        return HP == 0;
                }
                //设置HP
                public function set setHP(Num:int):void
                {
                        HP = HP - Num;
                }
        }
}


2、        我们小球需要运动,于是就需要增加一个EnterFrame事件了(可以不在小球那里添加enterFrane事件,只在小球里加了个公开的函数让文档类的enterframe调用,效果是差不多的。不过这样貌似增加了文档类和小球的耦合,改代码会麻烦点。)
运动嘛,就需要一个速度,X轴速度和Y轴速度,并且要写一个函数让小球跑到边界时会反弹。小球基本完成,以后需要什么再添加
package
{
        import flash.display.Graphics;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.EventDispatcher;
        
        public class Ball extends Sprite
        {
                //球的各种速度
                private var speedX:int = 10;
                private var speedY:int = 10;
                public function Ball()
                {
                        draw();
                        this.addEventListener(Event.ENTER_FRAME,gameStep);
                }
                
                //画小球
                private function draw():void
                {
                        var g:Graphics = this.graphics;
                        g.beginFill(0x000000);
                        g.drawCircle(-6,-6,6);
                        g.endFill();
                }
                //游戏运行时
                public function gameStep(evt:Event):void
                {
                        ballMove();
                        checkBall();
                }
                //小球移动
                private function ballMove():void
                {
                        this.x += speedX;
                        this.y += speedY;
                }
                //检测小球有没出界
                private function checkBall():void
                {
                        if(this.x > stage.stageWidth - 2 || this.x < 0) speedX = -speedX;
                        if(this.y > stage.stageHeight - 2 || this.y < 0)speedY = -speedY;
                }
                //设置小球X坐标和Y坐标
                /**
                 * 每次Y轴速度只需要取相反的。所以每次改变速度只需要传入-1就好了。
                 * 而X轴可能会改变,可能不变,因为撞到砖头的话X轴速度是不变的。
                 * 于是我们设一个不会取到的默认值,再判断一下就好了。
                 * */
                public function speedXY(Y:Number,X:Number = 100):void
                {
                        speedY = speedY*Y;
                        if(X != 100) speedX = X;
                }
                
        }
}


3、        挡板,无非就是左右移动了。然后就是左移动和右移动,移动可以用鼠标移动,也可以用键盘移动,键盘移动的话要有一个X轴速度。我用了键盘移动,所以要写个控制移动的接口函数。
package
{
        import flash.display.Graphics;
        import flash.display.Sprite;
        
        public class Bar extends Sprite
        {
                //挡板移动速度
                private var speed:int = 7;
                
                public function Bar()
                {
                        draw();
                        
                }
                
                //画画
                private function draw():void
                {
                        var g:Graphics = this.graphics;
                        g.beginFill(0x000000);
                        g.drawRect(-40,0,70,10);
                        g.endFill();
                }
                //向左移动
                public function moveLeft():void
                {
                        this.x -= speed;
                }
                //向右移动
                public function moveRight():void
                {
                        this.x += speed;
                }
        }
}


4、        最后就是文档类了,这货任重而道远。首先在他上面添加各种我们需要的物件。接着是添加各种侦听,enterframe和键盘侦听。
文档类在enterframe中要做的事是检测砖头状态(检测砖头有没被撞,血量多少),检测挡板有没被撞,撞后怎样报复小球-b-……还有是挡板的控制。
package
{
        import flash.display.DisplayObject;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.KeyboardEvent;
        
        
        public class BlickBreak extends Sprite
        {
                
                private var brick:Brick;                        //砖头
                private var ball:Ball = new Ball();        //小球
                private var bar:Bar = new Bar();        //挡板
                //砖头数量
                private var BrickNum:int = 20;
                //存放砖头的数组
                private var brickArray:Array = new Array();
                
                //按左和按右
                private var KeyLeft:Boolean ;
                private var KeyRight:Boolean;
                
                
                public function BlickBreak()
                {
                        addSomething();
                        //添加各种侦听
                        stage.addEventListener(KeyboardEvent.KEY_DOWN,KeyDownHandler);
                        stage.addEventListener(KeyboardEvent.KEY_UP,KeyUpHandler);
                        this.addEventListener(Event.ENTER_FRAME,gameStep);
                }
                //键盘按下
                private function KeyDownHandler(evt:KeyboardEvent):void
                {
                        if(evt.keyCode == 65) KeyLeft = true;
                        if(evt.keyCode == 68) KeyRight = true;
                }
                //抬起
                private function KeyUpHandler(evt:KeyboardEvent):void
                {
                        if(evt.keyCode == 65) KeyLeft = false;
                        if(evt.keyCode == 68) KeyRight = false;
                }
                //各种addChild
                private function addSomething():void
                {
                        addBrick(BrickNum);
                        addChild(ball);
                        ball.x = 200;
                        ball.y = 200;
                        addChild(bar);
                        bar.x = 350;
                        bar.y = 350;
                }
                //添加砖头
                private function addBrick(Num:int):void
                {
                        for(var i:int = 0; i < Num ;i++){
                                brick = new Brick();
                                addChild(brick);
                                brick.x = i%int(stage.stageWidth/50)*53;
                                brick.y = int(i/int(stage.stageWidth/50))*24;
                                brickArray.push(brick);
                        }
                }
                //游戏进行时
                private function gameStep(evt:Event):void
                {
                        checkBrick();
                        checkHitbar();
                        control();
                        
                }
                //检测小球与挡板碰撞
                private function checkHitbar():void
                {
                        if(hitTest(bar,ball)){
                                //碰撞后改变小球运动状态。
                                ball.speedXY(-1,(ball.x - bar.x)/bar.width*20)
                        }
                }
                
                //键盘控制挡板
                private function control():void
                {
                        if(KeyLeft == true) bar.moveLeft();
                        if(KeyRight == true) bar.moveRight();
                }
                
                //检测砖头状态
                private function checkBrick():void
                {
                        for (var i:int = 0;i < brickArray.length;i++){
                                var mc:Brick = brickArray[i];
                                if(hitTest(ball,mc)){
                                        ball.speedXY(-1);
                                        checkHP(mc,i);
                                        
                                }
                        }
                }
                //检查砖头剩余HP
                private function checkHP(mc:Brick,i:int):void
                {
                        if(mc.getHP){
                                reMoveChild(mc);
                                brickArray.splice(i,1);
                        }else mc.setHP = 1;
                }
                //移除某东东
                private function reMoveChild(mc:DisplayObject):void
                {
                        if(this.contains(mc)) this.removeChild(mc);
                }
                
                
                //碰撞检测
                private function hitTest(mc1:DisplayObject,mc2:DisplayObject):Boolean
                {
                        return mc1.hitTestObject(mc2);
                }
        }
}


各个类都做着自己的事,除了文档类= =。该公开的公开,该自己做的事自己做。。

实例三。纯爷都应该做的(是男人就下1000层。还有别的名字么。。= =)
算了,这个不说了,直接放源码……
我用了5个类,文档类,玩家类,控制类,地图,踏板。
要说的几点,首先是检测有没踏上踏板。
//判断是否踩在踏板上
               private function hitTest(plate:Plate):Boolean
                {
                        return char.Top < plate.Top &&
                                char.Right > plate.Left &&
                                char.Left < plate.Right &&
                                char.Bottom > plate.Top 
                }


我翻译一下,画个图吧。
一下是玩家的图示。




      那么上面的碰撞是怎样判断呢。我们先看图,假如,玩家与踏板之间还有5点像素间隙。而玩家现在的速度是6像素。




      这样的话下一帧玩家肯定会落在踏板上吧。那么char.Bottom > plate.Top这句就返回true了。
再看,char.Left < plate.Right,玩家的左边界的X轴坐标现在已经比踏板小了,下一帧也一样。于是这句也返回true。那么怎样才是false呢?如图。




char.Right > plate.Left同上。不解释

      最后是char.Top < plate.Top。这个,老师不是这样写的,我只是省时间。老师是记录碰撞后的上一帧位置作判断的。当然是老师的好了,我这种会有个猫腻,我只是懒。。=。 =。。那么为什么这样写也可以呢?试想一个,如果要条件不成立是怎样。



     明白了没?这是对立事件,如果条件为false就说明已经在踏板下面了,怎么碰啊?
至少我说这样的判断有猫腻,是因为如果玩家的人物长高一点,那人物就算脚踏不上踏板,但可能会用手“爬”上踏板。自己去理解。。。


     最重要的说过了,然后说说我为什么把东西都放到map上,只因为这样的话,以后添加一些规则,例如gameover之类的就可以直接移除map达到移除其他的东西。而且现在我是每个踏板(虽然只有3个,因为循环利用,超出范围的踏板都被我重新拉回舞台下面重新飘上来了。)都放一个enterframe,所以资源有点浪费,如果只在map上添加一个的话就省些了。

    最后,我使用了一个Control控制键盘,是我写的一个专门侦听键盘事件的类。教程如下:
http://bbs.9ria.com/thread-77596-1-1.html
今天讲了位图,切图啊,粒子特效啊神马的,下周见吧。。=,=!
  • 大小: 6.1 KB
  • 大小: 3.4 KB
  • 大小: 4.8 KB
  • 大小: 3.2 KB
分享到:
评论

相关推荐

    小黑C++学习

    根据给定文件的信息,我们可以提炼出与“小黑C++学习”相关的关键知识点,并围绕这些知识点进行详细阐述。 ### C++基础知识概述 C++是一种通用的编程语言,它结合了高级语言的特性与低级语言的功能,使得程序员...

    二维坐标空间经验的幼儿交互深度学习过程——以纸杯棋游戏活动为例.pdf

    《二维坐标空间经验的幼儿交互深度学习过程》 在幼儿教育中,深度学习是一个重要的概念,它强调通过探究、互动和反思来促进儿童的认知发展。本文以纸杯棋游戏活动为例,探讨了如何通过游戏引导幼儿进行二维坐标空间...

    Gavin小黑屋——高等公式大全

    高等数学是大学理工科学生必修的一门基础课程,它涵盖了广泛的理论和公式。...总的来说,这个高等公式大全覆盖了高等数学的主要知识点,为学习者提供了全面的参考资料,有助于他们深入理解和掌握这门学科。

    小黑记事本

    "小黑记事本"是一款简洁实用的编辑器软件,主要面向那些寻求高效文本处理工具的用户。在当今数字化时代,一个优秀的文本编辑器对于程序员、作家、学生以及任何需要频繁处理文字的人来说都是必不可少的。小黑记事本...

    托福阅读专题——插入题PPT学习教案.pptx

    【托福阅读专题——插入题】是托福考试中的一个重要题型,主要考察考生对文章结构、逻辑线索以及词汇关联的理解能力。这种题目通常设置在阅读部分的倒数第二个问题,且确保所缺失的句子不会影响到文章的整体大意,也...

    小黑课堂独家课程资料.rar

    【小黑课堂独家课程资料.rar】是一份专为学习计算机二级考试准备的资源包,它涵盖了计算机基础知识、操作系统、网络技术、数据库管理、程序设计语言等多个核心领域。这份压缩包旨在帮助学员系统地掌握和复习计算机二...

    【鸟哥笔记】运营增长实战手记小黑书.rar

    【鸟哥笔记】运营增长实战手记小黑书是一份深度探讨互联网运营与增长策略的专业资料,主要针对从事互联网行业,尤其是关注产品运营和市场增长的从业者。这本书籍的PDF版本包含了丰富的实战经验和策略,旨在帮助读者...

    小黑猪卡网器+教程

    【小黑猪卡网器+教程】是一款针对网吧断网工具的软件,主要用途是通过特定的技术手段对网络进行控制,比如模拟断网情况。在本文中,我们将深入探讨小黑猪卡网器的工作原理、功能特性以及相关教程,帮助读者理解和...

    前端 vue源码-小黑记事本.rar

    通过学习这个“小黑记事本”项目,开发者可以深入理解Vue的基础知识,包括如何组织项目结构、使用指令、实现数据绑定以及创建组件。同时,它也提供了实践HTML和CSS布局的机会。对于初学者来说,这是一个很好的起点,...

    小黑专用主题(黑友必备)Thinkpad

    然而,需要注意的是,尽管第三方主题可以丰富用户的使用体验,但也可能存在兼容性问题,可能会影响某些系统的稳定性。因此,在安装前,用户应确保该主题来自可靠来源,并备份重要数据,以防万一。同时,遵循官方的...

    小黑屋写作软件 v4.0.1.1.zip

    软件界面美观简洁、简单全面、实用方便,无需培训,即可快速上手,轻轻松松完成写作功能,真正做到简单全面实用,能极大地提高写作效率,是用户实现写作功能的好帮手。 小黑屋写做软件功能介绍 全新界面 化繁为...

    小黑课堂计算机二级Office题库5.6.7

    《小黑课堂计算机二级Office题库5.6.7》是一款专为准备计算机二级Office考试的用户设计的免费学习资源。这款软件集成了丰富的练习题目和解析,旨在帮助考生全面掌握Office的各项技能,包括Word、Excel、PowerPoint等...

    python笔记03(csdn)————程序.pdf

    在这个"python笔记03(csdn)——程序"中,主要探讨的是关于Python列表操作的一些基本知识点,这些知识点对于理解和操作Python列表至关重要。 1. **更改列表**: 列表的更改分为单个元素的更改和范围更改。单个...

    水源-小黑屋之歌-EE

    水源-小黑屋之歌-EE,2009-06-23

    小黑屋(一个可离线的网页文字游戏)

    《小黑屋》是一款独特的离线网页游戏,它突破了传统网络游戏依赖互联网连接的限制,为玩家提供了一种全新的游戏体验。在这个游戏中,玩家可以随时随地沉浸在游戏世界中,无需担心网络信号的问题,使得游戏的可玩性和...

    小黑课堂计算机二级题库配套的37套试题素材.txt

    小黑课堂计算机二级题库配套的37套试题素材,小黑课堂计算机一级题库配套的37套试题素材

    小黑课堂计算机一级题库2.3.rar

    总的来说,小黑课堂提供的这个题库资源是备考计算机一级考试的重要工具,考生应充分利用这些资料,全面学习并熟练掌握各部分知识,为顺利通过考试做好充分准备。同时,由于计算机技术更新迅速,考生还应注意实时更新...

Global site tag (gtag.js) - Google Analytics