如何动态设置 imageview sprite的Sprite

您目前使用的浏览器该进博物馆啦~~~
为了更佳的浏览体验,请使用现代浏览器访问本站
Outdated Browser
您的浏览器已禁用 Javascript,启用它获得更好的体验。
Outdated Browser
这是为桌面用户准备的工具,但您可以安心在这里浏览
46.5% 的互联网用户在使用 此款浏览器
GOOGLE CHROME
支持如下操作系统
16.5% 的互联网用户在使用 此款浏览器
MOZILLA FIREFOX
支持如下操作系统
21.6% 的互联网用户在使用 此款浏览器
INTERNET EXPLORER
支持如下操作系统
10.3% 的互联网用户在使用 此款浏览器
APPLE SAFARI
支持如下操作系统
1.5% 的互联网用户在使用 此款浏览器
支持如下操作系统
冷静 这是为桌面用户提供的不是为手机用户提供的依据NormalImage设置DisabledImage - 图形/图像当前位置:& &&&依据NormalImage设置DisabledImage依据NormalImage设置DisabledImage&&网友分享于:&&浏览:96次根据NormalImage设置DisabledImage
出于美术资源包大小的考虑,我们认为单独提供DisabledImage是不划算的。
如果你是直接create CCMenuItemSprite的话,这个就比较简单了。
Cocos2dx现已提供CCGraySprite
menuItem-&setDisabledImage(CCGraySprite::create(fileName));
然而,如果你跟我一样,是使用CocosBuilder来创建UI的话,有没有统一的方法来处理DisabledImage呢?
答案是肯定的。
以下为Lua代码:
function createDisabledImageIfNot(node)
if type(node.getDisabledImage) ~= 'function' then return end
local disabledImage = node:getDisabledImage()
-- 如果没有设置 disabled image
if not disabledImage then
-- 取得normal image
local normalSprite = tolua.cast(node:getNormalImage(), 'CCSprite')
if normalSprite then
-- 将normal image 整体变灰
local graySprite = CCGraySprite:createWithTexture(normalSprite:getTexture(), normalSprite:getTextureRect())
node:setDisabledImage(graySprite)
只要在初始化方法中调用上述方法即可。
createDisabledImageIfNot(ccbLayer.menuItem1)
createDisabledImageIfNot(ccbLayer.menuItem2)
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有你的位置: >
> UGUI之更换图片Image(八)
首先我们要知道,UGUI的Image的精灵主体是image.overrideSprite。然后通过Resources.Load加载赋值即可。
方法如下:
using UnityE
using System.C
public class LoadImage : MonoBehaviour {
public UnityEngine.UI.Image m_
// Use this for initialization
void Start () {
void ChangeImage()//修改image
m_image.overrideSprite=Resources.Load("image",typeof(Sprite))as S
// Update is called once per frame
void Update () {
123456789101112131415161718
using UnityEngine;using System.Collections;&public class LoadImage : MonoBehaviour {public UnityEngine.UI.Image m_image;// Use this for initializationvoid Start () { int intgtl;}void ChangeImage()//修改image{ m_image.overrideSprite=Resources.Load("image",typeof(Sprite))as Sprite;}// Update is called once per framevoid Update () {&}}
这样就可以轻松地更换image的图片了。是不是很方便。
欢迎大家可以多多留言,不明白的地方的地方可以向我提出来,大家一起交流。
关注半白色,关注Unity3D程序开发。
转载请注明: &
与本文相关的文章Sprite Kit教程:初学者 - 文章 - 伯乐在线
& Sprite Kit教程:初学者
在iOS 7中内置了一个新的Sprite Kit框架,该框架主要用来开发2D游戏。目前已经支持的内容包括:精灵、很酷的特效(例如视频、滤镜和遮罩),并且还集成了物理库等许多东西。iOS 7中附带了一个非常棒的Sprite Kit示例工程,名字叫做Adventure。不过这个示例工程稍微有点复杂,不太适合初学者。本文的目的就是做一个关于Sprite Kit使用的初级教程。
通过本文,你可以从头到尾的学习到如何为你的iPhone创建一个简单又有趣的2D游戏。如果你看过我们之前的教程:Simple Cocos2D game教程,你会发现非常的相似。在开始之前,请确保已经安装了最新版本的Xcode(5.X),里面支持Sprite Kit以及iOS 7。
Sprite Kit的优点和缺点
首先,我想指出在iOS中开发2D游戏Sprite Kit并不是唯一的选择,下面我们先来看看Sprite Kit的一些优点和缺点。
Sprite Kit的优点:
1、它是内置到iOS中的,因此并不需要下载额外的库或者其它一些外部依赖。并且它是由苹果开发的,所以对于它的支持和更新我们可以放心。
2、它内置的工具支持纹理和粒子。
3、它可以让你做一些其它框架很难做到的事情,例如把视频当做精灵一样处理,或者使用很酷的图形效果和遮罩。
Sprite Kit的缺点:
1、如果使用了Sprite Kit,那么你将被iOS生态圈所绑架,导致你无法很容易对你开发的游戏移植到Android上。
2、Sprite Kit现在还处于初始阶段,此时提供的功能还没有别的框架丰富,例如Cocos2D。最缺的东西应该是暂不支持写自定义的OpenGL代码。
Sprite Kit vs Cocos2D-iPhone vs Cocos2D-X vs Unity
此时,你可能在想“我该选择使用哪个2D框架呢?”这取决于你的实际情况,下面是我的一些想法:
1、如果你是一个初学者,并且只关注于iOS,那么就使用内置的Sprite Kit吧,它非常容易学习,并且完全可以把工作做好。
2、如果需要写自己的OpenGL代码,那么还是使用Cocos2D,或者其它框架吧,目前Sprite Kit并不支持自定义OpenGL代码。
3、如果要进行跨平台开发,那么选择Cocos2D-X或者Unity。Cocos2D-X非常出色,可以用它来构建2D游戏。Unity则更加的灵活(例如,如果有需要的话,你可以在游戏中添加一些3D效果)。
看到这里,如果你还想要继续了解Sprite Kit的话,请继续往下读吧。
Hello,Sprite Kit!
下面我们就开始利用Xcode 5内置的Sprite Kit模板来构建一个简单的Hello World工程吧。
启动Xcode,选择File\New\Project,接着选中iOS\Application\SpriteKit Game模板,然后单击Next:
输入Product Name为SpriteKitSimpleGame,Devices选择iPhone,接着单击Next:
选择工程保存的路径,然后点击Create。然后点击Xcode中的播放按钮来运行工程。稍等片刻,可以看到如下运行画面:
跟Cocos2D类似,Sprite Kit也是按照场景(scenes)来构建的,这相当于游戏中的”levels”和”screens”。例如,你的游戏中可能会有一个主游戏区的场景,以及一个世界地图的一个场景。
如果你观察一下创建好的工程,会发现SpriteKit Game模板已经创建好了一个默认的场景MyScene。现在打开MyScene.m,里面已经包含了一些代码,其中将一个lable放到屏幕中,并且添加了:当tap屏幕时,会在屏幕上新增一个旋转的飞船。
在本教程中,我们主要在MyScene中写代码。不过在开始写代码之前,需要进行一个小调整——让程序以横屏的方式运行。
首先,在Project Navigator中单击SpriteKitSimpleGame工程以打开target设置,选中SpriteKitSimpleGame target。然后在Deployment Info中,不要勾选Portrait,只选中Landscape和Landscape Right,如下所示:
编译并运行工程,会看到如下运行画面:
下面我们试着添加一个忍者(ninja)。
首先,下载此工程的资源文件,并将其拖拽到Xcode工程中。确保勾选上“Copy items into destination group’s folder (if needed)”和SpriteKitSimpleGame target。
接着,打开MyScene.m,并用下面的内容替换之:
#import &MyScene.h&
@interface MyScene ()
@property (nonatomic) SKSpriteNode *
@implementation MyScene
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
NSLog(@&Size: %@&, NSStringFromCGSize(size));
self.backgroundColor = [SKColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
self.player = [SKSpriteNode spriteNodeWithImageNamed:@&player&];
self.player.position = CGPointMake(100, 100);
[self addChild:self.player];
12345678910111213141516171819202122232425262728
#import &MyScene.h&&// 1@interface MyScene ()@property (nonatomic) SKSpriteNode * player;@end&@implementation MyScene&-(id)initWithSize:(CGSize)size {&&&&&&&&if (self = [super initWithSize:size]) {&&&&&&&&&// 2&&&&&&&&NSLog(@"Size: %@", NSStringFromCGSize(size));&&&&&&&&&// 3&&&&&&&&self.backgroundColor = [SKColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];&&&&&&&&&// 4&&&&&&&&self.player = [SKSpriteNode spriteNodeWithImageNamed:@"player"];&&&&&&&&self.player.position = CGPointMake(100, 100);&&&&&&&&[self addChild:self.player];&&&&&}&&&&return self;}&@end
我们来看看上面的代码。
1.为了给player(例如忍者)声明一个私有变量,在这里创建了一个私有的interface,之后可以把这个私有变量添加到场景中。
2.在这里打印出了场景的size,至于什么原因很快你就会看到了。
3.在Sprite Kit中设置一个场景的背景色非常简单——只需要设置backgroundColor属性,在这里将其设置位白色。
4.在Sprite Kit场景中添加一个精灵同样非常简单,只需要使用spriteNodeWithImageNamed方法,并把一副图片的名称传递进去就可以创建一个精灵。接着设置一下精灵的位置,然后调用addChild方法将该精灵添加到场景中。在代码中将忍者的位置设置为(100, 100),该位置是从屏幕的左下角到右上角计算的。
编译并运行,看看效果如何…
呀!屏幕是白色的,并没有看到忍者。这是为什么呢?你可能在想设计之初就是这样的,实际上这里有一个问题。
如果你观察一下控制台输出的内容,会看到如下内容
SpriteKitSimpleGame[] Size: {320, 568}
SpriteKitSimpleGame[3139:907] Size: {320, 568}
可能你会认为场景的宽度是320,高度则是568——实际上刚好相反!
我们来看看具体发生了什么:定位到ViewController.m的viewDidLoad方法:
- (void)viewDidLoad
[super viewDidLoad];
// Configure the view.
SKView * skView = (SKView *)self.
skView.showsFPS = YES;
skView.showsNodeCount = YES;
// Create and configure the scene.
SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectF
// Present the scene.
[skView presentScene:scene];
12345678910111213141516
- (void)viewDidLoad{&&&&[super viewDidLoad];&&&&&// Configure the view.&&&&SKView * skView = (SKView *)self.view;&&&&skView.showsFPS = YES;&&&&skView.showsNodeCount = YES;&&&&&// Create and configure the scene.&&&&SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];&&&&scene.scaleMode = SKSceneScaleModeAspectFill;&&&&&// Present the scene.&&&&[skView presentScene:scene];}
上面的代码中利用view的边界size创建了场景。不过请注意,当viewDidLoad被调用的时候,在这之前view已经被添加到view层次结构中了,因此它还没有响应出布局的改变。所以view的边界可能还不正确,进而在viewDidLoad中并不是开启场景的最佳时机。
提醒:要想了解更多相关内容,请看由Rob Mayoff带来的最佳解释。
解决方法就是将开启场景代码的过程再靠后一点。用下面的代码替换viewDidLoad:
- (void)viewWillLayoutSubviews
[super viewWillLayoutSubviews];
// Configure the view.
SKView * skView = (SKView *)self.
if (!skView.scene) {
skView.showsFPS = YES;
skView.showsNodeCount = YES;
// Create and configure the scene.
SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectF
// Present the scene.
[skView presentScene:scene];
123456789101112131415161718
- (void)viewWillLayoutSubviews{&&&&[super viewWillLayoutSubviews];&&&&&// Configure the view.&&&&SKView * skView = (SKView *)self.view;&&&&if (!skView.scene) {&&&&&&skView.showsFPS = YES;&&&&&&skView.showsNodeCount = YES;&&&&&&&// Create and configure the scene.&&&&&&SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];&&&&&&scene.scaleMode = SKSceneScaleModeAspectFill;&&&&&&&// Present the scene.&&&&&&[skView presentScene:scene];&&&&}}
编译并运行程序,可以看到,忍者已经显示在屏幕中了!
如上图所示,可以看到坐标系已经正确了,如果想要把忍者的位置设置为其中间靠左,那么在MyScene.m中用下面的代码来替换设置忍者位置相关的代码:
self.player.position = CGPointMake(self.player.size.width/2, self.frame.size.height/2);
self.player.position = CGPointMake(self.player.size.width/2, self.frame.size.height/2);
接下来,我们希望在场景中添加一些怪兽,让忍者进行攻击。为了让游戏更有趣一点,希望怪兽能够移动——否则没有太大的挑战!OK,我们就在屏幕的右边,离屏的方式创建怪兽,并给怪兽设置一个动作:告诉它们往左边移动。
将下面这个方法添加到MyScene.m中:
- (void)addMonster {
// Create sprite
SKSpriteNode * monster = [SKSpriteNode spriteNodeWithImageNamed:@&monster&];
// Determine where to spawn the monster along the Y axis
int minY = monster.size.height / 2;
int maxY = self.frame.size.height - monster.size.height / 2;
int rangeY = maxY - minY;
int actualY = (arc4random() % rangeY) + minY;
// Create the monster slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
monster.position = CGPointMake(self.frame.size.width + monster.size.width/2, actualY);
[self addChild:monster];
// Determine speed of the monster
int minDuration = 2.0;
int maxDuration = 4.0;
int rangeDuration = maxDuration - minD
int actualDuration = (arc4random() % rangeDuration) + minD
// Create the actions
SKAction * actionMove = [SKAction moveTo:CGPointMake(-monster.size.width/2, actualY) duration:actualDuration];
SKAction * actionMoveDone = [SKAction removeFromParent];
[monster runAction:[SKAction sequence:@[actionMove, actionMoveDone]]];
12345678910111213141516171819202122232425262728
- (void)addMonster {&&&&&// Create sprite&&&&SKSpriteNode * monster = [SKSpriteNode spriteNodeWithImageNamed:@"monster"];&&&&&// Determine where to spawn the monster along the Y axis&&&&int minY = monster.size.height / 2;&&&&int maxY = self.frame.size.height - monster.size.height / 2;&&&&int rangeY = maxY - minY;&&&&int actualY = (arc4random() % rangeY) + minY;&&&&&// Create the monster slightly off-screen along the right edge,&&&&// and along a random position along the Y axis as calculated above&&&&monster.position = CGPointMake(self.frame.size.width + monster.size.width/2, actualY);&&&&[self addChild:monster];&&&&&// Determine speed of the monster&&&&int minDuration = 2.0;&&&&int maxDuration = 4.0;&&&&int rangeDuration = maxDuration - minDuration;&&&&int actualDuration = (arc4random() % rangeDuration) + minDuration;&&&&&// Create the actions&&&&SKAction * actionMove = [SKAction moveTo:CGPointMake(-monster.size.width/2, actualY) duration:actualDuration];&&&&SKAction * actionMoveDone = [SKAction removeFromParent];&&&&[monster runAction:[SKAction sequence:@[actionMove, actionMoveDone]]];&}
在上面,我尽量让代码看起来容易理解。首先是通过一个简单的计算,确定怪兽出现的位置,并将该位置设置给怪兽,然后将其添加到场景中。
接着是添加动作(actions)。跟Cocos2D一样,Sprite Kit同样提供了很多方便的内置动作,例如移动动作、旋转动作、淡入淡出动作、动画动作等。在这里我们只需要在怪兽上使用3中动作即可:
moveTo:duration:使用这个动作可以把怪兽从屏幕外边移动到左边。移动过程中,我们可以指定移动持续的时间,上面的代码中,指定为2-4秒之间的一个随机数。
removeFromParent:在Sprite Kit中,可以使用该方法,方便的将某个node从parent中移除,能有效的从场景中删除某个对象。此处,将不再需要显示的怪兽从场景中移除。这个功能非常的重要,否则当有源源不断的怪兽出现在场景中时,会耗尽设备的所有资源。
sequence:sequence动作可以一次性就把一系列动作串联起来按照一定顺序执行。通过该方法我们就能让moveTo:方法先执行,当完成之后,在执行removeFromParent:动作。
最后,我们需要做的事情就是调用上面这个方法addMonster,以实际的创建出怪兽!为了更加好玩,下面我们来让怪兽随着时间持续的出现在屏幕中。
在Sprite Kit中,并不能像Cocos2D一样,可以配置每隔X秒就回调一下update方法。同样也不支持将从上次更新到目前为止的时间差传入方法中。(非常令人吃惊!)。
不过,我们可以通过一小段代码来仿造这种行为。首先在MyScene.m的private interface中添加如下属性:
@property (nonatomic) NSTimeInterval lastSpawnTimeI
@property (nonatomic) NSTimeInterval lastUpdateTimeI
@property (nonatomic) NSTimeInterval lastSpawnTimeInterval; @property (nonatomic) NSTimeInterval lastUpdateTimeInterval;
通过lastSpawnTimeInterval可以记录着最近出现怪兽时的时间,而lastUpdateTimeInterval可以记录着上次更新时的时间。
接着,我们写一个方法,该方法在画面每一帧更新的时候都会被调用。记住,该方法不会被自动调用——需要另外写一个方法来调用它:
- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast {
self.lastSpawnTimeInterval += timeSinceL
if (self.lastSpawnTimeInterval & 1) {
self.lastSpawnTimeInterval = 0;
[self addMonster];
- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast {&&&&&self.lastSpawnTimeInterval += timeSinceLast;&&&&if (self.lastSpawnTimeInterval > 1) {&&&&&&&&self.lastSpawnTimeInterval = 0;&&&&&&&&[self addMonster];&&&&}}
上面的代码中简单的将上次更新(update调用)的时间追加到self.lastSpawnTimeInterval中。一旦该时间大于1秒,就在场景中新增一个怪兽,并将lastSpawnTimeInterval重置。
最后,添加如下方法来调用上面的方法:
- (void)update:(NSTimeInterval)currentTime {
// Handle time delta.
// If we drop below 60fps, we still want everything to move the same distance.
CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeI
self.lastUpdateTimeInterval = currentT
if (timeSinceLast & 1) { // more than a second since last update
timeSinceLast = 1.0 / 60.0;
self.lastUpdateTimeInterval = currentT
[self updateWithTimeSinceLastUpdate:timeSinceLast];
12345678910111213
- (void)update:(NSTimeInterval)currentTime {&&&&// Handle time delta.&&&&// If we drop below 60fps, we still want everything to move the same distance.&&&&CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval;&&&&self.lastUpdateTimeInterval = currentTime;&&&&if (timeSinceLast > 1) { // more than a second since last update&&&&&&&&timeSinceLast = 1.0 / 60.0;&&&&&&&&self.lastUpdateTimeInterval = currentTime;&&&&}&&&&&[self updateWithTimeSinceLastUpdate:timeSinceLast];&}
Sprite Kit在显示每帧时都会调用上面的update:方法。
上面的代码其实是来自苹果提供的Adventure示例中。该方法会传入当前的时间,在其中,会做一些计算,以确定出上一帧更新的时间。注意,在代码中做了一些合理性的检查,以避免从上一帧更新到现在已经过去了大量时间,并且将间隔重置为1/60秒,避免出现奇怪的行为。
现在编译并运行程序,可以看到许多怪兽从左边移动到屏幕右边并消失。
现在我们开始给忍者添加一些动作,首先从发射炮弹开始!实际上有多种方法来实现炮弹的发射,不过,在这里要实现的方法时当用户tap屏幕时,从忍者的方位到tap的方位发射一颗炮弹。
由于本文是针对初级开发者,所以在这里我使用moveTo:动作来实现,不过这需要做一点点的数学运算——因为moveTo:方法需要指定炮弹的目的地,但是又不能直接使用touch point(因为touch point仅仅代表需要发射的方向)。实际上我们需要让炮弹穿过touch point,直到炮弹在屏幕中消失。
如下图,演示了上面的相关内容:
如图所示,我们可以通过origin point到touch point得到一个小的三角形。我们要做的就是根据这个小三角形的比例创建出一个大的三角形——而你知道你想要的一个端点是离开屏幕的地方。
为了做这个计算,如果有一些基本的矢量方法可供调用(例如矢量的加减法),那么会非常有帮助,但很不幸的时Sprite Kit并没有提供相关方法,所以,我们必须自己实现。
不过很幸运的时这非常容易实现。将下面的方法添加到文件的顶部(implementation之前):
static inline CGPoint rwAdd(CGPoint a, CGPoint b) {
return CGPointMake(a.x + b.x, a.y + b.y);
static inline CGPoint rwSub(CGPoint a, CGPoint b) {
return CGPointMake(a.x - b.x, a.y - b.y);
static inline CGPoint rwMult(CGPoint a, float b) {
return CGPointMake(a.x * b, a.y * b);
static inline float rwLength(CGPoint a) {
return sqrtf(a.x * a.x + a.y * a.y);
// Makes a vector have a length of 1
static inline CGPoint rwNormalize(CGPoint a) {
float length = rwLength(a);
return CGPointMake(a.x / length, a.y / length);
123456789101112131415161718192021
static inline CGPoint rwAdd(CGPoint a, CGPoint b) {&&&&return CGPointMake(a.x + b.x, a.y + b.y);}&static inline CGPoint rwSub(CGPoint a, CGPoint b) {&&&&return CGPointMake(a.x - b.x, a.y - b.y);}&static inline CGPoint rwMult(CGPoint a, float b) {&&&&return CGPointMake(a.x * b, a.y * b);}&static inline float rwLength(CGPoint a) {&&&&return sqrtf(a.x * a.x + a.y * a.y);}&// Makes a vector have a length of 1static inline CGPoint rwNormalize(CGPoint a) {&&&&float length = rwLength(a);&&&&return CGPointMake(a.x / length, a.y / length);}
上面实现了一些标准的矢量函数。如果你看得不是太明白,请看这里关于矢量方法的解释。
接着,在文件中添加一个新的方法:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// 1 - Choose one of the touches to work with
UITouch * touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
// 2 - Set up initial location of projectile
SKSpriteNode * projectile = [SKSpriteNode spriteNodeWithImageNamed:@&projectile&];
projectile.position = self.player.
// 3- Determine offset of location to projectile
CGPoint offset = rwSub(location, projectile.position);
// 4 - Bail out if you are shooting down or backwards
if (offset.x &= 0)
// 5 - OK to add now - we've double checked position
[self addChild:projectile];
// 6 - Get the direction of where to shoot
CGPoint direction = rwNormalize(offset);
// 7 - Make it shoot far enough to be guaranteed off screen
CGPoint shootAmount = rwMult(direction, 1000);
// 8 - Add the shoot amount to the current position
CGPoint realDest = rwAdd(shootAmount, projectile.position);
// 9 - Create the actions
float velocity = 480.0/1.0;
float realMoveDuration = self.size.width /
SKAction * actionMove = [SKAction moveTo:realDest duration:realMoveDuration];
SKAction * actionMoveDone = [SKAction removeFromParent];
[projectile runAction:[SKAction sequence:@[actionMove, actionMoveDone]]];
123456789101112131415161718192021222324252627282930313233343536
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {&&&&&// 1 - Choose one of the touches to work with&&&&UITouch * touch = [touches anyObject];&&&&CGPoint location = [touch locationInNode:self];&&&&&// 2 - Set up initial location of projectile&&&&SKSpriteNode * projectile = [SKSpriteNode spriteNodeWithImageNamed:@"projectile"];&&&&projectile.position = self.player.position;&&&&&// 3- Determine offset of location to projectile&&&&CGPoint offset = rwSub(location, projectile.position);&&&&&// 4 - Bail out if you are shooting down or backwards&&&&if (offset.x <= 0) return;&&&&&// 5 - OK to add now - we've double checked position&&&&[self addChild:projectile];&&&&&// 6 - Get the direction of where to shoot&&&&CGPoint direction = rwNormalize(offset);&&&&&// 7 - Make it shoot far enough to be guaranteed off screen&&&&CGPoint shootAmount = rwMult(direction, 1000);&&&&&// 8 - Add the shoot amount to the current position&&&&&& &&&&CGPoint realDest = rwAdd(shootAmount, projectile.position);&&&&&// 9 - Create the actions&&&&float velocity = 480.0/1.0;&&&&float realMoveDuration = self.size.width / velocity;&&&&SKAction * actionMove = [SKAction moveTo:realDest duration:realMoveDuration];&&&&SKAction * actionMoveDone = [SKAction removeFromParent];&&&&[projectile runAction:[SKAction sequence:@[actionMove, actionMoveDone]]];&}
上面的代码中做了很多事情,我们来详细看看。
1.SpriteKit为我们做了很棒的一件事情就是它提供了一个UITouch的category,该category中有locationInNode:和previousLocationInNode:方法。这两个方法可以帮助我们定位到在SKNode内部坐标系中touch的坐标位置。这样一来,我们就可以寻得到在场景坐标系中touch的位置。
2.然后创建一个炮弹,并将其放置到忍者的地方,以当做其开始位置。注意,现在还没有将其添加到场景中,因为还需要先做一个合理性的检查——该游戏不允许忍者向后发射。
3.接着利用touch位置减去炮弹的当前位置,这样就能获得一个从当前位置到touch位置的矢量。
4.如果X值小于0,就意味着忍者将要向后发射,由于在这里的游戏中是不允许的(真实中的忍者是不回头的!),所以就return。
5.否则,将可以将炮弹添加到场景中。
6.调用方法rwNormalize,将offset转换为一个单位矢量(长度为1)。这样做可以让在相同方向上,根据确定的长度来构建一个矢量更加容易(因为1 * length = length)。
7.在单位矢量的方向上乘以1000。为什么是1000呢?因为着肯定足够超过屏幕边缘了 。
8.将上一步中计算得到的位置与炮弹的位置相加,以获得炮弹最终结束的位置。
9.最后,参照之前构建怪物时的方法,创建moveTo:和removeFromParent:两个actions。
编译并允许程序,现在忍者可以发射炮弹了!
可能感兴趣的话题
关于伯乐在线博客
在这个信息爆炸的时代,人们已然被大量、快速并且简短的信息所包围。然而,我们相信:过多“快餐”式的阅读只会令人“虚胖”,缺乏实质的内涵。伯乐在线内容团队正试图以我们微薄的力量,把优秀的原创文章和译文分享给读者,为“快餐”添加一些“营养”元素。
新浪微博:
推荐微信号
(加好友请注明来意)
– 好的话题、有启发的回复、值得信赖的圈子
– 分享和发现有价值的内容与观点
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 翻译传播优秀的外文文章
– 国内外的精选文章
– UI,网页,交互和用户体验
– 专注iOS技术分享
– 专注Android技术分享
– JavaScript, HTML5, CSS
– 专注Java技术分享
– 专注Python技术分享
& 2016 伯乐在线

我要回帖

更多关于 动态设置imageview 的文章

 

随机推荐