Thread: Help with small project

  1. #1
    Registered User
    Join Date
    May 2012
    Posts
    3

    Help with small project

    I'm fairly new to this and have been stuck on some error's for quite a while now and was wondering if anyone would be able to help me with the following...

    Making the direction increment and decrement by one using the direction keys
    Stop the mouse from interfering with the direction
    Allow the 'jack' to enter from the centre of the screen
    Make the 'jack' only entered the screen once instead of a fast few times like it is doing

    I know I'm asking for alot of help but even if you could point me in the right direction to getting things sorted and point out obvious mistakes that would be greatly appreciated.

    Thanks


    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    #include <math.h>
    #include <SDL/SDL.h>
    #include <SDL/SDL_Image.h>
    #include <SDL/SDL_ttf.h>
    #include <chipmunk/chipmunk.h>
    
    
    #define SLEEP_TICKS 16
    #define XSIZE 382
    #define YSIZE 472
    #define XMID XSIZE/2
    #define YMID YSIZE/2
    
    
    
    
    int ticks = 0;
    int some_value = 42;
    cpSpace *space;
    cpBody *staticBody;
    cpBody *marble;
    
    
    SDL_Surface *screen;    //This pointer will reference the backbuffer
    SDL_Surface *marble_image,*jack_image; //This pointer will reference our bitmap sprite
    SDL_Surface *hline_image,*vline_image;
    SDL_Surface *pitch_image;
    SDL_Surface *temp;        //This pointer will temporarily reference our bitmap sprite
    SDL_Rect src, dest;        //These rectangles will describe the source and destination regions of our blit
    
    
    
    
    
    
    
    
    int running=0;         //Is the game running? 
    int num_marbles=1;     //Some marbles
    int direction=0;    
    
    
    /* return a pseudo-random number between 0 and limit inclusive.
    */
    int randomize(int limit) {
    int divisor = RAND_MAX/(limit+1);
    int rand_val;
    do {
    rand_val = rand() / divisor;
    } while (rand_val > limit);
    return rand_val;
    }
    
    
    SDL_Surface *loadImage(char *name)
    {
        /* Load the image using SDL Image */
        SDL_Surface *temp = IMG_Load(name);
        SDL_Surface *image;
        if (temp == NULL)
        {
            printf("Failed to load image %s\n", name);
            return NULL;
        }    
        /* Make the background transparent */
        SDL_SetColorKey(temp, (SDL_SRCCOLORKEY|SDL_RLEACCEL), SDL_MapRGB(temp->format, 0, 0, 0));    
        /* Convert the image to the screen's native format */
        image = SDL_DisplayFormat(temp);    
        SDL_FreeSurface(temp);    
        if (image == NULL)
        {
            printf("Failed to convert image %s to native format\n", name);
            return NULL;
        }    
        /* Return the processed image */
        return image;
    }
    
    
    void update(int ticks)
    {
        int i;
        int steps = 2;
        cpFloat dt = 1.0/60.0/(cpFloat)steps;
        for(i=0; i<steps; i++){
            cpSpaceStep(space, dt);
        }
    }
    
    
    static void postStepRemove(cpSpace *space,cpShape *shape,void *unused) {
           cpSpaceRemoveBody(space, shape->body);
           cpBodyFree(shape->body);
           cpSpaceRemoveShape(space, shape);
           cpShapeFree(shape);
    }
    
    
    static int begin(cpArbiter *arb, cpSpace *space,void *ignore) {
           cpShape *a,*b;
           cpArbiterGetShapes(arb, &a, &b);
           cpSpaceAddPostStepCallback(space,(cpPostStepFunc)postStepRemove,b,NULL);
           return 0;
    }
    
    
    static int collFunc(cpShape *a, cpShape *b, cpContact *contacts, int numContacts, cpFloat normal_coef, void *data)
    {
        int *some_ptr = (int *)data;
    
    
    // Do various things with the contact information. 
    // Make particle effects, estimate the impact damage from the relative velocities, etc.
    //    for(int i=0; i<numContacts; i++)
    //        printf("Collision at %s. (%d - %d) %d\n", cpvstr(contacts[i].p), a->collision_type, b->collision_type, *some_ptr);
        
    // Returning 0 will cause the collision to be discarded. This allows you to do conditional collisions.
        return 1;
    }
    
    
    void init(void)
    {
        int i;
        unsigned int iseed = (unsigned int)time(NULL);
      
        cpFloat radius = 25;
        cpFloat marble_mass = 0.4;
        cpFloat x,y;
        // Initialize a static body with infinite mass and moment of inertia
        // to attach the static geometry to.
        staticBody = cpBodyNew(INFINITY, INFINITY);
        
        // Optional. Read the docs to see what this really does.
        cpResetShapeIdCounter();
        
        // Create a space and adjust some of it's parameters.
        space = cpSpaceNew();
        space->damping=0.9;
        
        // Create a shape pointer 
        cpShape *shape;
        
        // Create a border around the edges of the screen.
        shape = cpSegmentShapeNew(staticBody, cpv(0,0), cpv(50,0), 0.0f);
        shape->e = 1.0; shape->u = 1.0;
        cpSpaceAddStaticShape(space, shape);
    
    
        shape = cpSegmentShapeNew(staticBody, cpv(0,0), cpv(0,480), 0.0f);
        shape->e = 1.0; shape->u = 1.0;
        cpSpaceAddStaticShape(space, shape);
    
    
        shape = cpSegmentShapeNew(staticBody,cpv(640,0), cpv(640,480), 0.0f);
        shape->e = 1.0; shape->u = 1.0;
        cpSpaceAddStaticShape(space, shape);
        
        shape = cpSegmentShapeNew(staticBody, cpv(0,480), cpv(640,480), 0.0f);
        shape->e = 1.0; shape->u = 1.0;
        cpSpaceAddStaticShape(space, shape);
        
        srand(iseed);
        
        // Create some marbles
        for(i=0;i<num_marbles;i++){
            marble = cpBodyNew(marble_mass, cpMomentForCircle(marble_mass, 0.0, radius, cpvzero));
            x=XMID-200+(cpFloat)181;
            y=YMID-200+(cpFloat)70;
            marble->p = cpv(x,y);
            //marble->v = cpv(x,y);
            cpSpaceAddBody(space, marble);
            shape = cpCircleShapeNew(marble, radius, cpvzero);
            shape->e = 0.0; shape->u = 2.5;
            shape->data=(cpDataPointer)0;
            //shape->collision_type = 1;
            cpSpaceAddShape(space, shape); 
        }
        // Create a jack
        marble = cpBodyNew(marble_mass, cpMomentForCircle(marble_mass, 0.0, radius, cpvzero));
        marble->p = cpv(XSIZE,YSIZE);
        marble->v = cpv(direction,-100); 
        //marble->v = cpv(-100,-160);
        cpSpaceAddBody(space, marble);
        shape = cpCircleShapeNew(marble, radius, cpvzero);
        shape->data=(cpDataPointer)1;
        shape->e = 0.0; shape->u = 6.5;
        //shape->collision_type = 1;
        cpSpaceAddShape(space, shape); 
        
        // Add a collision callback (begin).
        cpSpaceAddCollisionHandler(space,1,0,begin,NULL,NULL,NULL,NULL);
        
    }
    
    
    void destroy(void)
    {
        cpSpaceFree(space);    
        cpBodyFree(staticBody);
    }
    static void renderMarble(cpFloat x, cpFloat y, cpFloat r, cpFloat a,cpShape *shape)
    {
           SDL_Rect dest;
           /* Set the blitting rectangle to the size of the src image */
           dest.x = x;
           dest.y = y;
         if(shape->data){
              dest.w = jack_image->w;
              dest.h = jack_image->h;    
              /* Blit the entire image onto the screen at coordinates x and y */
              SDL_BlitSurface(jack_image, NULL, screen, &dest);
          }else{
                dest.w = marble_image->w;
                dest.h = marble_image->h;
                /* Blit the entire image onto the screen at coordinates x and y */
                SDL_BlitSurface(marble_image, NULL, screen, &dest);
          } 
    }
    static void renderShape(cpFloat x, cpFloat y, cpFloat r, cpFloat a,int type)
    {
           SDL_Rect dest;
           /* Set the blitting rectangle to the size of the src image */
           if(type==0){
                    dest.x = x;
                    dest.y = y;
                    dest.w = hline_image->w;
                    dest.h = hline_image->h;
                    /* Blit the entire image onto the screen at coordinates x and y */
                    SDL_BlitSurface(hline_image, NULL, screen, &dest);   
           }else if(type==1){
                    dest.x = x;
                    dest.y = y;
                    dest.w = vline_image->w;
                    dest.h = vline_image->h;
                    /* Blit the entire image onto the screen at coordinates x and y */
                    SDL_BlitSurface(vline_image, NULL, screen, &dest);  
           }else if(type==2){
                    dest.x = 0;
                    dest.y = 0;
                    dest.w = pitch_image->w;
                    dest.h = pitch_image->h;
                    /* Blit the entire image onto the screen at coordinates x and y */
                    SDL_BlitSurface(pitch_image, NULL, screen, &dest);  
           }      
    }
    static void drawMarbleShapes(cpShape *shape)
    {
        cpBody *body = shape->body;
        cpCircleShape *circle = (cpCircleShape *)shape;
        cpVect c = cpvadd(body->p, cpvrotate(circle->c, body->rot));
        renderMarble(c.x, c.y, circle->r, body->a,shape);
    }
    static void drawStaticShapes(cpShape *shape)
    {
        cpBody *body = shape->body;
        cpSegmentShape *segment = (cpSegmentShape *)shape;
        cpVect c = cpvadd(body->p, cpvrotate(segment->a, body->rot));
            
        renderShape(0, 0, segment->r, body->a,0);
        renderShape(0,475, segment->r, body->a,0);
        renderShape(0, 0, segment->r, body->a,1);
        renderShape(635,0, segment->r, body->a,1);
        renderShape(100,30, segment->r, body->a,2);
    }
    static void drawMarbles(void *ptr, void *unused)
    {
        cpShape *shape = (cpShape *)ptr;
        drawMarbleShapes(shape);
    }
    static void drawStaticObjects(void *ptr, void *unused)
    {
        cpShape *shape = (cpShape *)ptr;
        drawStaticShapes(shape);
    }
    int main(int argc, char* argv[])
    {
    int i;
    cpBody *body;
    cpShape *shape;
    SDL_Event  event; // SDL events
    
    
    running  = 1;
    
    
    //Initialise the physics engine
    cpInitChipmunk();
    
    
    //Initialise the stuff we need for marble physics
    init();
    
    
    //We must first initialize the SDL video component, and check for success
    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
        printf("Unable to initialize SDL: %s\n", SDL_GetError());
        return 1;
    }
    //When this program exits, SDL_Quit must be called
    //atexit(SDL_Quit);
    
    
    //Set the video mode to 640x480 with 16bit colour and double-buffering
    screen = SDL_SetVideoMode(XSIZE, YSIZE, 16, SDL_DOUBLEBUF);
    if (screen == NULL) {
        printf("Unable to set video mode: %s\n", SDL_GetError());
        return 1;
    }
    
    
    //Set up printing
    if (TTF_Init() != 0) {
      printf("Unable to initialize SDL_ttf: %s \n", TTF_GetError());
      return 1;
    }
    TTF_Font *fntCourier = TTF_OpenFont( "cour.ttf",24);
    SDL_Color clrFg = {255,255,255,0};  // White ("Fg" is foreground)
    SDL_Surface *textSurface;
    SDL_Rect textDest = {0,0,0};
    char textString[100];
    
    
    
    
    //Load a marble image
    temp =loadImage("marble.png");
    //Convert the surface to the appropriate display format
    marble_image = SDL_DisplayFormatAlpha(temp);
    
    
    //Load a jack image
    temp =loadImage("jack.png");
    //Convert the surface to the appropriate display format
    jack_image = SDL_DisplayFormatAlpha(temp);
    
    
    //Load a static object image
    temp =loadImage("hline.png");
    //Convert the surface to the appropriate display format
    hline_image = SDL_DisplayFormatAlpha(temp);
    
    
    temp =loadImage("vline.png");
    //Convert the surface to the appropriate display format
    vline_image = SDL_DisplayFormatAlpha(temp);
    
    
    temp =loadImage("pitch.png");
    //Convert the surface to the appropriate display format
    pitch_image = SDL_DisplayFormatAlpha(temp);
    
    
    //Release the temporary surface
    SDL_FreeSurface(temp);
    
    
    
    
    while (1) {
        while(SDL_PollEvent(&event)){
           switch(event.type) {
        if (event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE))
            running = 0;
        } 
        if(event.key.keysym.sym==SDLK_SPACE) {
                                        marble->p = cpv(XSIZE,YSIZE);
                                        marble->v = cpv(direction,-160);     
        }
        if(event.key.keysym.sym==SDLK_RIGHT) {
           direction++;
           sprintf(textString, "Direction=%d", direction);
           textSurface = TTF_RenderText_Solid(fntCourier, textString, clrFg);
           }
        if(event.key.keysym.sym=SDLK_LEFT) {
           direction--;
           sprintf(textString, "Direction=%d", direction);
           textSurface = TTF_RenderText_Solid(fntCourier, textString, clrFg);
           }                           
        } // while (handling events)
        if (running == 0)
          break;
          
        //Blank the background
        SDL_FillRect(screen, NULL, 0);
             
        //Draw the other stuff
        cpSpaceEachShape(space,(cpSpaceShapeIteratorFunc)drawStaticObjects,NULL);
        //Draw the marbles and jack
        cpSpaceEachShape(space,(cpSpaceShapeIteratorFunc)drawMarbles,NULL);
        //Draw the text
        SDL_BlitSurface(textSurface,NULL, screen,&textDest);
        
        //Double buffer
        SDL_Flip(screen);
        ticks++;
       update(ticks);
      } // while (main loop)
    //Release the surfaces
    SDL_FreeSurface(textSurface);
    SDL_FreeSurface(marble_image);
    SDL_FreeSurface(jack_image);
    SDL_FreeSurface(hline_image);
    SDL_FreeSurface(vline_image);
    TTF_CloseFont(fntCourier);
    //Return success!
    SDL_Quit();
    destroy();
    return 0;
    }
    Last edited by CroftxD; 05-13-2012 at 05:38 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Create a much simpler program which just draws one single shape (say a triangle) and then attempts to move/rotate that image using the keys/mouse/whatever.

    Then we (and you) don't have to wade through 300+ lines of code which have nothing to do with the immediate problem.

    When you understand how it works in a simple program, you can apply it to your larger program.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2012
    Posts
    3
    Sure, once I've simplified the code down to main area's I'll come back to you.

  4. #4
    Registered User
    Join Date
    May 2012
    Posts
    3
    After spending sometime messing with the code I managed to solve my own problems.

    So can this thread be locked/closed?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. a small project
    By ali.franco95 in forum C Programming
    Replies: 2
    Last Post: 09-27-2011, 08:57 PM
  2. Small Project - Help.
    By Cappa in forum C Programming
    Replies: 2
    Last Post: 08-28-2010, 08:44 PM
  3. Replies: 16
    Last Post: 09-21-2004, 11:08 PM
  4. Hey I fished the small little practice project
    By incognito in forum C Programming
    Replies: 3
    Last Post: 03-05-2003, 08:36 PM
  5. A small problem with a small program
    By Wetling in forum C Programming
    Replies: 7
    Last Post: 03-25-2002, 09:45 PM