catbug game!

This commit is contained in:
Iris Lightshard 2019-02-04 13:24:24 -08:00
commit 10448750d0
Signed by: Iris Lightshard
GPG key ID: 3B7FBC22144E6398
22 changed files with 878 additions and 0 deletions

72
Catbug.c Normal file
View file

@ -0,0 +1,72 @@
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include "config.h"
#include "Engine.h"
#include "Catbug.h"
#include "Timer.h"
#include "Pickups.h"
#include "extern.h"
Catbug* newCatbug(int x, int y)
{
Catbug* self = malloc(sizeof(Catbug));
self->x = x;
self->y = y;
self->vX = 0;
self->vY = 0;
self->HP = STARTING_HP;
self->frame = 0;
self->spriteSheet=loadImage("assets/catbug.png");
return self;
}
void deleteCatbug(Catbug* target)
{
SDL_FreeSurface(target->spriteSheet);
free(target);
}
void moveCatbug(Catbug* self)
{
self->x += self->vX;
self->y += self->vY;
if (self->x <= 0 || self->x >= 320)
self->x -= self->vX;
if (self->y <=0 || self->y >= 180)
self->y -= self->vY;
}
void drawCatbug(Catbug* self)
{
SDL_Rect clip;
clip.x = 0;
clip.y = 0;
clip.w = 43;
clip.h = 39;
switch (self->frame)
{
case 0:
clip.x = 0;
self->frame = 1;
break;
case 1:
clip.x = 43;
self->frame = 0;
break;
}
applySurface(self->x - 22, self->y - 19, self->spriteSheet, screen, &clip);
}
int isInRect(Catbug* self, SDL_Rect* box)
{
if (self->x >= box->x && self->x <= box->x + box->w
&& self->y >= box->y && self->y <= box->y + box->h)
return 1;
else return 0;
}

19
Catbug.h Normal file
View file

@ -0,0 +1,19 @@
typedef struct catbug
{
SDL_Surface* spriteSheet;
unsigned short int frame;
int x;
int y;
int vX;
int vY;
unsigned short int HP;
} Catbug;
Catbug* newCatbug(int x, int y);
void deleteCatbug(Catbug* target);
int isInRect(Catbug* self, SDL_Rect* box);
void moveCatbug(Catbug* self);
void drawCatbug(Catbug* self);

441
Engine.c Normal file
View file

@ -0,0 +1,441 @@
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "config.h"
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include "Engine.h"
#include "Timer.h"
#include "Catbug.h"
#include "Pickups.h"
#include "extern.h"
SDL_Surface* loadImage(char* filename)
{
SDL_Surface* loadedImage = NULL;
SDL_Surface* optimizedImage = NULL;
loadedImage = IMG_Load(filename);
if (loadedImage != NULL)
{
optimizedImage = SDL_DisplayFormat(loadedImage);
SDL_FreeSurface(loadedImage);
}
return optimizedImage;
}
void applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip)
{
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, clip, destination, &offset);
}
Uint32 getPixel(SDL_Surface* surface, int x, int y)
{
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * surface->format->BytesPerPixel;
return *(Uint32 *)p;
}
void scaleScreen()
{
Sint32 x, y;
static SDL_Rect superPixel = {0,0, SCALE_FACTOR,SCALE_FACTOR};
switch (SCALE_FACTOR)
{
case 1:
applySurface(0,0,screen,window,NULL);
break;
default:
superPixel.y = 0;
for (y = 0; y < SCREEN_HEIGHT; y++)
{
superPixel.x = 0;
for (x = 0; x < SCREEN_WIDTH; x++)
{
SDL_FillRect(window, &superPixel, getPixel(screen, x, y));
superPixel.x += SCALE_FACTOR;
}
superPixel.y += SCALE_FACTOR;
}
break;
}
}
void updateScore()
{
SDL_Color white = {255,255,255};
char sPoints[10];
sprintf(sPoints, "%d", points);
score = TTF_RenderText_Solid(font,sPoints,white);
applySurface(10, 20, score, screen, NULL);
}
void drawHP()
{
int i;
for (i = 0; i < player->HP; i++)
{
applySurface(10+(6*i), 10, hpwedge, screen, NULL);
}
}
void checkHP()
{
if (player->HP <= 0)
{
scoreSummary();
quit = 1;
}
}
void scoreSummary()
{
SDL_Surface* yougot = NULL;
SDL_Surface* hiscore = NULL;
SDL_Color white = {255, 255, 255};
char sPoints[10];
sprintf(sPoints,"%d", points);
yougot = TTF_RenderText_Solid(font2, "SCORE:" ,white);
hiscore = TTF_RenderText_Solid(font2, sPoints, white);
int here = 1;
while (here)
{
timeStart(&fps);
renderBG();
applySurface(120, 80, yougot, screen, NULL);
applySurface(120, 105, hiscore, screen, NULL);
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case FS_BUTTON:
toggleFullscreen();
break;
case PAUSE_BUTTON:
here = 0;
quit = 0;
break;
case QUIT_BUTTON:
here = 0;
playing = 0;
default:
break;
}
break;
case SDL_QUIT:
here = 0;
playing = 0;
break;
default:
break;
}
}
frameAdvance();
}
SDL_FreeSurface(yougot);
SDL_FreeSurface(hiscore);
}
void renderBG()
{
static int x = 0;
applySurface(x,0,bg,screen,NULL);
applySurface(x+1472,0,bg,screen,NULL);
x -= 8;
if (x == -1472) x = 0;
}
void interact()
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case DPAD_UP:
player->vY = -PLAYER_SPD;
break;
case DPAD_LEFT:
player->vX = -PLAYER_SPD;
break;
case DPAD_DOWN:
player->vY = PLAYER_SPD;
break;
case DPAD_RIGHT:
player->vX = PLAYER_SPD;
break;
case FS_BUTTON:
toggleFullscreen();
break;
case PAUSE_BUTTON:
pauseGame();
break;
case QUIT_BUTTON:
quit = 1;
playing = 0;
break;
default:
break;
}
break;
case SDL_KEYUP:
switch (event.key.keysym.sym)
{
case DPAD_UP:
if (player->vY < 0)
player->vY = 0;
break;
case DPAD_LEFT:
if (player->vX < 0)
player->vX = 0;
break;
case DPAD_DOWN:
if (player->vY > 0)
player->vY = 0;
break;
case DPAD_RIGHT:
if (player->vX > 0)
player->vX = 0;
break;
default:
break;
}
break;
case SDL_QUIT:
quit = 1;
playing = 0;
break;
default:
break;
}
}
}
int init(int argc, char* args[])
{
int i;
printf("Initializing SDL\n");
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) == -1) return 0;
printf("Initialized SDL\nCreating window\n");
if (argc >= 2)
{
if (strcmp(args[1], "-w"))
{
window = SDL_SetVideoMode(SCREEN_WIDTH*SCALE_FACTOR, SCREEN_HEIGHT*SCALE_FACTOR, 32, SDL_FULLSCREEN|SDL_HWSURFACE);
fullscreen = 1;
}
else window = SDL_SetVideoMode(SCREEN_WIDTH*SCALE_FACTOR, SCREEN_HEIGHT*SCALE_FACTOR, 32, SDL_HWSURFACE|SDL_RESIZABLE);
}
else
{
window = SDL_SetVideoMode(SCREEN_WIDTH*SCALE_FACTOR, SCREEN_HEIGHT*SCALE_FACTOR, 32, SDL_FULLSCREEN|SDL_HWSURFACE);
fullscreen = 1;
}
SDL_ShowCursor(0);
screen = loadImage("assets/rawscreen.png");
if (window == NULL || screen == NULL) return 0;
SDL_WM_SetCaption("Catbug", NULL);
printf("Window created\nInitializing data\n");
if (TTF_Init() == -1) return 0;
ticker = time(NULL);
bg = loadImage("assets/seethruzone.png");
hpwedge = loadImage("assets/hp.png");
font = TTF_OpenFont("assets/charriot.ttf", 10);
font2 = TTF_OpenFont("assets/charriot.ttf", 20);
player = newCatbug(35, 90);
stuff = malloc(10*sizeof(Pickup*));
for (i = 0; i < 10; i++)
{
stuff[i] = NULL;
}
return 1;
}
void title()
{
SDL_Surface* titletxt = loadImage("assets/titletext.png");
int here = 1;
while (here)
{
timeStart(&fps);
renderBG();
applySurface(0, 0, titletxt, screen, NULL);
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case FS_BUTTON:
toggleFullscreen();
break;
case PAUSE_BUTTON:
here = 0;
quit = 0;
break;
case QUIT_BUTTON:
here = 0;
quit = 1;
playing = 0;
default:
break;
}
break;
case SDL_QUIT:
here = 0;
playing = 0;
quit = 1;
break;
default:
break;
}
}
frameAdvance();
}
SDL_FreeSurface(titletxt);
}
void resetGame()
{
maxHP = STARTING_HP;
player->HP = STARTING_HP;
player->x = 35;
player->y = 90;
player->vX = 0;
player->vY = 0;
points = 0;
threshold = 10;
cleanPickups();
}
void pauseGame()
{
SDL_Color white = {255,255,255};
SDL_Surface* paused = TTF_RenderText_Solid(font,"paused",white);
int here = 1;
while (here)
{
timeStart(&fps);
player->vX = 0;
player->vY = 0;
applySurface(10,30,paused,screen,NULL);
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case FS_BUTTON:
toggleFullscreen();
break;
case PAUSE_BUTTON:
here = 0;
break;
case QUIT_BUTTON:
here = 0;
playing = 0;
quit = 1;
default:
break;
}
break;
case SDL_QUIT:
here = 0;
playing = 0;
quit = 1;
break;
default:
break;
}
}
frameAdvance();
}
SDL_FreeSurface(paused);
}
void timeDilation()
{
int i = getTicks(&fps);
if (i < 1000/30)
SDL_Delay(1000/30 - i);
}
void frameAdvance()
{
scaleScreen();
SDL_Flip(window);
timeDilation();
}
void toggleFullscreen()
{
if (!fullscreen)
{
SDL_SetVideoMode(SCREEN_WIDTH*SCALE_FACTOR, SCREEN_HEIGHT*SCALE_FACTOR, 32, SDL_FULLSCREEN|SDL_HWSURFACE);
fullscreen = 1;
}
else
{
SDL_SetVideoMode(SCREEN_WIDTH*SCALE_FACTOR, SCREEN_HEIGHT*SCALE_FACTOR, 32, SDL_HWSURFACE|SDL_RESIZABLE);
fullscreen = 0;
}
}
void cleanup()
{
if (fullscreen)
toggleFullscreen();
printf("Freeing assets\n");
deleteCatbug(player);
cleanPickups();
free(stuff);
SDL_FreeSurface(bg);
SDL_FreeSurface(hpwedge);
SDL_FreeSurface(score);
SDL_FreeSurface(screen);
SDL_FreeSurface(window);
TTF_CloseFont(font);
TTF_CloseFont(font2);
printf("Closing SDL systems\n");
TTF_Quit();
SDL_Quit();
printf("Cleanup complete\n");
}

22
Engine.h Normal file
View file

@ -0,0 +1,22 @@
SDL_Surface* loadImage(char* filename);
void applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip);
void scaleScreen();
void renderBG();
void drawHP();
void checkHP();
void updateScore();
void title();
void resetGame();
void pauseGame();
void scoreSummary();
void interact();
int init(int argc, char* args[]);
void cleanup();
void toggleFullscreen();
void timeDilation();
void frameAdvance();

16
Makefile Normal file
View file

@ -0,0 +1,16 @@
CFLAGS= -Wall -I/usr/include/SDL -L/usr/lib/ -lSDL -lSDL_image -lSDL_ttf
.PHONY: all clean cleanobj
all: game
game: main.c Catbug.o Engine.o Timer.o Pickups.o
$(CC) -o katbug $^ $(CFLAGS)
cleanobj:
rm -f *.o
clean:
rm -f katbug *.o
reconfigure: clean game

144
Pickups.c Normal file
View file

@ -0,0 +1,144 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include "config.h"
#include "Engine.h"
#include "Catbug.h"
#include "Pickups.h"
#include "Timer.h"
#include "extern.h"
Pickup* newPickup()
{
int pType;
srand(rand());
pType = rand()%10;
Pickup* self = malloc(sizeof(Pickup));
self->y = 16 + rand()%148;
self->x = 320 + rand()%120;
self->vX = -4 - rand()%maxHP;
self->vY = 0;
switch (pType)
{
case 0:
case 1:
case 2:
case 3:
case 4:
self->sprite = loadImage("assets/sugarpeas.png");
self->points = 1;
break;
case 5:
case 6:
case 7:
self->sprite = loadImage("assets/peanutbuttersquare.png");
self->points = 2;
break;
case 8:
case 9:
self->sprite = loadImage("assets/taco.png");
self->points = 3;
break;
}
return self;
}
void managePickups()
{
int i;
int genSpeed;
srand(rand());
if (points > 10)
genSpeed = rand()%points;
else genSpeed = rand()%10;
for (i = 0; i < 10; i++)
{
if (stuff[i] != NULL)
{
drawPickup(stuff[i]);
movePickup(stuff[i]);
if (stuff[i]->x < -16)
{
invalidatePickup(stuff[i]);
player->HP--;
stuff[i] = NULL;
}
else
{
SDL_Rect box;
box.x = stuff[i]->x - 18;
box.y = stuff[i]->y - 18;
box.w = 36;
box.h = 36;
if (isInRect(player, &box))
{
getPickup(stuff[i]);
stuff[i] = NULL;
}
}
}
else
{
if ( (stuff[i] == NULL) &&
((points >= 40 && genSpeed*genSpeed >= points*4) ||
(points <= 40 && genSpeed*genSpeed >= threshold*2)) )
{
if (ticker != time(NULL)){
stuff[i] = newPickup();
ticker = time(NULL);}
}
}
}
}
void movePickup(Pickup* self)
{
self->x += self->vX;
}
void drawPickup(Pickup* self)
{
applySurface(self->x - 16, self->y - 16, self->sprite, screen, NULL);
}
void invalidatePickup(Pickup* self)
{
SDL_FreeSurface(self->sprite);
free(self);
}
void getPickup(Pickup* self)
{
points += self->points;
if (points >= threshold)
{
threshold *= 2;
maxHP++;
player->HP = maxHP;
}
invalidatePickup(self);
}
void cleanPickups()
{
int i;
for (i = 0; i < 10; i++)
{
if (stuff[i] != NULL)
{
invalidatePickup(stuff[i]);
stuff[i] = NULL;
}
}
}

19
Pickups.h Normal file
View file

@ -0,0 +1,19 @@
typedef struct pickup
{
int x;
int y;
int vX;
int vY;
SDL_Surface* sprite;
int points;
} Pickup;
Pickup* newPickup();
void managePickups();
void movePickup(Pickup* self);
void drawPickup(Pickup* self);
void invalidatePickup(Pickup* self);
void getPickup(Pickup* self);
void cleanPickups();

25
Timer.c Normal file
View file

@ -0,0 +1,25 @@
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include "Timer.h"
Timer* newTimer()
{
Timer* self = (Timer*)malloc(sizeof(Timer));
self->startTicks = 0;
return self;
}
void timeStart(Timer* self)
{
self->startTicks = SDL_GetTicks();
}
int getTicks(Timer* self)
{
if (self->startTicks)
return SDL_GetTicks() - self->startTicks;
else return 0;
}

8
Timer.h Normal file
View file

@ -0,0 +1,8 @@
typedef struct timer
{
int startTicks;
} Timer;
void timeStart(Timer* self);
int getTicks(Timer* self);

BIN
assets/catbug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
assets/charriot.ttf Normal file

Binary file not shown.

BIN
assets/hp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

BIN
assets/press_space.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

BIN
assets/rawscreen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
assets/seethruzone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
assets/sugarpeas.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 B

BIN
assets/taco.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

BIN
assets/titletext.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

19
config.h Normal file
View file

@ -0,0 +1,19 @@
// key configuration
// see https://sdl.beuc.net/sdl.wiki/SDLKey for keysyms
// for joypad support use a tool like antimicro
#define DPAD_UP SDLK_UP
#define DPAD_DOWN SDLK_DOWN
#define DPAD_LEFT SDLK_LEFT
#define DPAD_RIGHT SDLK_RIGHT
#define PAUSE_BUTTON SDLK_SPACE
#define QUIT_BUTTON SDLK_q
#define FS_BUTTON SDLK_f
// difficulty settings: 3/6/7 is a good balance
#define STARTING_HP 3
#define PLAYER_SPD 6
#define SPEED_MOD 7
// video scaling factor
#define SCALE_FACTOR 2

27
extern.h Normal file
View file

@ -0,0 +1,27 @@
extern int playing;
extern int quit;
extern int fullscreen;
extern int points;
extern int threshold;
extern int maxHP;
extern time_t ticker;
extern Timer fps;
extern SDL_Event event;
extern SDL_Surface* screen;
extern SDL_Surface* window;
extern SDL_Surface* bg;
extern SDL_Surface* hpwedge;
extern SDL_Surface* score;
extern TTF_Font* font;
extern TTF_Font* font2;
extern Catbug* player;
extern Pickup** stuff;
enum screenDimension
{
SCREEN_WIDTH = 320,
SCREEN_HEIGHT = 180
};

66
main.c Normal file
View file

@ -0,0 +1,66 @@
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include "config.h"
#include "Engine.h"
#include "Catbug.h"
#include "Timer.h"
#include "Pickups.h"
int playing = 1;
int quit = 0;
int fullscreen = 0;
int points = 0;
int threshold = 10;
int maxHP = STARTING_HP;
time_t ticker;
Timer fps;
SDL_Event event;
SDL_Surface* screen = NULL;
SDL_Surface* window = NULL;
SDL_Surface* score = NULL;
SDL_Surface* bg = NULL;
SDL_Surface* hpwedge = NULL;
TTF_Font* font = NULL;
TTF_Font* font2 = NULL;
Catbug* player;
Pickup** stuff;
int main(int argc, char* args[])
{
if (!init(argc, args))
{
printf("Init failed\n");
return 1;
}
printf("Init complete\n");
while (playing)
{
title();
resetGame();
while(!quit)
{
timeStart(&fps);
renderBG();
drawCatbug(player);
moveCatbug(player);
managePickups();
updateScore();
drawHP();
interact();
frameAdvance();
checkHP();
}
}
cleanup();
return 0;
}