信手绘制线条刚体
来源:互联网 发布:管家婆可以导出数据吗 编辑:程序博客网 时间:2024/04/27 21:45
来自天地会的wkyjoey同学问道如何做一个重力大师游戏(如下图)。这里要特意表示一下歉意,最近一直忙于工作,没有及时更新教程。
对于重力大师游戏,试玩之后,不难发现,我们在运行时可以创建的刚体有两种,线条刚体和多边形刚体。今天我们来一起研究一下线条刚体的创建。多边形刚体会在下次教程中讨论。
这里我们要绘制的线条不是直线而是曲线,所以简单的矩形刚体无法实现这个效果。在圆形边界教程中,我们同样接触到了曲线。解决方法是用多个线段组合起来模拟一个圆圈。庆幸的是这个方法同样适用于本例中的曲线。下面我们详细讨论一下。
线条是又无数个点组成的,把点放大一些就成了线段,所以一个线条可以变成多个线段的组合。
如上图,我们假设每个先断掉长度为segmentLength,线段的长度越短,segmentLength越小,线条模拟就越逼真。
在线条绘制过程中,持续检测鼠标坐标curPoint与前一个点prePoint之间的距离distance,当distance大于线段长度时,创建一个新的线段,并将curPoint赋值给prePoint。
好吧,下面我介绍一下具体的步骤:
- 定义线段的长度segmentLength
- 在鼠标点下后,卡是绘制线条,并记录之前的鼠标坐标位置为prePoint
- 在绘制过程中。如果鼠标坐标与prePoint之间的距离distance大于segmentLength,则将鼠标坐标赋值给prePoint,创建新的线段,并添加到segmentList中
- 鼠标弹起后,遍历所有的线段,并利用多边形组合法,创建对于的线段刚体,然后组合成一个完整的线条。
效果如下,点击并拖动鼠标开始绘制,其中的红点是线段的坐标位置。另外这里我没有限制线段的交叉,所以在绘制时尽量避免交叉,防止意外的错误,后续我们再讨论如何防止绘制线段时交叉。
源码中用到了LDEasyBox2D来简化代码。完整的代码及注释如下:
package{import Box2D.Collision.b2AABB;import Box2D.Collision.Shapes.b2PolygonShape;import Box2D.Common.Math.b2Vec2;import Box2D.Dynamics.b2Body;import Box2D.Dynamics.b2BodyDef;import Box2D.Dynamics.b2DebugDraw;import Box2D.Dynamics.b2FixtureDef;import Box2D.Dynamics.b2World;import flash.display.Sprite;import flash.events.Event;import flash.events.MouseEvent;import flash.geom.Point;/** * http://www.ladeng6666.com * @author ladeng6666 */public class Main extends Sprite{private var world:b2World;private var spriteCanvas:Sprite;private var tipCanvas:Sprite;//前一个pointprivate var prePoint:Point = new Point();//当前的pointprivate var curPoint:Point = new Point();//1.设置线段长度segmentLengthprivate var segmentLength:Number = 20;private var segmentsList:Array=new Array();private var isDrawing:Boolean = false;public function Main(){//创建box2D世界world = LDEasyBox2D.createWorld();//创建box2D调试图addChild(LDEasyBox2D.createDebug(world));//创建地面LDEasyBox2D.createWrapWall(world,stage);spriteCanvas = new Sprite();addChild(spriteCanvas);tipCanvas = new Sprite();addChild(tipCanvas);//侦听事件addEventListener(Event.ENTER_FRAME, loop);stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);stage.addEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);}private function onStageMouseDown(e:MouseEvent):void{//2.开始绘制线条,并定义prePointisDrawing = true;spriteCanvas.graphics.lineStyle(2);spriteCanvas.graphics.moveTo(mouseX, mouseY);curPoint = new Point(mouseX, mouseY);prePoint = curPoint.clone();}private function onStageMouseMove(e:MouseEvent):void{if(!isDrawing) return;spriteCanvas.graphics.lineTo(mouseX, mouseY);curPoint = new Point(mouseX, mouseY);var distance:Number = Point.distance(prePoint, curPoint);if (distance >= segmentLength) {//3.创建线段,并添加到segmentsList中segmentsList.push( new Segment(prePoint, curPoint));prePoint = curPoint.clone();}}private function onStageMouseUp(e:MouseEvent):void{isDrawing = false;spriteCanvas.graphics.clear();//在鼠标位置随机创建一个圆形或矩形刚体createSegment(segmentsList);//清楚segmengsList里的内容segmentsList = new Array();}private function loop(e:Event):void{world.Step(1 / 30, 10, 10);world.ClearForces();world.DrawDebugData();drawTip(segmentsList);}private function createSegment(segmentsArray:Array):void{//1.创建刚体需求b2BodyDefvar bodyRequest:b2BodyDef = new b2BodyDef();bodyRequest.type = b2Body.b2_dynamicBody;bodyRequest.position.Set(0 ,0);//记得米和像素的转换关系//2.Box2D世界工厂更具需求创建createBody()生产刚体var body:b2Body=world.CreateBody(bodyRequest);//3.创建敢提形状需求b2ShapeDef的子类//创建矩形刚体形状需求var fixtureRequest:b2FixtureDef = new b2FixtureDef();fixtureRequest.density = 3;fixtureRequest.friction = 0.3;fixtureRequest.restitution = 0.2;for each(var segment:Segment in segmentsArray) {var shapeBoxRequest:b2PolygonShape = new b2PolygonShape();shapeBoxRequest.SetAsOrientedBox(segment.length /2/ 30, 2 / 30, new b2Vec2(segment.centerX/30, segment.centerY/30), segment.rotation);fixtureRequest.shape = shapeBoxRequest;body.CreateFixture(fixtureRequest);}}private function drawTip(segmengtsArray:Array):void {tipCanvas.graphics.clear();for each( var segment:Segment in segmengtsArray) {tipCanvas.graphics.beginFill(0xFF0000, 0.5);tipCanvas.graphics.drawCircle(segment.centerX, segment.centerY,3);}}}}
- 信手绘制线条刚体
- 绘制线条
- 绘制线条
- 积累绘制的线条!
- MFC绘制不规则线条
- iOS绘制线条
- DrictX 绘制线条
- MFC之绘制线条
- VC++之绘制线条
- 椭圆线条绘制动画
- VC++之绘制线条
- 【VC++】003绘制连续线条-扇形线条
- [DFB] 移动鼠标绘制线条
- osu! 绘制线条源码 C#
- Drawing Lines(绘制线条)
- Cocos2d-x3.2 绘制线条
- Matlab绘制线条消除锯齿
- Quartz2D - 基本图形绘制(线条)
- android单独编译
- Oracle 导出数据库后任然报错 找不到表等
- android.content.ActivityNotFoundException: No Activity found to handle Intent 的错误
- android中保存Bitmap图片到指定文件夹中的方法
- 优雅降级和渐进增强
- 信手绘制线条刚体
- 关于multiple plane的Stereo matching 一点理解
- 排序Python
- 提醒消息框的用法(Sprytooltip.js)
- linux shell中 括号的各种用法
- 大搜集—背景纹理
- 控件设计用到的Attribute
- axis1.4调用xfire代码模板
- 有关ecmall的东东3----登录用户信息$this->visitor->get("user_id")的实现