ios - Character falling through ground -
i'm using sprite kit part of basic game. game there guy who, depending on tap, moves location. currently, player not affected gravity (for sake of playibility) i'm trying implement gravity. however, when turn gravity on player, i'm having trouble character falling through ground. i've created node ground , have disabled ground physics (ground.physicsbody.dynamic = no) character still flies right on through. i'm using built in sprite-kit gravity feature, , if physics disabled, theoretically character should stop @ ground. i'm @ loss why problem still exists , appreciate on matter.
code in myscene.m file:
// // myscene.m // dodgeman // // created cormac chester on 3/8/14. // copyright (c) 2014 testman industries. rights reserved. // #import "myscene.h" #import "endgamescene.h" static const uint32_t redballcategory = 0x1 << 0; static const uint32_t playercategory = 0x1 << 1; @implementation myscene -(id)initwithsize:(cgsize)size { if (self = [super initwithsize:size]) { //sets data storage self.storedata = [nsuserdefaults standarduserdefaults]; //sets gravity self.physicsworld.gravity = cgvectormake(0,-2); self.physicsworld.contactdelegate = self; //set background self.backgroundcolor = [skcolor colorwithred:0.53 green:0.81 blue:0.92 alpha:1.0]; //set ground skspritenode *ground = [skspritenode spritenodewithimagenamed:@"ground"]; ground.position = cgpointmake(cgrectgetmidx(self.frame), 34); ground.xscale = 0.5; ground.yscale = 0.5; ground.physicsbody = [skphysicsbody bodywithrectangleofsize:ground.size]; ground.physicsbody.dynamic = no; ground.physicsbody.collisionbitmask = 1; ground.physicsbody.usesprecisecollisiondetection = yes; //player self.posx = 50; self.posy = 88; self.playersprite = [skspritenode spritenodewithimagenamed:@"character"]; self.playersprite.position = cgpointmake(self.posx, self.posy); //set player physics self.playersprite.physicsbody = [skphysicsbody bodywithrectangleofsize:self.playersprite.size]; self.playersprite.physicsbody.dynamic = no; self.playersprite.physicsbody.categorybitmask = playercategory; self.playersprite.physicsbody.contacttestbitmask = redballcategory; self.playersprite.physicsbody.collisionbitmask = 0; self.playersprite.physicsbody.usesprecisecollisiondetection = yes; //score label self.scorelabel = [sklabelnode labelnodewithfontnamed:@"arial-boldmt"]; self.scorelabel.text = @"0"; self.scorelabel.fontsize = 40; self.scorelabel.fontcolor = [skcolor blackcolor]; self.scorelabel.position = cgpointmake(50, 260); //pause button self.pausebutton = [skspritenode spritenodewithimagenamed:@"pausebutton"]; self.pausebutton.position = cgpointmake(self.frame.size.width / 2, self.frame.size.height - 40); self.pausebutton.name = @"pausebutton"; //pause label nsstring *pausemessage; pausemessage = @"game paused"; self.pauselabel = [sklabelnode labelnodewithfontnamed:@"arial-boldmt"]; self.pauselabel.text = pausemessage; self.pauselabel.fontsize = 40; self.pauselabel.fontcolor = [skcolor blackcolor]; self.pauselabel.position = cgpointmake(self.size.width/2, self.size.height/2); //set score self.score = 0; //add nodes [self addchild:ground]; [self addchild:self.playersprite]; [self addchild:self.scorelabel]; [self addchild:self.pausebutton]; } return self; } //add red ball -(void)addball { skspritenode *redball = [skspritenode spritenodewithimagenamed:@"locationindicator"]; int miny = redball.size.height / 2; int maxy = self.frame.size.height - redball.size.height / 2; int rangey = maxy - miny; int actualy = (arc4random() % rangey) + miny; //initiates red ball offscreen if (actualy >= 75) { //prevents balls spawning in ground redball.position = cgpointmake(self.frame.size.width + redball.size.width/2, actualy); [self addchild:redball]; } redball.physicsbody = [skphysicsbody bodywithcircleofradius:redball.size.width/2]; redball.physicsbody.dynamic = yes; redball.physicsbody.categorybitmask = redballcategory; redball.physicsbody.contacttestbitmask = playercategory; redball.physicsbody.collisionbitmask = 0; redball.physicsbody.affectedbygravity = no; redball.physicsbody.usesprecisecollisiondetection = yes; //determine speed of red ball int minduration = 3.0; int maxduration = 5.0; int rangeduration = maxduration - minduration; int actualduration = (arc4random() % rangeduration) + minduration; // create actions skaction *actionmove = [skaction moveto:cgpointmake(-redball.size.width/2, actualy) duration:actualduration]; skaction *actionmovedone = [skaction removefromparent]; skaction *ballcross = [skaction runblock:^{ self.score++; self.scorestring = [nsstring stringwithformat:@"%i", self.score]; self.scorelabel.text = self.scorestring; nslog(@"score incremented. score %d", self.score); }]; [redball runaction:[skaction sequence:@[actionmove, ballcross, actionmovedone]]]; } - (void)pausescene { self.paused = yes; [self addchild:self.pauselabel]; } - (void)updatewithtimesincelastupdate:(cftimeinterval)timesincelast { self.lastspawntimeinterval += timesincelast; if (self.lastspawntimeinterval > 0.35) { self.lastspawntimeinterval = 0; [self addball]; } } //update loop -(void)update:(cftimeinterval)currenttime { /* called before each frame rendered */ // handle time delta. cftimeinterval timesincelast = currenttime - self.lastupdatetimeinterval; self.lastupdatetimeinterval = currenttime; if (timesincelast > 1) { //more second since last update timesincelast = 1.0 / 120.0; self.lastupdatetimeinterval = currenttime; } [self updatewithtimesincelastupdate:timesincelast]; } -(void)touchesbegan:(nsset *)touches withevent:(uievent *)event { /* called when touch begins */ [super touchesbegan:touches withevent:event]; //starts timer starttime = [nsdate date]; } -(void)touchesended:(nsset *)touches withevent:(uievent *)event { /* called when touch ends */ [super touchesended:touches withevent:event]; nstimeinterval elapsedtime = [starttime timeintervalsincenow]; nsstring *elapsedtimestring = [nsstring stringwithformat:@"elapsed time: %f", elapsedtime]; nslog(@"%@", elapsedtimestring); (uitouch *touch in touches) { //gets location of touch cgpoint location = [touch locationinnode:self]; nslog(@"touch location x: %f \n touch location y: %f", location.x, location.y); sknode *node = [self nodeatpoint:location]; //runs when pause button pressed if ([node.name isequaltostring:@"pausebutton"]) { nslog(@"pause button pressed"); if (!self.paused) { [self pausescene]; } else if (self.paused) { self.paused = no; [self.pauselabel removefromparent]; } } else { //prevents destination being in ground if (location.y < 88) { location.y = 88; } //moves , animates player int velocity = 1000.0/1.0; nslog(@"velocity: %i", velocity); float realmoveduration = self.size.width / velocity; skaction *actionmove = [skaction moveto:location duration:realmoveduration]; [self.playersprite runaction:[skaction sequence:@[actionmove]]]; } } nslog(@"touch ended"); } //collision between ball , player - player dies - (void)redball:(skspritenode *)redball didcollidewithplayer:(skspritenode *)playersprite { nslog(@"player died"); [redball removefromparent]; [playersprite removefromparent]; //stores final score [self.storedata setobject:self.scorestring forkey:@"scorestringkey"]; sktransition *reveal = [sktransition fadewithduration:0.5]; skscene *endgamescene = [[endgamescene alloc] initwithsize:self.size]; [self.view presentscene:endgamescene transition: reveal]; } - (void)didbegincontact:(skphysicscontact *)contact { skphysicsbody *firstbody, *secondbody; if (contact.bodya.categorybitmask < contact.bodyb.categorybitmask) { firstbody = contact.bodya; secondbody = contact.bodyb; } else { firstbody = contact.bodyb; secondbody = contact.bodya; } //red ball collides player if ((firstbody.categorybitmask & redballcategory) != 0 && (secondbody.categorybitmask & playercategory) != 0) { [self redball:(skspritenode *) firstbody.node didcollidewithplayer:(skspritenode *) secondbody.node]; nslog(@"player , ball collided"); } } @end
i problem due line
self.playersprite.physicsbody.collisionbitmask = 0; instead of set category collisions occur, example
self.playersprite.physicsbody.collisionbitmask = redballcategory;
Comments
Post a Comment