首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >three.js 制作逻辑转体游戏(下)

three.js 制作逻辑转体游戏(下)

作者头像
郭先生的博客
发布于 2020-09-06 11:48:46
发布于 2020-09-06 11:48:46
3.2K00
代码可运行
举报
文章被收录于专栏:郭先生的博客郭先生的博客
运行总次数:0
代码可运行

上一篇已经对绕非定轴转动有所了解,这篇郭先生继续说一说逻辑转体游戏的制作,这部分我们同样会遇到一些小问题,首先是根据数据渲染陷阱和目标区域,然后是对可以转动的判定,最后是获胜的判定。

1. 根据数据渲染陷阱和目标区域

首先我们P一张底图和陷阱图,如下图

就像这样,然后就是根据数据渲染陷阱和目标区域了,首先陷阱的个数是固定的,而目标区域是随小方块的数量而定,先看数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
end: [[-1, -4], [-1, -5]],
trap: [[-1, -7], [-6, -2]],

这里我们看一下Shader怎么写的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let texture1 = new THREE.TextureLoader().load('/static/images/base/luojizhuanti.png');
let texture2 = new THREE.TextureLoader().load('/static/images/base/stack.png');
let trapArray = [];
let targetArray = new Array(7).fill('').map(() => new THREE.Vector2(0,0));
square[this.game].trap.forEach(d => {
    trapArray.push(new THREE.Vector2(d[0], d[1]));
})
square[this.game].end.forEach((d,i) => {
    targetArray[i] = new THREE.Vector2(d[0], d[1]);
})
uniforms = {
    texture1: {
        value: texture1
    },
    texture2: {
        value: texture2
    },
    point0: {
        value: trapArray[0]
    },
    point1: {
        value: trapArray[1]
    },
    target: {
        value: targetArray
    }
}
uniforms[ "texture2" ].value.wrapS = uniforms[ "texture2" ].value.wrapT = THREE.RepeatWrapping;
let planeMate = new THREE.ShaderMaterial({
    side: THREE.DoubleSide,
    uniforms: uniforms,
    vertexShader: `
        varying vec2 vUv;
        varying vec3 pos;
        void main() {
            vUv = uv;
            pos = position;
            gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
        }
    `,
    fragmentShader: `
        varying vec2 vUv;
        varying vec3 pos;
        uniform vec2 point0;
        uniform vec2 point1;
        uniform vec2 target[7];
        uniform sampler2D texture1;
        uniform sampler2D texture2;
        void main() {
            int index = 0;
            vec2 newUv = vec2(vUv.x * 7.0, vUv.y * 8.0);
            vec4 tcolor1 = texture2D( texture1, vUv );
            vec4 tcolor2 = texture2D( texture2, newUv );
            vec4 resultColor = tcolor1;
            if (pos.x < point0.x * 10.0 + 45.0 && pos.x > point0.x * 10.0 + 35.0 && pos.y < - point0.y * 10.0 - 40.0 && pos.y > - point0.y * 10.0 - 50.0) {
                resultColor = tcolor2;
            } else if(pos.x < point1.x * 10.0 + 45.0 && pos.x > point1.x * 10.0 + 35.0 && pos.y < - point1.y * 10.0 - 40.0 && pos.y > - point1.y * 10.0 - 50.0) {
                resultColor = tcolor2;
            } else {
                for(int i=0; i < 7; i++) {
                    if (pos.x < target[i].x * 10.0 + 45.0 && pos.x > target[i].x * 10.0 + 35.0 && pos.y < - target[i].y * 10.0 - 40.0 && pos.y > - target[i].y * 10.0 - 50.0) {
                        resultColor = vec4(1.0, 0.5, 0.0, 1.0);
                    }
                }
            }
            gl_FragColor = resultColor;
        }
    `
})

texture1和texture2是两个纹理图,trapArray是盛放陷阱的数组,targetArray是目标区域,默认长度是7,且默认值都是new THREE.Vector2(0,0),然后我们将二维向量加到以上两个数组中,最后添加到uniforms中,最后传到ShaderMaterial中,顶点着色器我们只需要将position和ui传到片元着色器中,关键是片元着色器,首先我们先得到一个新uv,这个新uv是沿x方向重复7次,沿y方向重复8次,然后tcolor1和tcolor2分别是底图的颜色和重复了7*8的陷阱的颜色。if中是渲染第一个陷阱,else if是渲染第二个陷阱,else中循环target数组,渲染target区域,具体的判断其实很简单。这样我们就根据关卡渲染了陷阱。

2. 对是否可以旋转进行判定

因为小方块是不可以超过底图的边缘的,而且也不可以直接覆盖到陷阱上面,因为这个操作是在点击上下左右的时候就要先判断可行性,但是此时我们还没有转,所以我们就要先拷贝一个boxes,先进行旋转看看出没出界或者压没压到陷阱,我们是这样实现的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
judge(num) {
    judgeGroup = new THREE.Group();
    boxesCopy = [];
    for(let i=0; i<boxes.length; i++) {
        let geom = new THREE.BoxGeometry(ratio, ratio, ratio);
        let mate = new THREE.MeshBasicMaterial({color: 0xffaa00, transparent: true, opacity: .8});
        let mesh = new THREE.Mesh(geom, mate);
        mesh.position.copy(boxes[i].position);
        boxesCopy[i] = mesh;
    }
    if(num == 1) {
        var offset = new THREE.Vector3(box3.max.x, 0, 0);
        judgeGroup.position.copy(offset);
        boxesCopy.forEach(d => {
            d.position.sub(offset);
            judgeGroup.add(d);
        })
        judgeGroup.rotation.z = - Math.PI / 2;
    } else if(num == 2) {
        var offset = new THREE.Vector3(box3.min.x, 0, 0);
        judgeGroup.position.copy(offset);
        boxesCopy.forEach(d => {
            d.position.sub(offset);
            judgeGroup.add(d);
        })
        judgeGroup.rotation.z = Math.PI / 2;
    } else if(num == 3) {
        var offset = new THREE.Vector3(0, 0, box3.min.z);
        judgeGroup.position.copy(offset);
        boxesCopy.forEach(d => {
            d.position.sub(offset);
            judgeGroup.add(d);
        })
        judgeGroup.rotation.x = - Math.PI / 2;
    } else if(num == 4) {
        var offset = new THREE.Vector3(0, 0, box3.max.z);
        judgeGroup.position.copy(offset);
        boxesCopy.forEach(d => {
            d.position.sub(offset);
            judgeGroup.add(d);
        })
        judgeGroup.rotation.x = Math.PI / 2;
    }
    judgeGroup.updateMatrixWorld();
    let canPass = true;
    boxesCopy.forEach(d => {
        var trans = new THREE.Vector3();
        d.matrixWorld.decompose(trans, new THREE.Quaternion(), new THREE.Vector3());
        let x = Math.round((trans.x - 5) / 10);
        let z = Math.round((trans.z - 5) / 10);
        let y = Math.round((trans.y + 5) / 10);
        if(x > -1 || x < -7 || z > -1 || z < -8) {
            canPass = false;
        } else {
            square[this.game].trap.forEach(d => {
                if(d[0] == x && d[1] == z && y == 1) {
                    canPass = false;
                }
            })
        }
    })
    return canPass;
},

boxesCopy就是对boxes进行的拷贝,num就是我们的上下左右操作,最后一个循环就是判断是否可翻转,x,y,z值分别对应我们的格子,if判断时候出界,因为x的界限就是-1,-7,z的界限就是-1,-8。else是判断是否压到陷阱,只要有一个成立,canPass就会变成false。这就完成了简单的旋转判断。

3. 获胜的判定

获胜的判定很简单,在每一个旋转之后,比较boxes和end数组,如果两个数组一样,那么就说明胜利了,代码如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
computedWin() {
    let win = true;
    let temp = [];
    boxes.forEach(d => {
        let x = Math.round((d.position.x - 5) / 10);
        let z = Math.round((d.position.z - 5) / 10);
        temp.push([x, z]);
    })
    square[this.game].end.forEach(d => {
        if(!temp.some(dd => dd[0] == d[0] && dd[1] == d[1])) {
            win = false;
        }
    })
    if(win) {
        this.win();
    }
},

最后加上一点tween动画,这样我们就完成了一个逻辑转体的游戏,游戏玩起来还是比较有意思的。

转载请注明地址:郭先生的博客

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/08/20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
2 条评论
热度
最新
谢谢博主 刚也在相同的地方卡住了!
谢谢博主 刚也在相同的地方卡住了!
回复回复点赞举报
哥你能说一下怎么让他的样式在项目中和组件里面一样吗,我引用到项目中他的样式老是改变,就拿input框来说在组件里面他们是整齐排列成两排的但引入到项目中就成了独立的排的了,时间选择器也一样
哥你能说一下怎么让他的样式在项目中和组件里面一样吗,我引用到项目中他的样式老是改变,就拿input框来说在组件里面他们是整齐排列成两排的但引入到项目中就成了独立的排的了,时间选择器也一样
回复回复点赞举报
推荐阅读
【愚公系列】2023年06月 攻防世界-Web(wtf.sh-150)
目录穿透漏洞是一种安全漏洞,允许攻击者通过在URL中操纵目录路径,访问到应用程序中不应该被公开访问的文件或目录。攻击者通常利用此漏洞来盗取敏感信息,如数据库凭证、用户密码等。
愚公搬代码
2025/05/28
900
【愚公系列】2023年06月 攻防世界-Web(wtf.sh-150)
攻防世界web进阶区ics-07详解
page不能为空,同时,他的值不能等于index.php这样,就会包含flag.php文件 否则重定向到flag.php这个文件
wuming
2021/01/21
1.5K0
攻防世界web进阶区ics-07详解
攻防世界web进阶区Web_php_wrong_nginx_config详解
那么我们使用御剑进行扫描,扫描到了admin和robots.txt 我们访问admin试试
wuming
2021/01/21
9800
攻防世界web进阶区Web_php_wrong_nginx_config详解
攻防世界web进阶区Zhuanxv详解
扫描目录发现了一个list 我们使用了好几个扫描工具,只有wwwscan,和webdirscan可以,(可能是我字典太菜了)
wuming
2021/01/21
1.1K1
攻防世界web进阶区Zhuanxv详解
Hackme-Web-Writeup
hide and seek Can you see me? I’m so close to you but you can’t see me. 这题查看源码即可。 guestbook This
wywwzjj
2023/05/09
4770
Hackme-Web-Writeup
Hgame_week3_web
Payload : 1andif((1=2),exp(999999999),1)#
安恒网络空间安全讲武堂
2019/03/08
1.2K0
Hgame_week3_web
34c3 部分Web Writeup
34c3应该算是2017年年末的最后一个惊喜了,比赛题目虽然有非预期导致难度降了很多,但是从CTF中能学到什么才是最重要的,其中Web有3个XSS题目,思路非常有趣,这里整理了一下分享给大家。
Seebug漏洞平台
2018/03/16
1.7K7
34c3 部分Web Writeup
【愚公系列】2023年06月 攻防世界-Web(ics-07)
php是一种弱类型语言,意味着在变量的赋值和使用过程中,不需要显式地定义变量的类型。php会根据变量的值自动判断变量的数据类型。
愚公搬代码
2025/05/28
870
【愚公系列】2023年06月 攻防世界-Web(ics-07)
攻防世界新手练习Web writeup
刷题 从简单的网站开始: https://adworld.xctf.org.cn 0x01查看源码 curl http://111.198.29.45:31684 0x02 get_post htt
用户5878089
2019/07/24
1.3K0
攻防世界Web部分Wp
{"action":"buy","numbers":[true,true,true,true,true,true,true]}
用户5878089
2019/07/24
1.3K0
PHP Web 木马扫描器
<?php /**************PHP Web木马扫描器************************/ /* [+] 版本: v1.0
用户1696846
2018/07/16
5.2K0
攻防世界web进阶区comment详解
只要我们输入任何一个评论,他就会让我们进行登录, 我们可以通过他的文字提示,发现少了三位,一般我们都会上数字
wuming
2021/01/21
1.4K2
攻防世界web进阶区comment详解
hackme.inndy.tw的19道web题解(下)
目录 写在前面 ...... dafuq-manager 1 dafuq-manager 2. dafuq-manager 3. wordpress 1. webshell 写在前面 最近发现了一
安恒网络空间安全讲武堂
2018/02/23
3.4K0
hackme.inndy.tw的19道web题解(下)
攻防世界web进阶区ics-05
发现了一个输入的函数 他如果是字母和数字组合的话,输出page内容,同时die掉 如果不是字母和数字的组合的话,
wuming
2021/01/18
6130
WordPress Popular Posts 5.3.2 远程代码执行
https://github.com/rapid7/metasploit-framework
Khan安全团队
2021/12/22
9940
python flask web 博客实例 博客模块 2
1  app/models.py from markdown import markdown import bleach class Post(db.Model): tablename = 'posts' id = db.Column(db.Integer, primary_key=True) body = db.Column(db.Text) timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow) author_id = db.Column(db.Integer, db.ForeignKey('users.id')) @staticmethod def on_changed_body(target, value, oldvalue, initiator): allowed_tags = ['a', 'abbr', 'acronym', 'b', 'blockquote', 'code','em', 'i', 'li', 'ol', 'pre','strong', 'ul','h1', 'h2', 'h3', 'p'] target.body_html = bleach.linkify(bleach.clean(markdown(value,output_format='html'),tags=allowed_tags, strip=True)) db.event.listen(Post.body, 'set', Post.on_changed_body) class User(UserMixin, db.Model): # ... posts = db.relationship('Post', backref='author', lazy='dynamic') @staticmethod def generate_fake(count=100): from sqlalchemy.exc import IntegrityError from random import seed import forgery_py
用户5760343
2019/07/05
5250
XCTF-赛博地球杯工业互联网安全大赛web部分题解
0x01工控云管理系统项目管理页面解析漏洞 题目首先给出了源码: `http://47.104.156.32:20007/view-source.php` 关键代码如下: 第一层绕过 php <?p
安恒网络空间安全讲武堂
2018/02/06
2.4K0
XCTF-赛博地球杯工业互联网安全大赛web部分题解
ACTF-Web部分题复现
goahead v5.1.4 存在环境变量注⼊漏洞 (CVE-2021-42342)
pankas
2022/08/10
8100
ACTF-Web部分题复现
BugkuCTF之web解题记录(一)
构造payload:**?file=php://filter/read=convert.base64-encode/resource=index.php**
十二惊惶
2024/02/28
2080
2017 LCTF WriteUp 4篇
周末刚刚结束的LCTF,我们队一共做出了4道web,一道misc还有一道问卷调查(好气啊没抢到一血换pwnhub邀请码),感谢吃饭去大佬带飞~ 前言 对本渣渣而言,本次比赛质量还是不错的,我们队做出的四道web就涉及到了CBC字节翻转攻击、PaddingOracle攻击、sprintf格式化注入、sql报错注出库名表名、join注入出列名、orderby无表名注入数据、SSRF绕过、条件竞争、7个字符内getshell等知识,收获颇丰。下面是4道web的题目和WriteUp: Simple blog “他
安恒网络空间安全讲武堂
2018/02/06
1.5K0
2017 LCTF WriteUp 4篇
相关推荐
【愚公系列】2023年06月 攻防世界-Web(wtf.sh-150)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档