27th December 2008

Gravity Tutorial for iPhone Part 1

posted in Objective C, iPhone |

In order to not make this tutorial book length, I'm going to start with some assumptions.

1. That you have a Mac.
2. That you have XCode and the iPhone SDK installed.
3. That you have some familiarity with the environment and Objective C 2.0. Not much, but at least SOME. If you do a couple of Hello World tutorials on the net, you should be fine.

Also, see this note.

OK, let's get started.

So, fire up XCode and start a new View-Based Application. Call it GravityTutorial or whatever.

The first thing we'll need to do is make a class to hold the ball. Add a new file to the classes folder. NSObject subclass, name it Ball. This will create two files: Ball.h and Ball.m. The header and the implementation file.

We'll add some properties to the ball for its position, velocity, radius, and color in Ball.h:

C:
  1. #import <Foundation/Foundation.h>
  2.  
  3.  
  4. @interface Ball : NSObject {
  5.     CGPoint position;
  6.     CGPoint velocity;
  7.     CGFloat radius;
  8.     CGColorRef color;
  9. }
  10.  
  11. @property CGPoint position;
  12. @property CGPoint velocity;
  13. @property CGFloat radius;
  14. @property CGColorRef color;
  15.  
  16. @end

First we declare them in the interface block, then we use the @property directive, which is one step in making automatic getter/setters. Since we are using Core Graphics for this, we'll keep everything as CG types.

Now, the implementation in Ball.m:

C:
  1. #import "Ball.h"
  2.  
  3.  
  4. @implementation Ball
  5. @synthesize position;
  6. @synthesize velocity;
  7. @synthesize radius;
  8. @synthesize color;
  9.  
  10. @end

The @synthesize directive is the second part of making the getter/setters. Congratulations. You made a custom class with public properties. Now we can make an instance of it and customize it.

If you named your project GravityTutorial, you'll have a GravityTutorialViewController class, consisting again of an .h and an .m file. Let's declare the ball in the header, GravityTutorialViewController.h - don't forget to import the Ball.h file so the Ball class will be available here.

C:
  1. #import <UIKit/UIKit.h>
  2. #import "Ball.h"
  3.  
  4. @interface GravityTutorialViewController : UIViewController {
  5.     Ball *ball;
  6. }
  7.  
  8. @end

Note that ball is of type Ball *, or a pointer to a Ball object. I'm not going to go into pointer theory here, but in general, dynamically created class instances like this will be pointers. This mainly comes into play when creating them and casting them. You'll get used to it. Since we are not using ball outside of the view controller class, we don't have to create a property for it or synthesize it. It will just be a private variable.

Then we'll create the instance in the implementation (.m) file. The best place to do this is in the viewDidLoad method. By the time this method is called, your application has generally done all the setup it needs to, and is ready for you to do your custom stuff. That method should already be in the template that was used to create the view controller, but commented out. Uncomment it and add the ball.

C:
  1. - (void)viewDidLoad {
  2.     [super viewDidLoad];
  3.     ball = [Ball alloc];
  4.     ball.position = CGPointMake(100.0, 100.0);
  5.     ball.velocity = CGPointMake(4.0, 3.0);
  6.     ball.radius = 20.0;
  7.     ball.color = [UIColor greenColor].CGColor;
  8. }

[Ball alloc] is analogous to new Ball() in ActionScript. You are allocating memory and filling it with an instance of the class. Then you can set the position, velocity, radius and color.

[Edit - I just noticed this reference: http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/ObjectiveC/Articles/chapter_4_section_2.html#//apple_ref/doc/uid/TP30001163-CH22-SW2, which says that we should be creating an init method to initialize instance variables, and should be calling that init method on creation. I do this in part 3 of this series. Just realize that it should really be done here.]

When you do create an object dynamically like this, you need to clean up after yourself. You've allocated the memory and the system will hold it for your object. When you are done with it, you need to tell the system that it's ok to take back that memory. Near the bottom of the view controller class you'll see a dealloc method. This is called when this class is destroyed, so that you can clean up anything you need to. Here we just need to call the release method of ball, which will release its memory.

C:
  1. - (void)dealloc {
  2.     [ball release];
  3.     [super dealloc];
  4. }

You should be able to run this application at this point, and have it compile and run without any errors or warning. Clean them up if you see them. Of course you won't see anything but a gray screen in the simulator, but that's fine.

Next, we need to add a method to the Ball class so we can make it move. Back to Ball.h:

C:
  1. #import <Foundation/Foundation.h>
  2.  
  3.  
  4. @interface Ball : NSObject {
  5.     CGPoint position;
  6.     CGPoint velocity;
  7.     CGFloat radius;
  8.     CGColorRef color;
  9. }
  10.  
  11. @property CGPoint position;
  12. @property CGPoint velocity;
  13. @property CGFloat radius;
  14. @property CGColorRef color;
  15.  
  16. - (void)update;
  17.  
  18. @end

That second to last line declares the method, update, which returns void. the "-" means it's a public instance method. "+" would be a static (class) method.

Now the implementation in Ball.m:

C:
  1. #import "Ball.h"
  2.  
  3.  
  4. @implementation Ball
  5. @synthesize position;
  6. @synthesize velocity;
  7. @synthesize radius;
  8. @synthesize color;
  9.  
  10. - (void)update {
  11.     position.x += velocity.x;
  12.     position.y += velocity.y;
  13.    
  14.     if(position.x + radius> 320.0) {
  15.         position.x = 320.0 - radius;
  16.         velocity.x *= -1.0;
  17.     }
  18.     else if(position.x - radius <0.0) {
  19.         position.x = radius;
  20.         velocity.x *= -1.0;
  21.     }
  22.    
  23.     if(position.y + radius> 460.0) {
  24.         position.y = 460.0 - radius;
  25.         velocity.y *= -1.0;
  26.     }
  27.     else if(position.y - radius <0.0) {
  28.         position.y = radius;
  29.         velocity.y *= -1.0;
  30.     }
  31.     NSLog([[NSString alloc] initWithFormat:@"x: %f, y:%f", position.x, position.y]);
  32. }
  33.  
  34. @end

This is basic velocity and bouncing code. Add the velocity to the position, check the boundaries, set to the edge of the boundary and reverse direction. The iPhone's screen is 320x480, minus a 20 pixel tall status bar, so 320x460.

The last line is a not-so-user-friendly version of trace(). NSLog sends a log message, but you need to allocate an NSString and format it with the numbers you want to trace. If you've ever used printf, that will look fairly familiar.

[Edit - It's been pointed out to me by a couple of people that that log line is leaking memory. I'm allocating memory for a string and never releasing it. Apparently, with NSLog, you can just do this:

NSLog(@"x: %f, y:%f", position.x, position.y);

and it does the formatting and takes care of memory for you. Good to know. You should replace that log line with this one.]

Test again just to make sure it compiles. Fix any errors.

Now let's make it move. Well, the theoretical ball will move. Rendering it to screen will come later. That's why we're logging the position, so you know it's happening.

Objective C doesn't have EnterFrame events, so we'll use a timer. An NSTimer to be exact. We'll do that in the view controller, again in the viewDidLoad method.

C:
  1. - (void)viewDidLoad {
  2.     [super viewDidLoad];
  3.     ball = [Ball alloc];
  4.     ball.position = CGPointMake(100.0, 100.0);
  5.     ball.velocity = CGPointMake(4.0, 3.0);
  6.     ball.radius = 20.0;
  7.     ball.color = [UIColor greenColor].CGColor;
  8.    
  9.     [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
  10. }

Here we are calling a static method of the NSTimer class called scheduledTimerWithTimeInterval. Objective C doesn't skimp on method names. The interval we are setting to 1.0/30.0 or 1/30th of a second. The target is self, which is like "this" in ActionScript. The selector is the method that you want to call on the target when the timer fires. We want to call the onTimer method. I'm not sure about the @selector(onTimer) syntax, but it some how formats the function name into something that can be used as a callback for the timer. User info is nil, which is like null, and yes, we want it to repeat. YES and NO are true and false.

Now of course we need that onTimer function. First declare it in the .h file:

C:
  1. #import <UIKit/UIKit.h>
  2. #import "Ball.h"
  3.  
  4. @interface GravityTutorialViewController : UIViewController {
  5.     Ball *ball;
  6. }
  7.  
  8. - (void)onTimer;
  9.  
  10. @end

Then in the implementation .m file, we create the function and call ball's update method:

C:
  1. - (void)onTimer {
  2.     [ball update];
  3. }

OK, start up your console (Cmd-Shift-R) and then Build and Go. You should get a bunch of lines being logged like so:

C:
  1. [Session started at 2008-12-27 11:27:56 -0500.]
  2. 2008-12-27 11:27:58.521 GravityTutorial[62409:20b] x: 104.000000, y:103.000000
  3. 2008-12-27 11:27:58.554 GravityTutorial[62409:20b] x: 108.000000, y:106.000000
  4. 2008-12-27 11:27:58.587 GravityTutorial[62409:20b] x: 112.000000, y:109.000000
  5. 2008-12-27 11:27:58.621 GravityTutorial[62409:20b] x: 116.000000, y:112.000000
  6. 2008-12-27 11:27:58.654 GravityTutorial[62409:20b] x: 120.000000, y:115.000000

As you can see, the x and y values are changing. When x reaches 320 or y reaches 460, you'll see them go in the opposite direction.

Well done. You've made a custom object, made an instance of it, assigned values to its properties, called a method on it, and used a timer to "animate" it.

Cocoa is very much MVC oriented. We've just create the ball model, and customized the controller. In part 2, we'll create the view, so we can actually see something moving.

Post to Twitter

This entry was posted on Saturday, December 27th, 2008 at 1:50 pm and is filed under Objective C, iPhone. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

There are currently 31 responses to “Gravity Tutorial for iPhone Part 1”

  1. 1 On December 27th, 2008, Gravity Tutorial for iPhone Part 2 | BIT-101 Blog said:

    [...] part 1, we created a Ball class which contained position, velocity, radius, and a color. And we set up a [...]

  2. 2 On December 27th, 2008, Flash vs Unity 3D « protopinions said:

    [...] that can be distributed online are reluctantly looking elsewhere. When Flash superstars like Bit 101 start blogging about the ABC’s of iPhone development with the zeal of a kid in a candyshop, code and tutorials included, the trend is clear. There are [...]

  3. 3 On December 27th, 2008, Rob Toole said:

    Wow Keith, add obj-c to your “ball tutorials” mantle. Great stuff, thank you!

  4. 4 On December 28th, 2008, chandler said:

    I think in viewDidLoad you want ball = [[Ball alloc] init]; you need init to get an instance.

  5. 5 On December 28th, 2008, kp said:

    chandler, you may be right, but it seems to work fine without it. actually, in part 3 I add a custom init method.

  6. 6 On December 28th, 2008, kp said:

    chandler, I think alloc still gives you an instance, but init sets the object up internally. again, I get around to this in part 3, but you are right I should do it here.

    http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/ObjectiveC/Articles/chapter_4_section_2.html#//apple_ref/doc/uid/TP30001163-CH22-SW2

    “Every class that declares instance variables must provide an init… method to initialize them.”

  7. 7 On December 28th, 2008, kp said:

    this is also very useful. http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/ObjectiveC/Articles/chapter_4_section_3.html#//apple_ref/doc/uid/TP30001163-CH22-SW3 describing why init is important.

  8. 8 On December 28th, 2008, chandler said:

    alloc allocates the memory, but doesn’t prepare the instance. I don’t think i’ve ever seen alloc without an init method before. you could also of course make an initWithPosition:(CGPoint)Pos velocity:(CGPoint)vel radius:(rad) color:(UIColor *)clr method to get something more akin to an ActionScript constructor. Awesome tutorial though, can’t wait to see what’s next!

  9. 9 On December 28th, 2008, Luke said:

    Objective C is truly hideous.

  10. 10 On December 28th, 2008, kp said:

    chandler, yes, I’m planning on doing at least initWithColor and radius. I think it’s fine to have default position and velocity of 0, 0, as well as default gravity and bounce.

    anyway, as i just quoted, “Every class that declares instance variables must provide an init… method to initialize them.”

    NSObject’s init does absolutely nothing. If you don’t have instance variables, or you want to leave them at 0 for default, then your init will be empty anyway. Of course, in this case, we really do need to define a color and radius as 0 is not very useful for either. At any rate, I know a lot more about it than I did yesterday and will faithfully provide inits for all my future classes.

  11. 11 On December 29th, 2008, 4 part iPhone Development Tutorial on Gravity from Keith Peters at The iPhone Developer Chronicles said:

    [...] (aka “bit101″ in the Flash world) saga in iPhone Development, and he recently posted a 4 part tutorial series on implementing gravity routines (one of his specialities, since he is the master of “Making [...]

  12. 12 On December 30th, 2008, Scott Janousek said:

    Weird. Are you running this in the simulator or on the actual device? All I get is a grey screen … however, I can see the timer working, etc … so I must have missed a (critical) step … I have no compile time errors.

  13. 13 On December 30th, 2008, kp said:

    Scott, running on both.

  14. 14 On December 30th, 2008, Scott Janousek said:

    Ah, disregard. This was creating the Ball object and timer only. I see it continues with part 2. :)

  15. 15 On December 31st, 2008, IPhone SDK - tutoriaux par Keith Peters | tweenpix said:

    [...] la liste complète des tutoriaux: – Part 1 – Part 2 – Part 3 – Part 4 – Part [...]

  16. 16 On January 2nd, 2009, WS-Blog » WSPluginSwitcher: Cocoa based tool for switching Flash plug-in on OS X said:

    [...] Peters: Gravity Tutorials for iPhone, Part 1 – [...]

  17. 17 On January 4th, 2009, Just my 99 cents – Antti Kupila said:

    [...] writing some flash -> iphone/cocoa articles/tutorials. Similar to some other ones seen online, Keith Peter’s in particular. All of this is actually really easy to get the hang of even if the syntax looks pretty weird at [...]

  18. 18 On January 13th, 2009, Matthi’s kleine Welt » iPhone SDK & OpenGL ES - Erste Versuche said:

    [...] Tutorial Part 1, Part 2, Part 3, Part 4, Part [...]

  19. 19 On January 19th, 2009, all manner of distractions » Blog Archive » iPhoning said:

    [...] a while since I last posted. I decided to shift gears a bit thanks to Keith Peters and his iPhone tutorial. I have always wanted to get into iPhone development but the weirdness of Objective C scared me [...]

  20. 20 On January 21st, 2009, Cronos said:

    Gr8.. tutorial

  21. 21 On February 14th, 2009, mkeefeDESIGN & Photography » Blog Archive » Baby steps in iPhone development said:

    [...] owe my initial interest to Keith Peters about a month ago as he started to write blog posts on Bit-101 while he was learning everything. Soon after I researched some things, read some articles and [...]

  22. 22 On February 22nd, 2009, イナヅマtvログ » iPhone SDK + Objective-C, 参考サイト メモ said:

    [...] Gravity Tutorial for iPhone – Part 1 [...]

  23. 23 On March 5th, 2009, Beginning iPhone Development | Raphael Wichmann said:

    [...] read the iPhone book and Keith Peters tutorial about gravity on the iPhone. And i watched some videos on this site: [...]

  24. 24 On March 9th, 2009, Bookmarks for March 9th from 11:18 to 11:19 « what i say // jon burger said:

    [...] Gravity Tutorial for iPhone Part 1 | BIT-101 Blog – [...]

  25. 25 On June 12th, 2009, mcteapot said:

    I just found this website and I am hooked! A note on the NSLog Edit, I believe u are ok in calling the NSLog([[NSString alloc] initWithFormat:@”text @%”, dataName]);. I believe this is a Factory method that will be will be auto-released. But the Edit fix is still the best practice.

  26. 26 On July 22nd, 2009, eheringe said:

    Oh, WOW, Helpfull information, THANKS. Greetings from Germany

  27. 27 On August 3rd, 2009, all manner of distractions » Blog Archive » Links! Hey everyone! Links! said:

    [...] for those in need of some iPhone development assistance, I recommend two sites. Keith Peters has posted a nice starter tutorial for those interested in developing iPhone apps. I used it to get [...]

  28. 28 On August 6th, 2009, Learning Iphone » Gravity Tutorial for iphone said:

    [...] Here’s the link, let’s see how much I can do tonight before I gotta get to bed. http://www.bit-101.com/blog/?p=1784 [...]

  29. 29 On September 28th, 2009, Freddythunder said:

    Thanks again for the tutorial! I’m well on my way. I love how you put relations in my head from NSTimer to onEnterFrame and I see I can draw much like the API in AS.

  30. 30 On October 17th, 2009, lostCoder said:

    Awesome tutorial! I was wondering what it would take to switch the draw ball to say a loaded .png image?

  31. 31 On November 17th, 2009, Gravity (Schwerkraft) Tutorial mit Source Code » LINK, Tutorial, Schwerkraft, Gravity, Hier » iPhone Sourcen | Flash Sourcen said:

    [...] LINK: http://www.bit-101.com/blog/?p=1784 [...]

Leave a Reply

Who is reading BIT-101?

Copyright ©2009 by Keith Peters. All rights reserved. This means that you may not reprint or repost the contents of this site without express written permission of the author.


  • Calendar

  • February 2010
    M T W T F S S
    « Jan    
    1234567
    891011121314
    15161718192021
    22232425262728
hoodia order buy Levitra Plus betablockers weight loss information buy pills without a prescription arthritis menopause ambien doses cat's eye health information on cholesterol cialis online order valtrex cheapest phentermine onlin e increase breast size lower blood sugar immediately terramycin which is better cialis or viagra buy cheap cialis reduce cholesterol naturally new blood pressure treatment products for back pain cheapest cialis index will levitra help piroxicam 20 mg order viagra online in germany buy tadalafil online buy levitra onlines how to naturally lower cholesterol buy generic viagra where to buy soma anti allergic drug levothyroxine dogs new hair loss treatmen buy levitra pain meds buy cheap malaria therapy weight loss after baby asthma medications chronic snoring viagra gel prostate cancer cures order viagra cialis alprazolam men health natural cure arthritis immune system support diet medicine cialis approval lipitor effects where can i buy arthritis drugs overactive bladder in men self help weight loss natural cholesterol control ativan medication cialis approval best cure for snoring breast enhancing pills order prozac celebrex pharmacy buy levitra onlines premature ejaculation cure confidence hypnotherapy free stop smoking bust enhance diet weight loss supplements skin fungal infection valium with no prescription viagra with out prescription breast enhancement products alpha blocker medications azithromycin 250mg skin disease chronic heart failure medicines dog care products buying cialis online gerd in children antibiotics to buy my drug store muscle building diet drugs affecting levitra anti anxiety medications really large breast enhancement help for constipation ulcers stomach drugs for high blood pressure selling pet products buy pain medicine viagra online overnight fucidin ointment generic zyrtec prices soft tab cialis smoking treatment dog products online weight loss solution cialis on line blue pills weight loss diet pill nitroglycerin sublingual floxin prevention of heart attack imuran order gasex vermox treatment of depression Viagra On Line buy generic cialis professional tooth whitening kits to buy valium 2mg treatment for hypertension ultram cheapest online stores hair loss products cheap weight loss diovan prescription malaria preventative taurine treating prostate cancer immune system support natural constipation cure phentermine no prescription fast delivery purchase meds without prescription buy plendil diet drug taking viagra after cialis protonix cheapest generic cialis online viagra levitra cialis yohimbe benefits muscle mass gain diet and health products medical treatment for insomnia buy blood pressure meds buy celexa levaquin interactions blood pressure drug skin disorder where can i buy arthritis drugs natural breast enhancer acute pain control online diazepam natural acne remedy antifungal strategies triphala pravachol online how can i stop smoking breast enhancement natural nautral breast enhancement beta blocker medications wellbutrin dosages order viagra cialis lower high blood pressure mass muscle phentermine from canada how to loss weight osteoporosis bone health lipitor use dog medication drug allergies buy diazepam buyviagra cialis phentermine 37.5 mg zestril medication parkinsons treatment generic revatio free nexium cosmetic dentistry tooth whitening avalide generic buy cheap tadalafil uk simvastatin tablets buy cialis online in usa breast pain cat care ovulating clomid medical skin care lines viagra to canada viagra or cialis cheap cialis tramadole buy azulfidine drugs used for cancer ear pain oral ketoconazole raloxifene evista taurine sex with levitra stop smoking today heart failure natural cholesterol control protonix dose oxybutynin 5mg irritable bowel syndrome treatments new treatment for hepatitis c cheap prescription drugs viagra online prescription depression therapy buy sumycin menopause treatment hair loss treatments medication pletal what is a natural antibiotic viagra purchase synthroid tablets generic prilosec lipitor cat health info discount vitamin cholesterol and health bacterial diarrhea weight loss medicine new treatment for depression removing retention fluids diuretic medicines soma 250mg cat anxiety loss weight online pharmacy viagra buy phentermine without a prescription herbs for breast growth cymbalta dosage fast weight loss supplement arthritis menopause levitra online order cheapest place to buy phentermine cold flu medications for nausea buy ultram where pills for acne free weight loss programs help with anxiety improve skin valium 2mg urinary tract health cat urinary tract disease crestor dosage drug zofran calan zyrtec buy nirdosh dosage digoxin buy pain patch acomplia alendronate cialis best price cheap wellbutrin small dog products depression medicine sildenafil dosage dog health depression and anxiety lamictal withdrawal viagra, levitra and cialis online drug buy bone maker strontium cures for hair loss nitroglycerin tablets natural arthritis treatment arimidex buy buy energy patch how to treat a yeast infection viagra herb alternative viagra cialis levitra order sublingual cialis cialis comparison breast lift augmentation seroquel for depression carisoprodol mg new treatment for depression cialis soft tabs safe sleep aid severe leg muscle pain natural weight loss gabapentin medication what is ambien clozapine medication viagra online ordering cures for hair loss free weight loss help buy viagra levitra pet treats order plan b diabetes type 2 phentermine risk ultram er side effects treatment for hepatitis b constipation cures drugs used in treating depression leg pain buy cheap generic cialis anti anxiety meds hypnotherapy for weight loss motilium body building fitness dog skin relieve upper back pain cures for high blood pressure cardura celecoxib Viagra Online Cheap cheap bactrim ambien online lamisil cost infertility meds progesterone clomid osteoporosis hormon urinary tract infection symptoms hypnotherapy for health how to buy viagra online joint pain cure online allegra buy generic cialis uk generic abilify cures for lung cancer new treatments for lung diseases pain meds buy cheap treatment for dry skin disease of the skin nexium drug free stop smoking buy tooth whitening products viagra tablet naprosyn dosage women's fertility male sexual power carisoprodol purchase asthma attack treatment estradiol pills phentermine from canada pet health care hair loss products online astelin generic cheap estrace free weight loss program buy rimonabant relieve lower back pain lexapro prescription new breast cancer drug buying ambien best online viagra scams home scabies treatment hair loss in woman buy generic cialis uk eye drop gabapentin medication amitriptyline uses ultram no prescription natural pain cures buy cla products back pain lowest price generic viagra pain meds buy cheap mg buy phentermine acne skin care cialis rx weight loss and fitness nitrofurantoin buy phentermine without a prescription high blood pressure medicines stop hair loss viagra china use levitra female health coreg dosage carisoprodol price pain relief product breast enlargement depression pills buy how to treat flu home neck pain relief order imitrex online vitamin b-6 cialis soft tabs pharmacy software description of soma buy isoniazid cheap prevacid help ear infections on dog fat burning stop smoking remedies rhinitis treatment chronic pain relief birth control online meds without prescriptions buy lovastatin drug stores penis enlargement without pill cancer medicine buy deltasone cure for throat infection thyroid dogs dosage cipro viagra from uk cheap alcoholism treatment natural cure for constipation paxil cialis 5mg tablets amitriptyline uses topamax drugs lower heart rate drug discount codes dog medicines body fat loss joint pain recurring urinary tract infections ativan information buy drugs online cheap fast valium body building ambien maximum dosage information on valium how to sperm more chlamydia medication dosage buy cialis online viagra chest pain heart fluconazole interaction calcium channel blocker side effects zolpidem dosage online drug stores zelnorm muscle strength fluconazole buy stress gum free weight loss products information on gout low immune system online viagra cialis 20 buy cefixime phentermine from canada gain muscle mass fast lasix side effects buy singulair penis enlargement free natural muscle and joint health viagra online overnight cialis online aceon allergies and asthma diamox side effects weight loss software generic compazine price for tramadol high blood pressure symtoms osteoporosis help treatment severe constipation drug new smoking stop pain relief product xanax online dog health info clonazepam .5mg buy tribulus pregnancy prevention methods allergy hives