miniLibx로 간단한 2D 게임 만들어보기!

koeyhoyh·2022년 4월 27일
1

42Seoul

목록 보기
10/11

부제 : 42서울 so_long 과제 구현하기!


참고

miniLibx 시작하기
https://harm-smits.github.io/42docs/libs/minilibx/getting_started.html

진짜 유용한 참고 자료
https://github.com/terry-yes/mlx_example

예제 시작시:
cc -L ./minilibx_opengl_20191021 -lmlx -framework OpenGL -framework Appkit main.c -I ./minilibx_opengl_20191021

쳐야 동영상의 기본 예제가 실행이 되었다.


처음 시작.

동영상의 예제를 따라하고, 그 후로 어떻게 해야할 지 막막해서 시작하기 문서를 따라하며 공부해보기로 했다.

첫 번째 작업물이다!!

miniLibx 시작하기를 보며, 사각형을 만들어 보았다!!
그리고 또 어떻게 이미지를 자르고 넣을지 생각해보고 질문했는데,

sujikim 님께서 도움이 되는 자료 하나를 던져주셨다!!!
이미지를 어떻게 배열하고, 놓고, 수정하는지 예제와 함께 살펴볼 수 있었다.

이제 해야 할 것은,

1. 사용할 이미지 셋 구성하기.

1-0. 알맞은 이미지 구하기 (보너스를 위한 연속적인 이미지도)

  • 이미지 화면에 띄워보기 O
  • 맵 파싱 O

1-1. 맵 구성하기. O

2. 캐릭터 움직이게 만들기

1-0. 캐릭터가 움직이게 구현하기
1-1. 캐릭터가 연속적으로 움직이게 만들기 (여러 개의 이미지를 통해)
1-2. 터미널에 움직인 횟수 출력하기

3. 보너스

2-0. 적 만들고, 일정 구역을 순찰하게 만들기.
2-1. 움직인 횟수를 윈도우에 출력하기.


추가

맵을 구성하고, 맵을 검사해주었다.
조건 :
1. 맵은 반드시 직사각형이어야 한다.
2. 적어도 수집품은 1개 이상 존재해야 한다.
3. 플레이어와 출구는 1개만 존재하여야 한다.

만들어놓은 gnl을 이용해 맵을 다 불러오고, ft_split 으로 개행문자를 제외한 2차원 배열로 만들어 정보를 저장해주었다.

그리고, 맵을 한 번에 만들려고 하니 플레이어와 출구가 겹치는 문제는 어떻게 해결하지?? 라는 생각이 들었다.

맵과 수집품, 출구를 먼저 이미지에 띄운 후 플레이어를 따로 맵에 표기해주는 방식으로 변경해 해결하였다.

맵을 만들었으니, 플레이어를 움직이게 만들어야 하는데 key_hook 에 대한 지식이 거의 없었다.

예제를 보며 이해해 본 key_hooking 이다.

#include <stdio.h>
#include <stdlib.h>
#include "../mlx/mlx.h"

#define X_EVENT_KEY_PRESS		2
#define X_EVENT_KEY_release		3
#define X_EVENT_KEY_EXIT		17 //exit key code

//Mac key code example
//All the key code example other than below is described on the site linked in READEME.md
#define KEY_ESC			53
# define KEY_Q			12
# define KEY_W			13
# define KEY_E			14
# define KEY_R			15
# define KEY_A			0
# define KEY_S			1
# define KEY_D			2

//Since key_press() can recieve only one argument, all the argument shold be gathered in one structure
//x,y and str are meaningless variables.
typedef struct s_param{
	int		x;
	int		y;
	char	str[3];
}				t_param;

//Only param->x will be used.
void			param_init(t_param *param)
{
	param->x = 3;
	param->y = 4;
	param->str[0] = 'a';
	param->str[1] = 'b';
	param->str[2] = '\0';
}

int				key_press(int keycode, t_param *param)
{
	static int a = 0;

	if (keycode == KEY_W)//Action when W key pressed
		param->x++;
	else if (keycode == KEY_S) //Action when S key pressed
		param->x--;
	else if (keycode == KEY_ESC) //Quit the program when ESC key pressed
		exit(0);
	printf("x: %d\n", param->x);
	return (0);
}

int			main(void)
{
	void		*mlx;
	void		*win;
	t_param		param;

	param_init(&param);
	mlx = mlx_init();
	win = mlx_new_window(mlx, 500, 500, "mlx_project");
	printf("-------------------------------\n");
	printf("'W key': Add 1 to x.\n");
	printf("'S key': Subtract 1 from x\n");
	printf("'ESC key': Exit this program\n");
	printf("'Other keys': print current x \n");
	printf("-------------------------------\n");
	printf("Current x = 3\n");
	mlx_hook(win, X_EVENT_KEY_PRESS, 0, &key_press, &param);
	mlx_loop(mlx);
}

해당 프로그램을 실행하면 w, s 키를 누를 때마다, console 에 x의 변경된 정보가 나온다.
esc 키를 누르면, 프로그램이 종료된다.

mlx_hook 을 이용해 오리를 움직이게 만들고 싶었는데, 계속 Segmentation Fault가 나왔다.

이유를 찾아낸 것 같다. 인터넷에서 mlx_docs와 사람들이 유의사항에 대해 정리해 놓은 블로그를 보고 해결했다.
mlx_hook은, funct_ptr 이라는 인자를 받는다.
mlx_hook(void win_ptr, int x_event, int x_mask, inf (funct)(), void param)
그리고, 해당 함수포인터로 들어갈 때는 반드시
int func_name(int key_num, void
param) 이런 형태로 만들어져야 한다고 한다.
나는 int moving(int key_num, t_mlx ..., t_img ..., ...) 이런 식으로 매개변수를 여러 개 사용해서 Segmentation Fault가 나왔다.

해당 부분의 형식을 맞춰주니 드디어 오리가 움직였다... 감동,,,

그런데, 전에 있던 오리가 사라지지를 않는다...
-> 맵 타일을 하나 깔아서, 오리에 맵타일을 붙여 지워줘야겠다.

profile
내가 만들어낸 것들로 세계에 많은 가치를 창출해내고 싶어요.

0개의 댓글