제가 아직 군대도 안간 대학교 2학년생이다보니 모르는게 많어요 ㅠㅠ
지금 게임만드는 중인데 룸, 뷰까지는 직접 구현을 했거든요.
근데 인스턴스를 생성했다 지웠다 그런걸 관리하는게 방법이 좀 애매했었어요.
어떻게든 되겠지 싶어서 무식하게 2000개나 되는 인스턴스들을 배열로 모조리 때려박아놓고 자신에게서 가장 가까운 인스턴스 id 얻어내는 함수가 반복문을 2000번 돌려버리는 구조로 만들어버림 ㅋㅋㅋㅋㅋㅋ
그래서 반복량이 2000*2000 해서 매 걸음마다(프레임 구현은 했는데 방식은 로크라이크로 할려구요) 프레임 운지 ㅋㅋㅋ 골때림
그래서 최근에 학교에서 배웠던 리스트 구조체 적용시켜서(배열은 괜히 생성했다 지웠다하면 골때릴것같아서) 플레이어 주변에만 적, apc들 스폰하는 방식으로 만들었긴 한데 그래도 왠지 이것보다 더 좋은 방법이 있을것같은 느낌이 드네요...
일단 소스,, 좀 골때림 ㅠㅠ 게임메이커라는툴 다루던때부터 개적화로 유명해섴ㅋㅋㅋ
// SDL GAME.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//
#include "stdafx.h"
#include <SDL.h>
#include <sdl_gdiplus.h>
#include <string>
#include <time.h>
#include <math.h>
#pragma comment(lib,"SDL")
#pragma comment(lib,"SDLmain")
#pragma comment(lib,"SDL_gdiplus")
#define MapWidth 500
#define view_wview 480
#define view_hview 480
#define MaxAct 2000
SDL_Surface *screen;
bool keyLeft=0,
keyRight=0,
keyUp=0,
keyDown=0,
keyLeftPress=0,
keyRightPress=0,
keyUpPress=0,
keyDownPress=0,
mbLeft=0;
int mouse_x,mouse_y,globalId=0;
short mapPos[MapWidth][MapWidth]={0};
bool canPass[7]={0},ally[4][4]={0};
int view_xview=0,view_yview=0,turnCount=16;
int random(int x){return rand()%(x+1);}
int sign(int x){return x>0?1:x<0?-1:0;}
int max(int x,int y){return x>y?x:y;}
int min(int x,int y){return x<y?x:y;}
float min(float x,float y){return x<y?x:y;}
float distance(int x1,int y1,int x2,int y2){return sqrt(pow((float)(x1-x2),2)+pow((float)(y1-y2),2));}
SDL_Surface* LoadIMG(std::string name){
SDL_Surface* Loadedimage=NULL;
SDL_Surface* Optimizedimage=NULL;
Loadedimage=IMG_Load(name.c_str());
if(Loadedimage!=NULL){
Optimizedimage=SDL_DisplayFormat(Loadedimage);
SDL_FreeSurface(Loadedimage);
//printf("\"%s\" loading success\n",name.c_str());
}//else printf("\"%s\" loading fail\n",name.c_str());
return Optimizedimage;
}
typedef struct Position{
int x,y;
}Position;
typedef struct Sprite{
SDL_Surface *res;
int width,height,xoffset,yoffset;
}Sprite;
typedef struct Object{
Object *link;
int id,flag;
Sprite spr;
Position pos,targetPos,posPrev;
}Object;
Object *act;
void SpriteInit(Sprite &spr){
spr.width=1;
spr.height=1;
spr.xoffset=0;
spr.yoffset=0;
//printf("width: %d / height: %d\n",spr.res->w,spr.res->h);
}
void InstanceCreate(int x,int y){
Object *obj,*get;
obj=(Object*)malloc(sizeof(Object));
obj->link=NULL;
obj->id=globalId;
globalId++;
obj->spr.res=LoadIMG("res\\img\\charactor.png");
SpriteInit(obj->spr);
obj->spr.width=4;
SDL_SetColorKey(obj->spr.res,SDL_SRCCOLORKEY,0x008000);
obj->pos.x=x;
obj->pos.y=y;
obj->flag=random(1)?3:random(1)?1:2;
if(act!=NULL){
for(get=act;get->link!=NULL;get=get->link);
get->link=obj;
}else{
act=obj;
}
printf("Instance %d 생성\n",obj->id);
}
void InstanceDestroy(int id){
Object *ins,*pre;
for(ins=act,pre=act;ins->link!=NULL;pre=ins,ins=ins->link){
if(ins->id==id){
pre->link=ins->link;
free(ins);
return;
}
}
printf("Instance %d 제거\n",ins->id);
}
void ActClear(){
Object *ins;
while(act->link!=NULL){
for(ins=act;ins->link!=NULL;);
printf("Instance %d 제거\n",ins->id);
free(ins);
}
printf("Instance %d 제거\n",act->id);
free(act);
printf("Instance 클리어\n");
}
Object* NearestEnemyIndex(Object *target){
Object *get,*tget=NULL;
float dist=10000,sub;
for(get=act;get->link!=NULL;get=get->link){
if(!ally[target->flag][get->flag]){
sub=distance(target->pos.x,target->pos.y,get->pos.x,get->pos.y);
if(sub<dist){
dist=sub;
tget=get;
}
}
}
return tget;
}
int CanMove(int x,int y){
Object *ins;
if(!canPass[mapPos[x][y]])return 0;
for(ins=act;ins->link!=NULL;ins=ins->link){if(ins->pos.x==x&&ins->pos.y==y)return 0;}
return 1;
}
void DrawSurface(SDL_Surface *dst,Sprite spr,int index,int x,int y){
SDL_Rect rectDst,rectSrc;
rectDst.x=x-spr.xoffset;
rectDst.y=y-spr.yoffset;
rectSrc.x = (index%spr.width) * spr.res->w/spr.width;
rectSrc.y = (index/spr.width) * spr.res->h/spr.height;
rectSrc.w = spr.res->w/spr.width;
rectSrc.h = spr.res->h/spr.height;
SDL_BlitSurface(spr.res,&rectSrc,dst,&rectDst);
}
void Render(){
SDL_Flip(screen);
}
void DrawObject(SDL_Surface *dst,Object *obj){
DrawSurface(dst,obj->spr,obj->flag,
obj->pos.x*16-view_xview-sign(obj->pos.x-obj->posPrev.x)*max(0,16-turnCount)+sign(act->pos.x-act->posPrev.x)*max(0,16-turnCount),
obj->pos.y*16-view_yview-sign(obj->pos.y-obj->posPrev.y)*max(0,16-turnCount)+sign(act->pos.y-act->posPrev.y)*max(0,16-turnCount)
);
}
int main(int argc,char **argv){
SDL_Init(SDL_INIT_VIDEO);
screen=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE | SDL_DOUBLEBUF);
//변수 선언
bool quit=0;
float fps=60;
clock_t fStart=clock();
int i,j;
SDL_Event event;
//게임변수 선언
int move_delay=0;
short turn=0;
//리소스 로드
Sprite back;
Sprite backstep;
Sprite background;
back.res=LoadIMG("res\\img\\back0.png");
SpriteInit(back);
SDL_SetColorKey(back.res,SDL_SRCCOLORKEY,SDL_MapRGB(back.res->format,0,128,0));
backstep.res=LoadIMG("res\\img\\back1.png");
SpriteInit(backstep);
background.res=LoadIMG("res\\img\\background.png");
SpriteInit(background);
background.width=7;
//게임관련 변수 초기화
SDL_WM_SetCaption("SDL GAME TEST",NULL);
srand((unsigned)time(NULL));
for(i=0;i<MapWidth;i++)for(j=0;j<MapWidth;j++)
mapPos[i][j]=random(6);
//블록 통행여부
canPass[0]=1;
canPass[1]=1;
canPass[2]=1;
canPass[3]=1;
canPass[4]=1;
canPass[5]=1;
canPass[6]=0;
//동맹 여부
ally[0][0]=1;
ally[0][1]=1;
ally[0][2]=0;
ally[0][3]=0;
ally[1][0]=1;
ally[1][1]=1;
ally[1][2]=0;
ally[1][3]=0;
ally[2][0]=0;
ally[2][1]=0;
ally[2][2]=0;
ally[2][3]=0;
ally[3][0]=0;
ally[3][1]=0;
ally[3][2]=0;
ally[3][3]=1;
//인스턴스 생성
InstanceCreate(random(MapWidth),random(MapWidth));
act->flag=0;
while(!quit){
if(clock()-fStart>=1000/fps)
{
Object *ins;
//프레임 초기화
fStart=clock();
keyLeftPress=0;
keyRightPress=0;
keyUpPress=0;
keyDownPress=0;
if(SDL_PollEvent(&event)){
switch(event.type){
case SDL_QUIT:
quit=1;
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym){
case SDLK_LEFT:
keyLeft=1;
keyLeftPress=1;
break;
case SDLK_RIGHT:
keyRight=1;
keyRightPress=1;
break;
case SDLK_UP:
keyUp=1;
keyUpPress=1;
break;
case SDLK_DOWN:
keyDown=1;
keyDownPress=1;
break;
case SDLK_SPACE:
printf("%d\n",act->pos.x);
break;
}
break;
case SDL_KEYUP:
switch(event.key.keysym.sym){
case SDLK_LEFT:
keyLeft=0;
break;
case SDLK_RIGHT:
keyRight=0;
break;
case SDLK_UP:
keyUp=0;
break;
case SDLK_DOWN:
keyDown=0;
break;
}
break;
case SDL_MOUSEBUTTONDOWN:
switch(event.button.button){
case SDL_BUTTON_LEFT:
mbLeft=1;
break;
}
break;
case SDL_MOUSEBUTTONUP:
switch(event.button.button){
case SDL_BUTTON_LEFT:
mbLeft=0;
break;
}
break;
case SDL_MOUSEMOTION:
mouse_x=event.motion.x;
mouse_y=event.motion.y;
break;
}
}
//캐릭터 이동
bool gR=0,gL=0,gD=0,gU=0;
if(mouse_x<480){
gR=mbLeft&&mouse_x-240>= abs(mouse_y-240);
gL=mbLeft&&mouse_x-240<=-abs(mouse_y-240);
gD=mbLeft&& abs(mouse_x-240)<=mouse_y-240;
gU=mbLeft&&-abs(mouse_x-240)>=mouse_y-240;
}
if((gR||gL||gD||gU||mbLeft)&&move_delay<=0){
move_delay=16;
act->posPrev.x=act->pos.x;
act->posPrev.y=act->pos.y;
if(gR&&CanMove(act->pos.x+1,act->pos.y)){
act->pos.x+=1;
if(!keyLeft)turn++;
}
if(gL&&CanMove(act->pos.x-1,act->pos.y)){
act->pos.x-=1;
if(!keyRight)turn++;
}
if(gD&&CanMove(act->pos.x,act->pos.y+1)){
act->pos.y+=1;
if(!keyUp)turn++;
}
if(gU&&CanMove(act->pos.x,act->pos.y-1)){
act->pos.y-=1;
if(!keyDown)turn++;
}
act->pos.x=max(0,min(MapWidth-1,act->pos.x));
act->pos.y=max(0,min(MapWidth-1,act->pos.y));
}else{move_delay-=1;}
turnCount++;
while(turn){
turn--;
turnCount=0;
for(ins=act;ins->link!=NULL;ins=ins->link){
Object *nearIndex;
ins->posPrev.x=ins->pos.x;
ins->posPrev.y=ins->pos.y;
if(!random(5)){
ins->targetPos.x=random(MapWidth);
ins->targetPos.y=random(MapWidth);
}
nearIndex=N
엌 소스 짤리네
나중에 소프트웨어공학 배우면 패턴이랑 아키텍쳐 뭐 써야겠다 느낌이 올거임
그리고 나중에 프로세스 패턴은 어디다 팔아먹었는지 의문을 가지며 신입사원이 되겠지
창조적인 생각도 중요하긴한데, 일단 발견된 개발 방법론에 대한 거는 익히고, 거기서 나름대로의 방법론을 구축해야 되지 않을까 생각한다. 자료구조나 알고리즘책을 참고하고, 그전에 sicp 를 읽어보면 훨씬더 도움이 될거 같다(번역본 보다는 원서가 훨씬 좋다). 난 너무 졸려서 이만 잘거고. 암튼 건투를 빈다. 멋지다.
대학교 2학년이 이걸 짰다고? 쩌네
헠헠 좋은 정보들 감사합니다. 레노미나님 응원 항상 감사합니다 ㅜㅜ
반헤일런// 헤헤 게임메이커라는 툴 한 2년가량 만져보니까 느낌이 오더라구요. 그래서 학교에서도 친구들이나 선배님들이 프로그래밍 실력 올리는 노하우같은거 물어보실때 맨날 게임메이커 써봐라고 그래요 ㅋㅋ
대문자//감사합니다 ㅎㅎㅎㅎ 아직 많이 모자라용