advanced east_SpriteKit Advanced —如何構建2,5D游戲(第二部分)

advanced east

by Luke Konior

盧克·科尼爾(Luke Konior)

SpriteKit Advanced —如何構建2,5D游戲(第二部分) (SpriteKit Advanced — How to build a 2,5D game (Part II))

介紹 (Intro)

This article shows how to write basic shaders in the SpriteKit. It’s split into two parts: first we play, then we learn.

本文介紹如何在SpriteKit中編寫基本著色器。 它分為兩個部分:首先我們玩,然后學習。

It also contains information how to use SKAttribute and SKAttributeValue classes that were added in iOS SDK 10.0.

它還包含有關如何使用iOS SDK 10.0中添加的SKAttributeSKAttributeValue類的信息。

If you haven’t already read it, here’s part 1 of this article series.

如果您還沒有閱讀它,請參閱本系列文章的第1部分 。

準備項目 (Prepare the project)

Let’s get quick and dirty.

讓我們變得快速又骯臟。

  • Open XCode 8 and create a new project from template: iOS > Game.

    打開XCode 8,然后從以下模板創建一個新項目:iOS>游戲。
  • Open the GameScene.sks and remove the label in the center of the screen.

    打開GameScene.sks并刪除屏幕中心的標簽。

  • Download this and put it inside Assets.xcassets

    下載此文件并將其放入Assets.xcassets

  • Name it “Trees”

    命名為“樹木”
  • Open the GameScene.m

    打開GameScene.m

  • remove all instance variables

    刪除所有實例變量
  • remove all methods

    刪除所有方法

片段著色器 (The Fragment Shader)

Now we create an empty fragment shader In XCode:

現在,我們在XCode中創建一個空的片段shader

  • In the Project Navigator select Supporting Files

    在項目瀏覽器中,選擇“支持文件”
  • Choose: File > New > File…

    選擇:文件>新建>文件…
  • Select: Other > Empty

    選擇:其他>空
  • Name it “myShader.fsh” and press Create.

    將其命名為“ myShader.fsh ”,然后按創建。

  • Put this inside:

    放在里面:
// currently a boring pass-thru shader void main( void ) { vec4 color = texture2D(utexture, vtexcoord); // here will emerge something worthy glFragColor = color;}

Above fragment shader does nothing perceptible. Quick explanation:

片段shader上方沒有任何可察覺的內容。 快速說明:

  • void main()

    void main()

    this function gets called for each pixel of the sprite and outputs color for that pixel

    為精靈的每個像素調用此函數,并輸出該像素的顏色

    Gets input data from surrounding globals and must set the

    從周圍的全局變量獲取輸入數據,并且必須設置

    gl_FragColor variable

    gl_FragColor變量

  • vec2, vec3and vec4 are the types similar to C's: float array[2], float array[3] and float array[4]

    vec2vec3vec4與C的類型相似: float array[2]float array[3]float array[4]

  • u_texture is a texture ID

    u_texture是紋理ID

    Leave it alone :-)

    不要管它 :-)

  • v_tex_coord is a vec2 which contains our current position in texture

    v_tex_coord是一個vec2 ,其中包含我們當前的紋理位置

  • texture2D(tex , p) is a function that returns color from texture tex in point p as vec4

    texture2D(tex , p)是一個函數,將point p處紋理tex顏色返回為vec4

    which contains rgba

    其中包含rgba

  • gl_FragColor is an output color

    gl_FragColor是輸出顏色

    We must assign it a

    我們必須給它分配一個

    vec4

    vec4

正在加載代碼 (Loading code)

What’s left is the loading code.

剩下的就是加載代碼。

  • Open the GameScene.m

    打開GameScene.m

  • add method -didMoveToView:

    添加方法-didMoveToView:

- (void)didMoveToView:(SKView *)view {	// 1. load the shader's source from myShaderFile.fsh	NSString *file = [[NSBundle mainBundle] pathForResource:@"myShader" ofType:@"fsh"];	NSString *sourceString = [NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil];	    	// 2. create the shader	SKShader *shader = [SKShader shaderWithSource:sourceString];		// 3. assign the shader to a newly created sprite node	SKSpriteNode *spriteNode = [SKSpriteNode spriteNodeWithImageNamed:@"Trees"];	spriteNode.shader = shader;		// 4. finally add the sprite to the scene	[self addChild:spriteNode];}

Ensure that myShader.fsh figures in ProjectFile > Target > Build Phases > Copy Bundle Resources!

確保myShader.fsh數字位于ProjectFile>目標>構建階段>復制捆綁資源中!

You may now run the project on the iOS device. There shall be no errors in the XCode’s console and you should see a screen similar to this below:

您現在可以在iOS設備上運行該項目。 XCode的控制臺中應該沒有錯誤,并且您應該看到類似于以下的屏幕:

讓我們玩吧! (Let’s play a bit!)

Now is the fun part. We’ll replace the shader’s main function.

現在是有趣的部分。 我們將替換著色器的主要功能。

顏色為紅色,保留alpha (Color with red with alpha preservation)

void main( void ){    vec4 color = texture2D(u_texture, v_tex_coord);    float alpha = color.a;    gl_FragColor = vec4(1,0,0, 1.0) * alpha; //google "premultiplied alpha"}

縮小2倍 (Scale down by 2x)

void main( void ){    vec4 color = texture2D(u_texture, v_tex_coord * 2.0);    gl_FragColor = color;}

1秒后交換顏色 (Swap colors after 1 second)

void main( void ){    vec4 color = texture2D(u_texture, v_tex_coord);    float alpha = color.a;    float phase = mod(u_time, 3);    vec3 outputColor = color.rgb;    if (phase < 1.0) {        outputColor = color.bgr;    } else if (phase < 2.0) {        outputColor = color.brg;    }    gl_FragColor = vec4(outputColor, 1.0) * alpha;}

隨時間著色 (Colorize over time)

void main( void ){    vec4 color = texture2D(u_texture, v_tex_coord);    float alpha = color.a;    float r = (sin(u_time+ 3.14 * 0.00)+1.0)*0.5;    float g = (sin(u_time+ 3.14 * 0.33)+1.0)*0.5;    float b = (sin(u_time+ 3.14 * 0.66)+1.0)*0.5;    gl_FragColor = vec4(r,g,b, 1.0) * alpha;}

波浪 (Waves)

void main( void ){    float deltaX = sin(v_tex_coord.y*3.14*10 + u_time * 4)*0.01;    vec2 coord = v_tex_coord;    coord.x = coord.x + deltaX;    vec4 color = texture2D(u_texture, coord);    gl_FragColor = color;}

新屬性 (New Attributes)

At WWDC 2016 Apple introduced an important update to SpriteKit — the SKAttribute and SKAttributeValue classes.

蘋果在WWDC 2016上對SpriteKit進行了重要更新,即SKAttributeSKAttributeValue類。

Before this SDK update, if we wanted to pass custom parameters into the shader program, we had to pass the data through a uniform value.

在此SDK更新之前,如果我們想將自定義參數傳遞給shader程序,則必須通過統一值傳遞數據。

This had two serious drawbacks:

這有兩個嚴重的缺點:

  • every uniform change caused shader recompilation

    每次統一更改都會導致著色器重新編譯
  • shader program handled every sprite in the exact same way

    著色器程序以完全相同的方式處理每個精靈

For example: if we wanted to dye a group of sprites red, and one of them blue, we had two ways. First we create two separate SKShader instances and change our custom myColor uniform.

例如:如果我們想將一組精靈染成紅色,而其中一個染成藍色,則有兩種方法。 首先,我們創建兩個單獨的SKShader實例,并更改我們的自定義myColor制服。

Second we make one shader instance and change its uniform which causes a recompilation.

其次,我們制作一個shader實例并更改其統一性,從而導致重新編譯。

Both ways cannot be drawn on same pass. And the second one requires complex management code.

兩種方法不能同時繪制。 第二個要求復雜的管理代碼。

SDK 10.0 introduced the SKAttribute and SKAttributeValue classes. These two allow (finally!) passing data to the shader programs without recompilation. The usage algorithm is simple:

SDK 10.0引入了SKAttributeSKAttributeValue類。 這兩個允許(最終!)將數據傳遞到著色器程序,而無需重新編譯。 用法算法很簡單:

  • The shader part:

    著色器部分:
  1. Create a shader program

    創建一個著色器程序

    Create a shader programSKShader

    創建一個著色器程序SKShader

  2. Create an array of SKAttributes

    創建一個SKAttributes數組

  3. Assign array of attributes to the shader program

    將屬性數組分配給著色器程序
  • The sprite part:

    sprite部分:

  1. Assign the shader program to a sprite

    將著色器程序分配給精靈
  2. Assign a dictionary of SKAttributeValues

    分配SKAttributeValues字典

屬性示例 (Example with attributes)

In the last example, we’ll add two more sprites. Every one of them will have the same shader program and will differ only in attributes. Let’s modify the -didMoveToView: inGameScene.m:

在最后一個示例中,我們將再添加兩個精靈。 它們中的每一個將具有相同的著色器程序,并且僅在屬性上有所不同。 讓我們修改- didMoveToView: inGameScene.m:

- (void)didMoveToView:(SKView *)view {    NSString *file = [[NSBundle mainBundle] pathForResource:@"myShader" ofType:@"fsh"];    NSString *sourceString = [NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil];    SKShader *shader = [SKShader shaderWithSource:sourceString];        // 1. Add a custom attribute to shader    SKAttribute *attrProgress = [SKAttribute attributeWithName:@"THE_MIGHTY_DARK_FACTOR" type:SKAttributeTypeFloat];    shader.attributes = @[attrProgress];    // 2. Create tree sprites    NSArray *trees = @[                       [self createTreeWithShader:shader mightyFactor:0.3f zPosition:1],                       [self createTreeWithShader:shader mightyFactor:0.6f zPosition:2],                       [self createTreeWithShader:shader mightyFactor:0.9f zPosition:3],                       ];    for (SKSpriteNode *tree in trees) {        [self addChild:tree];    }}- (SKSpriteNode*)createTreeWithShader:(SKShader*)shader mightyFactor:(CGFloat)mightyFactor zPosition:(CGFloat)zPosition {    SKSpriteNode *treeNode = [SKSpriteNode spriteNodeWithImageNamed:@"Trees"];    treeNode.shader = shader;    // 3. Fill the custom attribute on the sprite    treeNode.attributeValues = @{@"THE_MIGHTY_DARK_FACTOR": [SKAttributeValue valueWithFloat:mightyFactor]};    treeNode.zPosition = zPosition;return treeNode;}

… and the shader program:

…和著色器程序:

void main( void ){    vec4 color = texture2D(u_texture, v_tex_coord * (2.5 * THE_MIGHTY_DARK_FACTOR));    float alpha = color.a;    vec3 baseColor = color.rgb * THE_MIGHTY_DARK_FACTOR;    gl_FragColor = vec4(baseColor, 1.0) * alpha;}

... and see the parameterized result!

...并查看參數化結果!

注意事項 (Caveats)

  • The shader’s source code is typically loaded from a .fsh file to a plain NSString

    著色器的源代碼通常從.fsh文件加載到純NSString

    This code must compile on the target device during the runtime

    此代碼必須在運行時在目標設備上編譯

    no buildtime checks!

    沒有構建時間檢查!

  • Older devices may use different version of OpenGL ES so beware GLSL syntax differences!

    較舊的設備可能使用不同版本的OpenGL ES,因此請注意GLSL語法的不同!

    In Raft Challenge’s case there was the need to replace

    在Raft Challenge的情況下,需要更換

    __constant (valid in OpenGL ES 3.0) to const for OpenGL ES 2.0.

    __constant (在OpenGL ES 3.0中有效)以const表示OpenGL ES 2.0。

  • It’s a good idea to keep a reference to SKShader object somewhere and reuse it as frequently as needed to avoid visible frame rate drop

    最好在某個地方保留對SKShader對象的引用,并根據需要重復使用它,以避免可見的幀速率下降

    While allocation and shader compilation takes less than 1/60 sec, it may become a huge burden in render loop

    雖然分配和著色器編譯花費的時間少于1/60秒,但它可能會成為渲染循環中的巨大負擔

  • When using SpriteKit’s Texture Atlases be cautious of vtexcoord

    使用SpriteKit的Texture vtexcoord謹慎使用vtexcoord

    XCode may rotate some textures which swap

    XCode可能會旋轉一些交換的紋理

    X and Y axis

    XY

    X and Y axisColor modification is safe, geometry is not

    XY顏色修改是安全的,幾何圖形不是

摘要 (Summary)

We learned by examples how to use fragment shaders in the Sprite Kit. We added parameters to sprites so our shader program can render every instance in a different way without any performance loss.

我們通過示例學習了如何在Sprite Kit中使用片段著色器。 我們向精靈添加了參數,以便我們的著色器程序可以以不同的方式呈現每個實例而不會造成性能損失。

The complete project is available for a download.

完整的項目可下載。

You can read part 3 of this series here.

您可以在這里閱讀本系列的第3部分 。

About the author: Kamil Zi?tek is an iOS Developer at www.allinmobile.co

關于作者:KamilZi?tek是www.allinmobile.co上的iOS開發人員

翻譯自: https://www.freecodecamp.org/news/spritekit-advanced-how-to-build-a-2-5d-game-part-ii-30ddb613b568/

advanced east

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/395384.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/395384.shtml
英文地址,請注明出處:http://en.pswp.cn/news/395384.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

html原生上傳,一個基于HTML5及原生JS的文件上傳組件--JohnUploader

運行效果圖一、組件介紹基本特點基于HTML5的FileReader和FormData可以完成多文件選擇&#xff0c;并預覽完成文件的異步上傳原生XHR對象&#xff0c;適配多瀏覽器代碼class JohnUploader{url;fileField;vollay;/**** param url 文件上傳的地址* param fileField 一個"文件…

[20170617]vim中調用sqlplus.txt

[20170617]vim中調用sqlplus.txt --//以前寫過一篇emacs下調用sqlplus的文章,一直想學emacs,受限制自己掌握vim,對學習它沒有興趣,原鏈接如下: --//http://blog.itpub.net/267265/viewspace-1309032/ --//實際上vim也有插件連接數據庫,我覺得不好用,一直沒這樣用. --//今天在整…

centos redis驗證_centos7中安裝、配置、驗證、卸載redis

本文介紹在centos7中安裝、配置、驗證、卸載redis等操作&#xff0c;以及在使用redis中的一些注意事項。一 安裝redis1 創建redis的安裝目錄利用以下命令&#xff0c;切換到/usr/local路徑cd /usr/local鍵入以下命令&#xff0c;新建一個redis目錄&#xff0c;用于放置redis軟件…

實習生解雇_我們解雇了我們的頂尖人才。 我們做出的最佳決定。

實習生解雇by Jonathan Solrzano-Hamilton喬納森索洛薩諾漢密爾頓(JonathanSolrzano-Hamilton) 我們解雇了我們的頂尖人才。 我們做出的最佳決定。 (We fired our top talent. Best decision we ever made.) “You will never be able to understand any of what I’ve create…

微信企業號第三方應用開發[二]——創建應用

在應用套件里添加應用 當你創建完應用套件后&#xff0c;需要在套件配置應用&#xff0c;應用的信息填寫如下。 基本信息&#xff1a; 信息項要求及說明應用Logo應用的Logo&#xff0c;小于2M&#xff0c;640*640&#xff0c;在授權頁會被用于展示。應用名稱應用的名稱&#xf…

es6新增的html標簽,javascript – 如何導入已在html中的標簽中定義的es6模塊?

我可以在我的html文件me.html中定義一個模塊&#xff1a;import Atom from ./atom.js;console.log("definition of getAtom")export default function getAtom(){return new Atom(atom);}console.log("exported getAtom")另見>是否可以將該“匿名”模塊…

jQ效果:簡單的手風琴效果

實現效果如圖所示&#xff1a; html結構&#xff1a; <div class"item_box box10"><div class"item_box_wp"><div class"voice_2"><ul><li class"li1" id"li1"><div class"fold"…

golang 日志分析_容器日志采集利器:Filebeat深度剖析與實踐

在云原生時代和容器化浪潮中&#xff0c;容器的日志采集是一個看起來不起眼卻又無法忽視的重要議題。對于容器日志采集我們常用的工具有filebeat和fluentd&#xff0c;兩者對比各有優劣&#xff0c;相比基于ruby的fluentd&#xff0c;考慮到可定制性&#xff0c;我們一般默認選…

機器學習做自動聊天機器人_建立聊天機器人需要什么? 讓我們找出答案。

機器學習做自動聊天機器人by Vanco Stojkov通過Vanco Stojkov 建立聊天機器人需要什么&#xff1f; 讓我們找出答案。 (What does it take to build a chatbot? Let’s find out.) Without any delay, the image below shows what we are building:沒有任何延遲&#xff0c;下…

UVA 11582 Colossal Fibonacci Numbers!【數學】

大一剛開始接觸ACM就買了《算法競賽入門經典》這本書&#xff0c;當時只能看懂前幾章&#xff0c;而且題目也沒做&#xff0c;粗鄙地以為這本書不適合自己。等到現在快大三了再回過頭來看&#xff0c;發現劉老師還是很棒的&#xff01; 扯遠了。。。 題意&#xff1a;問f[a^b]%…

Codeforces 919D Substring (拓撲圖DP)

手動博客搬家: 本文發表于20180716 10:53:12, 原地址https://blog.csdn.net/suncongbo/article/details/81061500 給定一個\(n\)個點\(m\)條邊的有向圖&#xff08;不一定無環&#xff09;&#xff0c;每個點上有一個小寫字母。要找一條路徑&#xff0c;使得路徑上出現次數最多…

layui自定義查詢條件html頁面,Layui的數據表格+springmvc實現搜索功能的例子_飛雲_前端開發者...

如下所示&#xff1a;主要在前端頁面加&#xff1a;搜索ID&#xff1a;useridcontent搜索在reload:function () {var keyWord$("#keyWord").val();var keyType$("#key_type option:selected").val();table.reload(contenttable,{method:post,where:{keyWor…

mysql+keepalived 雙主熱備高可用

理論介紹&#xff1a;我們通常說的雙機熱備是指兩臺機器都在運行&#xff0c;但并不是兩臺機器都同時在提供服務。當提供服務的一臺出現故障的時候&#xff0c;另外一臺會馬上自動接管并且提供服務&#xff0c;而且切換的時間非常短。MySQL雙主復制&#xff0c;即互為Master-Sl…

java ldap userpassword 解密_Spring Boot中使用LDAP來統一管理用戶信息

LDAP簡介LDAP(輕量級目錄訪問協議&#xff0c;Lightweight Directory Access Protocol)是實現提供被稱為目錄服務的信息服務。目錄服務是一種特殊的數據庫系統&#xff0c;其專門針對讀取&#xff0c;瀏覽和搜索操作進行了特定的優化。目錄一般用來包含描述性的&#xff0c;基于…

第三章之枚舉、注解

2019-01-22內容&#xff1a;枚舉、注解一、自定義一個枚舉類1 public class TestSeason {2 3 public static void main(String[] args) {4 Season spring Season.Spring;5 System.out.println(spring);6 }7 }8 public class Season {9 //將屬性定…

html打開后默認瀏覽器頁面,使用VBA打開默認瀏覽器中的html頁面?

您可以使用Windows API函數ShellExecute來執行此操作&#xff1a;Option ExplicitPrivate Declare Function ShellExecute _Lib "shell32.dll" Alias "ShellExecuteA" ( _ByVal hWnd As Long, _ByVal Operation As String, _ByVal Filename As String, _Op…

數據科學r語言_您應該為數據科學學習哪些語言?

數據科學r語言Data science is an exciting field to work in, combining advanced statistical and quantitative skills with real-world programming ability. There are many potential programming languages that the aspiring data scientist might consider specializi…

Linux平臺不同解壓縮命令的使用方法

作者&#xff1a;郭孝星 微博&#xff1a;郭孝星的新浪微博 郵箱&#xff1a;allenwells163.com 博客&#xff1a;http://blog.csdn.net/allenwells github&#xff1a;https://github.com/AllenWell 一 .tar 解包 tar xvf FileName.tar 打包 tar cvf FileName.tar DirName 注意…

unity中怎么做河流_【干貨】工作中怎么做工業設計的?(一)

最近在找工作&#xff0c;一直在看招聘信息。看到工業設計工資還是蠻高的。應屆畢業生一般是4-6K&#xff0c;1-3年工作經驗是6-8K&#xff0c;3年以后的差不多是8K以上了。我沒有嫉妒羨慕恨&#xff0c;發誓&#xff0c;真的沒有。工業設計已經被重視&#xff0c;未來的道路會…

[易學易懂系列|golang語言|零基礎|快速入門|(一)]

golang編程語言&#xff0c;是google推出的一門語言。 主要應用在系統編程和高性能服務器編程&#xff0c;有廣大的市場前景&#xff0c;目前整個生態也越來越強大&#xff0c;未來可能在企業應用和人工智能等領域占有越來越重要的地位。 本文章是【易學易懂系列|編程語言入門】…