【Cocos Creator游戏开发教程】仿微信趣味画赛车小游戏(一)前言,界面UI
【Cocos Creator游戏开发教程】仿微信趣味画赛车小游戏(二)物理刚体关节

项目地址已放到 github 上,需要的小伙伴可自行下载。
这节我们讲一下游戏代码实现

1.开启物理世界

// GameMain.ts
protected onLoad(): void {cc.director.getPhysicsManager().enabled = true; // 开启物理引擎需要写在 onLoad 中
}protected start(): void {cc.debug.setDisplayStats(false);this.openPhysics();this.node.on(DrawArea.DRAW_VEHICLE, this.onDrawVehicle, this);
}private openPhysics(): void {let manager: cc.PhysicsManager = cc.director.getPhysicsManager();manager.enabledAccumulator = true;manager.debugDrawFlags = 1;     // 设置调试绘制标志cc.PhysicsManager.FIXED_TIME_STEP = 1 / 30;cc.PhysicsManager.VELOCITY_ITERATIONS = 8;cc.PhysicsManager.POSITION_ITERATIONS = 8;
}

2.画车

监听触摸DrawArea开始事件,将绘画节点移到触摸点,记录存储当前触摸点

// DrawArea.ts
private onTouchStart(event: cc.Event.EventTouch): void {// 转换到局部坐标let pos = this.node.convertToNodeSpaceAR(event.getLocation());this.drawLine.moveTo(pos.x, pos.y);this.recordPos = cc.v2(pos.x, pos.y);this.drawPoints.push(cc.v2(pos.x, pos.y));
}

监听触摸DrawArea移动事件

// DrawArea.ts
private onTouchMove(event: cc.Event.EventTouch): void {let pos: cc.Vec2 = this.node.convertToNodeSpaceAR(event.getLocation());let widthLimit: number = (this.node.width + DrawArea.DRAW_CIRCLE_R) / 2;let heightLimit: number = (this.node.height + DrawArea.DRAW_CIRCLE_R) / 2;// 检查当前触摸点是否超出绘画区域if (pos.x < -widthLimit || pos.x > widthLimit) {return;}if (pos.y < -heightLimit || pos.y > heightLimit) {return;}// 绘画this.drawLine.lineTo(pos.x, pos.y);this.drawLine.stroke();this.drawLine.moveTo(pos.x, pos.y);// 记录当前手移动到的点this.currentPos = cc.v2(pos.x, pos.y);//求两点之间的距离let subVec: cc.Vec2 = this.currentPos.sub(this.recordPos);let distance: number = subVec.mag() + 5;    // 防止线段间出现空隙,所以+5长度// 为了减少触摸点数量,如果距离大于等于预制体的width,记录存储该触摸点if (distance >= 25) {// 将此时的触摸点设为记录点this.recordPos = cc.v2(pos.x, pos.y);this.drawPoints.push(cc.v2(pos.x, pos.y));}
}

监听触摸DrawArea结束事件,发送自定义画车事件,将触摸点数组发送出去

// DrawArea.ts
private onTouchEnd(event: cc.Event.EventTouch): void {// 判断触摸点数量是否小于2,不是才发送画车事件if (this.drawPoints.length <= 1) {this.drawPoints = [];return;}// 发送自定义画车事件 DrawArea.DRAW_VEHICLElet customEvent: cc.Event.EventCustom = new cc.Event.EventCustom(DrawArea.DRAW_VEHICLE, true);customEvent.setUserData(this.drawPoints);this.node.dispatchEvent(customEvent);// 清空绘画区域,存储的触摸点this.drawLine.clear();this.drawPoints = [];
}

3.创建小车

监听自定义画车事件,获取绘画节点数组,调用Vehicle.ts脚本刷新小车

// GameMain.ts
private onDrawVehicle(event: cc.Event.EventCustom): void {event.stopPropagation();(this.vehicle.getComponent('Vehicle') as Vehicle).updateVehicle(event.getUserData());
}

收到监听,调用刷新车方法

// Vehicle.ts
public updateVehicle(drawPoints: Array<cc.Vec2>): void {if (drawPoints.length <= 0) {return;}let _self = this;// 重置车位置_self.node.x = 0;_self.node.y = 200;// 重置车_self.resetVehicle();// 画车身_self.drawVehicleBody(drawPoints);// 画轮子_self.drawWheel(drawPoints);// 激活车节点if (!_self.node.active) {_self.node.active = true;}
}

重置车,清空子节点

// Vehicle.ts
private resetVehicle(): void {let _self = this;let vehicleNode: cc.Node = _self.vehicle.node;   // 获取车节点vehicleNode.removeAllChildren();_self.vehicleBodys = [];_self.wheelRear = null;_self.wheelFront = null;
}

画车身

// Vehicle.ts
private drawVehicleBody(drawPoints: Array<cc.Vec2>): void {let _self = this;let vehicleNode: cc.Node = _self.vehicle.node;   // 获取车节点let beforePos: cc.Vec2 = drawPoints[0];for (let i = 1; i < drawPoints.length; i++) {let curPos: cc.Vec2 = drawPoints[i];let subVec: cc.Vec2 = curPos.sub(beforePos);let distance: number = subVec.mag() + 5;    // 防止线段间出现空隙,所以+5长度// 给定方向向量let tempVec: cc.Vec2 = cc.v2(0, 10);// 求两点的方向角度let rotateVec: number = subVec.signAngle(tempVec) / Math.PI * 180 - 90;// 创建车刚体小部件let lineItem: cc.Node = cc.instantiate(_self.linePrefab);lineItem.angle = -rotateVec;lineItem.setPosition(beforePos);lineItem.setParent(vehicleNode);// 这一步是为了防止两个线段之间出现空隙,动态改变预制体的长度lineItem.width = distance;// 设置刚体属性lineItem.getComponent(cc.PhysicsBoxCollider).offset.x = lineItem.width / 2;lineItem.getComponent(cc.PhysicsBoxCollider).size.width = lineItem.width;lineItem.getComponent(cc.PhysicsBoxCollider).sensor = true;lineItem.getComponent(cc.PhysicsBoxCollider).restitution = 100;lineItem.getComponent(cc.PhysicsBoxCollider).apply();// 首刚体不需要创建刚体焊接组件if (_self.vehicleBodys.length > 0) {let beforeLine: cc.Node = _self.vehicleBodys[_self.vehicleBodys.length - 1];// 焊接车刚体小部件let weldJoint: cc.WeldJoint = lineItem.addComponent(cc.WeldJoint);weldJoint.referenceAngle = -rotateVec - beforeLine.angle;weldJoint.connectedBody = beforeLine.getComponent(cc.RigidBody);weldJoint.connectedAnchor = cc.v2(beforeLine.width - 5, 0);}_self.vehicleBodys.push(lineItem);beforePos = cc.v2(curPos.x, curPos.y);}
}

画轮子

// Vehicle.ts
private drawWheel(drawPoints: Array<cc.Vec2>): void {let _self = this;let vehicleNode: cc.Node = _self.vehicle.node;// 首尾车身刚体let lineRear: cc.Node = _self.vehicleBodys[0];let lineFront: cc.Node = _self.vehicleBodys[_self.vehicleBodys.length - 1];let wheelSF: cc.SpriteFrame = new cc.SpriteFrame("HelloWorld");     // 轮胎精灵帧// 首尾触摸点let rearPos: cc.Vec2 = drawPoints[0];let frontPos: cc.Vec2 = drawPoints[drawPoints.length - 1];// 通过预制节点,创建后轮let wheelRear: cc.Node = cc.instantiate(_self.wheelPrefab);wheelRear.getComponent(cc.Sprite).spriteFrame = wheelSF;wheelRear.setPosition(rearPos);vehicleNode.addChild(wheelRear);// 通过预制节点,创建前轮let wheelFront: cc.Node = cc.instantiate(_self.wheelPrefab);wheelRear.getComponent(cc.Sprite).spriteFrame = wheelSF;wheelFront.setPosition(frontPos);vehicleNode.addChild(wheelFront);// 添加轮子刚体标识wheelRear.getComponent(cc.PhysicsCircleCollider).tag = VehicleEnum.COLLIDER_TAG.REAR_TAG;       // 后轮wheelFront.getComponent(cc.PhysicsCircleCollider).tag = VehicleEnum.COLLIDER_TAG.FRONT_TAG;      // 前轮wheelRear.getComponent(cc.PhysicsCircleCollider).apply();wheelFront.getComponent(cc.PhysicsCircleCollider).apply();// 加入轮子关节// 后轮let wheelJointRear: cc.WheelJoint = ComponentUtil.addWheelJointToObj(lineRear, {connectedNode: wheelRear,anchor: cc.v2(0, 0)});// 前轮let wheelJointFront: cc.WheelJoint = ComponentUtil.addWheelJointToObj(lineFront, {connectedNode: wheelFront,anchor: cc.v2(lineFront.width - 5, 0)});// 添加距离关节,约束两个轮子let distanceJoint: cc.DistanceJoint = wheelRear.addComponent(cc.DistanceJoint);distanceJoint.connectedBody = wheelFront.getComponent(cc.RigidBody);distanceJoint.distance = frontPos.sub(rearPos).mag();_self.wheelRear = wheelRear;_self.wheelFront = wheelFront;
}

【Cocos Creator游戏开发教程】仿微信趣味画赛车小游戏(三)代码实现相关推荐

  1. 【Cocos Creator游戏开发教程】仿微信趣味画赛车小游戏(一)前言,界面UI

    前言 这个是我去年3月份在简书上发布的,不玩简书了,就迁到CSDN吧-- 最近遇到一款游戏,感觉玩起来还行,于是顺带就用来熟悉一下Cocos Creator(太久没用). 项目地址已放到 github ...

  2. 【Cocos Creator游戏开发教程】仿微信趣味画赛车小游戏(二)物理刚体关节

    [Cocos Creator游戏开发教程]仿微信趣味画赛车小游戏(一)前言,界面UI 项目地址已放到 github 上,需要的小伙伴可自行下载. 这节我们讲一下车子的物理刚体关节. 我在项目中添加了一 ...

  3. CocosCreator拼手速小游戏(教程 + 源码)TS实现小游戏

    CocosCreator拼手速小游戏(教程 + 源码)TS实现小游戏 前言 游戏完成后的样子 玩法:在10秒内点击屏幕中间的按钮,最终记录一共点击了多少下 源码在Q群:1130122408 这个游戏比 ...

  4. 平衡球游戏开发教程(四)--深入了解WP7游戏底层原理

    前面我们都只是集中在物理引擎上,但是对于一个游戏来说,他包含的不只是物理引擎,他还要有游戏面板(普通的,可以滚动的),按钮,标签,图片,背景(层次背景),边界控制,输入处理,字体和纹理管理,帧率测速器 ...

  5. 【cocos2d游戏开发实战】一款射击类小游戏《Zombie Age》的开发(一)

    前言 因为学习的原因需要完成一款射击类的小游戏,之前做的飞机大战没有达到要求,在网上找了几款射击类游戏后因为素材和难度的关系最后决定山寨一下<僵尸时代2>这款小游戏,开发到游戏主体基本完整 ...

  6. 开发(仿微信)Android日常记录(三)

    Android开发记录(三) 1.全局Toast怎么弄?有全局的上下文 2.使用github上的源码,得下个gitbash吧,需要个git.exe命令 3.PopupWindow实现QQ微信右上角菜单 ...

  7. 2D平台类游戏开发教程(翻译)

    这是一篇实现2D平台类游戏的技术指导文章,原文地址:http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-pla ...

  8. 微信小程序案例源码-cocos creator跨平台开发小游戏案例

    前言 本人一直想学习游戏开发,以前做过Android游戏开发,但电脑坏了,所有源码都没有了,后面也就没有开发了,近来下班之余又想开发游戏了.开发游戏之前,需要考虑开发平台及语言,以前基于Android ...

  9. Cocos Creator游戏开发教程 学习笔记

    学完提问几个问题吧: position的锚点位置数值原点在哪里? 因为position是相对坐标,所以原点是父节点的锚点 .所以Canvas下面的直属节点原点就是世界坐标系的原点Canvas的锚点. ...

最新文章

  1. vue引用js文件的多种方式
  2. Java 18 都要来了,你不会还在用Java 8吧?
  3. GHOST分区丢失只剩C盘
  4. 正则表达式||grep的使用
  5. 查看db2数据库名linux,【名说】DB2数据库备份与恢复(linux环境)
  6. 从实践的角度来回顾一下SQL注入
  7. 工作笔记-安装完virtualbox,新建好虚拟机却提示无法打开
  8. 【BZOJ2584】memory,扫描线+拓扑图+骗
  9. ASP.NET简化编辑界面 V2
  10. liunx 下mysql 的安装(转载)
  11. 你的设备中缺少重要的安全和质量修复_2020华富管道非开挖修复工程施工欢迎前来咨询...
  12. 计算机加权限加密,局域网文件访问权限设置加密的使用方法
  13. V部落博客管理平台开源啦! Vue+SpringBoot强强联合!
  14. 麻将胡牌算法(C++版)
  15. 完美解决Pycharm报错[WinError 193] %1 不是有效的 Win32 应用程序
  16. 学生成绩录入及查询(C语言)-PTA
  17. 小红书直播收益怎么算?有效提高直播收益的小技巧
  18. 人机猜拳游戏(修改)
  19. 数据洪流来袭,企业转型势不可挡,如何四两拨千斤?
  20. openlayers摸爬滚打 5.openlayers使用GeoJSON绘制点、线

热门文章

  1. PCB/PCBA评审Checklist,可使用DFM快速分析
  2. 考博计算机博士研究计划,科研方法 | 写完了研究计划书?请不要功亏一篑!
  3. 天堂2登录服务器为维护中,关于天堂2系统维护问题~~
  4. mac室内设计软件planner 5d如何正确安装?
  5. 超全,超干,超实用 ,SAP 全线产品大解析「易拓科技」
  6. python工程师累吗_学完Python工程师好就业吗?
  7. 初学者计算机学什么软件好,「推荐」初学者学电脑绘画用什么软件
  8. Manacher算法总结
  9. php-388e,梅特勒-托利多RL003880E+以太网普及型条码秤 超市便利店计价秤
  10. 【倒计时最后 1 天】全场课程、电子书 5 折起!