cocos creator实例--3D 足球
程序员文章站
2022-07-14 11:41:04
...
体育类游戏,3D 足球射门 ,Cocos Creator 3D 实现,附源码!
效果预览
游戏介绍
点击屏幕,松开手指,足球就会被踢出去,还缺少力度和方向控制,同时也缺少力度和方向的界面展现,后期会继续完善。
工程结构介绍
- 游戏就 1 个场景 game ,所有游戏的元素都放在这个场景上,场景内 3D 元素主要 3 个,球场(使用 3D 平面实现)、足球(使用 3D 球体实现)、球门(柱子使用 3D 圆柱体实现,网使用 3D 四边形实现)。足球和球场,和之前的篮球类似,就是调整放大倍数,设置图片材质就行,主要的是球门。游戏中球门一个圆柱体都赋予碰撞,网的设置有些特殊,下面介绍。
- 球门网,由多个 3D 对象构成,球门柱子都是 3D 圆柱体,球网使用了上、后、左、右四个 3D 四边形构成,是通过一点点的网图片平铺设置的。
● 球门网,以 后表面的设置设置为例,除了设置材质,需要注意两点:1. 平铺的设置,如下图的①所示,设置以后会根据比例数量进行缩放,注意原图是个方形,拉伸的时候注意长宽比,设置的时候注意比例,网才不会变形,设置的数值越大,网的空越小,反之类似;2.透明度的设置,如下图②所示,默认的设置,透明的位置会显示黑色,改成透明以后,透明位置显示的就是透明的。
球门网组织结构
组装网的原图
● 游戏核心在足球里,足球内添加了刚体,因为需要模拟重力效果,添加碰撞体,还有主要的游戏逻辑核心 Ball ,游戏里的所有核心功能,都在 Ball 内,场景内所有需要添加弹力和摩擦力的,参考之前的 3D 篮球那篇,具体参数见代码。
足球相关组件关联
给3D对象添加材质
足球场的材质就是一张足球图片,网络上可以找一张类似的,根据足球场的长宽比,对 3D 平面进行缩放,然后在资源目录里创建材质,把对应的图片拖拉到材质内即可,注意,材质需要选择图片类型。
足球场材质设置
足球场
● 足球的实现,和球场类似,不过我找的图有些不匹配,所以足球看起来不太和谐。
足球材质设置
- 球门的网材质设置类似平铺设置和透明设置就行了,主要是注意下球门的柱子和网,摩擦力和阻力设置,区别一下,让球柱子容易碰撞,球网碰撞反应小点。
网的设置
球门柱的设置
● 后期计划,把力度和方向控制加上,同时在球场上以箭头的方式显示出来,力度越大,箭头伸的越长,力度越小,箭头伸的越短,箭头指向的位置就是足球发射发射出的位置
/* Ball.ts
* @Copyright: Copyright (c) 2019
* @Author: tony
* @Version: 1.0
* @Date: 2019-12-01 23:12:54
*/
import { _decorator, Component, Node, systemEvent, SystemEvent, SphereColliderComponent, RigidBodyComponent, Vec3, math, EventTouch,Touch,Vec2 } from "cc";
import { Direct } from "./Direct";
const { ccclass, property } = _decorator;
@ccclass("Ball")
export class Ball extends Component {
@property(Direct)
private diect: Direct = null;
private ballRigid: RigidBodyComponent = null; // 球刚体
private force: number = 5;
private angle: number = Math.PI / 4;
/* class member could be defined like this */
// dummy = '';
/* use `property` decorator if your want the member to be serializable */
// @property
// serializableDummy = 0;
onLoad(): void{
this.ballRigid = this.node.getComponent(RigidBodyComponent);
systemEvent.on(SystemEvent.EventType.TOUCH_START, this.onTouchStart, this);
systemEvent.on(SystemEvent.EventType.TOUCH_MOVE, this.onTouchMove, this);
systemEvent.on(SystemEvent.EventType.TOUCH_END, this.onTouchEnd, this)
}
onTouchStart(touch:Touch, event: EventTouch): void{
}
onTouchMove(touch:Touch, event: EventTouch): void{
let start: Vec2 = touch.getStartLocation();
let move: Vec2 = touch.getLocation();
let delta = move.subtract(start);
cc.log(delta);
let tan: number = delta.y / delta.x;
let angle: number = Math.atan(-tan);
cc.log(angle);
angle = -(180 / Math.PI * angle);
cc.log(angle);
angle += 90;
cc.log('d', angle);
// this.diect.setDirect(angle);
}
onTouchEnd(touch:Touch, event: EventTouch):void{
cc.log('end');
let v: Vec3 = cc.v3();
v.x = 0;
v.y = this.force * Math.sin(this.angle);
v.z = -this.force * Math.cos(this.angle);
this.ballRigid.setLinearVelocity(v);
}
start () {
// Your initialization goes here.
}
// update (deltaTime: number) {
// // Your update function goes here.
// }
}
//Direct.ts
import { _decorator, Component, Node, Vec3, v2, Quat } from "cc";
const { ccclass, property } = _decorator;
@ccclass("Direct")
export class Direct extends Component {
@property(Node)
private mid: Node = null;
@property(Node)
private top: Node = null;
@property(Node)
private ball: Node = null;
private ratio: number = 0.5;
/* class member could be defined like this */
// dummy = '';
/* use `property` decorator if your want the member to be serializable */
// @property
// serializableDummy = 0;
onLoad():void{
this.setLen(0.2);
}
start () {
// Your initialization goes here.
}
// update (deltaTime: number) {
// // Your update function goes here.
// }
setLen(len: number): void{
len = this.ratio * len;
let v3: Vec3 = cc.v3();
v3 = this.mid.getScale();
v3.y = len;
this.mid.setScale(v3);
v3 = this.mid.position;
cc.log(v3);
v3.z = - len / 2;
cc.log(v3);
this.mid.setPosition(v3);
v3 = this.top.position;
v3.z = -len;
this.top.setPosition(v3);
}
setDirect(angle: number): void{
let quat: Quat = new Quat();
quat = this.node.getRotation();
quat.y = angle;
this.node.setRotation(quat);
}
}
/* PhyMat.ts
* @Copyright: Copyright (c) 2019
* @Author: tony
* @Version: 1.0
* @Date: 2019-12-01 23:19:02
*/
import { _decorator, Component, Node,ColliderComponent,PhysicMaterial } from "cc";
const { ccclass, property } = _decorator;
@ccclass("PhyMat")
export class PhyMat extends Component {
@property
private friction: number = 0; // 摩擦力
@property
private restitution: number = 0; // 弹力
onLoad():void{
let comps: Array<ColliderComponent> = this.node.getComponents(ColliderComponent) as Array<ColliderComponent>;
let mat = new PhysicMaterial();
mat.friction = this.friction;
mat.restitution = this.restitution;
for(let i = 0; i < comps.length; i++){
comps[i].material = mat;
}
}
start () {
// Your initialization goes here.
}
// update (deltaTime: number) {
// // Your update function goes here.
// }
}
感谢:
本文参考自https://mp.weixin.qq.com/s/1ZXQS9ok-FyEMb6MbsR1Hg这篇文章,这里感谢原作者对于技术的分享。
下载:
推荐阅读
-
cocos creator Touch事件应用(触控选择多个子节点的实例)
-
荐 麒麟子Cocos Creator 3D研究笔记三:角色换装(无动画)
-
用 shader effect 实现雨滴落水效果!Cocos Creator 3D !
-
cocos creator 3D | 拇指投篮 | 3D项目入门实战
-
初探雾效果!shader 源码分析与讲解! Cocos Creator 3D Shader Fog !
-
瞄准器!3D入门实战!拇指射箭!Cocos Creator 3D !
-
蚂蚁庄园运动会登山赛!3d项目入门实战!Cocos Creator 3D!
-
cocos creator 3D | 拇指射箭
-
cocos creator实例--3D 足球
-
不好意思,我膨胀了!shader 入门精要!Cocos Creator 3D Shader !