零基础学编程Rust-实战篇-编写乒乓球小游戏2

乒乓球小游戏2-绘制球拍
上一期咱们成功运行了一个Piston示例,打开了一个窗口并在窗口上画了个红色的方框,为何画的是一个红色的方框呢?咱们能不能画个绿色的长方形呢?
game pingpang
接下来咱们就研究下代码:
打开main.rs文件
main.rs
在文件的第一行使用的extern关键子,声明须要使用外部crate piston_window;咱们先前介绍过crate是rust组织代码共享代码的一种形式,相似Java中的jar包。extern关键字咱们先前也有提到,说它在2018版本中几乎能够不用了。咱们能够把这一行代码注释掉,再运行看下效果。
没有报错吧,这主要得益于最新的rust 2018版本中对use关键字的功能加强。咱们看第二行代码就是使用use关键字把piston_window引入到当前做用域中。rust会先在本项目也就是咱们的game_pingpang中查找piston_window若是找不到就会在Cargo.toml中配置的依赖中查找。这就不须要extern再提早声明须要第三方依赖了,这也是为何咱们须要在Cargo.toml文件中添加piston_window依赖的缘由。
接下来是声明了一个main函数,建立了个PistonWindow类型的可变变量window.怎么建立的呢?是使用类型WindowSettings建立的,从类型名称就能够看出这个类型是用来设置窗口配置信息的。关联方法new的第一个参数Hello Piston是设置窗口的title。也就是显示在窗口头部的信息。咱们把它改为Game Pingpang。第二个参数是一个数组用来设置窗口的大小,640表示窗口的宽度为640像素,480表示窗口的高度为480像素。接下来调用exit_on_esc方法设置按esc键时是否退出。咱们待会能够试下按esc键,看程序是否退出。而后调用build方法建立一个窗口。窗口有可能建立失败,因此build方法的返回值为option类型,咱们还须要调用unwrap方法获取窗口对象。
上一期咱们介绍过若是要实现一个动画,须要不断的从新绘制图像。在piston中当绘制图像或者从新绘制图像时会激发render和update事件也就是渲染和更新事件。咱们就可使用while循环不段的获取window的事件,并在事件发生后调用window的draw 2d方法在窗口中绘制二维图像。这里是先调用clear函数将窗口整个清空。接下来调用rectangle函数绘制方框。rectange有四个参数,咱们这里先介绍前俩个。第一个参数是一个有四个值的数组,分别表示RGBA颜色值中的红色、绿色、蓝色和透明度值,这里红色值为1.0也就是100%红色,听说多看绿色对眼睛好一些,咱们能够把绿色值设为1.0把红色值和蓝色值设为0.0,这样就把颜色改成了绿色。
第二个参数也是一个有四个值的数组,其中前俩个值表明绘制的方框在窗口的位置,这里的0.0和0.0也就表明方框的左上角在窗口坐标系的0.0,0.0的位置也就是窗口的左上角。后面的俩个值分别表明方框的宽度和高度,这里的宽度和高度都是100,因此这是一个边长为100像素的正方形,咱们须要一个长方形作球拍,能够把高度改成20像素。这样咱们就绘制了一个宽为100像素高为20像素的绿色长方形球拍。咱们运行看下效果,没有报错,球拍已经绘制出来了,窗口的的title已经改为了Game pingpang,按ESC建,能够退出当前程序。虽然如今代码能够正常执行,可是代码都写在main方法中,违反了单一职责原则也不方便维护吧,接下来咱们给main方法瘦下身,咱们新建个绘制方法,把绘制方框的功能放到这个函数中,绘制时须要用到context和graphics,咱们的绘制方法须要包含这俩个参数,在闭包中声明参数是不须要声明参数类型的,但在函数中是须要声明参数类型的,怎么知道context,graphics的类型呢?固然咱们能够经过查看api文档得知,这里跟你们介绍个小技巧,能够经过声明俩个变量ctx和gph并声明它们的类型为空也就是一个空的圆括号,并给它们分别赋值为context和graphics。编写好后,运行下代码,这样编译器的提示信息就告诉了咱们context和graphics的类型。
咱们能够看到context的类型是piston_window模块下的Context类型,而graphics的类型是back_end模块下的GfxGraphics类型,从模块名称看,GfxGraphics是个具体的实现类,应该还有上层抽象类型,咱们能够先尝试使用Graphics试下,修改gph的类型为Graphics引用类型。ctx为Context类型。再运行看下效果。从错误信息里能够看出的确是存在Graphics的,可是它是个特征,咱们先前使用特征声明类型时是否是添加过impl关键字,咱们在Graphics前添加impl关键字再试下。错误信息提示咱们impl后跟特征这种写法只能用在函数声明或者方法的返回值类型声明中,咱们也恰好要把graphics作为函数draw的参数,给draw函数添加俩个参数,ctx和gph。而后把绘制相关的代码都复制到draw函数中,在main方法中只须要调用draw函数进行绘制,这下main方法就清爽多了吧。
咱们运行看下有没有报错,此次没有报错了。
接下来咱们还能够把绘制球拍相关的代码抽取出来,球拍有位置大小等信息,因此咱们能够定义一个球拍类型,封装球拍具有的相关信息,这样若是咱们须要修改球拍的样式只须要修改球拍类型就好。接下来咱们打开src/lib.rs文件,在lib.rs文件中声明tianlangstudio模块,在tianlangstuido模块中定义struct类型Racket也就是球拍,球拍有位置坐标信息x,y,有大小信息宽度和高度。为了方便实例化Racket对象咱们再给Racket添加一个new关联方法,当调用new关联方法时建立一个坐标在窗口底部水平居中的球拍,咱们知道窗口的宽度是640,球拍的宽度是100,因此球拍x坐标的值应该为270。窗口的高度是480,球拍的高度是20,因此球拍的y坐标值应该为460,这样球拍恰好贴紧窗口底部。设置球拍的宽度为100像素,高度为20像素。接下来再给Racket类型添加一个draw方法,将绘制球拍的功能放到球拍的绘制方法中。咱们须要在外部使用Racket类型和相关方法,因此要给他们添加pub关键字。在main.rs文件中,咱们就能够引入tianlangstuido模块,使用Racket的关联函数new建立一个球拍,并调用球拍对象的draw方法绘制球拍。这样函数draw是否是就清爽多了。可读性也好多了。接下来咱们运行看下效果。运行效果跟咱们预期一直,球拍紧贴窗口底部并水平居中。如今球拍仍是静态的,接下来咱们实现经过按左右方向键移动球拍的功能。api

相关文章
相关标签/搜索