Scratch 之 3D 画笔程序使用

news2024/11/26 8:41:12

目录

Part1 摄像头固定的3D效果

Part2 尝试移动摄像头

Part3 边缘裁剪

总结:


Part1 摄像头固定的3D效果

首先,我们知道sc中有xy坐标。
现在让我们在sc中引入一个新坐标——z坐标。z轴垂直于电脑屏幕,从屏幕外指向屏幕里。(如下图)

z坐标表示纵深,就是这个角色在屏幕内的深度。
z坐标越大,表示角色离屏幕所在平面越远,因为近大远小,z越大,物体看起来会越小;当z为0,物体刚好在屏幕面内;当z为负数表示角色跑到了屏幕外面,看不到。

为了方便你理解z坐标的含义,现在我们来看通过增减z坐标能够实现什么效果↓

可以看到,z坐标增加时,小猫远离屏幕,小猫变小;z坐标减小时,小猫靠近屏幕,小猫变大

下面第一个重头戏来了!!
接下来将向你展示实现3D的的代码

是的!你没有看错!代码只有一行!!!

使用这个代码可以让角色移动到对应的坐标
其中变量“#3D常数”设为350(也可以是其他的值,不同的值效果不同)
(接下来告诉你为什么是这么写,这一段不重要,听不懂也没关系)
————————————下面这一段可以跳过———————————————
(以下是我个人理解,非常不专业,请不要完全相信)
这个#3D常数(前面的#号是我的变量命名习惯,表示这个变量是常数)是什么?
在初中我们学过凸透镜成像原理,这个常数是像距——成像到凸透镜的距离。
以人眼为例,像距就是视网膜到晶状体的距离,这个距离是个定值,当然,如果像距是固定的,焦距就要随物距改变,所以晶状体会具有伸缩调焦的功能。
已知一个物体的长度和这个物体到凸透镜的距离,我们就能算出这个物体的成像的长度(屏幕上显示的长度)。
根据凸透镜成像原理和相似三角形,有如下关系:
实际长度:显示长度=物距(物体到凸透镜距离):像距(成像到凸透镜长度)
把这个式子变形一下,就是:
显示长度=实际长度*(像距/物距)

因此在代码中,我们看到:
显示y=实际y*(像距/z)
显示x=实际x*(像距/z)
显示大小=实际大小*(像距/z)
(你发现多了一行调大小的代码?当然,如果只使用画笔,大小可以不用调整;如果要使用角色,角色大小也要调整)

同时,上面的式子也可以解释为什么“近大远小”:
显示大小与z成反比例关系,z越大,显示大小越小,即物体离屏幕越远,物体看起来就越小
————————————接下来继续————————————

那么这个代码具体可以怎么用呢?
首先,如果让你在sc中用画笔绘制一个正方形,边长为100,左下角坐标为(0,0),你应该知道怎么做吧?
就像这样:

那么现在举一反三,我们来尝试用刚才的代码在三维空间中画一个正方形:边长为100,“放”在“地面”上(“地面”y坐标假设设为-150),正方形左下角坐标(-150,-150,300),你知道怎么画吗?
可以这样写:

运行效果:

怎么样?是不是很像某个正方体的底面?
那么现在,我们以这个正方形为底面,绘制出一个完整的正方体...
首先我们来尝试画正方体的左侧面,类似于刚才底面的画法,你应该明白怎么画吧?
像这样:

其他面的代码同理。接着我们把其他面依次画完...
(Tips:可以直接画边,不用每个面都写一个绘制代码)

怎么样?是不是有内味了!好了,到这里,你已经掌握了实现3D的基本内容了
怎样,是不是意外的简单?
如果你听懂了,尝试自己画一个正方体。

————————————练习时间———————————————
(接下来是运用刚才的知识可以实现的几个案例练习,如果你听懂了,可以尝试自己做一下)
案例1:让正方体动起来!
预期效果:按wasd可上下左右移动正方体,↑↓键可前后移动正方体
具体过程:我们用三个变量:左下x,左下y,左下z来储存正方体左下角的坐标,然后编写程序,按对应的按键就增减正方体对应的坐标(例如按↑键增加z坐标,↓键减少z坐标)
实现结果↓

参考代码:

案例2:画个圆吧!
预期效果:画个铺在“地上”的圆(“地面”y:-150(当然你也可以自己设置)),半径100,圆心(-40,-150,500)
Tips:首先我们先尝试在sc自带的坐标系中尝试画圆(注意,需要用到三角函数!)
(即使在二维平面画出一个圆,代码其实也不简单↓,因此需要各位在阅读此教程之前需要比较扎实的基础)
(其实也可以不用三角函数,用勾股定理也可以)

我们对上面的代码稍作修改:

效果↑

(平放在“地上”的圆看起来像个椭圆)

案例3:画个马路!(可以用来做公路跑酷游戏)
代码:

效果↑


Part2 尝试移动摄像头

首先什么是摄像头?
摄像头是指当前视野的位置,移动摄像头就是移动视野。用xyz三个坐标储存摄像头的位置。在上面的教程中,其实相当于摄像头的x、y、z的值均为0的视野。
当摄像头向右移动,摄像头的x增加,视野往右移动,反之,往左移动时,摄像头的x减小;
同理,上下移动就是增加和减小摄像头的y坐标;前后移动就是增加和减少摄像头的z坐标。

实现摄像头移动效果的代码其实非常简单:
首先新建三个变量,命名为摄像头x,摄像头y,摄像头z

然后对之前的代码

中的“x”,”y”,”z”进行下面的替换

改为:

然后,通过修改“摄像头x”“摄像头y”“摄像头z”就可以实现摄像头(即视野)的移动了。例如增减摄像头的x来向右和向左移动视野。


为什么这么做可以实现摄像头的移动呢?

如果你有制作“大地图”游戏的基础的话,上面的内容会很好理解。

例如,下面的作品的摄像头移动


用的就是类似下面的代码

比如,一个角色在地图上的坐标是(100,100),摄像头的坐标是(60,60),这时,角色实际在屏幕上显示的坐标为(40,40),即用角色的实际地图坐标减去摄像头的坐标,得到角色相对于摄像头的位置。

因此,我们进行下面的替换,得到的就是角色相对摄像头的坐标,即角色显示的坐标。

现在,我们来写移动摄像头的代码吧!
(其中绘制正方体的代码是之前写过的代码)

我们来看其中的这段新代码:

注意到摄像头的y初始为100,这是因为,游戏中的角色有一定的高度,这里的就是角色的视角到地面的高度。
绘制的立方体的y坐标为0,即把立方体放在地面上。

上面的代码很简单,就像移动一个角色一样,你应该很容易理解。


接下来我们来尝试加个跳跃效果:
如果你知道如何在2D的游戏中实现重力和跳跃效果,下面的代码将会非常好理解。
首先新建一个变量叫yv

其中v是速度的意思。yv就是y方向的速度,就是纵向速度。

下面的代码实现了重力和跳跃效果。

yv是纵向速度,因此在每次循环中,摄像头的y都增加了yv,当yv为正值,角色将向上移动,当yv为负值,角色将向下移动。


因为受到重力的影响,yv每次循环都会减少一定的值。当角色跳起(按下空格),将角色的yv设为10,即设置一个向上的速度,此后角色以该速度上移,并且随着时间的增加,上移的速度减小(yv减小),最终yv减少到0,角色不再上移,达到最高点。之后,yv还在减少,减少到负数,这时,角色开始下落。

下面的代码是角色落地后的代码。因为角色的高度是100,当角色落到地面上时,角色的y是0,但是摄像头固定在“头”上,高度是100。所以当摄像头y<100时,才判断为落地。之后将摄像头y设为100,即移到地面。落到地面后,没有纵向速度,将yv设为0。

于是,我们实现了移动,以及跳跃的效果。按WASD,摄像头就能前后左右移动;按下空格键,就可以跳跃。


Part3 边缘裁剪

(前排提醒:这一部分略难,我写的也比较凌乱,如果看不懂的话,可以跳过具体写代码的过程,只要知道最后的自定义模块怎么用就行了。)

  不知道你在运行之前的代码,移动正方体时是否遇到这样的问题:

  可以看到,当正方体移动到边缘时,发生了变形。
  这是怎么回事呢?
  我们知道,Scratch的舞台是有范围的,x坐标范围是-240~240,y坐标的范围是-180~180,当scratch角色移动到边缘时,会受到舞台限制。
  例如运行这个代码:

  得到的结果是:

因为受到舞台限制,角色没有移动到(1000,1000)而是移到了(290,218)
  (不同角色由于造型的大小不同,可能得到的结果不同。造型大的角色受到的约束会更小;当使用空造型,得到的结果则是240,180)
  
  因此,当我们运行下面这段代码:

我们希望得到的是下图中绿色的线(一条45°倾斜的线),可是实际运行的结果确实红色的线。

绿色是我们希望的绘制结果,红色是实际绘制结果

  因此,我们需要对绘制的线段进行裁剪(裁剪的意思就是把跨越屏幕边缘的线段裁剪为只剩下屏幕内的线段):

具体步骤为:
  当线段两端在屏幕内,直接画出;
  当线段两端都在屏幕外,不用画出;
  而当线段两端有一端在屏幕外,一段在屏幕内,就求出这个线段和屏幕边缘的交点,然后最后实际画出的线段就是从屏幕内的端点到交点的线段。(例如上面绘制的线段是(0,0)到(1000,1000),则实际画出的是(0,0),(180,180),即和屏幕上方边缘的交点)。
  如果未经裁剪的绘制线段的写法是这样:

  则经过裁剪的绘制线段的代码是这样:

看起来有亿点复杂

这段代码看不懂具体的过程没有关系,只要知道如何使用就行了。上面的代码用于绘制一条线段,并且当线段跨过屏幕边缘时,也能正确绘制。

  (上面的代码取自国外一个大佬的3D教程中的代码。我自己也写了一个裁剪,但是写的太复杂了……上面的写法应该是算比较简单的写法了。
  (建议直接使用上面的代码,不要自己写;当然如果你想挑战一下自己,也可以尝试自己写一个裁剪的代码)

  运行下面的代码

  可以看到绘制出来的线段是正确的。

正确的结果

  现在,我们再把之前绘制立方体的代码进行修改:
  首先写一条绘制3D线段的代码:

  前面我们分析过了,当线段的端点跑到屏幕外时,上面代码的画法是有问题的。因此我们需要用到刚刚写的这个代码:

(这个代码绘制的是2D线段)

修改之后:

补充说明:
  (三维空间中一个点在Scratch舞台上绘制时的二维坐标,称为这个点的投影)
  例如下面的两个黑圈中就是点(x,y,z)对应的投影的(x,y)坐标(在舞台上实际绘制的坐标)

  同样,下面的起点x,起点y是点(x1,y1,z1)对应的投影坐标

然后把之前绘制立方体的代码换成依次绘制每条边的代码。

  这样当立方体移动到边缘时,就不会变形了。


  但是!
  现在还有一个问题:

  当立方体靠近屏幕时,也会变形。这是因为,立方体的边和屏幕所在平面产生了交点,正方体有一部分跑到了屏幕外面。
  前面我们进行的是x和y方向的裁剪。接下来,我们还需要进行z方向的裁剪。
  具体步骤:
  如果两端点都在屏幕内(两端点的z都大于摄像头z),则使用我们之前写的画线段的代码直接画出);
  如果两端点都在屏幕后面(两端点的z都小于摄像头z),则不用画;
  如果两端点一端在屏幕内,一端在屏幕外,则这条线段和屏幕产生了交点,实际画出的线段为从屏幕内的端点到交点的线段。

具体的代码:

看起来也有亿点多

  接下来要做到,就是求交点的坐标。
  使用下面的代码求线段和平面z的交点
  (其中线段的端点坐标填相对摄像头的坐标,平面的z为相对摄像头)

(这里求出的是交点的三维空间的相对摄像头xy坐标,而非投影xy坐标。交点的z为平面的相对摄像头z)

  上面的代码大致的原理是相似三角形,不理解没关系,会用就行了。

最终代码

一些注释

  完成上面的代码后,现在当正方体和摄像头平面有交点时也不会变形。
  现在,使用下面的这个代码绘制3D线段,无论何种情况,画出的线段都不会变形了。

  学完以上的内容,你已经掌握了画笔3D的理论知识的一半了!即除了旋转摄像头,你已经掌握了其他关于画笔3D的大部分内容!


总结

Part1:核心代码

Part2:核心代码

Part3:核心代码

下面这段代码用于Scratch中绘制线段,并且当线段跨越舞台边缘时,对进行X和Y的裁剪,只绘制舞台内的线段,从而正确绘制。

下面这段代码用于绘制3D的线段。并且带有裁剪功能(当线段的一部分在摄像头后面时,进行Z的裁剪,只绘制摄像头前的线段,从而正确绘制)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/875752.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

O2OA (翱途) o2server 调用 webServices jaxws 样例

本文分两部分介绍如何在 o2server 服务器中调用 webServices(jaxws)服务. 第一部分介绍如何在tomcat上搭建一个webServices(jaxws)服务. 第二部分介绍如何在o2server服务器上来调用上面创建的服务. O2OA (翱途)官网&#xff1a;http://www.o2oa.net 一、在tomcat上搭建一个…

Redis辅助功能

一、Redis队列 1.1、订阅 subscribe ch1 ch2 1.2 publish:发布消息 publish channel message 1.3 unsubscribe: 退订 channel 1.4 模式匹配 psubscribe ch* 模糊发布&#xff0c;订阅&#xff0c;退订&#xff0c; p* <channelName> 1.5 发布订阅原理 订阅某个频道或…

【正点原子STM32连载】第五章 APM32基础知识入门摘自【正点原子】APM32F407最小系统板使用指南

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html# 第五…

电脑提示数据错误循环冗余检查怎么办?

有些时候&#xff0c;我们尝试在磁盘上创建分区或清理硬盘时&#xff0c;还可能会遇到这个问题&#xff1a;数据错误循环冗余检查。这是如何导致的呢&#xff1f;我们又该如何解决这个问题呢&#xff1f;下面我们就来了解一下。 导致冗余检查错误的原因有哪些&#xff1f; 数据…

使用AT命令操作Modem 3G/4G模块

1. 引言 AT命令是一种通信协议&#xff0c;用于控制和配置各种设备&#xff0c;尤其在通信领域中具有重要性。它的名称来源于"ATtention"&#xff08;注意&#xff09;&#xff0c;因为命令通常以"AT"开头。AT命令最早被用于调制解调器&#xff0c;用于与…

驱动阿托斯DLHZO-T伺服比例阀放大器定制

DLHZO-T型伺服比例换向阀&#xff0c;直动式&#xff0c;带LVDT位置传感器和阀芯零遮盖&#xff0c;可应用于各种位置闭环控制实现最佳的性能。 比例阀和模块式数字放大器配合使用。 LVDT传感器和阀套结构可确保非常高的调节精度和响应灵敏度。 失电保护位可实现在电源中断的…

一文读懂3D开发工具HOOPS SDK

近年来&#xff0c;随着对定制软件开发需求的增加&#xff0c;我们也目睹了新的软件开发工具和技术的加入。 大部分企业在移动和Web应用程序开发上投入了大量的精力&#xff0c;这表明市场对技术软件解决方案的需求在增加。然而&#xff0c;在开发软件的过程中&#xff0c;是可…

基于 SIFT 和 RANSAC 算法对高分辨率图像进行图像伪造检测(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

kafka基本概念及操作

kafka介绍 Kafka是最初由Linkedin公司开发&#xff0c;是一个分布式、支持分区的&#xff08;partition&#xff09;、多副本的 &#xff08;replica&#xff09;&#xff0c;基于zookeeper协调的分布式消息系统&#xff0c;它的最大的特性就是可以实时的处理大量数据以满足各…

技术解析丨主轴自动换刀系统是如何工作的?有哪些优点?

一、主轴气动自动换刀系统原理 1.当加工过程中需要更换主轴上的刀具时&#xff0c;操作人员通过控制系统发出换刀指令。 2.控制系统根据指令向气动系统发送动作信号&#xff0c;驱动气动马达带动换刀机构运动。 3.换刀机构中的刀具夹持器将现有刀具从主轴上取下&#xff0c;…

FreeRTOS(事件组)

资料来源于硬件家园&#xff1a;资料汇总 - FreeRTOS实时操作系统课程(多任务管理) 目录 一、事件的概念与应用 1、事件的概念 2、事件的应用 二、事件的运作机制 1、FreeRTOS中事件组的句柄 2、FreeRTOS 任务间事件标志组的实现 3、FreeRTOS 中断方式事件标志组的实现…

vue2学习:reduce方法和computed计算属性用法

reduce reduce可以遍历集合并将集合所有的值汇总为一个。 第一个参数是一个回调函数&#xff0c;函数第一个参数是汇总起来的最终值&#xff0c;默认是集合的第一项&#xff0c;函数第二个参数是集合遍历出来的集合元素&#xff1b; 第二个参数可以指定回调函数中第一个参数汇…

62、华为昇腾开发板Atlas 200I DK A2配置mmpose的hrnet模型推理python/c++

基本思想&#xff1a;适配mmpose模型&#xff0c;记录一下流水帐&#xff0c;环境配置和模型来自&#xff0c;请查看参考链接。 链接: https://pan.baidu.com/s/1IkiwuZf1anyKX1sZkYmD1g?pwdi51s 提取码: i51s 一、转模型 (base) rootdavinci-mini:~/sxj731533730# atc --mo…

优测云服务平台|【压力测试功能升级】轻松完成压测任务

一、本次升级主要功能如下&#xff1a; 1.多份报告对比查看测试结果 2.报告新增多种下载格式 Word格式Excel格式 3.新增多种编排复杂场景的控制器 漏斗控制器并行控制器事务控制器仅一次控制器分组控制器集合点 4.新增概览页面&#xff0c;包含多种统计维度 二、报告对比…

智慧工地源码,互联网+建筑工地,基于微服务+Java+Spring Cloud +Vue+UniApp开发

基于微服务JavaSpring Cloud VueUniApp MySql开发的智慧工地云平台源码 智慧工地概念&#xff1a; 智慧工地就是互联网建筑工地&#xff0c;是将互联网的理念和技术引入建筑工地&#xff0c;然后以物联网、移动互联网技术为基础&#xff0c;充分应用BIM、大数据、人工智能、移…

DoorGym:开源的可拓展的开门仿真环境,用于域随机化的强化学习、深度强化学习

0.概述 目的&#xff1a;创建一个可以改变门把手形状、类型、位置、环境颜色、照明条件、机械臂结构的仿真环境&#xff0c;以训练出鲁棒性更高、更能关注到任务本质特征、容易迁移到现实的模型 网址&#xff1a;环境下载&#xff0c; 1.领域随机化DR 假设很难对目标域进…

在Visual Studio上,使用OpenCV实现人脸识别

1. 环境与说明 本文介绍了如何在Visual Studio上&#xff0c;使用OpenCV来实现人脸识别的功能 环境说明 : 操作系统 : windows 10 64位Visual Studio版本 : Visual Studio Community 2022 (社区版)OpenCV版本 : OpenCV-4.8.0 (2023年7月最新版) 实现效果如图所示&#xff0…

SAP SM30 自动带出描述实现

需求&#xff1a; 在SM30中维护销售订单类型的时候&#xff0c;根据维护的销售订单类型自动带出订单类型描述 事务码&#xff1a; SE11 进入表维护生成器中 创建事件 选择【维护事件】: 05 自定义子例程&#xff1a; SET_DESCRIPTION 点击编辑器按钮进行代码编辑 具体代码…

浅学实战:探索PySpark实践,解锁大数据魔法!

文章目录 Spark和PySpark概述1.1 Spark简介1.2 PySpark简介 二 基础准备2.1 PySpark库的安装2.2 构建SparkContext对象2.3 SparkContext和SparkSession2.4 构建SparkSession对象2.5 PySpark的编程模型 三 数据输入3.1 RDD对象3.2 Python数据容器转RDD对象3.3 读取文件转RDD对象…

【力扣每日一题】1572. 矩阵对角线元素的和 8.11打卡

文章目录 题目思路代码 题目 1572. 矩阵对角线元素的和 难度&#xff1a; 简单 描述&#xff1a; 给你一个正方形矩阵 mat&#xff0c;请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 返回合并后的二叉树。 注意…