#その名は"食材フィーバー"
ルールは簡単。
上から落ちてくる食材やお金を集めよう。
それ以外のアイテムをひろうとゲームオーバー。より多くのスコアを出そう!
とにかく沢山の食材(+お金)を集めるゲームです。
プラットフォームはWindows(.exe)~~(Windows版は諸事情により公開していません)~~とAndroid(.apk)です。
開発はVisualStudio2017、C++、DXライブラリです。
https://play.google.com/store/apps/details?id=com.gaccho
↑ダウンロードURLはこちら
#操作方法
画面左半分をタッチすると左に移動、
画面右半分をタッチすると右に移動します。
ただ、それだけです。
#コード
このコードはCの構造体を学習している時期に作ったものなので、とても汚いです……。今でも汚いけど
#include "DxLib.h"
#define PIXELX 1920
#define PIXELY 1080
#define MUSIC_COUNT 32
#define RL_ITEM_EMPTY 0
#define RL_ITEM_MONEY 1
#define RL_ITEM_RED_MUSHROOM 6
#define RL_ITEM_BLUE_MUSHROOM 7
#define RL_MONSTER_IKARI 1 //イカリー;;;;;;;;;;
#define RL_ITEM_SEAWEED 15
#define RL_ITEM_STONE 16
#define RL_ITEM_CHESTNUT 17
#define RL_ITEM_DRUG 18
#define RL_ITEM_BLACK_GLASSES 30
#define RL_ITEM_ROUND_GLASSES 31
#define RL_ITEM_MONEY_GLASSES 32
#define PI 3.14159265358979323846
#define WHITE GetColor(255,255,255) //白
#define ITEM_SE 1
#define IMPORTANT_SE 2
#define END_SE 3
struct Eat_MG
{
int score = 0; //ゲームのスコア
int playerX = 0; //プレイヤーのX座標
int playerY = 0; //プレイヤーのY座標(頭の高さ)
int playerSpeed = 10; //プレイヤーの速さ
int playerItemCount = 0; //プレイヤーが持っているアイテムの数
unsigned char itemCount = 0; //降ってくるアイテムの数
unsigned char gameoverNumber = 0; //降ってくるゲームオーバーアイテムの数
int safeareaStart = 0;
int safeareaEnd = 0;
//int itemY = 0; //持っているアイテムの高さ
int widthX = 1920; //ゲーム内のX軸の長さ
int widthY = 1080; //ゲーム内のY軸の長さ
double probability = 5; //1fps間でアイテムが出る確率
double probability2 = 2;
int itemNumberData = 5; //出る個数
int itemNumber = 0; //
unsigned char playerItem[1024]; //持っているアイテムの数
unsigned char playerItemS[1024]; //持っているアイテム向き
int playerItemX[1024]; //持っているアイテムのX座標
int playerItemY[1024]; //持っているアイテムのY座標
unsigned char item[256]; //降ってくるアイテムのID
unsigned char itemS[256]; //降ってくるアイテムの向き
int itemX[256]; //降ってくるアイテムのX座標
int itemY[256]; //降ってくるアイテムのY座標
};
int gacha(double kakuritu)
{
if (kakuritu >= 100) {
return 1;
}
if (kakuritu <= 0) {
return 0;
}
int bangou = (int)(20000000 * kakuritu);
int atari = 1 + GetRand(1999999999);
if (bangou >= atari) {
return 1;
}
return 0;
}
#ifdef __ANDROID__
//Android版のコンパイルだったら android_main
int android_main()
#else
//Windows版のコンパイルだったら WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
#endif
{
//logの出力を無しにする
if (SetOutApplicationLogValidFlag(FALSE)) return -1;
#ifndef __ANDROID__
// Windows版のコンパイルだったら ChangeWindowMode を実行する
if (ChangeWindowMode(TRUE)) return -1;
//タイトル文字
if (SetMainWindowText("Food Fever")) return -1;
#endif
SetGraphMode(1920, 1080, 32);
if (DxLib_Init() == -1) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}
SetDrawScreen(DX_SCREEN_BACK);
struct Eat_MG eat;
int mainBGM = LoadSoundMem("Music/BGM/stage09.ogg");
PlaySoundMem(mainBGM, DX_PLAYTYPE_LOOP);
for (int i = 0; i < 256; i++) {
eat.item[i] = 0;
eat.itemS[i] = 0;
eat.itemX[i] = 0;
eat.itemY[i] = 0;
}
for (int i = 0; i < 1024; i++) {
eat.playerItem[i] = 0;
eat.playerItemS[i] = 0;
eat.playerItemX[i] = 0;
eat.playerItemY[i] = 0;
}
//比率に関する変数宣言
int pixelX2 = PIXELX >> 1; //X座標の半分の画面解像度
int pixelY2 = PIXELY >> 1; //Y座標の半分の画面解像度
int pixelX32 = PIXELX >> 5; //X座標の1/32の画面解像度
int pixelX64 = PIXELX >> 6; //X座標の1/64の画面解像度
eat.playerX = eat.widthX / 2; //プレイヤーのX座標
eat.playerY = (int)(eat.widthY*0.7); //プレイヤーのY座標
int softSE[MUSIC_COUNT];
int mainSE[MUSIC_COUNT];
softSE[ITEM_SE] = LoadSoftSound("Music/SE/item.wav");
mainSE[ITEM_SE] = LoadSoundMemFromSoftSound(softSE[ITEM_SE]);
softSE[END_SE] = LoadSoftSound("Music/SE/end.wav");
mainSE[END_SE] = LoadSoundMemFromSoftSound(softSE[END_SE]);
int back = LoadGraph("Picture/Run/back.png");
int basket = LoadGraph("Picture/Eat/basket.png");
int ground = LoadGraph("Picture/Eat/ground.png");
int test3 = LoadGraph("Picture/Run/test3.png");
int brush = LoadGraph("Picture/Run/brush.png");
int brush2 = LoadGraph("Picture/Run/brush2.png");
int keisanX = 0;
int mapChipItem[256];
//アイテム画像をロード
mapChipItem[RL_ITEM_MONEY] = LoadGraph("Picture/RogueLike/Item/money.png");
mapChipItem[RL_ITEM_RED_MUSHROOM] = LoadGraph("Picture/RogueLike/Item/mushroom.png");
mapChipItem[RL_ITEM_BLUE_MUSHROOM] = LoadGraph("Picture/RogueLike/Item/mushroom2.png");
mapChipItem[RL_ITEM_SEAWEED] = LoadGraph("Picture/RogueLike/Item/seaweed.png");
mapChipItem[RL_ITEM_STONE] = LoadGraph("Picture/RogueLike/Item/stone.png");
mapChipItem[RL_ITEM_CHESTNUT] = LoadGraph("Picture/RogueLike/Item/chestnut.png");
mapChipItem[RL_ITEM_DRUG] = LoadGraph("Picture/RogueLike/Item/drug.png");
mapChipItem[255] = LoadGraph("Picture/Eat/gameover.png");
int monsterPicture[2][64];//16個の画像を格納する配列
LoadDivGraph("Picture/RogueLike/Player/ikari.png", 64, 8, 8, 120, 120, monsterPicture[RL_MONSTER_IKARI]);
eat.safeareaStart = GetRand(eat.widthX - 300);
eat.safeareaEnd = eat.safeareaStart + 300;
unsigned char direction = 3; //mobの向き
unsigned char move = 0; //mobの動き(パラパラ漫画)
unsigned char moveTime = 0; //
int FontHandle = CreateFontToHandle("メイリオ", pixelX32, 10, DX_FONTTYPE_ANTIALIASING_EDGE_8X8);
int FontHandle2 = CreateFontToHandle("メイリオ", pixelX64, 10, DX_FONTTYPE_ANTIALIASING_EDGE_8X8);
int moveCount = 0; //動いているか
int rand = 0;
int gameCount = 0;
int timeCount = 0;
int x[10] = { 0,0,0,0,0,0,0,0,0,0 };
int y[10] = { 0,0,0,0,0,0,0,0,0,0 };
int left = 0, right = 0;
while (1)
{
/*エラー処理////////////////////////////////////////////////////////////////////////*/
if (ProcessMessage() != 0) {
break;
}
if (ClearDrawScreen() != 0) {
break;
}
//if (updateKey() != 0) {//CheckHitKey(KEY_INPUT_ESCAPE)
// break;
//}
/*終了処理////////////////////////////////////////////////////////////////////////*/
DrawRotaGraph(pixelX2, pixelY2, 1.0, 0.0, back, TRUE);
DrawRotaGraph(pixelX2, pixelY2, 1.0, 0.0, ground, TRUE);
moveCount = 0;
for (int i = 0; i < GetTouchInputNum(); i++) {
GetTouchInput(i, &x[i], &y[i]);
if (x[i] < (PIXELX >> 1)) {
left++;
}
else {
right++;
}
}
switch (gameCount)
{
case 0:
eat.playerX += (eat.playerSpeed*(right + (-1 * left)));
if (right + (-1 * left) != 0) {
moveCount++;
}
break;
}
right = 0;
left = 0;
switch (timeCount)
{
case 120:
eat.safeareaStart = GetRand(eat.widthX - 300);
eat.safeareaEnd = eat.safeareaStart + 300;
timeCount = -1;
break;
default:
timeCount++;
break;
}
if (eat.playerX >= eat.widthX) {
eat.playerX = eat.widthX;
}
else if (eat.playerX <= 0) {
eat.playerX = 0;
}
/*プレイヤーの向きや移動系*/
if (moveCount >= 1) {
if (moveTime >= 7) {
if (move >= 16) {
move = 0;
}
else {
move += 8;
}
moveTime = 0;
}
else {
moveTime++;
}
direction = move;
}
else {
direction = 0;
}
if (gacha(eat.probability2) == 1) {
eat.gameoverNumber = GetRand(eat.score >> 9);
for (int i = 0; i < eat.gameoverNumber; i++) {
for (int j = 0; j < 256; j++) {
if (eat.item[j] == 0) {
eat.item[j] = 255;
eat.itemS[j] = GetRand(179);
eat.itemX[j] = GetRand(eat.widthX);
eat.itemY[j] = -100;
if (eat.safeareaStart <= eat.itemX[j] && eat.safeareaEnd >= eat.itemX[j]) {
eat.item[j] = 0;
}
break;
}
}
}
}
if (gacha(eat.probability) == 1) {
eat.itemNumber = 1 + GetRand(eat.itemNumberData - 1);
for (int i = 0; i < eat.itemNumber; i++) {
for (int j = 0; j < 256; j++) {
if (eat.item[j] == 0) {
rand = GetRand(4);
switch (rand)
{
case 1:
eat.item[j] = RL_ITEM_RED_MUSHROOM;
break;
case 2:
eat.item[j] = RL_ITEM_BLUE_MUSHROOM;
break;
case 3:
eat.item[j] = RL_ITEM_SEAWEED;
break;
case 4:
eat.item[j] = RL_ITEM_CHESTNUT;
break;
default:
eat.item[j] = RL_ITEM_MONEY;
break;
}
eat.itemS[j] = GetRand(179);
eat.itemX[j] = GetRand(eat.widthX);
eat.itemY[j] = -100;
break;
}
}
}
}
for (int i = 0; i < 256; i++) {
switch (eat.item[i]) {
case 0:
break;
default:
switch (gameCount)
{
case 0:
eat.itemY[i] += 5;
break;
}
if (eat.playerItemCount < 1024 && eat.itemY[i] + 30 <= eat.playerY + 50 - eat.playerItemCount * 2 && eat.itemY[i] >= eat.playerY - eat.playerItemCount * 2 && eat.itemX[i] >= eat.playerX - 60 && eat.itemX[i] <= eat.playerX + 60) {
switch (eat.item[i]) {
case 255:
PlaySoundMem(mainSE[END_SE], DX_PLAYTYPE_BACK); //ゲームオーバー音を流す
gameCount = 1;
break;
default:
PlaySoundMem(mainSE[ITEM_SE], DX_PLAYTYPE_BACK); //アイテム音を流す
break;
}
eat.playerItem[eat.playerItemCount] = eat.item[i];
eat.playerItemS[eat.playerItemCount] = eat.itemS[i];
eat.playerItemX[eat.playerItemCount] = eat.itemX[i] - eat.playerX;
eat.playerItemY[eat.playerItemCount] = eat.itemY[i] - eat.playerY;
switch (eat.item[i])
{
case RL_ITEM_RED_MUSHROOM:
eat.score += 10;
break;
case RL_ITEM_BLUE_MUSHROOM:
eat.score += 50;
break;
case RL_ITEM_SEAWEED:
eat.score += 20;
break;
case RL_ITEM_CHESTNUT:
eat.score += 15;
break;
default:
eat.score += 60;
break;
}
eat.item[i] = 0;
eat.itemS[i] = 0;
eat.itemX[i] = 0;
eat.itemY[i] = 0;
eat.playerItemCount++;
}
if (eat.itemY[i] - 30 >= eat.widthY) {
eat.item[i] = 0;
eat.itemS[i] = 0;
eat.itemX[i] = 0;
eat.itemY[i] = 0;
}
else {
DrawRotaGraph((int)(eat.itemX[i]), (int)(eat.itemY[i]), 0.5, eat.itemS[i] / 90.0*PI, mapChipItem[eat.item[i]], TRUE);
}
break;
}
}
for (int i = eat.playerItemCount - 1; i >= 0; i--) {
DrawRotaGraph((int)((eat.playerX + eat.playerItemX[i])), (int)((eat.playerY + eat.playerItemY[i])), 0.5, eat.playerItemS[i] / 90.0*PI, mapChipItem[eat.playerItem[i]], TRUE);
}
if (CheckHitKey(KEY_INPUT_ESCAPE) && gameCount == 0 && eat.score > 0)
{
break;
}
switch (gameCount)
{
case 1:
DrawFormatStringToHandle((int)((PIXELX >> 1) - 250), (int)((PIXELY >> 1) - 100), WHITE, FontHandle, "ゲームオーバー");
DrawFormatStringToHandle((int)((PIXELX >> 1) - 250), (int)((PIXELY >> 1)), WHITE, FontHandle, "スコア: %d円相当", eat.score);
DrawFormatStringToHandle((int)(PIXELX - 540), (int)(PIXELY - 50), WHITE, FontHandle2, " Produced by Gaccho , Music tsuzu");
if (CheckHitKey(KEY_INPUT_ESCAPE))
{
gameCount = 0;
eat.score = 0;
for (int i = 0; i < 256; i++) {
eat.item[i] = 0;
eat.itemS[i] = 0;
eat.itemX[i] = 0;
eat.itemY[i] = 0;
}
for (int i = 0; i < 1024; i++) {
eat.playerItem[i] = 0;
eat.playerItemS[i] = 0;
eat.playerItemX[i] = 0;
eat.playerItemY[i] = 0;
}
eat.playerX = eat.widthX / 2; //プレイヤーのX座標
eat.playerY = (int)(eat.widthY*0.7); //プレイヤーのY座標
eat.playerSpeed = 10; //プレイヤーの速さ
eat.playerItemCount = 0; //プレイヤーが持っているアイテムの数
eat.itemCount = 0; //降ってくるアイテムの数
eat.gameoverNumber = 0; //降ってくるゲームオーバーアイテムの数
}
break;
}
DrawRotaGraph((int)(eat.playerX), (int)((eat.playerY + 60)), 1.0, 0.0, monsterPicture[RL_MONSTER_IKARI][direction], TRUE);
DrawRotaGraph((int)(eat.playerX), (int)((eat.playerY + 60)), 1.0, 0.0, basket, TRUE);
DrawFormatStringToHandle(0, 0, WHITE, FontHandle, "スコア: %d円相当", eat.score);
if (ScreenFlip() != 0) {
break;
}
}
DxLib_End(); // DXライブラリ使用の終了処理
return 0; // ソフトの終了
}
#おわりに
こんな形でゲームを紹介しましたが、何か疑問点や改善点などがあれば教えてください。
最後までお付き合いいただきありがとうございました。
「いいね!」していただけると、とても励みになります。
##ソースコードのライセンス
These codes are licensed under CC0.
ソースコードは自由に使用してください。