I'm trying make a MegaMan-like game with Cocos2d-x and trying to make it work on an Android device.
The thing is, I can press the buttons seperatly and there's no problem whatsover, but when I'm running left/right and also press jump the player stops moving.
When I manually set right=true and jump=true the player makes a nice looking jump to the right, so the if else stuff is executed good.
Here's what I do in init()
//add controls
buttonLeft = CCMenuItemImage::create(
"button_left.png",
"button_left.png");
buttonLeft->setPosition( ccp(buttonLeft->getContentSize().width/2, buttonLeft->getContentSize().height/2) );
buttonRight = CCMenuItemImage::create(
"button_right.png",
"button_right.png");
buttonRight->setPosition( ccp(buttonRight->getContentSize().width/2 + buttonLeft->getContentSize().width, buttonRight->getContentSize().height/2) );
CCMenu* controlMenu1 = CCMenu::create(buttonLeft, buttonRight, NULL);
controlMenu1->setPosition(CCPointZero);
this->addChild(controlMenu1, 1);
buttonJump = CCMenuItemImage::create(
"button_jump.png",
"button_jump.png");
buttonJump->setPosition(ccp(winSize.width - buttonJump->getContentSize().width/2, buttonJump->getContentSize().height/2));
CCMenu* controlMenu2 = CCMenu::create(buttonJump, NULL);
controlMenu2->setPosition(CCPointZero);
this->addChild(controlMenu2, 1);
And I got this scheduled every 0.02 seconds:
void BeginScene::updatePlayerMove(float dt)
{
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
int newYpos;
int maxYpos;
int minYpos;
int newXpos;
int maxXpos;
int minXpos;
if(buttonJump->isSelected() && !maxJumpReached){
//jump
if(playerMoveAction != NULL){
player->stopAction(playerMoveAction);
playerMoveAction = NULL;
}
if(playerJumpAction != NULL){
player->stopAction(playerJumpAction);
playerJumpAction = NULL;
}
if(buttonLeft->isSelected()){
player->setTexture(CCTextureCache::sharedTextureCache()->addImage("player2.png"));
minXpos = player->getContentSize().height/2;
newXpos = player->getPosition().x - PIXELS_PLAYER_MOVES;
if(newXpos < minXpos){
newXpos = minXpos;
}
}else if(buttonRight->isSelected()){
player->setTexture(CCTextureCache::sharedTextureCache()->addImage("player1.png"));
maxXpos = winSize.width - player->getContentSize().height/2;
newXpos = player->getPosition().x + PIXELS_PLAYER_MOVES;
if(newXpos > maxXpos){
newXpos = maxXpos;
}
}else{
newXpos = player->getPosition().x;
}
maxYpos = player->getContentSize().height/2 + closestGround + MAX_JUMP_HEIGHT;
newYpos = player->getPosition().y + PIXELS_PLAYER_MOVES;
if(newYpos > maxYpos){
newYpos = maxYpos;
maxJumpReached = true;
}
CCPoint destination = ccp(newXpos, newYpos);
float lengthX = destination.x - player->getPosition().x;
float lengthY = destination.y - player->getPosition().y;
float length = sqrtf((lengthX * lengthX) + (lengthY*lengthY));
float duration = length/DURATION_DIVIDER;
playerJumpAction = player->runAction( CCSequence::create(
CCMoveTo::create(duration, destination),
CCCallFuncN::create(this, NULL),
NULL) );
}else if(!buttonJump->isSelected() || maxJumpReached){ //basicly: if not jumping -> gravity will pull always)
//descent
if(playerMoveAction != NULL){
player->stopAction(playerMoveAction);
playerMoveAction = NULL;
}
if(playerJumpAction != NULL){
player->stopAction(playerJumpAction);
playerJumpAction = NULL;
}
if(buttonLeft->isSelected()){
player->setTexture(CCTextureCache::sharedTextureCache()->addImage("player2.png"));
minXpos = player->getContentSize().height/2;
newXpos = player->getPosition().x - PIXELS_PLAYER_MOVES;
if(newXpos < minXpos){
newXpos = minXpos;
}
}else if(buttonRight->isSelected()){
player->setTexture(CCTextureCache::sharedTextureCache()->addImage("player1.png"));
maxXpos = winSize.width - player->getContentSize().height/2;
newXpos = player->getPosition().x + PIXELS_PLAYER_MOVES;
if(newXpos > maxXpos){
newXpos = maxXpos;
}
}else{
newXpos = player->getPosition().x;
}
minYpos = player->getContentSize().height/2 + closestGround;
newYpos = player->getPosition().y - PIXELS_PLAYER_MOVES;
if(newYpos < minYpos){
newYpos = minYpos;
maxJumpReached = false;
jumpButtonPressed = false;
}
CCPoint destination = ccp(newXpos, newYpos);
float lengthX = destination.x - player->getPosition().x;
float lengthY = destination.y - player->getPosition().y;
float length = sqrtf((lengthX * lengthX) + (lengthY*lengthY));
float duration = length/DURATION_DIVIDER;
playerDescentAction = player->runAction( CCSequence::create(
CCMoveTo::create(duration, destination),
CCCallFuncN::create(this, NULL),
NULL) );
}else if(buttonLeft->isSelected()){
//left
minXpos = player->getContentSize().height/2;
newXpos = player->getPosition().x - PIXELS_PLAYER_MOVES;
if(newXpos < minXpos){
newXpos = minXpos;
}
player->setTexture(CCTextureCache::sharedTextureCache()->addImage("player2.png"));
CCPoint destination = ccp(newXpos, player->getPosition().y);
float lengthX = destination.x - player->getPosition().x;
float lengthY = destination.y - player->getPosition().y;
float length = sqrtf((lengthX * lengthX) + (lengthY*lengthY));
float duration = length/DURATION_DIVIDER;
playerMoveAction = player->runAction( CCSequence::create(
CCMoveTo::create(duration, destination),
CCCallFuncN::create(this, NULL),
NULL) );
}else if(buttonRight->isSelected()){
//right
maxXpos = winSize.width - player->getContentSize().height/2;
newXpos = player->getPosition().x + PIXELS_PLAYER_MOVES;
if(newXpos > maxXpos){
newXpos = maxXpos;
}
player->setTexture(CCTextureCache::sharedTextureCache()->addImage("player1.png"));
CCPoint destination = ccp(newXpos, player->getPosition().y);
float lengthX = destination.x - player->getPosition().x;
float lengthY = destination.y - player->getPosition().y;
float length = sqrtf((lengthX * lengthX) + (lengthY*lengthY));
float duration = length/DURATION_DIVIDER;
playerMoveAction = player->runAction( CCSequence::create(
CCMoveTo::create(duration, destination),
CCCallFuncN::create(this, NULL),
NULL) );
}
}
It seems that it's only not working on my old LG, but works perfectly on my Galaxy s2 and tablet...
so probably my LG is too old :P
Related
I am trying to make a jump game in Xcode 5 with SpriteKit.
First I want to spawn Blocks in a random position, but reachable for the 'human' in the game that is jumping.
I got a 1. Block, that spawn at a set position. From this position, there should spawn a 2. Block, that can be + or - 80 higher or lower, and < 80 away. Now here is the problem, I don`t know how to code it in Xcode. My code so far :
SKTexture * BlockTexture1 = [SKTexture textureWithImageNamed:#"Block"];
BlockTexture1.filteringMode = SKTextureFilteringNearest;
SKTexture * BlockTexture2 = [SKTexture textureWithImageNamed:#"Block"];
BlockTexture2.filteringMode = SKTextureFilteringNearest;
SKSpriteNode * Block1 = [SKSpriteNode spriteNodeWithTexture:BlockTexture1];
[Block1 setScale:1];
Block1.position = CGPointMake( 100 , 150 );
Block1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:Block1.size];
Block1.physicsBody.dynamic = NO;
Block1.physicsBody.usesPreciseCollisionDetection = YES;
Block1.zPosition = 3;
[self addChild:Block1];
SKSpriteNode * Block2 = [SKSpriteNode spriteNodeWithTexture:BlockTexture2];
[Block2 setScale:1];
Block2.position = CGPointMake( **Block1 + or - 80, Block 1 < 80** );
Block2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:Block2.size];
Block2.physicsBody.dynamic = NO;
Block2.physicsBody.usesPreciseCollisionDetection = YES;
Block2.zPosition = 3;
[self addChild:Block2];
To get your started, something like this perhaps:
int block1x = 100;
int block1y = 150;
Block1.position = CGPointMake(block1x, block1y);
int block2x = 0;
int block2y = 0;
int r1 = arc4random() % 2; // produces random numbers between 0 and 1
if(r1 == 0)
block2x = block1x + 80;
if(r1 == 1)
block2x = block1x - 80;
int r2 = arc4random() % 2;
if(r2 == 0)
block2y = block1y + 80;
if(r2 == 1)
block2y = block1y - 80;
Block2.position = CGPointMake(block2x, block2y);
I am developing a game that uses the gyroscope to keep enemies in relatively the same place, with the following code:
if([motionManager isGyroAvailable])
{
[motionManager setGyroUpdateInterval:0.05];
[motionManager startGyroUpdatesToQueue:[NSOperationQueue mainQueue]
withHandler:^(CMGyroData *gyroData, NSError *error)
{
valueX3 = gyroData.rotationRate.y* 50;
valueY3 = gyroData.rotationRate.x* 50;
int newX3 = (int)(enemyufoG.center.x +valueY3);
int newY3 = (int)(enemyufoG.center.y -valueX3);
CGPoint newCenter2 = CGPointMake(newX3, newY3);
enemyufoG.center = newCenter2;
valueX2 = gyroData.rotationRate.y* 50;
valueY2 = gyroData.rotationRate.x* 50;
int newX2 = (int)(enemyufoR.center.x +valueY2);
int newY2 = (int)(enemyufoR.center.y -valueX2);
CGPoint newCenter = CGPointMake(newX2, newY2);
enemyufoR.center = newCenter;
valueX = gyroData.rotationRate.y* 50;
valueY = gyroData.rotationRate.x* 50;
int newX = (int)(enemyAlien.center.x +valueY);
int newY = (int)(enemyAlien.center.y -valueX);
CGPoint newCenter3 = CGPointMake(newX, newY);
enemyAlien.center = newCenter3;
}];
}
Once you shoot an enemy that is in the crosshairs of the gun, it hides the UIImageView, then uses NSTimer to call a different method that shows it again. I would like to have the enemies reappear in random positions on the screen.
CGPoint pos = enemyAlien.center;
if ((pos.x > 254) && (pos.x < 304) && (pos.y > 140) && (pos.y < 160 && _ammoCount != 0))
{
enemyAlien.hidden = YES;
[dangerBar setProgress:dangerBar.progress-0.10];
_killCount = _killCount+3;
[killCountField setText: [NSString stringWithFormat:#"%d", _killCount]];
timer = [NSTimer scheduledTimerWithTimeInterval: 4.0
target: self
selector: #selector(showAlien)
userInfo: nil
repeats: NO];
}
- (void) showAlien {
enemyAlien.hidden = NO;
}
When I try and use enemyAlien.center = enemyAlien.center + arc4random()%100; above enemyAlien.hidden = NO, I get the following error:
'Invalid operands to binary expression ('CGPoint (aka 'struct CGPoint') and 'unsigned int').
You're trying to add an integer to a cgpoint.
try this.
enemyAlien.center = CGPointMake(enemyAlien.center.x + (arc4random()%100),enemyAlien.center.y + (arc4random()%100));
although this will only move the alien in a diagonal direction. You should probably change it to the following for a better experience.
enemyAlien.center = CGPointMake((arc4random()%SCREEN_WIDTH),(arc4random()%SCREEN_HEIGHT));
where SCREEN_WIDTH and SCREEN_HEIGHT are the dimensions of your playing field.
Ok, so I have these powerups that I want to slow/speed up the movement of the other objects in the game for a few seconds.
I have an array of objects that I have a variable called spawnInterval that gets faster and faster as the game progresses, making the ame get harder after a few mins.
But I can't really grasp how to make it so the character in the game will react differently to different objects as in when the fastPowerUp is hit by the character sprite, the spawn interval doesn't change.
And vice versa with the slowPowerUp.
the code I have at the moment is this in a move sequence method that gets called in an update method:
-
(void) updateObstacles:(ccTime)delta{
for (int i = 0; i < 20; i++) {
//int randomizer = CCRANDOM_0_1() * [obstacles count];
//NSLog(#"randomizer: %i",randomizer);
CCSprite* randomObject = [obstacles randomObject];
currentObject = [obstacles indexOfObject:randomObject];
if ([randomObject numberOfRunningActions] == 0) {
[self runObstacleMoveSequence:randomObject withTimer:delta];
break;
}
}
}
-(void) runObstacleMoveSequence:(CCSprite *)object withTimer:(ccTime)delta{
static int time;
//Slowly increase object speed
numObstaclesMoved++;
if (!slowPowerUp && !fastPowerUp) {
time += delta;
if (numObstaclesMoved % 17 == 0 && obstacleMoveDuration > 2.0f) {
obstacleMoveDuration -= 0.2f;
if (spawnInterval > 0.1f) {
[self unschedule:#selector(updateObstacles:)];
[self schedule:#selector(updateObstacles:) interval:spawnInterval];
spawnInterval-=0.1f;
NSLog(#"interval: %f",spawnInterval);
}
}
}else if (slowPowerUp && !fastPowerUp) {
if (numObstaclesMoved % 17 == 0 && obstacleMoveDuration > 2.0f) {
obstacleMoveDuration += 3.0f;
if (spawnInterval > 0.1f) {
[self unschedule:#selector(updateObstacles:)];
[self schedule:#selector(updateObstacles:) interval:spawnInterval];
spawnInterval-=0.1f;
NSLog(#"interval: %f",spawnInterval);
if (time >= (delta + 3)) {
slowPowerUp = NO;
obstacleMoveDuration -= 3.0f;
}
}
}
}else if (!slowPowerUp && fastPowerUp) {
if (numObstaclesMoved % 17 == 0 && obstacleMoveDuration > 2.0f) {
obstacleMoveDuration -= 3.0f;
if (spawnInterval > 0.1f) {
[self unschedule:#selector(updateObstacles:)];
[self schedule:#selector(updateObstacles:) interval:spawnInterval];
spawnInterval-=0.1f;
NSLog(#"interval: %f",spawnInterval);
if (time >= (delta + 3)) {
fastPowerUp = NO;
obstacleMoveDuration += 3.0f;
}
}
}
}
CGSize screenSize = [[CCDirector sharedDirector]winSize];
CGPoint aboveScreenPosition = CGPointMake(object.position.x, screenSize.height - object.position.y);
int rotations = (CCRANDOM_0_1()*3) * 360;
float duration = (CCRANDOM_0_1()*5.0f) + 8.0f;
CCMoveTo* move = [CCMoveTo actionWithDuration:obstacleMoveDuration position:aboveScreenPosition];
CCRotateTo* rotate = [CCRotateBy actionWithDuration:duration angle:rotations];
CCSpawn* moveRotate = [CCSpawn actions: move, rotate, nil];
CCCallFuncN* call = [CCCallFuncN actionWithTarget:self selector:#selector(objectAboveScreen:)];
CCSequence* sequence = [CCSequence actions:moveRotate, call, nil];
[object runAction:sequence];
if (time >= (delta + 3)) {
fastPowerUp = NO;
}
}
-(void) objectAboveScreen:(id) sender{
//make sure sender is actually of the right class
NSAssert([sender isKindOfClass:[CCSprite class]], #"sender is not a CCSprite!");
CCSprite* obstacle = (CCSprite*)sender;
//move the back to the bottom of the screen
CGPoint pos = obstacle.position;
CGSize screenSize = [[CCDirector sharedDirector]winSize];
pos.y = (-screenSize.height - [obstacle texture].contentSize.height);
pos.x = CCRANDOM_0_1() * screenSize.width;
obstacle.position = pos;
}
I really just don't know where to go from here... Should I make the powerUps a different class? If so, how would I implement something like this? I really hate trying to ask for someone to solve my question, but I really just can't rack my brain around this and I'm rather new... if it were explained to me, then I know I would be able to implement it in future games on my own...
Thanks in advance, and let me know if more information is needed...
I'd do something like
in the .h file
float speedModifier;
-(void)resetPowerUp;
in the .m
-(void)resetPowerUp
{
speedModifier = 1;
}
wherever you are initializing the level
[self resetPowerUp];
upon collision with powerup:
speedModifier = 2;
[self performSelector:#selector(resetPowerUp) withObject:nil afterDelay:5];
then wherever you are moving whatever it is which speed should be effected by the powerup mode, multiply the speed of the animation (or divide the duration it takes for it to get wherever it's going) by speedModified
hope that helps
i am new in iphone,i am using horizontal scrollview these are horizontally scrolling properly
but i want these horizontally scrolling on previous and next button action.please help me asap.
Thanks:)
Here are the steps that was worked for me
in .h file write following code.
int scrollMove;
UIScrollView *aScrView;
-(IBAction)nextBtnAction:(id)sender;
-(IBAction)previousBtnAction:(id)sender;
in .m file
- (void)viewDidLoad
{
[super viewDidLoad];
scrollMove=50;
aScrView=[[UIScrollView alloc]init];
aScrView.frame=CGRectMake(25,50, 270, 50);
aScrView.delegate=self;
aScrView.contentSize=CGSizeMake(1200, 0);
[self.view addSubview:aScrView];
// Do any additional setup after loading the view from its nib.
}
-(IBAction)nextBtnAction:(id)sender{
float coordinate = 2.0f;
//scrollMove=50;
[aScrView setContentOffset:CGPointMake(scrollMove * coordinate, 0) animated:YES];
scrollMove=scrollMove+50;
}
-(IBAction)previousBtnAction:(id)sender{
float coordinate = 1.0f;
[aScrView setContentOffset:CGPointMake(scrollMove * coordinate, 0) animated:YES];
scrollMove=scrollMove-50;
}
Hope this helps you!!!
Use this one when you want to go on next visible content of Scroll view:
(Put this one inside next button method)
float coordinate = 2.0f;
[nodeScrollView setContentOffset:CGPointMake(460 * coordinate, 0) animated:YES];
move on previous visible content view:
float coordinate = 1.0f;
[nodeScrollView setContentOffset:CGPointMake(460 * coordinate, 0) animated:YES];
(Put this one inside previous button method)
**You need some mathematical calculation with coordinate
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * pageNumberYouWantToGoTo;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
- (void)viewDidLoad
{
x=0;
y=320;
}
- (IBAction)next:(id)sender
{
y=320;
[scrl_Knot setContentOffset:CGPointMake(x+320,0) animated:YES];
x+=320;
}
- (IBAction)pre:(id)sender
{
x=0;
[scrl_Knot setContentOffset:CGPointMake(y,0) animated:YES];
y-=320;
}
- (IBAction)pre:(id)sender
{
btnNext.enabled = TRUE;
imageID--;
[scrl_venuelist setContentOffset:CGPointMake(imageID*273, 0) animated:YES];
pagecontrol.currentPage=imageID;
if(imageID <= 0)
{
btnPrevious.enabled = FALSE;
}
}
- (IBAction)next:(id)sender
{
btnPrevious.enabled = TRUE;
imageID++;
[scrl_venuelist setContentOffset:CGPointMake(imageID*273, 0) animated:YES];
pagecontrol.currentPage=imageID;
if(imageID >= imageArr.count-1)
{
btnNext.enabled = FALSE;
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
{
imageID = scrollView.contentOffset.x / scrollView.frame.size.width;
pagecontrol.currentPage=imageID;
if(imageID <= 0)
{
btnPrevious.enabled = FALSE;
imageID = 0;
}
else
{
btnPrevious.enabled = TRUE;
}
if(imageID >= imageArr.count-1)
{
btnNext.enabled = FALSE;
imageID = imageArr.count-1;
}
else
{
btnNext.enabled = TRUE;
}
}
- (void)viewDidLoad
{
scrl_venuelist.delegate=self;
scrl_venuelist.contentSize =CGSizeMake(273 * [imageArr count], 137);
if(imageID == 0)
{
btnPrevious.enabled = FALSE;
if(imageID == imageArr.count-1)
{
btnNext.enabled = FALSE;
}
}
else if(imageID == imageArr.count-1)
{
btnNext.enabled = FALSE;
}
else if(imageID > imageArr.count-1)
{
imageID = [imageArr count]-1;
}
scrl_venuelist.pagingEnabled=YES;
pagecontrol.numberOfPages=[imageArr count];
pagecontrol.currentPage=0;
}
If Any one Looking for way of doing in C# for Xamarin
public int CurrentIndex
{
get => (int)Math.Round(this.scrollView.ContentOffset.X / this.scrollView.Frame.Width);
set => this.scrollView.ScrollRectToVisible(new CGRect(new CGPoint(this.scrollView.Frame.Size.Width * value, 0), this.scrollView.Frame.Size), true);
}
This getter and Setter should provide you current page as well let you scroll to the specified page
On Button Actions Just Update Current Index to new Values, Which could current Index +1/-1.
Can someone please explain to me why my variable called activity is 0 when defined as a float, but displays the correct value when defined as an int? I have another float which is used for pretty much the same thing but works perfectly!
#implementation AppPrefsViewController
float age;
int activity;
...
-(void) updateAValues{
if (selectedActivityUnit == 0){
activity = 50;
NSLog(#"activity = %d",activity);
}
if (selectedActivityUnit == 1){
activity = 75;
NSLog(#"activity = %d",activity);
}
}
....
- (void)updateLabel {
if (selectedUnit == 0) {
subView.hidden = YES;
age = 1;
NSLog(#"age = %d",age);
}
if (selectedUnit == 1) {
subView.hidden = YES;
age = 2;
NSLog(#"age = %d",age);
}
if (selectedUnit == 2) {
subView.hidden = NO;
age = 3;
NSLog(#"age = %d",age);
}
}
You're using
NSLog(#"activity = %d", activity);
To display your values. This works if activity is an int type as %d is for displaying ints. If you want to display floats you need the float formater %f, as in:
NSLog(#"activity = %f", activity);