#include "SDL.h"
#include <stdio.h>
#include <stdlib.h>
#define RANDOM(N) ((int)(((double)rand()/RAND_MAX)*(N)))
#define WinXSize 320
#define WinYSize 240
#define ColorDepth 8
#define RECTSIZE 100
#define CHARSIZ 8
int charx, chary=193;
int jumpcnt, jumpflg;
#define JUMPHIGH 20
#define JUMPSPD 4
#define BLOCKSIZ 4
#define MAPWID (WinXSize/BLOCKSIZ)
#define MAPHIG (WinYSize/BLOCKSIZ)
char map[MAPWID][MAPHIG];
void init_map()
{
int i, j;
for (i = 0; i < MAPWID; i++) {
map[i][MAPHIG-1] = 1;
}
for (i = 0; i < MAPWID; i++) {
for (j = 0; j < MAPHIG; j++) {
if (RANDOM(30)==0) {
map[i][j] = 1;
}
}
}
}
int hit_map(int ax, int ay){
int i, j;
int x, y, x2, y2;
x = ax / BLOCKSIZ;
if (x< 0 || x >= MAPWID) return 0;
y = ay / BLOCKSIZ;
if (y< 0 || y >= MAPHIG) return 0;
x2 = (ax+ CHARSIZ-2) / BLOCKSIZ;
if (x2< 0 || x2 >= MAPWID) return 0;
y2 = (ay+CHARSIZ-2) / BLOCKSIZ;
if (y< 0 || y >= MAPHIG) return 0;
for (i = 0; i < CHARSIZ / BLOCKSIZ; i++) {
for (j = 0; j < CHARSIZ / BLOCKSIZ; j++) {
if (map[x+i][y+j]) return 1;
}
}
for (i = 0; i < CHARSIZ / BLOCKSIZ; i++) {
if (map[x2][y+i]) return 1;
}
for (i = 0; i < CHARSIZ / BLOCKSIZ; i++) {
if (map[x+i][y2]) return 1;
}
if (map[x2][y2]) return 1;
return 0;
}
void move(int xv, int yv)
{
int maxv, i;
jumpflg = 0;
if (abs(xv) > abs(yv)){
maxv = abs(xv);
} else {
maxv = abs(yv);
}
for (i = 0; i < maxv; i++) {
if ( abs(xv) > i) {
if (!hit_map(charx + xv, chary) ){
charx += xv > 0 ? 1: -1;
}
}
if ( abs(yv) > i) {
if (!hit_map(charx, chary + yv) ){
chary += yv > 0 ? 1: -1;
} else if (yv > 0) {
jumpflg = 1;
}
}
}
}
void put_box(SDL_Surface *screen, int x, int y, int w, int h, Uint32 color)
{
SDL_Rect dest;
dest.w = w;
dest.h = h;
dest.x = x;
dest.y = y;
SDL_FillRect(screen,&dest,color);
}
void disp_map(SDL_Surface *screen)
{
int i, j;
for (i = 0; i < MAPWID; i++) {
for (j = 0; j < MAPHIG; j++) {
if (map[i][j]) {
put_box(screen, i*BLOCKSIZ, j*BLOCKSIZ, BLOCKSIZ, BLOCKSIZ, SDL_MapRGB(screen->format, 0, 255, 0));
}
}
}
}
void ctrl(SDL_Event e){
static int charxvel, charyvel;
switch(e.type){
case SDL_KEYDOWN:
switch(e.key.keysym.sym){
case SDLK_LEFT:
charxvel = -1;
break;
case SDLK_RIGHT:
charxvel = 1;
break;
case SDLK_SPACE:
if (jumpflg) {
jumpcnt = JUMPHIGH;
}
break;
default:
break;
}
break;
case SDL_KEYUP:
switch(e.key.keysym.sym){
case SDLK_LEFT:
charxvel = 0;
break;
case SDLK_RIGHT:
charxvel = 0;
break;
default:
break;
}
}
if ((charxvel == -1 && charx <= 0) || (charxvel == 1 &&charx >= WinXSize - CHARSIZ)){
charxvel = 0;
}
if (jumpcnt > 0) {
charyvel = -JUMPSPD;
jumpcnt --;
} else {
charyvel = JUMPSPD;
}
move(charxvel, charyvel);
}
void gmain(SDL_Surface *screen){
put_box(screen, 0, 0, WinXSize, WinYSize, SDL_MapRGB(screen->format, 0, 0, 0));
disp_map(screen);
put_box(screen, charx, chary, CHARSIZ, 10, SDL_MapRGB(screen->format, 255, 0, 0));
SDL_UpdateRect(screen,0,0,0,0);
}
int main(int argc,char *argv[])
{
SDL_Surface *screen;
SDL_Event e;
int done = 0;
if(SDL_Init(SDL_INIT_VIDEO)<0)
exit(1);
screen = SDL_SetVideoMode(WinXSize,WinYSize,ColorDepth,SDL_HWSURFACE);
if(screen == NULL){
SDL_Quit();
exit(2);
}
init_map();
do{
if (SDL_PollEvent(&e) != 0){
switch(e.type){
case SDL_QUIT:
done = 1;
break;
}
}
ctrl(e);
gmain(screen);
SDL_Delay(16);
}while(!done);
SDL_Quit();
return 0;
}