对ios layer 旋转或精灵做setRotation3D旋转后,触摸需要特殊处理吗

01:58:47 UTC
I added a image on the layer, and rotate the layer with an angle. as long as the angle is greater than one particular value (22 degree), the image will be truncated from the top. The code is following, but why?
Sprite *s = Sprite::create("HelloWorld.png");
s-&setPosition(DLConfig::GetInstance()-&centerPoint);
this-&addChild(s);
this-&setRotation3D(Vertex3F(-60,0.0f,0.0f));
(219.0 KB)
02:18:28 UTC
Does anybody know?
16:21:02 UTC
I can at least say I am seeing the exact same thing.
19:14:42 UTC
I tried with the latest 3.1 and I think this is still the case.
06:51:17 UTC
Your sprite has been truncated from the top. If you changed the angle to -60, it will be easylier to see.
08:39:05 UTC
The Projection,ZFarPlane is too small. you can modify at function: void Director::setProjection(Projection projection)
10:02:04 UTC
Yes!This solves my problem! Thank you very much!
04:32:30 UTC
What are you modify? please send me. I'm get same problem. Thanks you very much!当前位置:
& Swift - 动画效果的实现方法总结(附样例)
Swift - 动画效果的实现方法总结(附样例)
发布:hangge
阅读:12841
在iOS中,实现动画有两种方法。一个是统一的animateWithDuration,另一个是组合出现的beginAnimations和commitAnimations。这三个方法都是类方法。
一,使用animateWithDuration来实现动画
(1)此方法共有5个参数:
duration:动画从开始到结束的持续时间,单位是秒
delay:动画开始前等待的时间
options:动画执行的选项。里面可以设置动画的效果。可以使用UIViewAnimationOptions类提供的各种预置效果
anmations:动画效果的代码块
completion:动画执行完毕后执行的代码块
(2)UIView支持动画效果的属性
frame:此属性包含一个矩形,即边框矩形,此值确定了当前视图在其父视图坐标系中的位置与尺寸
bounds:也是矩形,边界矩形,它指的是视图在其自己的坐标系中的位置和尺寸,左上角坐标永远是(0,0)
center:确定视图的中心点在其父视图坐标系中的位置坐标。即定义当前视图在父视图中的位置
alpha:视图的透明度。(但视图完全透明时,不能响应触摸消息)
backgroundColor:背景色
transform:这是一种3×3的变化矩阵。通过这个矩阵我们可以对一个坐标系统进行缩放、平移、旋转以及这两者的任意组操作。
(3)Transform(变化矩阵)的四个常用的变换方法
CGAffineTransformMake():返回变换矩阵
CGAffineTransformMakeTranslation():返回平移变换矩阵
CGAffineTransformMakeScale():返回缩放变换矩阵
CGAffineTransformMakeRotation():返回旋转变换矩阵
(4)样例1:方块初始缩小为原始尺寸1/10。在1秒的动画中复原到完整大小,同时还伴随旋转效果。
import UIKit
class ViewController: UIViewController {
//游戏方格维度
var dimension:Int = 4
//数字格子的宽度
var width:CGFloat = 50
//格子与格子的间距
var padding:CGFloat = 6
//保存背景图数据
var backgrounds:Array&UIView&!
override func viewDidLoad()
super.viewDidLoad()
self.backgrounds = Array&UIView&()
setupGameMap()
playAnimation()
func setupGameMap()
var x:CGFloat = 50
var y:CGFloat = 150
for i in 0..&dimension
for _ in 0..&dimension
//初始化视图
let background = UIView(frame:CGRectMake(x, y, width, width))
background.backgroundColor = UIColor.darkGrayColor()
self.view.addSubview(background)
//将视图保存起来,以备后用
backgrounds.append(background)
y += padding + width
x += padding+width
func playAnimation()
for tile in backgrounds{
//先将数字块大小置为原始尺寸的 1/10
tile.layer.setAffineTransform(CGAffineTransformMakeScale(0.1,0.1))
//设置动画效果,动画时间长度 1 秒。
UIView.animateWithDuration(1, delay:0.01,
options:UIViewAnimationOptions.TransitionNone, animations:
()-& Void in
//在动画中,数字块有一个角度的旋转。
tile.layer.setAffineTransform(CGAffineTransformMakeRotation(90))
completion:{
(finished:Bool) -& Void in
UIView.animateWithDuration(1, animations:{
()-& Void in
//完成动画时,数字块复原
tile.layer.setAffineTransform(CGAffineTransformIdentity)
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
(5)样例2:只有从小变大的效果
func playAnimation()
for tile in backgrounds{
//先将数字块大小置为原始尺寸的 1/10
tile.layer.setAffineTransform(CGAffineTransformMakeScale(0.1,0.1))
//设置动画效果,动画时间长度 1 秒。
UIView.animateWithDuration(1, delay:0.01,
options:UIViewAnimationOptions.TransitionNone, animations:
()-& Void in
tile.layer.setAffineTransform(CGAffineTransformMakeScale(1,1))
completion:{
(finished:Bool) -& Void in
UIView.animateWithDuration(0.08, animations:{
()-& Void in
tile.layer.setAffineTransform(CGAffineTransformIdentity)
(6)样例3:方块从不透明到透明的效果
func playAnimation()
for tile in backgrounds{
tile.alpha = 0;
//设置动画效果,动画时间长度 1 秒。
UIView.animateWithDuration(1, delay:0.01,
options:UIViewAnimationOptions.CurveEaseInOut, animations:
()-& Void in
completion:{
(finished:Bool) -& Void in
UIView.animateWithDuration(1, animations:{
()-& Void in
tile.alpha = 1
二,使用beginAnimations和commitAnimations方法来实现动画
beginAnimations:此方法开始一个动画块,调用commitAnimations结束一个动画块,并且动画块是允许嵌套的。
commitAnimations:此方法用于结束一个动画块,动画是在一个独立的线程中运行的,动画在生效时,所有应用程序不会中断。
在beginAnimations和commitAnimations中间的代码中,我们可以设置各种动画的属性。比如持续时间,使用哪种预置的动画效果等。
(1)淡入,淡出,移动,改变大小动画
//淡出动画
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(2.0)
imageView.alpha = 0.0
mitAnimations()
//淡入动画
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(2.0)
imageView.alpha = 1.0
mitAnimations()
//移动动画
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(2.0)
imageView.center = CGPointMake(250, 250)
UIView.setAnimationCurve(UIViewAnimationCurve.EaseOut) //设置动画相对速度
mitAnimations()
//大小调整动画
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(2.0)
imageView.frame = CGRectMake(100,180,50,50)
mitAnimations()
(2)两个视图切换的过渡动画
& UIViewAnimationTransition定义了5种过渡动画类型:
None:无过渡动画效果
FlipFromLeft:从左侧向右侧翻转
FlipFromRight:从右侧向左侧翻转
CurlUp:向上卷数翻页
CurlDown:向下翻页
import UIKit
class ViewController: UIViewController {
override func viewDidLoad()
super.viewDidLoad()
//创建一个按钮,用来点击播放动画
let button:UIButton = UIButton(type:.System)
button.frame=CGRectMake(10, 20, 100, 30)
button.setTitle("播放动画", forState:UIControlState.Normal)
button.addTarget(self,action:Selector("play"),forControlEvents:.TouchUpInside)
self.view.addSubview(button);
//添加两个红蓝视图
let redView:UIView = UIView(frame: CGRectMake(50,50,150,400))
redView.backgroundColor = UIColor.redColor()
self.view.insertSubview(redView, atIndex: 0)
let blueView:UIView = UIView(frame: CGRectMake(50,50,150,400))
blueView.backgroundColor = UIColor.blueColor()
self.view.insertSubview(blueView, atIndex: 1)
//切换视图并播放动画
func play(){
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(3.0)
UIView.setAnimationTransition(.CurlUp, forView: self.view, cache: true)
self.view.exchangeSubviewAtIndex(1, withSubviewAtIndex: 0)
mitAnimations()
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
(3)页面或元件翻转效果
import UIKit
class ViewController: UIViewController {
override func viewDidLoad()
super.viewDidLoad()
//创建一个按钮,用来点击播放动画
let button:UIButton = UIButton(type:.System)
button.frame=CGRectMake(10, 20, 100, 30)
button.setTitle("播放动画", forState:UIControlState.Normal)
button.addTarget(self,action:Selector("play"),forControlEvents:.TouchUpInside)
self.view.addSubview(button);
//切换视图并播放动画
func play(){
//将整个主视图面板实现一个翻转效果
UIView.beginAnimations("animation", context: nil)
UIView.setAnimationDuration(2)
UIView.setAnimationCurve(UIViewAnimationCurve.EaseInOut)
UIView.setAnimationTransition(.FlipFromLeft, forView: self.view, cache: false)
mitAnimations()
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()cocos2d-x 3.x之触摸事件
Layer类的一个重要作用就是接受输入事件,它封装了触摸输入的处理接口。一般情况下,我们可以通过setTouchEnabled方法来开启或关闭接收触摸输入。事实上并不是只有Layer才支持接收触摸事件,任何一个游戏元素都可以接收事件,只不过Layer提供了现成的支持。
我们只需通过创建一个事件监听器用来实现各种触发后的逻辑,然后添加到事件分发器_eventDispatcher中,所有事件监听器由这个分发器统一管理,即可完成事件响应。
为一个精灵添加触摸事件的四个步骤
1.创建一个精灵
2.创建一个事件监听器(单点触摸或多点触摸)
3.实现各种触发后的逻辑(onTouchBegan,onTouchMoved,onTouchEnded等)
4.将事件监听器添加到事件分发器中
// 1.首先添加一个精灵元素
bool GameScene::init()
sprite = Sprite::create();
sprite-&setPosition(100, 100);
this-&addChild(sprite);
void GameScene::addTouchEvent()
// 2.创建一个单点触摸监听器
auto touchListener = EventListenerTouchOneByOne::create();
// 3.实现触摸后的逻辑处理,使用lambda表达式实现触摸事件处理的回调函数
// 触摸开始
touchListener-&onTouchBegan = [](Touch *touch, Event *event)
// 获取点击的openGL坐标
auto touchPos = touch-&getLocation();
// 获取触摸事件的相关目标,即玩家飞机
auto target = static_cast(event-&getCurrentTarget());
// 获取飞机所在区域
auto playerPos = target-&getPosition();
auto playerSize = target-&getContentSize();
auto rect = Rect(playerPos.x - playerSize.width/2, playerPos.y - playerSize.height/2,
playerSize.width, playerSize.height);
if(rect.containsPoint(touchPos))
// 返回false会导致后面的onTouchMoved和onTouchEnded不会执行
touchListener-&onTouchMoved = [](Touch *touch, Event *event)
auto touchPos = touch-&getLocation();
auto target = static_cast(event-&getCurrentTarget());
target-&setPosition(touchPos);
// 触摸结束
touchListener-&onTouchEnded = [](Touch *touch, Event *event)
log(touch end);
4.最后将事件监听器添加到事件分发器_eventDispatcher中 _eventDispatcher是Node的属性,通过它管理当前节点(场景、层、精灵等)的所有事件的分发。但它本身是一个单例模式值的引用,在Node的构造函数中,通过Director::getInstance()-&getEventDispatcher(); 获取,有了这个属性,就能方便的处理事件。
// _eventDispatcher = Director::getInstance()-&getEventDispatcher();
_eventDispatcher-&addEventListenerWithSceneGraphPriority(touchListener, sprite);
// 为第二个精灵添加触摸监听_eventDispatcher-&addEventListenerWithSceneGraphPriority(touchListener-&clone(), sprite2);
当再次使用touchListener 的时候,需要使用clone()方法创建一个新的克隆,因为在使用addEventListenerWithSceneGraphPriority或者addEventListenerWithFixedPriority方法时,会对当前使用的事件监听器添加一个已注册的标记,这使得它不能够被添加多次。另外,有一点非常重要,FixedPriority listener添加完之后需要手动remove,而SceneGraphPriority listener是跟Node绑定的,在Node的析构函数中会被移除。具体的示例用法可以参考引擎自带的tests。
我们可以通过以下方法移除一个已经被添加了的监听器。
_eventDispatcher-&removeEventListener(listener);
也可以使用如下方法,移除当前事件分发器中所有监听器。
_eventDispatcher-&removeAllEventListeners();
当使用removeAll的时候,此节点的所有的监听将被移除,推荐使用指定删除的方式。removeAll之后菜单也不能响应。因为它也需要接受触摸事件。
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'

我要回帖

更多关于 layer旋转动画 的文章

 

随机推荐