I'm wondering if anyone can help me with this. I want to add 4 CCScrollViews, that will scroll horizontally, on a CCNode. The CCNode, positioned and held on the device in portrait mode, will fill the entire screen with a normalized contentSize set to cover the entire screen.
So in essence the scroll views will pile on top of each other with the 4th being at the bottom of the screen and the 1st being at the top. Now, I have managed to add the 4 CCScrollViews but only one responds to touches. The others are flat an unmovable. It's almost as though the last CCScrollView added to the node is overlaying the other three and it is the only thing responding to touch requests. All 4 CCScrollViews have their delegate property set to self.
I'm someone coming at Cocos2d with a fair bit of UIKit experience. So, i'm trying to apply my UIScrollView mode of thinking to all of this. Having had a good Google about and coming up with little, I'm wondering if SO can help. I've even been considering winding UIScrollView into Cocos2d.
I guess my main issues here are two-fold. One, I have an issue with touch response. Two, I have an issue with the paging aspect and control of content-size. Via trial and error, I'm sort of getting along but if someone could perhaps write up a bit of a best-practive guide to CCScrollView implementation, specifically where one does not set the contentSize of the CCNode or CCspriteFrame that's added to larger contentView does not fill the entire width of the screen.
Thanks in advance.
#import "CCToolKit.h"
#import "GameShip.h"
typedef enum ShipPart
{
ShipPartHead,
ShipPartBody,
ShipPartWings,
ShipPartBoosters
} ShipPart;
#implementation GameShip
-(instancetype)init {
if (self = [super init]) {
[self addBackground];
[self addScrollTo:ShipPartHead forQtyOfParts:3];
[self addScrollTo:ShipPartBody forQtyOfParts:4];
[self addScrollTo:ShipPartWings forQtyOfParts:3];
[self addScrollTo:ShipPartBoosters forQtyOfParts:3];
}
return self;
}
-(void)addBackground {
CCSprite *bg = [CCSprite spriteWithImageNamed:kGameMainBackGround];
bg.positionType = CCPositionTypeNormalized;
bg.position = ccp(0.5f,0.5f);
[self addChild:bg];
}
-(void)addScrollTo:(ShipPart)shipPart forQtyOfParts:(int)partQty {
NSString *imageFileNameSegment;
switch (shipPart) {
case ShipPartHead:
imageFileNameSegment = #"head";
break;
case ShipPartBody:
imageFileNameSegment = #"body";
break;
case ShipPartWings:
imageFileNameSegment = #"wings";
break;
case ShipPartBoosters:
imageFileNameSegment = #"boosters";
break;
default:
break;
}
CCNode *scrollViewContents = [CCNode node];
scrollViewContents.contentSizeType = CCSizeTypeNormalized;
scrollViewContents.contentSize = CGSizeMake(partQty * 0.65, 0.25f);
NSLog(#"scrollView,height %f", scrollViewContents.boundingBox.size.height);
for (int i = 1; i <= partQty; i++) {
NSString *imageFileName = [NSString stringWithFormat:#"%#%d.png", imageFileNameSegment, i];
CCSprite *shipPartSprite = [CCSprite spriteWithImageNamed:imageFileName];
shipPartSprite.positionType = CCPositionTypeNormalized;
shipPartSprite.position = ccp((i + 0.5f) / partQty, 0.5f);
[scrollViewContents addChild:shipPartSprite];
}
CCScrollView *scrollView = [[CCScrollView alloc] initWithContentNode:scrollViewContents];
scrollView.pagingEnabled = YES;
scrollView.horizontalScrollEnabled = YES;
scrollView.verticalScrollEnabled = NO;
scrollView.color = [CCColor redColor];
scrollView.contentSize = CGSizeMake(0.5f, 0.25f);
scrollView.positionType = CCPositionTypeNormalized;
scrollView.position = ccp(-1.0f, ((shipPart * 0.25f) -0.1f));
scrollView.delegate = self;
//scrollView.description = [NSString stringWithFormat:#"%d", shipPart];
[self addChild:scrollView];
//[scrollView setHorizontalPage:1];
}
Related
I try to implement side bar menu. I already have done it with standard UIView animations, but now i want to add some feelings to it. I decided to use UIViewDynamics. I noticed that, after main view frame changed, it is necessary to recreate UIViewAnimator and all behaviors.
I usually use layoutSubviews view's method. But in that case, my controller inherit UINavigationController and i couldn't override its view, so i worked with controller life cycle methods.
To avoid unexpected result, first i remove all animator behaviors in viewWillLayoutSubviews method. After that, at end of viewDidLayoutSubviews I create an animator and behaviors (gravity, item, push, collision).
That works fine, but when layoutSubviews triggered, it is some lags (looks like low fps).
Some code:
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
if (_animator) {
[_animator removeAllBehaviors];
_animator = nil;
}
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self configSubviewFrames];
[self configAnimator];
}
- (void)configSubviewFrames
{
CGFloat offset = [UIApplication sharedApplication].isStatusBarHidden ? 0 : _statusBarHeight;
CGRect drawerFrame, protectionFrame, unusedFrame;
CGRectDivide(self.view.frame, &drawerFrame, &unusedFrame, _drawerWidth, CGRectMinXEdge);
protectionFrame= self.view.frame;
if (!_isMenuShown) {
drawerFrame.origin.x -= _drawerWidth;
}
drawerFrame.origin.y += offset;
drawerFrame.size.height -= offset;
protectionFrame.origin.y += offset;
protectionFrame.size.height -= offset;
_drawerView.frame = drawerFrame;
_protectionView.frame = protectionFrame;
}
- (void)configAnimator
{
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
_collisionBehavior = [[UICollisionBehavior alloc] initWithItems:#[_drawerView]];
_itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:#[_drawerView]];
_gravityBehavior = [[UIGravityBehavior alloc] initWithItems:#[_drawerView]];
_pushBehavior = [[UIPushBehavior alloc] initWithItems:#[_drawerView] mode:UIPushBehaviorModeInstantaneous];
_itemBehavior.allowsRotation = NO;
_itemBehavior.elasticity = kDrawerElacity;
_gravityBehavior.gravityDirection = CGVectorMake(_isMenuShown ? 1.0f : -1.0f, 0.0f);
_pushBehavior.magnitude = 0.0f;
_pushBehavior.angle = 0.0f;
_collisionBehavior.collisionDelegate = self;
[_collisionBehavior setTranslatesReferenceBoundsIntoBoundaryWithInsets:UIEdgeInsetsMake(0, - _drawerWidth, 0, self.view.frame.size.width - _drawerWidth)];
[self addInititalBihaviors];
}
- (void)addInititalBihaviors
{
[_animator addBehavior:_collisionBehavior];
[_animator addBehavior:_pushBehavior];
[_animator addBehavior:_gravityBehavior];
[_animator addBehavior:_itemBehavior];
}
Hope you will help and feel free to ask any related questions.
Thanks you.
App consume 9-12 % cpu on screen rotate.
P.S.: I already tried to move animator and behaviors creation into separated thread, but:
Working with view in background thread - bad idea
It just didn't help
I can't find any helpful tutorials or explanation on how to use a CCScrollView. I have a grid-layout of sprites and labels (listing achievements for an iOS game). There are more than can fit on the screen so I want the user to be able to scroll.
To scroll, the user would swipe/pan upwards, to reveal the sprites etc which are lower.
I've found a few code samples and they seem to indicate you just need to add your content node to the scroll node and it will take care of the rest.
It doesn't seem to work. There's no scroll, and the pan/touch events on the scroll layer never seem to fire. The close button I have at the same child (sibling to the scroll view) no longer works as well.
I'm not using SpriteBuilder.
// Node to hold all sprites/labels
scrollContents = [CCNode node];
// I add a bunch of sprites/labels in a grid view
for( NSString *key in badgeKeys ){
// logic to load the sprite would be here
CCSprite *badge = [CCSprite spriteWithSpriteFrame:frame];
badge.positionType = CCPositionTypeNormalized;
badge.position = ccp(xPos,yPos);
[scrollContents addChild:badge];
// some logic to increment x/y position logic, for grid layout
}
// Scroll view
scrollView = [[CCScrollView alloc] initWithContentNode:scrollContents];
scrollView.horizontalScrollEnabled = NO;
scrollView.verticalScrollEnabled = YES;
[scrollView setBounces:NO];
// My sprites never even show unless I manually set this
scrollContents.contentSize = CGSizeMake(self.contentSize.width,960);
NSLog(#"scrollContents contentsize: %f %f", scrollContents.contentSize.width,scrollContents.contentSize.height);
[self addChild:scrollView];
ok, here is a working example (i deconstructed part of my code to give you a fully working code sample) of a scrolling menu with 'live' buttons inside. I just tested this 'deconstruction' , it works
- (void) scrollingMenuWithCharmsTest {
// setup something to scroll
GameInventory *gi = [GameInventory sharedGameInventory];
while (gi.armorCharms.count < 20) {
[gi addArmorCharm:[ArmorCharm createRandomArmorCharm]];
}
CCNode *contentNode = [self charmsContentNodeFor:gi.armorCharms
showEquiped:NO
spacingBetweenMenuItems:8
target:self
selector:#selector(onArmorCharmSelected:)];
// setup a clipping node to crop out the CCScrollingMenu
CCNodeColor *ccn = [CCNodeColor nodeWithColor:[CCColor blackColor] width:180 height:200];
ccn.anchorPoint = ccp(0, 0);
CCClippingNode *cn = [CCClippingNode clippingNodeWithStencil:ccn];
cn.alphaThreshold = 0.05f;
[self addChild:cn];
cn.inverted = NO;
cn.positionInPointsV = ccp(50, 50);
cn.anchorPoint = ccp(0, 0);
cn.contentSizeInPoints = CGSizeMake(180, 200);
// setup scrolling menu
CCScrollView * bsm = [[CCScrollView alloc] initWithContentNode:contentNode];
bsm.contentSize=CGSizeMake(180,200);
[cn addChild:bsm];
bsm.position = ccp(0, 0);
bsm.bounces = YES;
bsm.pagingEnabled = NO;
bsm.verticalScrollEnabled = YES;
bsm.horizontalScrollEnabled = NO;
bsm.contentSizeInPoints = CGSizeMake(180, 200); // inPoints only after the node has a parent
for (CharmAbstractBoxMenuItem *lmi in bsm.contentNode.children) {
TRACE(#"item %# is at %#", lmi.item.description, NSStringFromCGPoint(lmi.positionInPointsV));
}
TRACE(#"number of pages : %i", bsm.numVerticalPages);
}
- (CCNode *)charmsContentNodeFor:(NSDictionary *)keyedItems
showEquiped:(BOOL)isShowEquiped
spacingBetweenMenuItems:(float)inSpacing
target:(id)inTarget
selector:(SEL)inSelector {
NSSortDescriptor *sortOrder = [NSSortDescriptor sortDescriptorWithKey:#"self" ascending:YES];
NSArray *sortedKeys = [[keyedItems allKeys] sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortOrder]];
float initialY = 0;
float currentY = initialY;
NSUInteger itemNumber = 0;
CGFloat width = 0;
CGFloat height = 0;
CCNode *contentNode = [CCNode node];
for (NSUInteger loopi = 0; loopi < [sortedKeys count]; loopi++) {
NSString *key = [sortedKeys objectAtIndex:loopi];
CharmAbstract *ci = [keyedItems objectForKey:key];
if (ci) {
CharmAbstractBoxMenuItem *cmi = [CharmAbstractBoxMenuItem itemBoxFor:ci
target:inTarget
selector:inSelector
];
cmi.toolTip = ci.toolTip;
cmi.position = ccp(deviceOffset(0), currentY);
cmi.key = key;
[contentNode addChild:cmi z:0 name:[NSString stringWithFormat:#"%li", (long) itemNumber]];
currentY += cmi.contentSizeInPoints.height + inSpacing;
itemNumber++;
if (cmi.contentSize.width > width) width = cmi.contentSize.width;
height += cmi.contentSize.height;
if (loopi < sortedKeys.count - 1) height += inSpacing;
}
else {
MPLOG(#"*** Key [%#] yielded no items.", key);
}
}
contentNode.contentSizeType = CCSizeTypePoints;
contentNode.contentSize = CGSizeMake(width, height);
return contentNode;
}
some notes :
i gave you my 'build content node' routine so you know the ins and outs of positions and sizes.
my charmBoxMenuItemss derive from 'CCButton' and are hot ... In the full version of this code snippet, i extended CCScrollView to prevent the buttons from being 'hot' outside the crop area (although they are cropped out from view, they are still 'visible' by default, and could respond when a random tap occurs above or below the crop area).
For clipping node with stencil, you need to add this in your setupCocos2dWithOptions line:
CCSetupDepthFormat : [NSNumber numberWithUnsignedInt:GL_DEPTH24_STENCIL8_OES]
Attempting to simply have a scene where I have the gameplay, and the hud. Since I have it positioning the scene (which contains both layers), I assume this is why my Menu button is moving even though it's in the Hud Layer.
To fix it I would think that I would maybe have to change this line
[self setCenterOfScreen: mainChar.position];
to something like this:
[gameLayer setCenterOfScreen: mainChar.position];
But then I get this:
No visible #interface for CCNode declares the selector
'setCenterOfScreen:'
Here is the
GameScene (commented where I think issue is):
+ (GameScene *)scene
{
return [[self alloc] init];
}
// -----------------------------------------------------------------------
- (id)init
{
self = [super init];
if (!self) return(nil);
CGSize winSize = [CCDirector sharedDirector].viewSize;
self.userInteractionEnabled = YES;
self.theMap = [CCTiledMap tiledMapWithFile:#"AftermathRpg.tmx"];
self.contentSize = theMap.contentSize;
CCNode *gameLayer = [CCNode node];
gameLayer.userInteractionEnabled = YES;
gameLayer.contentSize = self.contentSize;
[self addChild:gameLayer];
[gameLayer addChild:theMap z:-1];
self.mainChar = [CCSprite spriteWithImageNamed:#"mainChar.png"];
mainChar.position = ccp(200,300);
[gameLayer addChild:mainChar];
// POSSIBLY WHY BOTH LAYERS ARE SHIFTING, RATHER THEN HUD STANDING STILL,
// I essentially want the gameLayer to be centered on screen, not both.
// I tried [gameLayer setCenterOfScreen: mainChar.position] but got error posted above
[self setCenterOfScreen: mainChar.position];
CCNode *hudLayer = [CCNode node];
hudLayer.userInteractionEnabled = YES;
hudLayer.position = ccp(winSize.width * 0.9, winSize.height * 0.9);
[self addChild:hudLayer];
CCButton *backButton = [CCButton buttonWithTitle:#"[ Menu ]" fontName:#"Verdana-Bold" fontSize:18.0f];
backButton.positionType = CCPositionTypeNormalized;
backButton.position = ccp(0.85f, 0.95f); // Top Right of screen
[backButton setTarget:self selector:#selector(onBackClicked:)];
[hudLayer addChild:backButton];
return self;
}
but then I just get:
Just confused on how I would set up a scene, to initially have 2 layers - one that keeps position in say the top right as a HUD, and the other that scrolls with scene for gameplay when telling it to.
This is related to the other question you asked here (Adding a Hud Layer to Scene Cocos2d-3) which I posted the answer to. In the future it is better to modify your original OP in your first question rather than create a new question that is almost the same.
Hope this helped.
I have an iOS endless runner game where the path appears from the top and scrolls down.
Here's how I do it: 2 sprites are created and when the first one disappears from the screen, I load another sprite from an image and run the same logic.
The problem: There's a small lag right after the first sprite disappears and the new one appears.
Edit: This problem only occurs when running on iPhone 5. iPhone 4 works perfectly !
Anyone have any ideas? or has run into this problem before and solved it?
if (CurrentObstacle.frame.origin.y < -self.frame.size.height + 10) {
// clear old obstacle
CurrentObstacle = nil;
CurrentObstacle = nextObstacle;
currentObstacleImage = nextObstacleImage; // for pixel processing stuff
[self generateObstacle];
}
- (void)generateObstacle{
// genrate random image name
int i = rand()%10+1;
NSString *imageName = [NSString stringWithFormat:#"ob%i", i];
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
if(screenSize.height == 480)
{
//Load 3.5 size
imageName = [imageName stringByAppendingString:#"small"];
}
imageName = [imageName stringByAppendingString:#".png"];
// create obstacle
nextObstacle = [SKSpriteNode spriteNodeWithImageNamed:imageName];
nextObstacleImage = [imageDictionary objectForKey:imageName];
nextObstacle.size = self.size;
nextObstacle.position = CGPointMake(self.view.center.x, 1.48*nextObstacle.size.height);
// set speed to be the same as the other obstacles
nextObstacle.speed = CurrentObstacle.speed;
// show obstacle
[self addChild:nextObstacle];
// move obstacle
SKAction *moveAction = [SKAction moveByX:0 y:-2*self.size.height-1 duration:8];
[nextObstacle runAction:moveAction];
}
Ok, solved this problem by removing the #2x images. Apparently processing big images was the cause of the lag.
Hope this helps someone!
You shouldn't load the image each time you want to add an obstacle. You should do a methode like this that you would call at "initWithSize"
//MyScene.h
#interface MyScene : SKScene{
SKTexture * textureObstacle1;
SKTexture * textureObstacle2;
//...//
}
-(id)initWithSize;
-(void)LoadSprites;
#end
//MyScene.m
#implementation MyScene
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
[self LoadSprites];
}
return self;
}
-(void)LoadSprites{
textureObstacle1=[[SKTexture alloc] initWithImageNamed:#"obstacle1.png"];
//...//
}
- (void)generateObstacle{
//...//
nextObstacle = [SKSpriteNode alloc]init];
[nextObstacle setTexture:textureObstacle1];
}
#end
In the iOS game flappy bird, there are pipes that generate after a certain distance and they generate at random heights
I am also trying to make flappy bird pipes (I called it a tree branch in my code instead of pipe). Except the pipes are moving vertically instead of horizontally because it is a vertical scrolling game (it scrolls like the game doodle jump)
This is a drawing of what I want it to be: https://docs.google.com/drawings/d/18bxsVsNOlScCvgi1mwuzD2At7R6xKM3QCh6BfAVMuMo/edit?usp=sharing
(The horizontal lines are the branches)
So this is what I have tried to do so far to make the vertical branches (or pipes)...
in my .h
CCSprite *branch;
NSMutableArray *_branches;
CCSprite *obstacle;
CCNode *previousBranch;
CGFloat previousBranchYPosition;
in my .m
#implementation HelloWorldLayer
static const CGFloat firstBranchPosition = 426.f;
static const CGFloat distanceBetweenBranches = 140.f;
#define ARC4RANDOM_MAX 0x100000000
static const CGFloat minimumXPositionRightBranch = 280.f;
static const CGFloat maximumXPositionLeftBranch = 50.f;
static const CGFloat pipeDistance = 100.f;
static const CGFloat maximumXPositionRightBranch = maximumXPositionLeftBranch - pipeDistance;
setBranchInitialPosition method
/* This is where I am setting the initial position of the branches.
So I am specifying the position of the first branch and the other branches after it so it gets placed every time a certain distance is passed. I have a left branch and a right branch*/
-(void) setBranchInitialPosition {
CGFloat random = ((double)arc4random() / ARC4RANDOM_MAX);
CGFloat range = maximumXPositionRightBranch - minimumXPositionRightBranch;
_rightBranch.position = ccp(minimumXPositionRightBranch + (random * range), _rightBranch.position.y);
_leftBranch.position = ccp(_rightBranch.position.x + pipeDistance, _leftBranch.position.y);
}
spawnNewBranches method
// This is how I want the branches to spawn and I want to add them to an array full of branches
- (void)spawnNewBranches {
previousBranch = [_branches lastObject];
previousBranchYPosition = previousBranch.position.y;
if (!previousBranch) {
// this is the first obstacle
previousBranchYPosition = firstBranchPosition;
}
_rightBranch = [CCSprite spriteWithFile:#"branch.png"];
_leftBranch = [CCSprite spriteWithFile:#"branch.png"];
[_leftBranch addChild:_rightBranch];
[self setBranchInitialPosition];
obstacle = [CCSprite node];
[obstacle addChild:_leftBranch];
obstacle.position = ccp(160, previousBranchYPosition + distanceBetweenBranches);
[self addChild:obstacle];
[_branches addObject:obstacle];
}
scroll method
-(void) scroll:(ccTime)dt
{
// moves the bg
background.position = ccp(screenCenter.x, background.position.y + [[NSUserDefaults standardUserDefaults] integerForKey:#"scrollSpeed"]*dt);
bg2.position = ccp(screenCenter.x, background.position.y-background.contentSize.height);
// it adds the new bg's to the screen before the old bg's move off the screen
if (background.position.y >= screenSize.height*1.5)
{
background.position = ccp(screenCenter.x, (screenCenter.y)-(background.size.height/2));
} else if (bg2.position.y >= screenSize.height*1.5) {
bg2.position = ccp(screenCenter.x, (screenCenter.y)-(bg2.size.height/2));
}
// This is where I want them to appear every certain distance and also move with the brackground
obstacle.position = ccp(obstacle.position.x, obstacle.position.y*[[NSUserDefaults standardUserDefaults] integerForKey:#"scrollSpeed"]*dt);
NSMutableArray *offScreenObstacles = nil;
if (obstacle.position.y >= screenSize.height*1.5) {
[offScreenObstacles addObject:obstacle];
}
for (CCNode *obstacleToRemove in offScreenObstacles) {
[obstacleToRemove removeFromParent];
[_branches removeObject:obstacleToRemove];
// for each removed obstacle, add a new one
[self spawnNewBranches];
}
}
Right now, the branches are appearing, but they stay in the bottom left corner and they dont move or spawn at all. I want to make them move with the background and spawn after a certain distance while also being generated in random heights. I provided you with all my code, do you know how I can make this work? Thanks in advance!
You may want to try placement of the pipes based on a trigonometric curve like sine or cosine (https://en.wikipedia.org/wiki/Trigonometric_functions). It seems like you are placing the pipes within a fairly define random range though if you change this range to an offset from the plot of the trigonometric curve it would take into account the ability of the player to transition between the open gaps better. At least that's my feel. I think the code would be easier to follow as well as I'm a bit confused going through it. You can also easily vary the difficulty of the curve by changing the parameters such as increasing the amplitude or frequency.
I created a copy of Flappy Bird just for fun. I used this code to create the pipes:
-(void)createPipes{
//Create Random
int from = 65;
int max = [[UIScreen mainScreen] bounds].size.height - 124;
int delta = max - from - dy;
int y = from + arc4random() % (delta - from);
//Pipe Bottom
UIImageView *pipeBottom = [[UIImageView alloc] init];
[pipeBottom setContentMode:UIViewContentModeTop];
[pipeBottom setImage:[UIImage imageNamed:#"pipeBottom"]];
[pipeBottom setFrame:CGRectMake(320, y+dy, 60, max - y - dy)];
[pipeBottom setClipsToBounds:YES];
//Pipe Top
UIImageView *pipeTop = [[UIImageView alloc] init];
[pipeTop setFrame:CGRectMake(320, 0, 60, y)];
[pipeTop setContentMode:UIViewContentModeBottom];
[pipeTop setImage:[UIImage imageNamed:#"pipeTop"]];
[self.view insertSubview:pipeTop atIndex:1];
[self.view insertSubview:pipeBottom atIndex:1];
if (!self.pipes)
self.pipes = [[NSMutableArray alloc] init];
[self.pipes addObject:pipeBottom];
[self.pipes addObject:pipeTop];
}
and to move them:
-(void)moveArray:(NSMutableArray *)array{
float ds = dv * dt;
NSMutableArray *trash = [NSMutableArray array];
for (UIImageView *obj in array) {
CGRect frame = obj.frame;
frame.origin.x -= ds;
if (frame.origin.x < -frame.size.width) {
[obj removeFromSuperview];
[trash addObject:obj];
}else{
obj.frame = frame;
}
}
[array removeObjectsInArray:trash];
}
-(void)movePipes{
[self moveArray:self.pipes];
}
I call this function every 0.01 seconds, to run the game:
-(void)runGame{
_time += dt;
if (_time >= 180.0/dv) {
_time = 0;
[self createPipes];
}
[self movePipes];
[self moveEnemies];
[self moveYoshi];
[self moveBar];
[self verifyScore];
[self verifyCollision];
[self verifyState];
}
I defined dt = 0.01 and dv = 110.
You can see my parody in youtube: (http://www.youtube.com/watch?v=tTcYdpSIKJg)
I hope this help you.
Best, Rafael Castro.