如何uikit使用教程UIKit创造一款文字游戏

如何创造一款带有喜剧元素的游戏
发布时间: 11:12:00
Tags:,,,,
作者:Matthias Zarzecki
市场上不乏带有有趣元素的游戏,而一种互动体验在什么时候才会变成一款喜剧游戏呢?
有些游戏从表面看来就是喜剧游戏,如《边境之地》系列。还有些游戏如《求生之路》等便通过角色去传达一些讥讽内容,并且从电影角度看来看,它们也具有喜剧性。
但当着眼于游戏性质时你会发现,它们其实都具有喜剧性。甚至连最严肃的戏剧也可以通过让座位玩家的你做些违背它们风格的事而具有喜剧效果。
找到开发者并不想看到的幽默
玩家在游戏世界中可能创造出的任何效果都有可能推动他们做出一些有趣的事。在《半条命》中,朝一面墙射击将留下一个小洞—-如此便会出现各种恶作剧选择。
在游戏发行前即当这一功能首先出现在测试房时,开发者便对测试者们开始在墙上“写”字感到非常惊讶。
team fortress 2(from tutsplus)
我发现:当你提供一个空房间以及一个能够影响游戏世界的能力给玩家时,他们总是会选择做些能让自己开心的事。
如果背景更严肃时这种情况也就更明显。例如《骇客任务》是以一个遭受瘟疫的黑暗世界为背景。然而当玩家最初花费10分钟去收集一些碎石并将其堆积在boss的桌面上时,任何对话将以另一种角度呈现出来。
还是你们想要看个更现代化的例子?最近刚发行的《合金装备5》是属于较深沉的间谍惊悚游戏,但同时它也让玩家能够朝任何可疑人扔板条箱,将动物抛向空中,以及从粉色直升机上跳下来。
除了这种无意识的内在喜剧元素外,还存在一些在游戏中有意创造喜剧和幽默元素的方法,如故事,混乱和游戏玩法。它们并行不悖,并且总是能够相互补充。
故事中的幽默
整合幽默的一种方法便是通过故事。归结下来也就是“一个角色说某些事很有趣”,但这却比真正做好一件事复杂得多。
对此的一个有效例子便是《传送门》,在整款游戏中你都能听到GLaDOS(游戏AI)的故事。
一开始比较简单,但随着游戏的发展故事将变得更加让人惊讶且有趣。《传送门2》更是使用了多个叙述角色去延续这一方法。
《猴子岛》系列在这方面也做得很好。它们的游戏世界中充满了许多能够提供有趣对话的角色,并且游戏会一直鼓励玩家去寻找各种有趣的回应。
《战地:叛逆连队2》也属于这类型游戏。即它的游戏玩法虽然与其它《战地》游戏相似,但却突出了更多讲着有趣对话的角色。
简单的陈述或嘲弄都是执行这些元素的一种直接方式,并且它们都是基于某种特定条件:“如果出现条件X,角色Y会说Z。”“当你进入一间房时,酒保会以三种幽默的表达中的一种欢迎你。”“当你进入一个全新的实验室时,GLaDOS将通过几行内容向你解释这里的设置。”“有时候Francis会哀叹自己并不是真的喜欢桥梁,特别是充满僵尸的桥。”“当你在《星际争霸2》中点击一个单位15次,它们的固定设置将变成一个有趣的设定。”
但是你也需要避免做得太过火。因为不管一句话或一个玩笑有多妙,人们一旦频繁听到这样的内容便会逐渐厌恶它。
对此还有一个重要元素是不要让所有内容都变成一个玩笑。喜剧是基于一种对比,如果所有一切都变得愚蠢的话,也就不存在什么具有吸引力的内容了。《边境之地2》便是通过突出主要故事的同时保持许多其它元素的严肃性而有效地做到了这点;如此与背景形成反差的有趣元素便能够更好地突显出来。甚至在《传送门2》中,轻松的叙述只会在玩家进入一个全新实验室时才会出现,而剩下的游戏则仍是提供给玩家严肃且并不特别有趣的事物。
对于引用流行文化或其它玩笑也需要非常小心。像“这里有着与Monty Python(游戏邦注:英国6人喜剧团体)同样的笑话”这样的引用只会表现出你的懒惰。如果你想要创造一个基于引用的玩笑的话,你应该只是将其作为跳板去传达你的理念。而它甚至有可能完全赶超你最初的想法。
各种混乱总是很滑稽
混乱中的喜剧是关于一些始料不及的内容。它的出现可能是毫无计划性的,有可能是你在《赛道狂飙》中炫技前偏离了轨道,或者是你在任何行动游戏中使用了错误的策略而导致自己在游戏前几秒中便遭遇失败。
《Magicka》便是一款真正围绕着这一元素进行创造的游戏。在游戏中,玩家能够结合不同元素创造咒语,这里拥有几千种不同的组合。所以这也将导致无数次的出错,从而造就许多不可预见的喜剧效果。
对于你的团队的首次尝试,你可能会在向所有人开火前表示“我不知道这么做会怎样。”
magicka(from tutsplus)
在下一次尝试时所有人都希望表现得更好。再之后你的治愈咒语将瞄准敌人,重新恢复他们的生命,你的伙伴所留下的破冰雷将来到你的团队中,你的一个伙伴所投掷的能量爆破在他们面前炸开了,并将你弹向了熔岩坑。
而之后你还是会选择“再一次!”因为这很有趣。
但是创造这样的时刻是很棘手的,因为它们可能会在受挫与有趣间徘徊着。当着眼于围绕这一内容展开的游戏(游戏邦注:如《Magicka》,《模拟山羊》,《外科医生》,《我是面包》,《QWOP》)时,你会注意到整体的游戏体验通常是以混乱的想象展开。
它们同样也会提供突然失败的可能性。就像当你在《Magicka》中遭遇了失败,那么这一失败很有可能是以一种惊人的方式出现。当你在《赛道狂飙》遭遇了失败,你可能是因为速度太快而飞出了赛道。而当你在《坎巴拉太空计划》遭遇了失败,你可能已经发现自己的三级火箭拥有一些较严重的设计缺陷,但是你却只能看着它在发射台出现倾斜并随之爆炸。
需要注意的一点是失败必须是公平的—-玩家必须了解所有的元素。如果是莫名其妙且毫无预兆的死亡只会让玩家感到受挫,这是一点乐趣都没有的。
贯穿游戏玩法的幽默
确定游戏玩法是较为棘手的。它是依赖于用于传达玩笑的不可预期且独特的互动游戏元素。这里的要点是你需要积极执行某些内容并获得反应。
《边境之地2》在这点便表现得很好。《边境之地》中的经典任务通常是在玩家获得奖励前努力得到某些东西,前往某个地方,射击一群敌人,然后找到一个或多个macguffin(游戏邦注:是一个电影用语,指在电影中可以推展剧情的物件、人物、或目标,例如一个众角色争夺的东西)。
这种游戏玩法“体制”贯穿于第一款《边境之地》以及《边境之地2》的早前部分。那时候这些任务便是玩家所期待看到的内容,所以这也是颠覆玩家期待的绝佳时刻。
如果现在能完全忽视这一既定的公式而创造一个完全不同的任务便会让玩家感到幽默。举个例子来说吧,“朝我的脸开***”任务便是让玩家朝着一个角色的脸开***。还有其它目标是不能在他们的其它身体部位上开***,虽然这已经经过证实,但是射击每个部位却是未经证实的行动。
除此之外还有更多其它任务!例如在某个地方从悬崖上跳下自杀的任务。还有一个是听取Grandma Torgue讲15分钟话的任务。这时候你并不需要与任何人对抗,只需要用耳朵倾听便可。你甚至不能在此时离开(这是游戏并未告诉你的),因为如果你离开了Grandma便会察觉到并因此大哭。然后当她停止讲话时你便需要继续等待,她将会询问一个有关她提到的各种细节的问题。如果这时候你不能答出问题的话,一切都要重新开始。对此我一直大笑着,并对开发者添加这样的任务表示赞赏,我甚至认为这是游戏中最难对抗的boss。
我们可以通过了解游戏所使用的系统以及玩家所期待的系统并颠覆该系统去做到这点。就像聆听任务从性质看来就很有趣的,因为我们知道的其它任务都是关于射击某物。
同时面向其它行动重新决定一般游戏行动的目的。在《传送门2》中,Wheatley让玩家通过按压Space去谈话。这时候你并不能真正进行交谈,而按压按键能让你开始跳跃。在《边境之地》的多个时候玩家可以与角色击掌,即通过对他们进行近战攻击做到这点。同样的系统也适用于拍击其它角色。在
存在许多创造出更具喜剧效果的游戏的方法。使用这些方法能够让玩家沉浸于一些更有趣的元素中,而不是只是等待着有趣内容自己出现。
但开发者们需要注意的是,尽管你们尝试着去避免这种情况,但是玩家还是能够找到某种方式去颠覆一款严肃的游戏,所以你们能做的便是去接受它并更大程度地发挥这种情况的作用。
(本文为游戏邦/编译,拒绝任何不保留版权的转发,如需转载请联系:游戏邦)
What Makes Games Funny? A Look at Comedy and Humour in Video Games
by Matthias Zarzecki
Games with funny elements have always existed, but at what point does an interactive experience become a comedy game?
There are games that are obviously flat-out comedies, like the Borderlands series. Other titles, like Left 4 Dead, feature constant quipping by characters, and by movie standards could easily be described as comedic.
But looking at games you’ll notice that, by their very nature, they are comedic. Even ultra-serious dramas can become comedic by virtue of allowing you, the player, to do things that go against their style…
Finding Humor Where the Developers Didn’t Intend It
Any effect the player can have on the world can let them do or create something humorous. In Half-Life, shooting a wall leaves a bullet hole--suddenly, all kinds of options for shenanigans open up.
Long before the release, when this feature was first implemented in empty test rooms, developers were surprised by how testers started “writing” words on the wall. (Half-Life 2: Raising The Bar)
I find this telling: Given an empty room and only a single (inherently violent) ability to affect the world, people chose to do something that made them laugh.
This becomes more pronounced the more serious the setting is. Deus Ex, for example, is set in a dark and serious world ravaged by a plague. Yet any conversation is instantly seen in another light when you’ve first spent ten minutes collecting random detritus and piling it onto your boss’s desk.
Want a more modern example? The recent Metal Gear Solid 5 styles itself as an ultra-serious espionage thriller, yet at the same time allows you to drop crates of equipment on unsuspecting people, hoist animals into the sky, and jump from a pink helicopter as Billy Idol’s Rebel Yell plays over its loudspeakers.
Old Man Murray’s Deus Ex Walkthrough, in which you are advised to carry a flag to every conversation and decorate your office.
Besides this unintentional, inherent comedy, there are a few ways to intentionally create comedy and humour in games, which boil down to story, chaos and gameplay. They are not mutually exclusive, and often actually complement each other well. Let’s take a look at them…
Humor Through Story and Narrative
One way to include humor is via the story. This essentially boils down to “a character says something funny”, but is a bit more complicated than that to get right.
One of the best examples of this can be found in Portal, where throughout the entire game you hear the narration of GLaDOS, the AI.
It starts out simple, but gets progressively more outrageous and ludicrous throughout the game. Portal 2 repeats this with its multiple narrator characters.
The Monkey Island series (and the majority of point-and-click adventure games) also do this nicely. Their worlds are filled with characters that offer funny dialogue, and players are encouraged to look for all funny and interesting responses.
Battlefield: Bad Company 2 falls into this camp, too. The gameplay is identical to other Battlefield titles, but it features most characters spouting funny and witty dialogue.
A straightforward way to implement these elements are simple statements or quips, triggered on certain conditions: “If situation X occurs, character Y says Z.” “When you walk into the room, the bartender greets you with one of three humorous statements.” “When you begin the new test chamber, GLaDOS gets a few lines explaining the setup.” “Every once in a while, Francis laments that he doesn’t really like bridges, especially with zombies on them.” “After you have clicked a unit in Starcraft 2 15 times, their regular barks turn into comedic, fourth-wall-breaking-lines.”
But make sure to not overdo it. Because no matter how brilliant a line or gag is, people will grow to hate it if they’re continually bombarded with it.
Another important element of this is to not make everything into a joke. Comedy is based on contrast, and when everything is zany, nothing stands out. Borderlands 2 does this nicely by having its main story and a lot of other elements remai against this backdrop, unique and fun elements tend to stick out better. Even in Portal, the light-hearted narration only occurs when entering a new test chamber, with the rest of the game offering serious and not-particularly-funny surroundings.
Referencing pop-culture or other jokes also needs to be approached carefully. A simple reference á la “here is the same Monty Python gag that has been repeated for decades” will only point out how lazy you are with this. If you need to make a reference-based joke, always use it as a springboard to start your own idea. In the process, it might even surpass your initial idea.
Dying is Funny, Comedy is Easy by Anthony Burch of Borderlands 2
Eric Wolpaw’s 80 minute NYU lecture, in which he discusses Portal 2
Chaos and Mayhem Are Often Hilarious
Comedy from chaos is about the unforeseen. It can appear unplanned, when you careen off the track in Trackmania before doing some amazing stunts (yet still failing), or somehow so gravely miscalcutating a manoeuvre in any action game that you fail abruptly within the first few seconds.
One game actually engineered around this is Magicka. In it, you can combine elements to create spells, of which there are thousands of combinations. These tend to go wrong an alarmingly high proportion of times, which creates a lot of unforeseen comedy.
On your team’s first attempt, you might say “I wonder what this does…” before setting everybody on fire.
The next attempt, everybody vows to do better. And then, oops, your healing spell targets an enemy, restoring them to maximum health, the ice mines laid by your buddy go off on your own team, and the energy blast cast by one of your comrades blows up in their face to catapult you all into a lava pit.
And then you all hit “Again!”, because it was just too much fun.
Engineering these moments can be tricky, as they walk the line between frustration and fun. When looking at games that center around this (Magicka, Goat Simulator, Surgeon Simulator, I am Bread, QWOP) you’ll notice that the entire experience is often centered around the conceit of chaos.
They all also offer the ever-present possibility of abrupt explosive failure. When you fail in Magicka, you mostly fail in a spectacular manner. When you fail in Trackmania, you do so by driving off the road at mach speed before doing something ludicrous. When you fail in Kerbal Space Program, you do it often by realizing that your massive three-stage-rocket might have some rather profound design flaws, as you watch it tip over on the launchpad and explode on the spot.
An important thing to note is that the failure must be fair--all elements must be known to the player. A sudden, un-telegraphed death out of nowhere is just frustrating and no fun.
Subversive Humor in Games
Humor Through Gameplay
Gameplay is a bit more tricky to pin down. It relies on unexpected and unique interactive gameplay elements that serve to illustrate the joke (compared to spoken lines, which are non-interactive). A vital point is that you have to actively perform something and get a reaction.
Borderlands 2 does this nicely. A typical quest in Borderlands consists of getting it, going to a place, having to shoot a bunch of enemies, and then possibly finding one or several macguffins, before returning to get your reward.
This “scheme” of gameplay has been established all throughout the first Borderlands and the early parts of Borderlands 2. At that point these quests are what players expect--so it is a perfect time to subvert their expectations.
Now, creating a quest that’s completely different can be humorous just through the sudden and complete disregard of this established formula. For example, the “Shoot me in the face” quest wants you to shoot a character in the face. Additional objectives consist of not shooting them in other body-parts, which are already “checked off”, but can be unchecked by shooting the respective parts. And just as soon as it’s started, the entire thing is over.
And there are more! One quest can be completed by jumping off a cliff and killing yourself in a certain spot. Another has you listen to Grandma Torgue talk droningly for 15 minutes. You don’t fight anything, you just listen. You can’t even leave (which you aren’t told), because she realizes and bursts out in tears. Then, when you’ve stopped listening and resigned yourself to waiting it out, she asks a question about the myriad of random details she mentioned. Fail, and the entire thing starts over. All the while I was laughing, admiring the developers for putting this in, and describing it as the hardest boss fight in the game.
Use this by noticing the system that the game employs, that the player expects, and then subverting it. A mission that is comprised of nothing but listening is by its nature funnier when every other mission is about shooting things.
Also, re-purpose regular game actions for other actions. In Portal 2, Wheatley asks you to talk by pressing Space. You can’t actually talk, and pressing the key makes you jump, which he remarks upon as the wrong action. At multiple points in Borderlands you can high-five characters, which you do by performing a melee-attack on them. The same system is used for slapping another character. At one point you have to “teabag” the corpse of an enemy, which you have to perform by repeatedly ducking over them.
Hideo Kojima – Tactical Action Comedy
How to Make Your Game Just Completely Hilarious by William Pugh of The Stanley Parable
Conclusion
There are a lot of straightforward ways to make a game more comedic. Use these to engage the player with comedic elements, instead of just having funny things appear.
And remember, even when you try to avoid this, your players will probably find a way to subvert a serious game, so accepting this and going with it might be more efficient.()
CopyRight Since 2010 GamerBoom All rights reserved &&闽ICP备&号-1很喜欢一款文字冒险类游戏,希望把里面的文字保存下来,不知道有什么方法?_百度知道如何使用UIKit创造一款文字游戏(一)
你是一名想着创造一款iOS游戏,但却没有任何编程经验的资深iOS开发者吗?也许学习OpenGLES会让你感到不安,或者你从未使用过Cocos2d在iPhone上开发游戏? 而现在我将告诉你一个好消息,即UIKi
你是一名想着创造一款iOS游戏,但却没有任何编程经验的资深iOS开发者吗?也许学习OpenGLES会让你感到不安,或者你从未使用过Cocos2d在iPhone上开发游戏?
而现在我将告诉你一个好消息,即UIKit将成为所有游戏开发者都可以使用的强大工具。他的高端框架将帮助你创造所有游戏逻辑&-不管是创造动画(游戏邦注:包括框架动画)还是播放音频和视频。
这三部分教程将引导着你面向iPad创造一款桌面游戏。你将在此学习创造一款稳定且标准的iOS应用的最佳方法。
这系列教程是针对于那些熟悉Objective-C的开发者,因此不会过多阐述像原语类型或语法等细节。
开始:引入重组字
你将在这篇教程中使用UIKit所创造的文字游戏是关于重组字的内容。
重组字是关于重新排列某些文字或短语的字母而组成一个新单词或短语。例如,单词cinema可以重新编排而成为iceman。你将让玩家根据所提供的单词和短语而创造重组字。
完成后的游戏将如下:
finished game(from raywenderlich)
就像我们所看到的,在屏幕最底端有一排字母,便是它们构成了最初的短语。从上面的截图中我们可以看出是少了字母M的admirer,因为玩家已经将M拖到上列中了。
玩家的任务便是使用admirer中的字母组合成不同的单词。你能猜到是什么吗?我已经给予暗示了,即首个字母是M!不管怎样,这便是你将创造的一款游戏。当你在创造这款游戏时,你将学到以下基本内容:
适当的控制器(MVC)游戏结构。
从配置文件中加载关卡配置。
组织你的游戏控制器逻辑。
基于*** Foundation为UIKit编写简单的音频控制。
使用QuartzCore创造静态视觉效果。
使用UIAnimation在游戏内部顺畅地移动。
使用UIKit粒子去添加视觉效果。
单独创建HUD和游戏层。
使用游戏字体去完善外观。
将默认的UIKit组件升级为游戏般的组件。
同时也包括:我在创造游戏时所使用的软件工具。
为了使用UIKit去创造iOS游戏,本篇教程将提供一个包含启动XCode项目以及所有游戏资产(游戏邦注:包括图像,字体,音频和配置文件)的ZIP文件。
下载重组字第一部分的启动文件,解压并在Xcode中打开它。
着眼于启动项目中包含了哪些内容。左边的项目文件浏览器应该如下:
starter project(from raywenderlich)
以下是关于你所看到的内容的总结:
config.h:放在一起的代码配置。
Levels:包含3个.plist文件的文件夹,用于定义游戏的3个难度关卡。
Classes/models:你将在此添加数据模式。
Classes/views:你将在此创造控制器。
Assets/Fonts:对于游戏HUD的定制TTF字体。
Assets/Particles:这里有一个PNG文件能够用于创造粒子效果。
Assets/Audio:创意共享许可音频文件。
Assets/Images:这是你将用于创造游戏的所有图像。
MainStoryboard.storyboard:打开故事板你将看到那里只有一个带有背景的屏幕,并且只有一张模糊的木纹图像,这同时也包含于项目资产中。
credits.txt:包含项目中所使用的所有资产来源的链接。
播放声音并浏览图像并运行项目。
run project(from raywenderlich)
这比空空的应用窗口好多了吧?
在本系列教程的第一部分中,你的目标便是在屏幕上呈现最初的重组字与目标盒。在今后的教程中,你还将添加能力去拖动文件与游戏逻辑。在这里你的任务将被分为8个小步骤:
1.加载关卡配置文件。
2.创造游戏控制器类。
3.创造屏幕视图。
4.创造组块视图。
5.处理屏幕上的组块。
6.添加字母。
7.轻微且随机地旋转字母。
8.添加目标。
让我们分析这些步骤。
1)加载关卡配置文件
在项目文件浏览器中选择level.plist文件。着眼于里面所包含的内容:
这里有3个关键元素:pointsPerTile:对于每个正确放置的组块的奖励点。timeToSolve:玩家解决谜题所花费的时间。anagrams:一列重组字,每个重组字包含2个条款,即最初短语和最终短语。
让我们暂时先专注于anagrams。这是一列数组元素,每个元素拥有两串元素。你将创造一个数据模型在Objective-C中加载这一配置。
在Anagrams/Classes/models文件夹中创造一个全新Objective-C类文件。调用全新类Level,并将其设置为NSObject的子类。
打开Level.h,并在@interface和@end行中间添加如下属性和方法:
&@property&(assign,&nonatomic)&int&pointsPerT&@property&(assign,&nonatomic)&int&timeToS&@property&(strong,&nonatomic)&NSArray*&&&&+(instancetype)levelWithNum:(int)levelN&
这一属性符合.plist文件的结构,所以你只需要加载数据并填入属性便可。你同样也需要提出一个工厂方法为特定的难度关卡创造Level类。其范围将从1到3,即从最简单到最复杂。
现在,添加代码去提高Level数据模式类。在Level.m的类执行中,添加工厂方法的方法体去创造Level实体:
+(instancetype)levelWithNum:(int)levelN&{&&NSString*&fileName&=&[NSString&stringWithFormat:@&level%i.plist&,&levelNum];&NSString*&levelPath&=&[[[NSBundle&mainBundle]&resourcePath]&stringByAppendingPathComponent:fileName];&&&NSDictionary*&levelDict&=&[NSDictionary&dictionaryWithContentsOfFile:levelPath];&&&NSAssert(levelDict,&@&level&config&file¬&found&);&&&Level*&l&=&[[Level&alloc]&init];&&&l.pointsPerTile&=&[levelDict[@&pointsPerTile&]&intValue];&l.anagrams&=&levelDict[@&anagrams&];&l.timeToSolve&=&[levelDict[@&timeToSolve&]&intValue];&&return&l;&}&
在方法体中有4个小环节&-即四个朝向方法目标的步骤:
1.基于传达到方法中的LevelNum值而决定通向关卡配置文件(level1.plist,level2.plist等等)的道路。
2.将文件内容加载到NSDictionary中。幸运的是,NSDictionary类知道如何分析.plist文件!
3.验证levelDict中所加载的某些内容。我经常使用NSAssert去寻找错误(如果这种情况曾出现在开发过程中,我便希望能够停止应用的开发,从而让我能够尽早解决这些错误。)
4.创造一个全新的Level实体。
5.从NSDictionary中复制值到Level对象属性中。现在让我们尝试以下类,并验证你的第一步是否达到了预期目标!打开ViewController并在最上方添加如下代码:
#import&&Level.h&&
在viewDidLoad最后添加:
Level* level1 = [Level levelWithNum:1];
NSLog(@&anagrams: %@&, level1.anagrams);
在Xcode主机只能够你将看到Level 1的一列重组字。
现在你便可以将NSLog行从viewDidLoad中删除以保持主机的整洁。
2)创造一个游戏控制器类
那些未接触过MVC便直接跳到iOS开发的人将会对控制器和UIViewController感到困惑。
控制器是一个专注于应用逻辑某些部分的类,区别于应用数据和呈现这些数据所使用的类。
子类UIViewController只是一个管理特殊UIView描述的控制器。(UIViews用于在屏幕上呈现某些内容。)
在本篇教程中,你将创造一个控制器类去管理游戏逻辑。让我们开始进行尝试。
首先在Anagrams/Classes/controllers中创造一个全新的Objective-C类文件。调用全新的类GameController并将其设置为NSObject的子类。
打开GameController.h并添加如下代码:
#import&&Level.h&&
然后在GameController界面添加如下:
&@property&(weak,&nonatomic)&UIView*&gameV&&&@property&(strong,&nonatomic)&Level*&&&&-(void)dealRandomA&
我打赌你已经发现当前目标的构建模块了:
gameView:你将用于在屏幕上呈现游戏元素的视图。Level:为当前游戏关卡储存重组字和其它设置的Level对象。dealRandomAnagram:你将调用这一方法在屏幕上呈现当前的重组字。
到目前为止的代码还非常简单。让我们转到GameController.m并添加dealRandomAnagram的占位符版本:
&-(void)dealRandomAnagram&{&&NSAssert(self.level.anagrams,&@&no&level&loaded&);&&&int&randomIndex&=&arc4random()%[self.level.anagrams&count];&NSArray*&anaPair&=&self.level.anagrams[&randomIndex&];&&&NSString*&anagram1&=&anaPair[0];&NSString*&anagram2&=&anaPair[1];&&&int&ana1len&=&[anagram1&length];&int&ana2len&=&[anagram2&length];&&&NSLog(@&phrase1[%i]:&%@&,&ana1len,&anagram1);&NSLog(@&phrase2[%i]:&%@&,&ana2len,&anagram2);&}&
这是关于上述代码的解释:
1.你需要确保这一方法只有在设置了Level属性后才能调用,并且它的Level对象包含了重组字。
2.你生成了一个随机索引并将其整合到重组字列表中,然后根据这一索引抓取重组字。
3.你在anagram1和anagram2中储存了2个短语。
4.然后你在每个短语中将字符数储存到ana1len和ana2len中。你将在之后进一步处理这一信息。
5.最后,你将在主机中呈现这些短语。这需要经历测试。
现在你的应用已经能够在一开始加载故事板MainStoryboard.storyboard。这一故事板使用ViewController类创造了一个屏幕。
因为你的游戏只能拥有一个屏幕,所以你将在ViewController的init方法中添加所有初始化内容。对于包含一个以上视图控制器的游戏,你便可能想要将初始化内容放置在其它地方,如AppDelegate类中。
打开ViewController.m,并在最上方添加如下:
#import&&GameController.h&&
放置私有类界面:
@interface&ViewController&()&@property&(strong,&nonatomic)&GameController*&&@end&
&最后,在执行中添加新的初始化方法:
-(instancetype)initWithCoder:(NSCoder&*)decoder&{&self&=&[super&initWithCoder:decoder];&if&(self&!=&nil)&{&&self.controller&=&[[GameController&alloc]&init];&}&return&&}&
&上述方法initWithCoder:当应用从故事板中初始化时将会自动调用。
现在你创造了一个GameController类,并在ViewController执行中拥有一个实体,现在是时候在屏幕上设置一些字母组块了。
3)创造一个屏幕视图
下一步很简单:你需要在屏幕上创造一个视图,并将其与GameController连接在一起。
打开config.h并着眼于文件中的前两个定义:KScreenWidth和kScreenHeight。这是两个快捷方式,也能够在Landscape模式中处理屏幕的交换大小。你将使用这些定义去创造游戏视图。
回到ViewController.m并在viewDidLoad最后添加如下代码:
&UIView*&gameLayer&=&[[UIView&alloc]&initWithFrame:CGRectMake(0,&0,&kScreenWidth,&kScreenHeight)];&[self.view&addSubview:&gameLayer];&&self.controller.gameView&=&gameL&
&在上述代码块中,你创造了一个基于屏幕尺寸的新视图,并将其添加到ViewController的视图中。然后你将其分配到GameController实体的gameView属性中。基于这一方法,GameController将使用这一视图去处理所有游戏元素(除了HUD)。
现在你已经创造了模式和控制类,并且你也已经为重组字游戏创造了第一个定制视图类。
4)创造组块视图
在这一部分,你将创造一个视图去呈现如下组块:
view(from raywenderlich)
现在,你将专注于创造带有背景图像的放心组块。之后你将在上面添加字母。
在文件租Anagram/Classes/view中创造一个名为TileView的新类,并将其设置为UIImageView的子类。这是一个好的开始&-UIImageView类将提供呈现图像的意义,所以你只需要在图像上方添加标签即可。
打开TileView.h并在界面上添加如下代码:
@property&(strong,&nonatomic,&readonly)&NSString*&&@property&(assign,&nonatomic)&BOOL&isM&&-(instancetype)initWithLetter:(NSString*)letter&andSideLength:(float)sideL&
以下是关于你刚刚所创造的内容:
letter:将控制分配到组块上的字母的属性。isMatched:控制Boolean去预示某一组快是否成功&匹配&屏幕上方目标的属性。initWithLetter:andSideLength:一个定制init方法,能够设置带有特定字母和组块大小的类实体。
你可能会好奇为什么需要设置组块的大小?
让我们着眼于下面两种设置:
setup(from raywenderlich)
第一种设置呈现的是一个短字,所以要求更大的组块去填充屏幕。第二种设置呈现的是一个短语,要求增加组块数量,所以便需要缩小组块。你可以从中看到为什么组块需要设置一个合理的尺寸,如此你便可以根据屏幕上呈现的组块数而设置不同大小的组块。
你的控制器将估算短语的长度,根据字符数去分割屏幕宽度并决定组块大小。你将快速执行这一步,但首先你需要执行组块的代码。
转换到TileView.并用以下基本类架构换置里面的内容:
#import&&TileView.h&&#import&&config.h&&&@implementation&TileView&&&-&(id)initWithFrame:(CGRect)frame&{&NSAssert(NO,&@&Use&initWithLetter:andSideLength&instead&);&return&&}&&&-(instancetype)initWithLetter:(NSString*)letter&andSideLength:(float)sideLength&{&&UIImage*&img&=&[UIImage&imageNamed:@&tile.png&];&&&self&=&[super&initWithImage:img];&&if&(self&!=&nil)&{&&&float&scale&=&sideLength/img.size.&self.frame&=&CGRectMake(0,0,img.size.width*scale,&img.size.height*scale);&&&}&&return&&}&&@end&
&这是一个较长的代码块,但是如果你仔细看的话便会发现,它只是关于定义占位符,所以你可以在之后创建组块的功能。在代码中有一些不同的环节,让我们在此进行分析:
1.你覆盖了initWithFrame:因为你已经拥有一个定制初始化方法,你不再需要调用initWithFrame:。相反的,你添加了一个每次都会衰败的NSAssert。这意味着你拥有足够的机会去创造一个可进行初始化的组块。
在一个小小应用中,这只是保护你自己的方法。但是在一个大型应用中,或者当你身处一个团队时,这便是一种预防措施能够通过阻止任何人调用这一方法而减少犯错的机率。(为了真正保护自己,你需要为如下每个方法创造类似的执行:init, initWithCoder:, initWithImage: and initWithImage:highlightedImage:。)
2.initWithLetter:andSideLength:是你的定制方法,能够初始化组块实体。它加载了tile.png图像并通过在父类(在这里便是UIImageView)上调用initWithImage:而创造了TileView实体。
3.然后你需要根据默认组块的大小进行计算,从而明确一个适合特定单词或短语的面板大小。为此,你只需要调整TileView的frame便可。UIImageView能够自动调整其图像去匹配框架大小。
这时候的代码已经能够呈现出默认的空白组块图像了。现在你需要执行更多游戏控制功能,从而才能看到一些空白组块排列在屏幕上。
5)处理屏幕上的组块
转换到GameController.m&-你的dealRandomAnagram方法已经加载了所需要的数据,但却还不够多。是时候去处理这种情况了!
在GameController.m的上方添加如下代码:
#import&&config.h&&#import&&TileView.h&&
&现在你便能够访问TileView类以及你储存在config.h中的任何共享设置。
在@implementation环节添加如下私有变量:
@implementation&GameController&{&&NSMutableArray*&_&NSMutableArray*&_&}&
如何解释这些变量?
_tiles是一个数组,控制着TileViews在屏幕下方呈现的组块。这些组块包含重组字的最初短语。
_targets是一个数组,控制着目标视图在屏幕最下方呈现的空间,玩家将在此拖曳组块去形成重组字的第二个短语。
继续前进前,你还需要在组块间设置一个常数。跳到config.h并添加如下定义:
#define&kTileMargin&20&
有些人会反驳道:&难道我不能只是用20?&这是个很有趣的点,但是我们之所以要在配置文件中进行预定义是有原因的。
根据以往的经验,当你可以开始挑战游戏玩法时,你便需要去调整代码中的任何数字。最佳实践便是具体化配置文件中的所有数字,并赋予这些变量有意义的名称。这一做法将能带给你很大的帮助,特别是当你致力于团队工作并需要将游戏递交给设计师进行调整时。
让我们回到GameController.m,准备在dealRandomAnagram最后添加一些代码。你在两个短语中都拥有一些字符,所以你能够很轻松地估算所需要的组块大小。在方法最后添加如下代码:
&float&tileSide&=&ceilf(&kScreenWidth*0.9&/&(float)MAX(ana1len,&ana2len)&)&&&kTileM&
你占据了90%屏幕宽度,并将其以字符数划分开来。你使用的是拥有更多字符数的短语&-需要牢记的是空间的数值总是会不断变化!你通过kTileMargin而有效设置了组块间的距离。
接下来需要找到第一个组块的最初x位置。这取决于单词的长度以及你所计算的组块大小。再一次,你需要在dealRandomAnagram最后添加如下内容:
&float&xOffset&=&(kScreenWidth&&&MAX(ana1len,&ana2len)&*&(tileSide&+&kTileMargin))/2;&&&xOffset&+=&tileSide/2;&
通过将屏幕宽度减去单词组块的宽度,你便能够确定第一个组块在屏幕上的位置。如果存在一种更简单的&居中&组块的方法该多好!
据需在相同的方法中添加如下代码去呈现组块:
&_tiles&=&[NSMutableArray&arrayWithCapacity:&ana1len];&&&for&(int&i=0;i&ana1i++)&{&NSString*&letter&=&[anagram1&substringWithRange:NSMakeRange(i,&1)];&&&if&(![letter&isEqualToString:@&&&])&{&TileView*&tile&=&[[TileView&alloc]&initWithLetter:letter&andSideLength:tileSide];&tile.center&=&CGPointMake(xOffset&+&i*(tileSide&+&kTileMargin),&kScreenHeight/4*3);&&&[self.gameView&addSubview:tile];&[_tiles&addObject:&tile];&}&}&
让我们分析上述代码:
1.首先你初始化了_tiles可变数组的最新副本,确保它足够大能容纳最初短语中的所有字母。在一开始面向明确的数组非常重要,因为这一方法将在应用的运行过程中被多次调用。因为空间被略过了,所以如果你未能明确数组,那么便会遗留下一些来自最初短语的组块。
2.然后你需要循环通过短语并为每个字符创造全新的NSString。将其保存为letter。
3.你检查了每个字母。你创造了一款全新组块并使用xOffset,tileSide和kTileMargin对其进行设置。在此你需要根据字母在短语中的位置去估算位置(以i进行表示)。所以如果是5,这一算式将估算出5个组块所占据的空间并会在空间右边添加新组块。
你将在屏幕高度的四分之三处垂直排列组块。
4.最后,你在gameView和_tiles数组中添加了组块。首先在屏幕上呈现了组块,这能帮助你在之后加速组块的循环。
是时候进行最后的接触了&-你需要加载关卡数据并调用dealRandomAnagram。转换到ViewController.m并在viewDiaLoad最后添加这两行代码:
self.controller.level&=&level1;&[self.controller&dealRandomAnagram];&
记得你已经拥有一个Level项目(游戏邦注:你在这个方法最上方创造了它),所以你只需要将其传送到GameController并调用dealRandomAnagram便可。
现在你需要通过运行去检查结果!你的模拟器应该如下:
simulator(from raywenderlich)
注:你的视图可能会因为应用每次运行选择随机重组字的不同而与上图有所差异。如此你便可以基于不同短语多运行几次。
6)添加字母
转换到TileView.m。在此你将添加字母到组块中。找到initWithLetter:andSideLength中的评论&//more initialization here&,并在它下方添加如下代码:
&UILabel*&lblChar&=&[[UILabel&alloc]&initWithFrame:self.bounds];&lblChar.textAlignment&=&NSTextAlignmentC&lblChar.textColor&=&[UIColor&whiteColor];&lblChar.backgroundColor&=&[UIColor&clearColor];&lblChar.text&=&[letter&uppercaseString];&lblChar.font&=&[UIFont&fontWithName:@&Verdana-Bold&&size:78.0*scale];&[self&addSubview:&lblChar];&
上述代码创造了一个新的UILabel,将它添加到组块视图中。因为你希望字母能够一目了然,所以你创造了一个与组块一样大的标签。然后你将字母排列在一起并呈现在组块中。
你通过调用[letter uppercaseString]而确保字母均是大写。使用大写字母能够让降低游戏玩法的难度,因为玩家能够更轻松地意识到它们,特别是小孩(这便是你们游戏的目标用户)。
最后,你在此使用了之前所估算的比例引子。对于原尺寸的组块来说,78pts的Verdana字体最合适了,但是对于其它尺寸,你则需要相应地调整字体的大小。
在initWithLetter:andSideLength最后添加如下初始化代码:
&self.isMatched&=&NO;&&&_letter&=&&
上述代码将组块的isMatched标志设为NO,即预示着组块并不匹配屏幕上方的目标。它同时也将字母保存到组块的letter属性中。
创建并运行项目。就像我所说的,现在的你正朝着目标靠近。做得好!
run project(from raywenderlich)
再一次地,你的屏幕可能与上图有所差异。但这意味着你的游戏控制器正在执行预期任务并处理随机重组字。
再次着眼于上图,你会发现现在的组块就像是被不会思考的机器人放置在面板上一样&-整齐得让人别扭。所以现在你需要添加一些随机性。
7)轻微且随机地旋转字母
随机性是创造一款成功的计算机游戏的关键。你总是想要尽可能地随机化游戏。举个例子来说吧,没有玩家喜欢面对永远都做着同样事情的敌人。
在重组字游戏中,你可以随机放置每个组块,从而让它们能够更自然地呈现于面板上,就像人们未可以对齐而进行放置一样。
random(from raywenderlich)
为了实现这种随机性,你需要在TileView.h的界面上添加如下方法:
在TileView.中添加如下randomize执行:
-(void)randomize&{&&&&float&rotation&=&randomf(0,50)&/&(float)100&&&0.2;&self.transform&=&CGAffineTransformMakeRotation(&rotation&);&&&&int&yOffset&=&(arc4random()&%&10)&&&10;&self.center&=&CGPointMake(self.center.x,&self.center.y&+&yOffset);&}&
这一代码主要在执行两个任务:
1.它在-0.2和0.3弧度间生成了一个随机角度(使用config.h中所定义的辅助功能randomf)。然后调用了CGAffineTransformMakeRotation为视图创造了一全新转换,即将基于随机角度围绕着中心进行旋转。
2.它在-10和0之间生成了一个随机值,并基于这种偏移量移动组块。
注:你可能想要用config.h中定义的常数去替换所有的这些数字,从而更轻松地调整组块外观。
现在你只需要调用这一方法。在GameController.m中通过在tile.center= &之后添加如下代码而编辑dealRandomAnagram:
[tile&randomize];&
再次运行,你便能够看到面板上随机放置的组块:
run(from raywenderlich)
使用你所创造的内容,你也能够在游戏面板上快速添加目标。
8)添加目标
目标视图与组块视图相类似。它们也将UIImageView划为子类并呈现了默认图像,它们同时也根据字母而进行了分配。而区别就在于,它们并未呈现出带有字母的标签,并且不能四处拖动。这便意味着你在设置目标视图所需要的代码与之前的类似&-这就简单多了!
在Anagrams/Classes/views中创造一个新类并调用TargetView,将其设置为子类UIImageView。
打开刚刚创造的TargetView.h,并在界面声明中添加如下属性和方法:
@property&(strong,&nonatomic,&readonly)&NSString*&&@property&(assign,&nonatomic)&BOOL&isM&&-(instancetype)initWithLetter:(NSString*)letter&andSideLength:(float)sideL&
&是的,这与你之前用于TileView的属性和方法名称一样。就像你所看到的,现在你可以快速移动了。你已经知道上述代码的作用是什么了,所以你可以直接执行。
转换到TargetView.m并以如下代码替换假设方法:
-&(id)initWithFrame:(CGRect)frame&{&NSAssert(NO,&@&Use&initWithLetter:andSideLength&instead&);&return&&}&&&-(instancetype)initWithLetter:(NSString*)letter&andSideLength:(float)sideLength&{&UIImage*&img&=&[UIImage&imageNamed:@&slot&];&self&=&[super&initWithImage:&img];&&if&(self&!=&nil)&{&&self.isMatched&=&NO;&&float&scale&=&sideLength/img.size.&self.frame&=&CGRectMake(0,0,img.size.width*scale,&img.size.height*scale);&&_letter&=&&}&return&&}&
再一次,这与你在TileView.m中所使用的代码也一样。你根据假设的边长重新调整了图像并分配字母。
现在你可以在屏幕上呈现图像了。打开GameController.m并添加如下代码:
#import&&TargetView.h&&
然后在dealRandomAnagram的评论&//initialize tile list&前添加如下代码:
&_targets&=&[NSMutableArray&arrayWithCapacity:&ana2len];&&&for&(int&i=0;i&ana2i++)&{&NSString*&letter&=&[anagram2&substringWithRange:NSMakeRange(i,&1)];&&if&(![letter&isEqualToString:@&&&])&{&TargetView*&target&=&[[TargetView&alloc]&initWithLetter:letter&andSideLength:tileSide];&target.center&=&CGPointMake(xOffset&+&i*(tileSide&+&kTileMargin),&kScreenHeight/4);&&[self.gameView&addSubview:target];&[_targets&addObject:&target];&}&}&
这与你在处理面板上的组块的代码类似,除了这次你是从anagram2中的短语抓取字母并且并未随机排列它们的位置之外。你希望目标视图能够非常整洁。
为什么目标初始化必须出现在组块初始化前?因为你需要将子视图添加到父视图上,所以你先添加了目标视图才能确保它们最终是出现在组块之后。
如果你想要在组块视图后添加目标视图,你还可以采取其它方法让它们出现在组块后,如UIView的sendSubviewToBack:方法。但是先添加它们才是最有效的解决方法。
再次运行,你将看到面板设置即将完成了!
run again(from raywenderlich)
等等!这两个短语并不匹配。在下方分别有3个组块紧跟着4个组块,而上方则是4个组块紧跟着3个组块!
不要担心,这是很正常的现象。毕竟包含两个短语的重组字可能拥有不同的字数。只要整体的字符数是一样的便可以。
恭喜你,现在你便已经创造了一个很棒的基础了。而在接下来的教程中你将开始与玩家互动并创造游戏玩法。
CocoaChina是全球最大的苹果开发中文社区,官方微信每日定时推送各种精彩的研发教程资源和工具,介绍app推广营销经验,最新企业招聘和外包信息,以及Cocos2d引擎、Cocos Studio开发工具包的最新动态及培训信息。关注微信可以第一时间了解最新产品和服务动态,微信在手,天下我有!
请搜索微信号“CocoaChina”关注我们!
关注微信 每日推荐
扫一扫 浏览移动版

参考资料

 

随机推荐