トップページに戻る / GCCページに戻る / SDL目次


21 配布されている素材を使ってみる

※ 注意:以下のサンプルではSDL2を使用しています。

世の中にはとても親切な人がいまして、ゲームの素材を無料で公開して「自由に使っていいよ」という人がいます。

そんな方々のご厚意に甘えまして、公開されているゲーム素材を使って動くものを作ってみましょう。

ぴぽやさんの、ぴぽや倉庫よりダウンロードした素材を使わさせていただきます。

(ウディタ向けの素材だけれども、ウディタ以外でも使用OKとのことです。ありがたや。)

おお、本当にゲームっぽい。

なお、使用する場合は配布元様の利用条件などをよく確認しましょう。

特に何もできないゲームだけれども、とりあえずソース公開。

ヘッダファイル

All.h

#pragma once

#include "Libs.h"
#include "Resources.h"
#include "Map.h"
#include "Player.h"

Libs.h

#pragma once

/* SDLのインクルードファイルをどこに置いたかな? */
#if 1
#	include <SDL2/SDL.h>
#	include <SDL2/SDL_image.h>
#	include <SDL2/SDL_ttf.h>
#else
#	include <SDL.h>
#	include <SDL_image.h>
#	include <SDL_ttf.h>
#endif

Map.h

#pragma once

#include "Libs.h"
#include "Resources.h"

#define MAP_WIDTH (20)
#define MAP_HEIGHT (16)

void InitMap();

Player.h

#pragma once

#include "Libs.h"
#include "Resources.h"
#include "Map.h"

typedef struct {
	int direction;
	int pause;
} TDirection;

void DrawPlayer();
void InitPlayer();
void MovePlayerDown();
void MovePlayerUp();
void MovePlayerLeft();
void MovePlayerRight();
void NextPlayer(TDirection* direction);

Resources.h

#pragma once

#include "Libs.h"

#define LAYER_INDEX_BASE (0)
#define LAYER_INDEX_MAP_BASE (1)
#define LAYER_INDEX_MAP_OBJ (2)
#define LAYER_INDEX_PLAYER (3)

#define CHIP_WIDTH (32)
#define CHIP_HEIGHT (32)

typedef struct {
	SDL_Surface* surface;
	SDL_Rect src_rect;
	SDL_Rect dst_rect;
	int display;
} TLayer;

typedef struct {
	int x;
	int y;
} TPoint;

TLayer g_layers[4];

SDL_Window* g_window;
SDL_Surface* g_screen;

SDL_Surface* g_map_chip;
SDL_Surface* g_player_chip;

TTF_Font* g_font;

/* プロトタイプ宣言 */
void InitResources();
void InitLayers();
void InitRect(SDL_Rect* rect);
void CreateLayer(int index, int w, int h);
void CreateRGBLayer(int index, int w, int h, int r, int g, int b);
void CreateRGBALayer(int index, int w, int h, int r, int g, int b, int a);
void DrawLayers();
void BlitLayer(SDL_Surface* src, SDL_Rect* srcRect, int dstIndex, SDL_Rect* dstRect);
void DestroyAllSurface();
void DestroyLayers();
void DestroyLayer(int index);
void HideLayer(int index);
void DisplayLayer(int index);
int LoadResources();
void BlitLayers();
void Flip();
void BlitScreen(SDL_Surface* src, SDL_Rect* srcRect, SDL_Rect* dstRect);

ソースファイル

Main.c

#include "All.h"

void InitAll() {
	SDL_Init(SDL_INIT_EVERYTHING);
	IMG_Init(IMG_INIT_PNG);
	TTF_Init();
}

void QuitAll() {
	TTF_Quit();
	SDL_Quit();
}

int main(int argc, char* argv[]) {

	SDL_Surface* text_surface;

	SDL_Event event;

	int endFlag = 0;

	InitAll();

	g_window = SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
		640, 480, SDL_WINDOW_SHOWN);

	g_screen = SDL_GetWindowSurface(g_window);

	LoadResources();

	InitLayers();

	InitMap();

	InitPlayer();
	DrawPlayer();

	while (endFlag == 0) {
		while (SDL_PollEvent(&event)) {
			switch (event.type)
			{
			case SDL_KEYDOWN:
				switch (event.key.keysym.sym) {
				case SDLK_ESCAPE:
					endFlag = 1;
					break;
				case SDLK_UP:
					MovePlayerUp();
					break;
				case SDLK_DOWN:
					MovePlayerDown();
					break;
				case SDLK_LEFT:
					MovePlayerLeft();
					break;
				case SDLK_RIGHT:
					MovePlayerRight();
					break;
				}
				break;
			case SDL_MOUSEBUTTONDOWN:
				break;
			case SDL_QUIT:
				endFlag = 1;
				break;
			}
		}
		SDL_Delay(50);
	}
	DestroyLayers();
	DestroyAllSurface();

	QuitAll();

	return 0;
}

Map.c

#include "Map.h"

int _world_map[MAP_HEIGHT][MAP_WIDTH] = {
{ 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 2, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }
};

SDL_Rect _map_rects[] = {
	{.x = CHIP_WIDTH * 0,.y = CHIP_HEIGHT * 0,.w = CHIP_WIDTH,.h = CHIP_HEIGHT },
	{.x = CHIP_WIDTH * 2,.y = CHIP_HEIGHT * 1,.w = CHIP_WIDTH,.h = CHIP_HEIGHT },
	{.x = CHIP_WIDTH * 5,.y = CHIP_HEIGHT * 1,.w = CHIP_WIDTH,.h = CHIP_HEIGHT },
	{.x = CHIP_WIDTH * 3,.y = CHIP_HEIGHT * 1,.w = CHIP_WIDTH,.h = CHIP_HEIGHT },
	{.x = CHIP_WIDTH * 3,.y = CHIP_HEIGHT * 6,.w = CHIP_WIDTH,.h = CHIP_HEIGHT },
	{.x = CHIP_WIDTH * 4,.y = CHIP_HEIGHT * 6,.w = CHIP_WIDTH,.h = CHIP_HEIGHT },
	{.x = CHIP_WIDTH * 3,.y = CHIP_HEIGHT * 7,.w = CHIP_WIDTH,.h = CHIP_HEIGHT },
	{.x = CHIP_WIDTH * 4,.y = CHIP_HEIGHT * 7,.w = CHIP_WIDTH,.h = CHIP_HEIGHT }
};

static void PutMapChip(int layerIndex, int chipIndex, int x, int y) {
	SDL_Rect rect;
	rect.x = x;
	rect.y = y;
	rect.w = _map_rects[chipIndex].w;
	rect.h = _map_rects[chipIndex].h;
	BlitLayer(g_map_chip, &_map_rects[chipIndex], layerIndex, &rect);
}

void InitMap() {
	int x, y;
	CreateLayer(LAYER_INDEX_MAP_BASE, CHIP_WIDTH * 20, CHIP_HEIGHT * 20);
	for (y = 0; y < 20; y++) {
		for (x = 0; x < 20; x++) {
			PutMapChip(LAYER_INDEX_MAP_BASE, 0, CHIP_WIDTH * x, CHIP_HEIGHT * y);
		}
	}
	DisplayLayer(LAYER_INDEX_MAP_BASE);

	CreateLayer(LAYER_INDEX_MAP_OBJ, CHIP_WIDTH * 20, CHIP_HEIGHT * 20);
	for (y = 0; y < MAP_HEIGHT; y++) {
		for (x = 0; x < MAP_WIDTH; x++) {
			PutMapChip(LAYER_INDEX_MAP_OBJ, _world_map[y][x], CHIP_WIDTH * x, CHIP_HEIGHT * y);
		}
	}
	DisplayLayer(LAYER_INDEX_MAP_OBJ);

}

Player.c

#include "Player.h"

static SDL_Rect _player_chip_rect = { 0, 0, CHIP_WIDTH, CHIP_HEIGHT };

static TPoint _player_pos = { 0, 0 };
static TDirection _player_direction = { 0, 1 };

void PutPlayer(int x, int y) {
	_player_pos.x = x;
	_player_pos.y = y;
	DrawPlayer();
}

void MovePlayerLeft() {
	_player_pos.x --;
	if (_player_pos.x < 0) {
		_player_pos.x = 0;
	}
	_player_direction.direction = 1;
	NextPlayer(&_player_direction);
	DrawPlayer();
}

void MovePlayerRight() {
	_player_pos.x ++;
	if (_player_pos.x >= MAP_WIDTH) {
		_player_pos.x = MAP_WIDTH - 1;
	}
	_player_direction.direction = 2;
	NextPlayer(&_player_direction);
	DrawPlayer();
}

void MovePlayerUp() {
	_player_pos.y --;
	if (_player_pos.y < 0) {
		_player_pos.y = 0;
	}
	_player_direction.direction = 3;
	NextPlayer(&_player_direction);
	DrawPlayer();
}

void MovePlayerDown() {
	_player_pos.y ++;
	if (_player_pos.y >= MAP_HEIGHT) {
		_player_pos.y = MAP_HEIGHT - 1;
	}
	_player_direction.direction = 0;
	NextPlayer(>_player_direction);
	DrawPlayer();
}

void InitPlayer() {
	CreateLayer(LAYER_INDEX_PLAYER, 640, 480);
	DisplayLayer(LAYER_INDEX_PLAYER);
}

void NextPlayer(TDirection* direction) {
	direction->pause++;
	if (direction->pause == 4) {
		direction->pause = 0;
	}
}

void DrawPlayer() {
	SDL_Rect player_rect = {
		.x = CHIP_WIDTH * _player_pos.x,
		.y = CHIP_HEIGHT * _player_pos.y,
		CHIP_WIDTH,
		CHIP_HEIGHT };
	int pause;
	if (_player_direction.pause == 3) {
		pause = 1;
	}
	else {
		pause = _player_direction.pause;
	}
	SDL_Rect chip_rect = {
		.x = CHIP_WIDTH * pause,
		.y = CHIP_HEIGHT * _player_direction.direction,
		CHIP_WIDTH,
		CHIP_HEIGHT };
	BlitLayers();
	BlitScreen(g_player_chip, &chip_rect, &player_rect);
	Flip();
}

Resources.c

#include "Resources.h"

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
static Uint32 _rmask = 0xff000000;
static Uint32 _gmask = 0x00ff0000;
static Uint32 _bmask = 0x0000ff00;
static Uint32 _amask = 0x000000ff;
#else
static Uint32 _rmask = 0x000000ff;
static Uint32 _gmask = 0x0000ff00;
static Uint32 _bmask = 0x00ff0000;
static Uint32 _amask = 0xff000000;
#endif

static int LoadImages() {
	/* マップチップファイルの読み込み */
	g_map_chip = IMG_Load("pipo-map001.png");

	/* キャラクタチップファイルの読み込み */
	g_player_chip = IMG_Load("pipo-charachip021.png"); /* 注:好きなキャラクタのチップを指定しよう */

	return 0;
}

static int LoadFont() {
	g_font = TTF_OpenFont("ume-tgc4.ttf", 16);

	return 0;
}

int LoadResources() {
	LoadImages();
	LoadFont();

	return 0;
}

void InitRect(SDL_Rect* rect) {
	rect->x = 0;
	rect->y = 0;
	rect->h = 0;
	rect->w = 0;
}

void CreateLayer(int index, int w, int h) {
	TLayer* layer = &g_layers[index];
	if (layer->surface != NULL) {
		SDL_FreeSurface(layer->surface);
	}
	layer->surface = SDL_CreateRGBSurface(0, 640, 480, 32, _rmask, _gmask, _bmask, _amask);
	InitRect(&layer->src_rect);
	InitRect(&layer->dst_rect);
	layer->src_rect.w = layer->surface->w;
	layer->src_rect.h = layer->surface->h;
}

void CreateRGBLayer(int index, int w, int h, int r, int g, int b) {
	TLayer* layer = &g_layers[index];
	CreateLayer(index, w, h);
	SDL_FillRect(layer->surface, NULL, SDL_MapRGB(layer->surface->format, r, g, b));
}

void CreateRGBALayer(int index, int w, int h, int r, int g, int b, int a) {
	TLayer* layer = &g_layers[index];
	CreateLayer(index, w, h);
	SDL_FillRect(layer->surface, NULL, SDL_MapRGBA(layer->surface->format, r, g, b, a));
}

void DisplayLayer(int index) {
	TLayer* layer = &g_layers[index];
	layer->display = 1;
}

void HideLayer(int index) {
	TLayer* layer = &g_layers[index];
	layer->display = 0;
}

void InitLayers() {
	int loop = 0;
	TLayer* layer;
	SDL_Rect rect = { .x = 0,.y = 0,.w = 640,.h = 480 };
	for (loop = 0; loop < sizeof(g_layers) / sizeof(g_layers[0]); loop++) {
		layer = &g_layers[loop];
		layer->surface = NULL;
		InitRect(&layer->dst_rect);
		InitRect(&layer->src_rect);
		layer->display = 0;
	}

	CreateRGBLayer(LAYER_INDEX_BASE, 640, 480, 0, 0, 0);
	DisplayLayer(LAYER_INDEX_BASE);
}

void DestroyLayer(int index) {
	TLayer* layer = &g_layers[index];
	if (layer->surface != NULL) {
		SDL_FreeSurface(layer->surface);
		layer->surface = NULL;
	}
}

void DestroyLayers() {
	int loop;
	for (loop = 0; loop < sizeof(g_layers) / sizeof(g_layers[0]); loop++) {
		DestroyLayer(loop);
	}
}

void BlitLayers() {
	TLayer* layer;
	int loop;
	for (loop = 0; loop < sizeof(g_layers) / sizeof(g_layers[0]); loop++) {
		layer = &g_layers[loop];
		if (layer->surface != NULL && layer->display == 1) {
			SDL_BlitSurface(layer->surface, &layer->src_rect, g_screen, &layer->dst_rect);
		}
	}
}

void DrawLayers() {
	BlitLayers();
	Flip();
}

void BlitScreen(SDL_Surface* src, SDL_Rect* srcRect, SDL_Rect* dstRect) {
	SDL_BlitSurface(src, srcRect, g_screen, dstRect);
}

void Flip() {
	SDL_UpdateWindowSurface(g_window);
}

void BlitLayer(SDL_Surface* src, SDL_Rect* srcRect, int dstIndex, SDL_Rect* dstRect) {
	SDL_BlitSurface(src, srcRect, g_layers[dstIndex].surface, dstRect);
}

void InitResources() {
	LoadImages();
	InitLayers();
}

void DestroyAllSurface() {
	SDL_FreeSurface(g_map_chip);
	SDL_FreeSurface(g_player_chip);
}

※ 上記ソースは予告なく変更する可能性があります。コメントがなくて不親切なのは多分そのうち直します。

使用素材

この辺のファイルをプログラムと同じフォルダにおいて動かすと動くと思います。(動かないんだけど…と言われても多分こちらからベストな回答はできないと思います。ので、いろいろ試して、がんばって!)


indexに戻る