diff --git a/Anim.c b/Anim.c index 19118e8..bcd5ca1 100644 --- a/Anim.c +++ b/Anim.c @@ -1,3 +1,107 @@ +#include +#include +#include "Draw.h" #include "Anim.h" +typedef struct { + DrawImg img; + int w; + int fps; + int frames; + int ftime; + int time; +} Animation; + +Anim Anim_LoadAnim(char *fichero,int frames,int fps){ + DrawImg img; + Animation *anim; + int w,h; + + img=Draw_LoadImage(fichero); + if(!img){ + return(NULL); + } + Draw_GetSize(img,&w,&h); + + // Create the animation container + anim=malloc(sizeof(Animation)); + anim->img=img; + anim->w=w/frames; + anim->fps=fps; + anim->frames=frames; + anim->ftime=1000/fps; + anim->time=anim->ftime*frames; + + return((Anim)anim); +} + + +int Anim_GetTime(Anim a){ + Animation *anim=a; + + return(anim->time); +} + +void Anim_SetOffset(Anim a,int x,int y){ + Animation *anim=a; + + Draw_SetOffset(anim->img,x,y); +} +void Anim_GetOffset(Anim a,int *x,int *y){ + Animation *anim=a; + + Draw_GetOffset(anim->img,x,y); +} + +void Anim_Draw(Anim a,int time_ms,int x,int y){ + Animation *anim=a; + int frame; + + frame=(time_ms%anim->time)/anim->ftime; + Draw_DrawImgPart(anim->img,x,y,anim->w,frame); +} + + + + + + + + + + +void AnimPlay_Copy(AnimPlay *ad,AnimPlay *ao){ + ad->img=ao->img; + ad->anim=ao->anim; + ad->time_ms=ao->time_ms; +} + + +void AnimPlay_SetImg(AnimPlay *ap,DrawImg img){ + ap->anim=NULL; + ap->img=img; + ap->time_ms=0; +} +void AnimPlay_SetAnim(AnimPlay *ap,Anim ani){ + ap->anim=ani; + ap->img=NULL; + ap->time_ms=0; +} + + +void AnimPlay_Draw(AnimPlay *ani,int x,int y){ + if(ani->anim){ + Anim_Draw(ani->anim,ani->time_ms,x,y); + }else + if(ani->img){ + Draw_DrawImg(ani->img,x,y); + } +} + +void AnimPlay_IncTime(AnimPlay *ani,int t){ + if(ani->anim){ + ani->time_ms+=t; + } +} + diff --git a/Anim.h b/Anim.h index 73cc821..dbf1f5f 100644 --- a/Anim.h +++ b/Anim.h @@ -1,5 +1,33 @@ #ifndef _ANIM_H_ #define _ANIM_H_ +#include "Draw.h" + +typedef void *Anim; + + +Anim Anim_LoadAnim(char *fichero,int frames,int fps); + +int Anim_GetTime(Anim anim); + +void Anim_SetOffset(Anim anim,int x,int y); +void Anim_GetOffset(Anim anim,int *x,int *y); + +void Anim_Draw(Anim anim,int time_ms,int x,int y); + +typedef struct { + Anim anim; + DrawImg img; + int time_ms; +} AnimPlay; + +void AnimPlay_Copy(AnimPlay *ad,AnimPlay *ao); + +void AnimPlay_SetImg(AnimPlay *ap,DrawImg img); +void AnimPlay_SetAnim(AnimPlay *ap,Anim ani); + +void AnimPlay_Draw(AnimPlay *ani,int x,int y); + +void AnimPlay_IncTime(AnimPlay *ani,int t); #endif diff --git a/Draw.c b/Draw.c index 60132df..5a3d13b 100644 --- a/Draw.c +++ b/Draw.c @@ -178,8 +178,25 @@ DrawImg Draw_LoadImage(char *filename){ // FIX: Setting up the alpha channel. if(surf->format->BytesPerPixel==4){ + int i,len,trans; + + // set the correct values surf->format->Amask=0xFF000000; surf->format->Ashift=24; + + // Check if the image has some area transparent + trans=0; + len=surf->w*surf->h; + for(i=0;ipixels)[i]&0xFF000000)!=0xFF000000){ + trans=1; + break; + } + } + if(trans){ + // Make it use the alpha channel + SDL_SetAlpha(surf, SDL_SRCALPHA, 255); + } } // Create the image container @@ -277,6 +294,28 @@ void Draw_DrawImg(DrawImg img,int x,int y){ } +///////////////////////////// +// Draw_DrawImgPart +// +// Draws an image part. +void Draw_DrawImgPart(DrawImg img,int x,int y,int w,int i){ + DrawImage *image=img; + SDL_Rect orig; + SDL_Rect dest; + + // Prepare the rects + orig.x=w*i; + orig.y=0; + dest.x=x+image->x; + dest.y=y+image->y; + orig.w=dest.w=w; + orig.h=dest.h=image->surf->h; + + // Blit the surface on the screen + SDL_BlitSurface(image->surf,&orig,_screen,&dest); +} + + //////////////////////////////////////////////// // DrawFnt // ///////////// diff --git a/Draw.h b/Draw.h index cb34ad7..cdf42d9 100644 --- a/Draw.h +++ b/Draw.h @@ -80,6 +80,13 @@ void Draw_ImgSetAlpha(DrawImg img, unsigned char a); void Draw_DrawImg(DrawImg img,int x,int y); +///////////////////////////// +// Draw_DrawImgPart +// +// Draws an image part. +void Draw_DrawImgPart(DrawImg img,int x,int y,int w,int i); + + //////////////////////////////////////////////// // DrawFnt // ///////////// diff --git a/Entity.c b/Entity.c index 5b9fc3b..2eed55c 100644 --- a/Entity.c +++ b/Entity.c @@ -4,6 +4,7 @@ #include "Util.h" #include "Draw.h" +#include "Anim.h" #include "Entity.h" @@ -27,10 +28,12 @@ Entity *Entity_New(){ e->fric_static=1.0f; e->fric_dynamic=0.0f; - e->img=NULL; + //e->img=NULL; + AnimPlay_SetImg(&e->anim,NULL); e->proc=NULL; e->postproc=NULL; + e->collision=NULL; return(e); } @@ -64,10 +67,12 @@ Entity *Entity_Copy(Entity *e){ n->fric_static=e->fric_static; n->fric_dynamic=e->fric_dynamic; - n->img=e->img; + //n->img=e->img; + AnimPlay_Copy(&n->anim,&e->anim); n->proc=e->proc; n->postproc=e->postproc; + n->collision=e->collision; return(n); } @@ -78,8 +83,9 @@ Entity *Entity_Copy(Entity *e){ // // void Entity_Draw(Entity *e){ - if(e->img) - Draw_DrawImg(e->img,e->pos[0],e->pos[1]); + //if(e->img) + // Draw_DrawImg(e->img,e->pos[0],e->pos[1]); + AnimPlay_Draw(&e->anim,e->pos[0],e->pos[1]); } @@ -87,11 +93,11 @@ void Entity_Draw(Entity *e){ // Entity_Process // // -void Entity_Process(Entity *b){ +void Entity_Process(Entity *b,int ft){ // Launch method if(b->proc){ - b->proc(b); + b->proc(b,ft); } } @@ -100,12 +106,12 @@ void Entity_Process(Entity *b){ // Entity_PostProcess // // -void Entity_PostProcess(Entity *e){ +void Entity_PostProcess(Entity *e,int ft){ float qlen,len; // Launch method if(e->postproc){ - e->postproc(e); + e->postproc(e,ft); } // Determine if there is movement @@ -126,6 +132,57 @@ void Entity_PostProcess(Entity *e){ 1.0f-(e->fric_dynamic+(e->fric_static/len))); } } + + // Animate + AnimPlay_IncTime(&e->anim,ft); +} + + +///////////////////////////// +// Entity_CollisionResponse +// +// Response to a collision +void Entity_CollisionResponse( + Entity *b1,Entity *b2,float t,vec2 n) +{ + float moment; + vec2 temp,temp2; + float elast; + + if(b1->mass>0.0f && b2->mass>0.0f){ + // Calculate elasticity + elast=(b1->mass*b1->elast+b2->mass*b2->elast)/ + (b1->mass+b2->mass); + + // Collision between two massed balls + moment=((1.0f+elast)*b1->mass*b2->mass* + (vec2_dot(b1->vel,n)+vec2_dot(b2->vel,n))) + /(b1->mass+b2->mass); + vec2_scale(temp,n,moment/b1->mass); + vec2_minus(b1->vel,b1->vel,temp); + vec2_scale(temp,n,moment/b2->mass); + vec2_plus(b2->vel,b2->vel,temp); + }else + if(b1->mass>0.0f && b2->mass<=0.0f){ + // Collision between a massed ball and a fixed ball + moment=(1.0f+b1->elast)* + (vec2_dot(b1->vel,n)); + vec2_scale(temp,n,moment); + vec2_minus(b1->vel,b1->vel,temp); + }else + if(b1->mass<=0.0f && b2->mass>0.0f){ + // Collision between a massed ball and a fixed ball + // (imposible, but better safe) + moment=(1.0f+b2->elast)* + (vec2_dot(b2->vel,n)); + vec2_scale(temp,n,moment); + vec2_plus(b2->vel,b2->vel,temp); + }else{ + // Collision between 2 fixed balls + // (imposible, but better safe) + vec2_set(b1->vel,0,0); + vec2_set(b2->vel,0,0); + } } @@ -153,47 +210,29 @@ int Entity_Collide(Entity *b1,Entity *b2){ vec2_minus(cir1[1],cir1[1],b2->vel); if(Colision_CircleCircle(cir1,b1->radius,b2->pos,b2->radius,&t,n)){ - float moment; - vec2 temp,temp2; - float elast; + int response=1; + + // Check the collision methods + if(b1->collision){ + if(!b1->collision(b1,b2,t,n)){ + response=0; + } + } + if(b2->collision){ + vec2 n2; + vec2_scale(n2,n,-1.0f); + if(!b2->collision(b2,b1,t,n2)){ + response=0; + } + } // Collision response - - if(b1->mass>0.0f && b2->mass>0.0f){ - // Calculate elasticity - elast=(b1->mass*b1->elast+b2->mass*b2->elast)/ - (b1->mass+b2->mass); - - // Collision between two massed balls - moment=((1.0f+elast)*b1->mass*b2->mass* - (vec2_dot(b1->vel,n)+vec2_dot(b2->vel,n))) - /(b1->mass+b2->mass); - vec2_scale(temp,n,moment/b1->mass); - vec2_minus(b1->vel,b1->vel,temp); - vec2_scale(temp,n,moment/b2->mass); - vec2_plus(b2->vel,b2->vel,temp); - }else - if(b1->mass>0.0f && b2->mass<=0.0f){ - // Collision between a massed ball and a fixed ball - moment=(1.0f+b1->elast)* - (vec2_dot(b1->vel,n)); - vec2_scale(temp,n,moment); - vec2_minus(b1->vel,b1->vel,temp); - }else - if(b1->mass<=0.0f && b2->mass>0.0f){ - // Collision between a massed ball and a fixed ball - // (imposible, but better safe) - moment=(1.0f+b2->elast)* - (vec2_dot(b2->vel,n)); - vec2_scale(temp,n,moment); - vec2_plus(b2->vel,b2->vel,temp); + if(response){ + Entity_CollisionResponse(b1,b2,t,n); + return(1); }else{ - // Collision between 2 fixed balls - // (imposible, but better safe) - vec2_set(b1->vel,0,0); - vec2_set(b2->vel,0,0); + return(0); } - return(1); } return(0); } diff --git a/Entity.h b/Entity.h index 264f3e3..79edb39 100644 --- a/Entity.h +++ b/Entity.h @@ -3,6 +3,7 @@ #include "Util.h" #include "Draw.h" +#include "Anim.h" //////////////////////////////////////////////// @@ -22,10 +23,15 @@ typedef struct Tag_Entity{ float fric_static; float fric_dynamic; - DrawImg img; + //DrawImg img; + AnimPlay anim; - void (*proc)(struct Tag_Entity *ent); - void (*postproc)(struct Tag_Entity *ent); + void (*proc)(struct Tag_Entity *ent,int ft); + void (*postproc)(struct Tag_Entity *ent,int ft); + int (*collision)( + struct Tag_Entity *ent, + struct Tag_Entity *ent2, + float t,vec2 n); } Entity; @@ -61,13 +67,13 @@ void Entity_Draw(Entity *e); // Entity_Process // // -void Entity_Process(Entity *e); +void Entity_Process(Entity *e,int ft); ///////////////////////////// // Entity_PostProcess // // -void Entity_PostProcess(Entity *e); +void Entity_PostProcess(Entity *e,int ft); ///////////////////////////// diff --git a/GameLib.c b/GameLib.c index 484cc2e..64ef8d3 100644 --- a/GameLib.c +++ b/GameLib.c @@ -17,7 +17,7 @@ int _n_entities=0; int _n_entities_res=0; void (*_gameproc)()=NULL; void (*_gamepostproc)()=NULL; - +int _ft; ///////////////////////////// // GameLib_Init @@ -31,6 +31,9 @@ int GameLib_Init(int w,int h,char *title,int fps){ return(0); } Audio_Init(); + + _ft=1000/fps; + return(1); } @@ -106,10 +109,17 @@ int GameLib_ProcLoop(){ } // Process entities + vec2 grav; + vec2_set(grav,0,1); for(i=0;i<_n_entities;i++){ if(!_entity[i]) continue; - Entity_Process(_entity[i]); + Entity_Process(_entity[i],_ft); +/* + if(_entity[i]->mass>0.0f){ + vec2_plus(_entity[i]->vel,_entity[i]->vel,grav); + } + */ } // Process colisions between entities @@ -144,7 +154,7 @@ int GameLib_ProcLoop(){ for(i=0;i<_n_entities;i++){ if(!_entity[i]) continue; - Entity_PostProcess(_entity[i]); + Entity_PostProcess(_entity[i],_ft); Entity_Draw(_entity[i]); } diff --git a/SDL.dll b/SDL.dll deleted file mode 100644 index a5da7bb..0000000 Binary files a/SDL.dll and /dev/null differ diff --git a/Util.c b/Util.c index e726273..1c423d9 100644 --- a/Util.c +++ b/Util.c @@ -40,18 +40,18 @@ int Intersec_RayUnitCircle(vec2 orig,vec2 vel,vec2 center,float *t){ // Solve as a unit circle a=vec2_dot(vel,vel); - if(fabs(a)<0.000001f){ + if(fabs(a)<0.0f){ return(0); } vec2_minus(temp,orig,center); b=2.0f*vec2_dot(temp,vel); c=vec2_dot(temp,temp)-1.0f; if(SolveQuadratic(a,b,c,&Rmin,&Rmax)){ - if(Rmin>=-0.0001f && Rmin=-0.0f && Rmin=-0.0001f && Rmin>Rmax && Rmax<=1.0f){ + if(Rmax>=-0.0f && Rmin>Rmax && Rmax<=1.0f){ *t=Rmax; return(1); } diff --git a/data/bloque.bmp b/data/block.bmp similarity index 100% rename from data/bloque.bmp rename to data/block.bmp diff --git a/data/block2.bmp b/data/block2.bmp new file mode 100644 index 0000000..ff63c9e Binary files /dev/null and b/data/block2.bmp differ diff --git a/data/bisho2_alpha.bmp b/data/rball.bmp similarity index 100% rename from data/bisho2_alpha.bmp rename to data/rball.bmp diff --git a/data/whitey.bmp b/data/whitey.bmp new file mode 100644 index 0000000..09a92a4 Binary files /dev/null and b/data/whitey.bmp differ diff --git a/data/bisho_alpha.bmp b/data/yball.bmp similarity index 100% rename from data/bisho_alpha.bmp rename to data/yball.bmp diff --git a/macosx/SDL_dev.zip b/macosx/SDL_dev.zip deleted file mode 100644 index e860dfb..0000000 Binary files a/macosx/SDL_dev.zip and /dev/null differ diff --git a/main.c b/main.c index bbe1921..403d02f 100644 --- a/main.c +++ b/main.c @@ -7,16 +7,25 @@ DrawFnt font; DrawFnt font_shad; -DrawImg img_bisho; -DrawImg img_bisho2; -DrawImg img_bloque; +DrawImg img_yball; +DrawImg img_rball; +DrawImg img_block; +DrawImg img_block2; + +Anim anim_whitey; AudioSnd coin; -Entity *bisho; -Entity *bisho2; -Entity *bloque; - +enum { + Ent_Player, + Ent_Ball, + Ent_Block, + Ent_Block2 +} EntityType; +Entity *ent_player; +Entity *ent_ball; +Entity *ent_block; +Entity *ent_block2; void ProcGame(){ @@ -30,10 +39,9 @@ void PostProcGame(){ Draw_DrawText(font_shad,"Hola Mundo!",11,11); Draw_DrawText(font ,"Hola Mundo!",10,10); - } -void player_proc(Entity *e){ +void player_proc(Entity *e,int ft){ vec2 vel; if(Input_GetDir(vel)){ @@ -42,7 +50,17 @@ void player_proc(Entity *e){ } } +int block2_collision(Entity *e,Entity *e2,float t,vec2 n){ + if(e2->type==Ent_Ball){ + return(0); + }else{ + return(1); + } +} + int main(int argc,char *argv[]){ + int i; + Entity *e; srand(time(NULL)); @@ -51,79 +69,98 @@ int main(int argc,char *argv[]){ font=Draw_DefaultFont(255,255,255,255); font_shad=Draw_DefaultFont(0,0,0,127); - img_bisho=Draw_LoadImage("data/bisho_alpha.bmp"); - Draw_ImgSetAlpha(img_bisho,255); - Draw_SetOffset(img_bisho,-16,-16); + img_yball=Draw_LoadImage("data/yball.bmp"); + Draw_SetOffset(img_yball,-16,-16); - img_bisho2=Draw_LoadImage("data/bisho2_alpha.bmp"); - Draw_ImgSetAlpha(img_bisho2,255); - Draw_SetOffset(img_bisho2,-16,-16); + img_rball=Draw_LoadImage("data/rball.bmp"); + Draw_SetOffset(img_rball,-16,-16); - img_bloque=Draw_LoadImage("data/bloque.bmp"); - Draw_ImgSetAlpha(img_bloque,255); - Draw_SetOffset(img_bloque,-16,-16); + img_block=Draw_LoadImage("data/block.bmp"); + Draw_SetOffset(img_block,-16,-16); + + img_block2=Draw_LoadImage("data/block2.bmp"); + Draw_SetOffset(img_block2,-16,-16); + +// img_whitey=Draw_LoadImage("data/whitey.bmp"); +// Draw_SetOffset(img_whitey,-16,-16); + anim_whitey=Anim_LoadAnim("data/whitey.bmp",4,5); + Anim_SetOffset(anim_whitey,-16,-16); coin=Audio_LoadSound("data/coin.wav"); - bisho=Entity_New(); - bisho->radius=16.0f; - bisho->img=img_bisho; - bisho->proc=player_proc; + ent_player=Entity_New(); + ent_player->type=Ent_Player; + ent_player->radius=16.0f; + //AnimPlay_SetImg(&ent_player->anim,img_whitey); + AnimPlay_SetAnim(&ent_player->anim,anim_whitey); + ent_player->proc=player_proc; - bisho2=Entity_New(); - bisho2->radius=16.0f; - bisho2->fric_static=0.1f; - bisho2->elast=0.0f; - bisho2->img=img_bisho2; + ent_ball=Entity_New(); + ent_ball->type=Ent_Ball; + ent_ball->radius=16.0f; + ent_ball->fric_static=0.1f; + ent_ball->elast=1.0f; + AnimPlay_SetImg(&ent_ball->anim,img_rball); - bloque=Entity_New(); - bloque->mass=-1.0f; - bloque->radius=15.5f; - bloque->img=img_bloque; + ent_block=Entity_New(); + ent_block->type=Ent_Block; + ent_block->mass=-1.0f; + ent_block->radius=15.5f; + AnimPlay_SetImg(&ent_block->anim,img_block); + + ent_block2=Entity_New(); + ent_block2->type=Ent_Block2; + ent_block2->mass=-1.0f; + ent_block2->radius=15.5f; + AnimPlay_SetImg(&ent_block2->anim,img_block2); + ent_block2->collision=block2_collision; - int i; - Entity *e; for(i=0;i<20;i++){ - e=Entity_Copy(bloque); + e=Entity_Copy(ent_block); vec2_set(e->pos,16+i*32,16); GameLib_AddEntity(e); } for(i=0;i<20;i++){ - e=Entity_Copy(bloque); + e=Entity_Copy(ent_block); vec2_set(e->pos,16+i*32,464); GameLib_AddEntity(e); } for(i=1;i<14;i++){ - e=Entity_Copy(bloque); + e=Entity_Copy(ent_block); vec2_set(e->pos,16,16+i*32); GameLib_AddEntity(e); } for(i=1;i<14;i++){ - e=Entity_Copy(bloque); + e=Entity_Copy(ent_block); vec2_set(e->pos,624,16+i*32); GameLib_AddEntity(e); } for(i=0;i<4;i++){ - e=Entity_Copy(bloque); + e=Entity_Copy(ent_block); vec2_set(e->pos,100,100+i*32); GameLib_AddEntity(e); } for(i=0;i<4;i++){ - e=Entity_Copy(bloque); + e=Entity_Copy(ent_block); vec2_set(e->pos,164,100+i*32); GameLib_AddEntity(e); } - e=Entity_Copy(bisho2); + e=Entity_Copy(ent_block2); + vec2_set(e->pos,132,100+3*32); + GameLib_AddEntity(e); + + e=Entity_Copy(ent_ball); vec2_set(e->pos,132,100); GameLib_AddEntity(e); - e=Entity_Copy(bisho); + e=Entity_Copy(ent_player); vec2_set(e->pos,132,50); GameLib_AddEntity(e); + GameLib_Loop(ProcGame,PostProcGame);