欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

cocos creator实例--3D 足球

程序员文章站 2022-07-14 11:41:04
...

体育类游戏,3D 足球射门 ,Cocos Creator 3D 实现,附源码!

效果预览

 

cocos creator实例--3D 足球

游戏介绍

点击屏幕,松开手指,足球就会被踢出去,还缺少力度和方向控制,同时也缺少力度和方向的界面展现,后期会继续完善。

工程结构介绍

  • 游戏就 1 个场景 game ,所有游戏的元素都放在这个场景上,场景内 3D 元素主要 3 个,球场(使用 3D 平面实现)、足球(使用 3D 球体实现)、球门(柱子使用 3D 圆柱体实现,网使用 3D 四边形实现)。足球和球场,和之前的篮球类似,就是调整放大倍数,设置图片材质就行,主要的是球门。游戏中球门一个圆柱体都赋予碰撞,网的设置有些特殊,下面介绍。

cocos creator实例--3D 足球

  • 球门网,由多个 3D 对象构成,球门柱子都是 3D 圆柱体,球网使用了上、后、左、右四个 3D 四边形构成,是通过一点点的网图片平铺设置的。

 

cocos creator实例--3D 足球

 

●  球门网,以 后表面的设置设置为例,除了设置材质,需要注意两点:1. 平铺的设置,如下图的①所示,设置以后会根据比例数量进行缩放,注意原图是个方形,拉伸的时候注意长宽比,设置的时候注意比例,网才不会变形,设置的数值越大,网的空越小,反之类似;2.透明度的设置,如下图②所示,默认的设置,透明的位置会显示黑色,改成透明以后,透明位置显示的就是透明的。

cocos creator实例--3D 足球

球门网组织结构

 

cocos creator实例--3D 足球

组装网的原图

 

● 游戏核心在足球里,足球内添加了刚体,因为需要模拟重力效果,添加碰撞体,还有主要的游戏逻辑核心 Ball ,游戏里的所有核心功能,都在 Ball 内,场景内所有需要添加弹力和摩擦力的,参考之前的 3D 篮球那篇,具体参数见代码。
 

cocos creator实例--3D 足球

足球相关组件关联

给3D对象添加材质

足球场的材质就是一张足球图片,网络上可以找一张类似的,根据足球场的长宽比,对 3D 平面进行缩放,然后在资源目录里创建材质,把对应的图片拖拉到材质内即可,注意,材质需要选择图片类型。

cocos creator实例--3D 足球

足球场材质设置

cocos creator实例--3D 足球

足球场

 

● 足球的实现,和球场类似,不过我找的图有些不匹配,所以足球看起来不太和谐。

cocos creator实例--3D 足球

足球材质设置

  • 球门的网材质设置类似平铺设置和透明设置就行了,主要是注意下球门的柱子和网,摩擦力和阻力设置,区别一下,让球柱子容易碰撞,球网碰撞反应小点。

cocos creator实例--3D 足球

网的设置

cocos creator实例--3D 足球

球门柱的设置

 

● 后期计划,把力度和方向控制加上,同时在球场上以箭头的方式显示出来,力度越大,箭头伸的越长,力度越小,箭头伸的越短,箭头指向的位置就是足球发射发射出的位置

 

cocos creator实例--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这篇文章,这里感谢原作者对于技术的分享。

下载:

本文章源码和资源下载地址

上一篇: K均值聚类

下一篇: unity编辑器