I have been wondering on how to set up a scrolling (Horizontal) Menu. I have seen some tutorials but in Cocos2d and Cocos2d and SpriteKit are completely different things. I am working in swift and have no clue on how to implement this. I saw a GithHub repository which did a scrolling menu tutorial but it was in Objective-C and I know a bit of Objective-C but there was alot of files in the project to convert. Or is it possible to convert the Cocos2d to swift? I was thinking that I may be able to use a UIPageViewController to get my desired effect. If there is anybody out there who knows how to do this.
Thanks!
Here's the Cocos2d Code and the blog post is here.
// get screen size
CGSize screenSize = [CCDirector sharedDirector].winSize;
/////////////////////////////////////////////////
// PAGE 1
////////////////////////////////////////////////
// create a blank layer for page 1
CCLayer *pageOne = [[CCLayer alloc] init];
// create a label for page 1
CCLabelTTF *label = [CCLabelTTF labelWithString:#"Page 1" fontName:#"Arial Rounded MT Bold" fontSize:44];
label.position = ccp( screenSize.width /2 , screenSize.height/2 );
// add label to page 1 layer
[pageOne addChild:label];
/////////////////////////////////////////////////
// PAGE 2
////////////////////////////////////////////////
// create a blank layer for page 2
CCLayer *pageTwo = [[CCLayer alloc] init];
// create a custom font menu for page 2
CCLabelBMFont *tlabel = [CCLabelBMFont labelWithString:#"Page 2" fntFile:#"customfont.fnt"];
CCMenuItemLabel *titem = [CCMenuItemLabel itemWithLabel:tlabel target:self selector:#selector(testCallback:)];
CCMenu *menu = [CCMenu menuWithItems: titem, nil];
menu.position = ccp(screenSize.width/2, screenSize.height/2);
// add menu to page 2
[pageTwo addChild:menu];
////////////////////////////////////////////////
// now create the scroller and pass-in the pages (set widthOffset to 0 for fullscreen pages)
CCScrollLayer *scroller = [[CCScrollLayer alloc] initWithLayers:[NSMutableArray arrayWithObjects: pageOne,pageTwo,pageThree,nil] widthOffset: 230];
// finally add the scroller to your scene
[self addChild:scroller];
Click for the The GithHub Project
Related
I am new in cocos2d iPhone development.My question is how to use CCSlider in Cocos2d v3.2.
CCSlider has only two parameter (background spriteFrame and HandleImage).How we can change the colour/Image of slider when we change the Thumb position.How we can differentiate between empty and full bars, how to make progress of filling?
Suppose I want to use to colour like red(Empty) and green(Fill)/two different images for slider.By default the slider colour is red means the slider value is 0.0f(Empty).if I increase the value of slider then the slider colour will change to green(Fill) from position 0.0 to current thumb position.Please help me.sorry for my question i am very week in english
Thank You.
Here is how i use CCSlider for volume control. This code is in the init method of a GameOptions menu class:
CCSpriteFrame *frRuler = [CCSpriteFrame frameWithImageNamed:#"slider_track.png"];
CCSpriteFrame *frKnob = [CCSpriteFrame frameWithImageNamed:#"slider_knob.png"];
_mainGain = [[CCSlider alloc] initWithBackground:frRuler andHandleImage:frKnob];
[self addChild:_mainGain];
[_mainGain setTarget:self selector:#selector(onMainGainChange:)];
_mainGain.anchorPoint = ccp(.5, .5);
_mainGain.visible = YES;
_mainGain.positionType = CCPositionTypePoints;
_mainGain.position = ccp(kScreenWidth / 2, kScreenHeight / 2 - 55);
_mainGain.continuous = YES;
_mainGain.sliderValue = _battlesSettings.audio.masterVolumeGain; // initial
with the following method to receive the slider control 'slide' events :
- (void)onMainGainChange:(id)sender {
CCSlider *sl = (CCSlider *) sender;
_battlesSettings.audio.masterVolumeGain = sl.sliderValue;
_isSettingsDirty = YES;
}
I just saw Facebook's new paper app that makes images move based on the parallax effect. So it zoom's the image to full screen and when you tilt the screen, it scrolls the image to the side you tilted. I have been able to add the parallax effect like apple has it, but not like how facebook has it. Does anyone have any ideas how they did this. Here is the basic code I was using for parallax:
UIInterpolatingMotionEffect *interpolationHorizontal = [[UIInterpolatingMotionEffect alloc]initWithKeyPath:#"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
interpolationHorizontal.minimumRelativeValue = #-10.0;
interpolationHorizontal.maximumRelativeValue = #10.0;
UIInterpolatingMotionEffect *interpolationVertical = [[UIInterpolatingMotionEffect alloc]initWithKeyPath:#"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
interpolationVertical.minimumRelativeValue = #-10.0;
interpolationVertical.maximumRelativeValue = #10.0;
[self.backgroundView addMotionEffect:interpolationHorizontal];
[self.backgroundView addMotionEffect:interpolationVertical];
Update:
Just found a very nice 3rd party library for achieving this, it's called CRMotionView, it works very smooth and you can modify a lot of things.
here is the github link: https://github.com/chroman/CRMotionView
==================================================================================
i was thinking the same parallax when i first saw Facebook paper app. but after play with my code for a little bit, i don't think parallax is what we looking for. I could be wrong, but i went to do it all from the base, gyro motion manager. Here is my sample code:
//import the motion manager frame work first
#import <CoreMotion/CoreMotion.h>
//then need to add a motionManager
#property (strong, nonatomic) CMMotionManager *motionManager;
//you can paste all those codes in view did load
//i added a scroll view on the view controller nib file
self.mainScrollView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
//we don't want it to bounce at each end of the image
self.mainScrollView.bounces = NO;
//and we don't want to allow user scrolling in this case
self.mainScrollView.userInteractionEnabled = NO;
//set up the image view
UIImage *image= [UIImage imageNamed:#"YOUR_IMAGE_NAME"];
UIImageView *movingImageView = [[UIImageView alloc]initWithImage:image];
[self.mainScrollView addSubview:movingImageView];
//set up the content size based on the image size
//in facebook paper case, vertical rotation doesn't do anything
//so we dont have to set up the content size height
self.mainScrollView.contentSize = CGSizeMake(movingImageView.frame.size.width, self.mainScrollView.frame.size.height);
//center the image at intial
self.mainScrollView.contentOffset = CGPointMake((self.mainScrollView.contentSize.width - self.view.frame.size.width) / 2, 0);
//inital the motionManager and detec the Gyroscrope for every 1/60 second
//the interval may not need to be that fast
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.gyroUpdateInterval = 1/60;
//this is how fast the image should move when rotate the device, the larger the number, the less the roation required.
CGFloat motionMovingRate = 4;
//get the max and min offset x value
int maxXOffset = self.mainScrollView.contentSize.width - self.mainScrollView.frame.size.width;
int minXOffset = 0;
[self.motionManager startGyroUpdatesToQueue:[NSOperationQueue currentQueue]
withHandler:^(CMGyroData *gyroData, NSError *error) {
//since our hands are not prefectly steady
//so it will always have small rotation rate between 0.01 - 0.05
//i am ignoring if the rotation rate is less then 0.1
//if you want this to be more sensitive, lower the value here
if (fabs(gyroData.rotationRate.y) >= 0.1) {
CGFloat targetX = self.mainScrollView.contentOffset.x - gyroData.rotationRate.y * motionMovingRate;
//check if the target x is less than min or larger than max
//if do, use min or max
if(targetX > maxXOffset)
targetX = maxXOffset;
else if (targetX < minXOffset)
targetX = minXOffset;
//set up the content off
self.mainScrollView.contentOffset = CGPointMake(targetX, 0);
}
}];
I tested this on my device, worked pretty similar like facebook new app.
However, this is just an example code i wrote in half hour, may not be 100% accurate, but hope this would give you some ideas.
Im adding views to an animator like so:
-(void)drawCellLikeViews{
//2. Add Animator
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self];
//Alloc array
viewsArray = [[NSMutableArray alloc] initWithCapacity:6];
for (int numberOfViews = 0; numberOfViews < 5; numberOfViews++) {
//Create views
UIView* cell = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 70)];
cell.backgroundColor = [UIColor grayColor];
[self addSubview:cell];
[viewsArray addObject:cell];
}
//3. Add Gravity
_gravity = [[UIGravityBehavior alloc] initWithItems:viewsArray];
[_animator addBehavior:_gravity];
//4. Add boundaries
_collision = [[UICollisionBehavior alloc] initWithItems:viewsArray];
_collision.translatesReferenceBoundsIntoBoundary = YES;
[_animator addBehavior:_collision];
//8. Add ItemProperties' Behaviors
UIDynamicItemBehavior* itemBehaviour = [[UIDynamicItemBehavior alloc] initWithItems:viewsArray];
itemBehaviour.elasticity = 0.6;
//9. itemBehaviour.action = ^{};
[_animator addBehavior:itemBehaviour];
NSLog(#"viewcount %d", [[self subviews] count]);
}
I only see one drop down to the bottom.
#HalR is correct—your views are being added to the animator; they're just all being added at the same time with the same starting attributes, so they will all behave in exactly the same way and appear as one item. And yes, by default, the collision behavior's mode is UICollisionBehaviorModeEverything, meaning its items should collide with each other and with the boundaries. Yet, by implying UICollisionBehaviorModeEverything and placing all of the items on top of each other, you've created an impossible scenario wherein you've explicitly told the edges of each item to overlap, but you've told the animator that they're not allowed to overlap. The animator's behavior at that point is undefined—I think it just ignores whatever physics rule you've manually broken, but it can get much weirder than that. In WWDC 2013 Session 206 (Getting Started with UIKit Dynamics), Apple at one point says "don't expect the impossible" saying that "you can create setups which don't have solutions" and showing overlapping items with collision behaviors set as an example. In other words, they saw this coming, and they just don't want you to do it. ;)
The way to make this work, of course, would just be to give each of the items a starting position that doesn't overlap with other items' starting positions, or to add them all to where you're adding them now, only a few seconds apart from each other so the last one can fall out of the way.
Hello I am making a side scrolling cocos2d game and I want a label to show how far the user has flown in the game. For some reason with the code I wrote the label is not appearing. Here is my GameEngine class that calls the class method that is supposed to make the label appear:
//Set the meterDistance
meterDistance = [MeterDistance createTheMeterDistance];
[self addChild:meterDistance z:10];
Here is the code in the MeterDistance class:
meters = 1;
meterLabel = [CCLabelBMFont labelWithString:#"0" fntFile:#"green_arcade-ipad.fnt"];
meterLabel.position = ccp(200, screenHeight - 100);
[self addChild:meterLabel z:10];
meterLabel.anchorPoint = ccp(1.0, 0.5);
[self schedule:#selector(updateLabel:)interval:1.0f/20.0f];
Here is the updateLabel method:
-(void)updateLabel:(ccTime)delta{
meters++;
NSString* scoreString = [NSString stringWithFormat:#"%d", meters];
[meterLabel setString:scoreString];
}
It's been a while since I last dealt with cocos2d code...
What you've written looks ok.
Take it one step at a time and see where it goes wrong.
Position your label in the middle of the screen (maybe screenheight is off, or anchorPoint moves the label outside of the screen).
Another possible cause is if the font file name is not exactly #"green_arcade-ipad.fnt".
Maybe you missed a capital letter?
Otherwise maybe some other element of your layer could be obstructing the label.
I'm using altered sample code from PhotoScroller within my app. I have a table view of image thumbnails, and I can pass the array of images that populate that table to PhotoViewController. Currently, PhotoViewController starts with the first image in my array and I can scroll back and forth. This works properly as Apple's sample code.
Now What I want to do is tap a table cell with thumbnail, and start scrolling images beginning with the image in my array at that index. Ex: if I have 5 images in a table and I tap image #3, I want the first image in PhotoViewController to be that third image, and able to scroll left or right to #2 or #4. Hope this makes sense.
I see in PhotoViewController that sub views are being added per image. Any way I can tell it "jump to view #3" without destroying the other views or their overall order of appearance? Any ideas or advice is welcome. Code can be found on the iOS developer site for PhotoScroller sample code.
Ok, I'm rambling... Thanks in advance for your help!
The way I do this is to have a variable called startingPage which gets set in the initialiser of the photo view controller. Then when the pages are being created, first set the correct offset for the scroll view.
So in the PhotoScroller case that would be in loadView. Like so:
- (void)loadView
{
// Step 1: make the outer paging scroll view
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView.pagingEnabled = YES;
pagingScrollView.backgroundColor = [UIColor blackColor];
pagingScrollView.showsVerticalScrollIndicator = NO;
pagingScrollView.showsHorizontalScrollIndicator = NO;
pagingScrollView.contentSize = [self contentSizeForPagingScrollView];
pagingScrollView.delegate = self;
self.view = pagingScrollView;
// Set the content offset of the scrollview
CGRect bounds = pagingScrollView.bounds;
CGPoint contentOffset = CGPointMake(bounds.size.width * startingPage, 0.0f);
[pagingScrollView setContentOffset:contentOffset animated:NO];
// Step 2: prepare to tile content
recycledPages = [[NSMutableSet alloc] init];
visiblePages = [[NSMutableSet alloc] init];
[self tilePages];
}