FallSimulator/FallSimulation.cpp

653 lines
18 KiB
C++
Raw Normal View History

2019-09-13 14:43:18 +03:00
#include <TXLib.h>
2019-09-20 15:08:09 +03:00
#include <iostream>
2019-10-04 15:32:55 +03:00
#include <fstream>
2019-09-20 15:08:09 +03:00
using namespace std;
const COLORREF MY_LIGHTBLUE = RGB(75, 127, 196);
const COLORREF MY_BISQUE = RGB(255, 214, 89);
const int BLOCK_SIZE = 120;
2019-10-04 15:32:55 +03:00
const int BLOCK_TYPE = 0;
const int QUEST_TYPE = 1;
const int WATER_TYPE = 2;
const int FIRE_TYPE = 3;
2019-10-28 15:43:34 +03:00
const int MAP_LENGHT = 15;
2019-09-20 15:08:09 +03:00
int middleX;
int middleY;
int extentX;
int extentY;
bool lvlCreatingIsStarted = false;
2019-09-30 15:30:46 +03:00
bool gameIsStarted = false;
2019-09-23 15:35:44 +03:00
struct Button {
RECT coords;
const char* text;
HDC picture;
};
2019-10-04 15:32:55 +03:00
struct MapPart {
RECT coords;
bool visible;
HDC picture;
int blocktype;
};
MapPart gettedMapParts[MAP_LENGHT + 1];
HDC block;
HDC quest;
HDC water;
2019-10-12 17:06:30 +03:00
HDC fire;
2019-11-16 12:07:16 +03:00
HDC light_stone;
HDC dark_stone;
HDC vdark_stone;
2019-09-20 15:08:09 +03:00
void background(COLORREF color);
void drawMenu();
void drawButton(Button but);
void loadingAnimation(int delay, int speed);
2019-09-23 15:35:44 +03:00
void mainFunc();
2019-10-28 15:43:34 +03:00
bool addingBlock(bool clicked, RECT blockBut, HDC pic,
int blocktype, int* arrElem, MapPart mapParts[]);
2019-09-20 15:08:09 +03:00
int readFile(string file, MapPart gettedMapParts[]);
void playGame(MapPart gettedMapParts[]);
bool areElemWithTheseCoordsExisting(RECT coords, MapPart mapParts[]);
2019-11-08 15:36:32 +03:00
2019-09-20 15:08:09 +03:00
int main()
{
txCreateWindow(1300, 600);
block = txLoadImage("pictures\\block.bmp");
quest = txLoadImage("pictures\\question.bmp");
water = txLoadImage("pictures\\water.bmp");
fire = txLoadImage("pictures\\fire.bmp");
2019-09-20 15:08:09 +03:00
middleX = txGetExtentX() / 2;
middleY = txGetExtentY() / 2;
extentX = txGetExtentX();
extentY = txGetExtentY();
background(TX_WHITE);
txSleep(50);
txBegin();
2019-09-23 15:35:44 +03:00
txSleep(1000);
txSetColor(MY_LIGHTBLUE, 2);
txSetFillColor(TX_WHITE);
txRectangle(0, 0, extentX, extentY);
txSetColor(MY_LIGHTBLUE, 2);
txSetFillColor(MY_LIGHTBLUE);
txRectangle(0, 0, extentX, 50);
txSetColor(TX_BLACK, 3);
txSetFillColor(TX_WHITE);
txDrawText(0, 0, extentX, 50, "����������� ������� ���� FallSimulation");
2019-09-20 15:08:09 +03:00
drawMenu();
if (lvlCreatingIsStarted) {
mainFunc();
}
else if (gameIsStarted) {
playGame(gettedMapParts);
}
2019-09-20 15:08:09 +03:00
txEnd();
txDeleteDC(block);
txDeleteDC(quest);
2019-10-11 15:36:39 +03:00
txDeleteDC(water);
2019-10-12 17:06:30 +03:00
txDeleteDC(fire);
txDeleteDC(light_stone);
txDeleteDC(dark_stone);
txDeleteDC(vdark_stone);
2019-09-20 15:08:09 +03:00
txDisableAutoPause();
}
void background(COLORREF color)
{
txSetFillColor(color);
txClear();
}
void drawButton(Button but)
2019-09-23 15:35:44 +03:00
{
//drawing button
txRectangle(but.coords.left,
but.coords.top,
but.coords.right,
but.coords.bottom);
//drawing text
txDrawText (but.coords.left,
but.coords.top,
but.coords.right,
but.coords.bottom,
2019-10-28 15:43:34 +03:00
but.text,
DT_CENTER | DT_VCENTER);
2019-09-23 15:35:44 +03:00
}
2019-09-20 15:08:09 +03:00
void drawMenu()
{
2019-11-15 15:33:30 +03:00
//button "Start" (to start level creating)
Button buttonStart = {
2019-09-23 15:35:44 +03:00
{
middleX - 100, extentY / 3 - 50,
middleX + 100, extentY / 3 + 50
2019-11-15 15:33:30 +03:00
}, "Start"
2019-09-20 15:08:09 +03:00
};
2019-09-23 15:35:44 +03:00
//button "Exit"
Button buttonExit = {
{
middleX - 100, extentY / 2 - 50,
middleX + 100, extentY / 2 + 50
}, "Exit"
2019-09-20 15:08:09 +03:00
};
//button "Help"
Button buttonHelp = {
{
extentX - 100, 0,
2019-11-15 15:33:30 +03:00
extentX , 50
}, "? Help"
};
2019-11-15 15:33:30 +03:00
//button "Play" (to play on created level)
Button buttonPlay = {
{
extentX - 100, extentY - 60,
extentX, extentY
}, "Play"
};
2019-09-20 15:08:09 +03:00
txSetColor(TX_BLACK, 3);
txSetFillColor(TX_WHITE);
drawButton(buttonStart);
drawButton(buttonExit);
drawButton(buttonPlay);
txSetColor(TX_BLACK, 3);
txSetFillColor(TX_TRANSPARENT);
drawButton(buttonHelp);
2019-09-23 15:35:44 +03:00
2019-09-20 15:08:09 +03:00
txSleep(50);
2019-11-29 15:32:09 +03:00
while (!GetAsyncKeyState('Q') || !GetAsyncKeyState(VK_ESCAPE)) {
if (!lvlCreatingIsStarted && !gameIsStarted) {
2019-11-15 15:33:30 +03:00
if (In(txMousePos(), buttonStart.coords) && txMouseButtons() & 1) {
2019-09-30 15:30:46 +03:00
while (txMouseButtons() & 1) {
txSleep(10);
}
2019-12-05 10:53:46 +03:00
loadingAnimation(2, 7);
2019-09-30 15:30:46 +03:00
txSleep(50);
lvlCreatingIsStarted = true;
2019-09-20 15:08:09 +03:00
}
if (In(txMousePos(), buttonExit.coords) && txMouseButtons() & 1) {
2019-09-30 15:30:46 +03:00
while (txMouseButtons() & 1) {
txSleep(10);
}
2019-09-20 15:08:09 +03:00
2019-09-30 15:30:46 +03:00
break;
2019-09-20 15:08:09 +03:00
}
2019-11-29 15:32:09 +03:00
if (In(txMousePos(), buttonHelp.coords)) {
txSetColor(TX_BLACK);
txDrawText(buttonHelp.coords.left - 130,
buttonHelp.coords.bottom + 10,
txGetExtentX() - 10,
buttonHelp.coords.bottom + 100,
"This hyperlink will be\nopen in browser");
}
2019-11-29 15:32:09 +03:00
else {
txSetColor(TX_WHITE);
txSetFillColor(TX_WHITE);
txRectangle(buttonHelp.coords.left - 130,
buttonHelp.coords.bottom + 10,
txGetExtentX() - 10,
buttonHelp.coords.bottom + 100);
}
if (In(txMousePos(), buttonHelp.coords) && txMouseButtons() & 1) {
2019-09-30 15:30:46 +03:00
while(txMouseButtons() & 1) {
txSleep(10);
}
2019-09-20 15:08:09 +03:00
2019-11-29 15:32:09 +03:00
system("start help\\index.html");
2019-11-15 15:33:30 +03:00
}
2019-11-15 15:33:30 +03:00
if (In(txMousePos(), buttonPlay.coords) && txMouseButtons() & 1) {
int arrElem = readFile("level1.fslvl", gettedMapParts);
2019-11-15 15:33:30 +03:00
gameIsStarted = true;
2019-09-30 15:30:46 +03:00
}
}
if (lvlCreatingIsStarted || gameIsStarted) {
break;
}
txSleep(10);
2019-09-20 15:08:09 +03:00
}
}
void loadingAnimation(int delay, int speed)
2019-09-23 15:35:44 +03:00
{
background(TX_WHITE);
for (int circle_radius = 0;
circle_radius * circle_radius < extentX * extentX + extentY * extentY;
circle_radius += speed) {
2019-09-23 15:35:44 +03:00
2019-10-04 15:32:55 +03:00
background(TX_WHITE);
2019-09-23 15:35:44 +03:00
txSetColor(TX_BLACK, 2);
txSetFillColor(TX_BLACK);
txCircle(0, 0, circle_radius);
txSleep(delay);
}
background(TX_WHITE);
}
void mainFunc()
{
2019-10-04 15:32:55 +03:00
int arrElem = 0;
2019-10-18 15:27:39 +03:00
int selectedPict = -1;
2019-10-11 15:36:39 +03:00
const int BLOCK_SIZE = 120;
2019-10-04 15:32:55 +03:00
2019-09-30 15:30:46 +03:00
RECT blockBut = {
2019-10-18 15:27:39 +03:00
extentX - BLOCK_SIZE, 0, extentX, BLOCK_SIZE
2019-09-30 15:30:46 +03:00
};
2019-10-18 22:01:38 +03:00
RECT questBut = {
2019-10-18 22:04:20 +03:00
extentX - BLOCK_SIZE, BLOCK_SIZE, extentX, 2 * BLOCK_SIZE
2019-10-18 22:01:38 +03:00
};
RECT waterBut = {
2019-10-11 15:36:39 +03:00
extentX - BLOCK_SIZE, 2 * BLOCK_SIZE, extentX, 3 * BLOCK_SIZE
2019-09-30 15:30:46 +03:00
};
2019-10-15 16:56:07 +03:00
2019-10-12 17:06:30 +03:00
RECT fireBut = {
extentX - BLOCK_SIZE, 3* BLOCK_SIZE, extentX, 4 * BLOCK_SIZE
};
2019-10-04 15:32:55 +03:00
RECT doneBut = {
2019-10-28 15:43:34 +03:00
extentX - 120, extentY - 120, extentX, extentY
2019-10-04 15:32:55 +03:00
};
2019-10-11 15:36:39 +03:00
MapPart mapParts[MAP_LENGHT + 1];
2019-11-29 15:32:09 +03:00
txSetColor(TX_BLACK, 3);
txSetFillColor(TX_WHITE);
2019-10-28 15:43:34 +03:00
Button completeButton = {doneBut, "\n\nSave\n\nFile"};
for (int elem = 0; elem < MAP_LENGHT; elem++) {
mapParts[elem].visible = false;
}
2019-10-04 15:32:55 +03:00
2019-09-30 15:30:46 +03:00
bool clickedBlock = false;
bool clickedQuest = false;
bool clickedWater = false;
2019-10-18 15:27:39 +03:00
bool clickedFire = false;
2019-09-30 15:30:46 +03:00
while (!GetAsyncKeyState('Q') || !GetAsyncKeyState(VK_ESCAPE)) {
2019-09-30 15:30:46 +03:00
background(TX_WHITE);
2019-10-11 15:36:39 +03:00
Win32::TransparentBlt(txDC(), blockBut.left, blockBut.top, 120, 120, block,
0, 0, 60, 60, -1);
Win32::TransparentBlt(txDC(), questBut.left, questBut.top, 120, 120, quest,
0, 0, 60, 60, -1);
Win32::TransparentBlt(txDC(), waterBut.left, waterBut.top, 120, 120, water,
0, 0, 60, 60, -1);
2019-10-28 15:43:34 +03:00
2019-10-18 15:27:39 +03:00
Win32::TransparentBlt(txDC(), fireBut.left, fireBut.top, 120, 120, fire,
2019-10-12 17:06:30 +03:00
0, 0, 60, 60, -1);
2019-10-11 15:36:39 +03:00
drawButton(completeButton);
2019-10-18 15:27:39 +03:00
for (int elem = 0; elem < MAP_LENGHT; elem++) {
mapParts[elem].coords.left = round((mapParts[elem].coords.left + 30) / 60) * 60;
mapParts[elem].coords.top = round((mapParts[elem].coords.top + 30) / 60) * 60;
if (mapParts[elem].visible) {
txBitBlt(txDC(),
mapParts[elem].coords.left,
mapParts[elem].coords.top,
60, 60,
mapParts[elem].picture
);
}
}
2019-10-04 15:32:55 +03:00
2019-10-28 15:43:34 +03:00
//blocks
clickedBlock = addingBlock(clickedBlock, blockBut, block, BLOCK_TYPE, &arrElem, mapParts);
clickedQuest = addingBlock(clickedQuest, questBut, quest, QUEST_TYPE, &arrElem, mapParts);
clickedWater = addingBlock(clickedWater, waterBut, water, WATER_TYPE, &arrElem, mapParts);
clickedFire = addingBlock(clickedFire, fireBut, fire, FIRE_TYPE, &arrElem, mapParts);
2019-10-18 15:27:39 +03:00
2019-11-29 15:32:09 +03:00
//checking
if (clickedBlock)
{
clickedQuest = false;
clickedWater = false;
clickedFire = false;
}
else if (clickedQuest)
{
clickedWater = false;
clickedFire = false;
}
else if (clickedWater)
{
clickedFire = false;
}
2019-10-28 15:43:34 +03:00
//selecting block
for (int i = 0; i < arrElem; i++) {
if (selectedPict < 0 &&
In(txMousePos(), mapParts[i].coords) && txMouseButtons() & 1 &&
!(clickedBlock || clickedQuest || clickedWater || clickedFire)) {
2019-10-12 17:06:30 +03:00
2019-10-28 15:43:34 +03:00
selectedPict = i;
2019-10-12 17:06:30 +03:00
}
2019-10-18 15:27:39 +03:00
}
2019-10-28 15:43:34 +03:00
//deleting picture
2019-10-18 15:27:39 +03:00
for (int i = 0; i < arrElem; i++) {
if (selectedPict < 0 &&
2019-10-28 15:43:34 +03:00
In(txMousePos(), mapParts[i].coords) && txMouseButtons() & 2 &&
2019-10-18 15:27:39 +03:00
!(clickedBlock || clickedQuest || clickedWater || clickedFire)) {
selectedPict = i;
2019-10-28 15:43:34 +03:00
mapParts[selectedPict] = mapParts[arrElem - 1];
mapParts[arrElem - 1].visible = false;
arrElem--;
selectedPict = -1;
2019-10-18 15:27:39 +03:00
}
}
//round((mapParts[elem].coords.left + 30) / 60) * 60
2019-10-18 15:27:39 +03:00
//moving picture
RECT oldCoords = mapParts[selectedPict].coords;
2019-10-18 15:27:39 +03:00
if (selectedPict >= 0 && txMouseButtons() & 1) {
txBitBlt(txDC(),
txMouseX() - 30, txMouseY() - 30,
2019-10-18 15:27:39 +03:00
60, 60, mapParts[selectedPict].picture);
}
if (selectedPict >= 0 && !(txMouseButtons() & 1)) {
RECT elRectCoords = {
2019-12-05 10:53:46 +03:00
(round((txMouseX() - 30) / 60) * 60),
(round((txMouseY() - 30) / 60) * 60),
(round((txMouseX() + 30) / 60) * 60),
(round((txMouseY() + 30) / 60) * 60)
2019-10-18 15:27:39 +03:00
};
if (!areElemWithTheseCoordsExisting(elRectCoords, mapParts)) {
mapParts[selectedPict].coords = elRectCoords;
selectedPict = -1;
}
else {
mapParts[selectedPict].coords = oldCoords;
selectedPict = -1;
}
2019-10-18 15:27:39 +03:00
}
2019-10-04 15:32:55 +03:00
//button to complete LevelCreating
2019-10-18 15:27:39 +03:00
if (In(txMousePos(), doneBut) && txMouseButtons() & 1) {
2019-10-04 15:32:55 +03:00
while (txMouseButtons() & 1) {
txSleep(10);
}
ofstream lvlfile;
lvlfile.open("level1.fslvl");
2019-10-11 15:36:39 +03:00
for (int elem = 0; elem < arrElem; elem++) {
2019-10-04 15:32:55 +03:00
if (mapParts[elem].visible) {
switch(mapParts[elem].blocktype)
{
case BLOCK_TYPE:
2019-10-11 15:36:39 +03:00
lvlfile << "Block,";
break;
case QUEST_TYPE:
2019-10-11 15:36:39 +03:00
lvlfile << "Quest,";
break;
case WATER_TYPE:
lvlfile << "Water,";
break;
2019-10-12 17:06:30 +03:00
case FIRE_TYPE:
lvlfile << "Fire,";
break;
2019-10-28 15:43:34 +03:00
default:
lvlfile << "Null,";
break;
2019-10-04 15:32:55 +03:00
}
2019-10-28 15:43:34 +03:00
mapParts[elem].coords.left =
round((mapParts[elem].coords.left + 30) / 60) * 60;
mapParts[elem].coords.top =
round((mapParts[elem].coords.top + 30) / 60) * 60;
mapParts[elem].coords.right =
round((mapParts[elem].coords.right + 30) / 60) * 60;
mapParts[elem].coords.bottom =
round((mapParts[elem].coords.bottom + 30) / 60) * 60;
lvlfile << mapParts[elem].coords.left;
2019-10-11 15:36:39 +03:00
lvlfile << ",";
lvlfile << mapParts[elem].coords.top;
2019-10-11 15:36:39 +03:00
lvlfile << ",";
lvlfile << mapParts[elem].coords.right;
2019-10-11 15:36:39 +03:00
lvlfile << ",";
lvlfile << mapParts[elem].coords.bottom;
2019-10-11 15:36:39 +03:00
lvlfile << "\n";
lvlfile << "";
2019-10-04 15:32:55 +03:00
}
2019-09-30 15:30:46 +03:00
}
txMessageBox("Level File created!", "Information");
2019-09-30 15:30:46 +03:00
}
txSleep(10);
if (GetAsyncKeyState('Q') || GetAsyncKeyState(VK_ESCAPE)) {
break;
}
2019-10-18 15:27:39 +03:00
}
2019-09-23 15:35:44 +03:00
}
2019-10-28 15:43:34 +03:00
bool addingBlock(bool clicked, RECT blockBut, HDC pic,
int blocktype, int* arrElem, MapPart mapParts[])
{
if (In(txMousePos(), blockBut) && txMouseButtons() & 1) {
clicked = true;
}
if (txMouseButtons() & 1 && clicked) {
txBitBlt(txDC(), txMouseX() - 30, txMouseY() - 30, 60, 60, pic);
}
if (!(txMouseButtons() & 1) && clicked) {
if (*arrElem < MAP_LENGHT) {
RECT elRectCoords = {
2019-12-05 10:53:46 +03:00
(round((txMouseX() - 30) / 60) * 60),
(round((txMouseY() - 30) / 60) * 60),
(round((txMouseX() + 30) / 60) * 60),
(round((txMouseY() + 30) / 60) * 60)
};
if ((txMouseX() < txGetExtentX() - BLOCK_SIZE) &&
!(areElemWithTheseCoordsExisting(elRectCoords, mapParts)))
{
cout << !(areElemWithTheseCoordsExisting(elRectCoords, mapParts)) << endl;
mapParts[*arrElem] = {
elRectCoords, true, pic, blocktype
};
(*arrElem)++;
}
2019-10-28 15:43:34 +03:00
}
else {
2019-10-28 15:43:34 +03:00
char maplen_str[50];
2019-10-28 15:43:34 +03:00
sprintf(maplen_str, "You cannot add more than %d blocks", MAP_LENGHT);
txMessageBox(maplen_str, "Error");
2019-10-28 15:43:34 +03:00
(*arrElem)--;
}
clicked = false;
}
return clicked;
}
int readFile(string file, MapPart gettedMapParts[])
{
for (int i = 0; i < MAP_LENGHT; i++) {
gettedMapParts[i].visible = false;
}
int arrElem = 0;
ifstream lvlfile(file);
string buff;
while (lvlfile.good()) {
getline(lvlfile, buff);
if (buff.size() > 5) {
int posComma = buff.find(",");
int posComma2 = buff.find(",", posComma + 1);
int posComma3 = buff.find(",", posComma2 + 1);
int posComma4 = buff.find(",", posComma3 + 1);
string buff1 = buff.substr(0, posComma);
string buff2 = buff.substr(posComma + 1, posComma2 - posComma - 1);
string buff3 = buff.substr(posComma2 + 1, posComma3 - posComma2 - 1);
string buff4 = buff.substr(posComma3 + 1, posComma4 - posComma3 - 1);
string buff5 = buff.substr(posComma4 + 1, buff.size() - posComma4 - 1);
gettedMapParts[arrElem].coords = {
atoi(buff2.c_str()), atoi(buff3.c_str()),
atoi(buff4.c_str()), atoi(buff5.c_str())
};
gettedMapParts[arrElem].visible = true;
if (buff1 == "Block") {
gettedMapParts[arrElem].blocktype = BLOCK_TYPE;
gettedMapParts[arrElem].picture = block;
}
else if (buff1 == "Quest") {
gettedMapParts[arrElem].blocktype = QUEST_TYPE;
gettedMapParts[arrElem].picture = quest;
}
else if (buff1 == "Water") {
gettedMapParts[arrElem].blocktype = WATER_TYPE;
gettedMapParts[arrElem].picture = water;
}
else if (buff1 == "Fire") {
gettedMapParts[arrElem].blocktype = FIRE_TYPE;
gettedMapParts[arrElem].picture = fire;
}
else {
gettedMapParts[arrElem].blocktype = 0;
gettedMapParts[arrElem].visible = false;
}
arrElem++;
}
}
lvlfile.close();
return arrElem;
}
void playGame(MapPart gettedMapParts[])
{
background(TX_WHITE);
for (int i = 0; i < MAP_LENGHT; i++) {
if (gettedMapParts[i].visible) {
txBitBlt(txDC(),
gettedMapParts[i].coords.left,
gettedMapParts[i].coords.top,
60, 60,
gettedMapParts[i].picture
);
}
}
}
bool areElemWithTheseCoordsExisting(RECT coords, MapPart mapParts[])
{
RECT elemCoords;
bool areElemExisting;
for (int i = 0; i < MAP_LENGHT + 1; i++) {
elemCoords = mapParts[i].coords;
if (coords.left == elemCoords.left &&
coords.top == elemCoords.top &&
coords.right == elemCoords.right &&
coords.bottom == elemCoords.bottom &&
2019-12-05 10:53:46 +03:00
mapParts[i].visible
) {
areElemExisting = true;
}
else {
areElemExisting = false;
}
}
return areElemExisting;
}