init
80
.clang-format
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
AlignConsecutiveMacros: Consecutive
|
||||||
|
# AlignEscapedNewlines: LeftWithLastLine
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignTrailingComments:
|
||||||
|
Kind: Always
|
||||||
|
AllowShortLambdasOnASingleLine: Empty
|
||||||
|
IndentWidth: 4
|
||||||
|
ColumnLimit: 180
|
||||||
|
UseTab: Never
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
UseCRLF: false
|
||||||
|
AlignArrayOfStructures: None
|
||||||
|
AllowShortBlocksOnASingleLine: Empty
|
||||||
|
AllowShortCaseLabelsOnASingleLine: true
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: Inline
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
PointerAlignment: Left
|
||||||
|
QualifierAlignment: Left
|
||||||
|
ReferenceAlignment: Left
|
||||||
|
ReflowComments: IndentOnly # ?
|
||||||
|
SpaceAroundPointerQualifiers: Before
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: true
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesInAngles: Never
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
NamespaceIndentation: All
|
||||||
|
SortIncludes: Never
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
BinPackArguments: true
|
||||||
|
# BinPackLongBracedList: true # ?
|
||||||
|
BinPackParameters: BinPack # ?
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: MultiLine
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BreakAdjacentStringLiterals: true
|
||||||
|
BreakArrays: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
EmptyLineAfterAccessModifier: Never
|
||||||
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
IndentPPDirectives: BeforeHash
|
||||||
|
InsertBraces: true
|
||||||
|
KeepEmptyLines: # ?
|
||||||
|
AtEndOfFile: false
|
||||||
|
AtStartOfBlock: false
|
||||||
|
AtStartOfFile: false
|
||||||
|
LineEnding: LF
|
||||||
|
PPIndentWidth: 4
|
||||||
|
PackConstructorInitializers: BinPack
|
||||||
|
RemoveBracesLLVM: false
|
||||||
|
RemoveEmptyLinesInUnwrappedLines: true # ?
|
||||||
|
RemoveParentheses: MultipleParentheses
|
||||||
|
RemoveSemicolon: true
|
||||||
|
# SeparateDefinitionBlocks: Always # dont use
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
AccessModifierOffset: -4
|
||||||
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/.vscode/
|
||||||
|
/.vs/
|
||||||
|
/.cache/
|
||||||
|
/build/
|
||||||
|
/build_linux/
|
||||||
38
CMakeLists.txt
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5.0)
|
||||||
|
project(KolyahGame)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||||
|
|
||||||
|
include(${CMAKE_SOURCE_DIR}/cmake/CPM.cmake)
|
||||||
|
|
||||||
|
CPMAddPackage("gh:raysan5/raylib#5.5")
|
||||||
|
CPMAddPackage("gh:lsalzman/enet#v1.3.18")
|
||||||
|
CPMAddPackage("gh:nemtrif/utfcpp#v4.0.6")
|
||||||
|
# CPMAddPackage("gh:zpl-c/enet#dfe906c400a2d68c61f7b5f40f51f7566503a6f6")
|
||||||
|
|
||||||
|
file(GLOB SOURCES
|
||||||
|
${CMAKE_SOURCE_DIR}/src/*.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||||
|
|
||||||
|
cmake_policy(SET CMP0079 NEW)
|
||||||
|
# target_link_libraries(${PROJECT_NAME} PUBLIC raylib enet_static)
|
||||||
|
if (WIN32)
|
||||||
|
target_link_libraries(enet PUBLIC winmm ws2_32)
|
||||||
|
if (MSVC)
|
||||||
|
target_link_options(${PROJECT_NAME} PUBLIC /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
target_link_libraries(${PROJECT_NAME} PUBLIC raylib enet utf8cpp)
|
||||||
|
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||||
|
${CMAKE_SOURCE_DIR}/src
|
||||||
|
${enet_SOURCE_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
# if(EXISTS ${CMAKE_SOURCE_DIR}/assets)
|
||||||
|
# add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/assets" "$<TARGET_FILE_DIR:${PROJECT_NAME}>/assets")
|
||||||
|
# else()
|
||||||
|
# message("-- WARNING: Don't forget to copy resources from .jar file to a directory with the game before launching!")
|
||||||
|
# endif()
|
||||||
BIN
assets/citrim.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
assets/danilka22ah.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
assets/fullharmony.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/gradient.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
assets/invisedivine.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
assets/jaan.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/kolyah35.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
assets/level.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
assets/minecraft.ttf
Normal file
BIN
assets/player.pdn
Normal file
BIN
assets/playertest.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
1291
cmake/CPM.cmake
Normal file
9
file_to_header.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import sys
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
fname = pathlib.Path(sys.argv[1]).stem
|
||||||
|
|
||||||
|
data = open(sys.argv[1], 'rb').read()
|
||||||
|
|
||||||
|
print(f'inline uint8_t {fname}_data[{hex(len(data))}] = {{{",".join(map(hex, data))}}};')
|
||||||
|
print(f'\nconstexpr auto {fname}_data_size = {hex(len(data))};')
|
||||||
219
src/Game.cpp
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
#include "Game.hpp"
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "Multiplayer.hpp"
|
||||||
|
#include "assets.hpp"
|
||||||
|
|
||||||
|
Game::Game() : camPos(0, 0), spawnPointChangedTime(0), chatOpen(false), entered(false) {}
|
||||||
|
|
||||||
|
void Game::start(std::string name) {
|
||||||
|
InitWindow(1280, 720, "SFF Sandbox..?");
|
||||||
|
SetTargetFPS(60);
|
||||||
|
|
||||||
|
// std::string texture = "assets/";
|
||||||
|
// std::string nicknamee = name;
|
||||||
|
// std::transform(nicknamee.begin(), nicknamee.end(), nicknamee.begin(), ::tolower);
|
||||||
|
// texture.append(nicknamee).append(".png");
|
||||||
|
|
||||||
|
player = Player(skinFromName(name), name);
|
||||||
|
// player.spawnPoint = {2100, -1088}; // middle
|
||||||
|
// player.spawnPoint = {3821, -1728}; // end
|
||||||
|
player.spawnPoint = {-66, -448}; // start
|
||||||
|
player.pos = player.spawnPoint;
|
||||||
|
level.load();
|
||||||
|
|
||||||
|
auto lastTime = GetTime();
|
||||||
|
|
||||||
|
SetExitKey(KEY_NULL);
|
||||||
|
|
||||||
|
std::vector<int> codepoints;
|
||||||
|
for (int i = 0x20; i <= 0x7e; i++) {
|
||||||
|
codepoints.push_back(i);
|
||||||
|
}
|
||||||
|
for (int i = 0x401; i <= 0x451; i++) {
|
||||||
|
codepoints.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto myFont = LoadFontFromMemory(".ttf", minecraft_data, minecraft_data_size, 20, codepoints.data(), codepoints.size());
|
||||||
|
|
||||||
|
// const auto gradText = LoadTexture("assets/gradient.png");
|
||||||
|
const auto gradText = texFromMem(gradient_data, gradient_data_size);
|
||||||
|
|
||||||
|
while (!WindowShouldClose()) {
|
||||||
|
auto time = GetTime();
|
||||||
|
float dt = time - lastTime;
|
||||||
|
|
||||||
|
serverTime += dt;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (dt > (1 / 30.f)) {
|
||||||
|
lastTime = time;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (chatOpen) {
|
||||||
|
// Get char pressed (unicode character) on the queue
|
||||||
|
int key = GetCharPressed();
|
||||||
|
|
||||||
|
// Check if more characters have been pressed on the same frame
|
||||||
|
while (key > 0) {
|
||||||
|
// printf("%i\n", key);
|
||||||
|
// NOTE: Only allow keys in range [32..125]
|
||||||
|
// if ((key >= 32) && (key <= 125)) {
|
||||||
|
// chatMsg.append({(char)key});
|
||||||
|
// }
|
||||||
|
utf8::append(key, chatMsg);
|
||||||
|
|
||||||
|
key = GetCharPressed(); // Check next character in the queue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyPressedRepeat(KEY_BACKSPACE) || IsKeyPressed(KEY_BACKSPACE)) {
|
||||||
|
if (chatMsg.size() != 0) {
|
||||||
|
// chatMsg.pop_back();
|
||||||
|
auto it = chatMsg.end();
|
||||||
|
auto lastCP = utf8::prior(it, chatMsg.begin());
|
||||||
|
chatMsg = chatMsg.substr(0, it - chatMsg.begin());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_ENTER) && !chatMsg.empty()) {
|
||||||
|
char* packetData = new char[1 + 2 + chatMsg.size()];
|
||||||
|
packetData[0] = Header::MESSAGE;
|
||||||
|
*(uint16_t*)(packetData + 1) = chatMsg.size();
|
||||||
|
memcpy(packetData + 3, chatMsg.c_str(), chatMsg.size());
|
||||||
|
|
||||||
|
Multiplayer::get().sendPacket(packetData, 1 + 2 + chatMsg.size());
|
||||||
|
|
||||||
|
chatMsg.clear();
|
||||||
|
|
||||||
|
delete[] packetData;
|
||||||
|
// chatOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_T) && !chatOpen) {
|
||||||
|
chatOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_ESCAPE) && chatOpen) {
|
||||||
|
chatOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
level.update(dt);
|
||||||
|
|
||||||
|
player.update(dt);
|
||||||
|
|
||||||
|
auto& mp = Multiplayer::get();
|
||||||
|
if (mp.m_state != MultiplayerState::CONNECTING) {
|
||||||
|
mp.update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spawnPointChangedTime != 0) {
|
||||||
|
if (GetTime() - spawnPointChangedTime >= 0.5f) {
|
||||||
|
spawnPointChangedTime = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& [_, p] : otherPlayers) {
|
||||||
|
if (p.vel.x != 0) {
|
||||||
|
p.animTime += dt;
|
||||||
|
if (p.animTime >= p.targetFrameTime) {
|
||||||
|
p.animTime -= p.targetFrameTime;
|
||||||
|
p.curFrame = (p.curFrame + 1) % (p.totalFrames - 1);
|
||||||
|
// printf("%i\n", curFrame);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p.curFrame = 0;
|
||||||
|
p.animTime = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(GRAY);
|
||||||
|
level.drawBack();
|
||||||
|
|
||||||
|
for (auto& [_, player] : otherPlayers) {
|
||||||
|
player.draw();
|
||||||
|
auto p = worldToScreen(player.pos);
|
||||||
|
auto w = MeasureText(player.name.c_str(), 20);
|
||||||
|
|
||||||
|
DrawText(player.name.c_str(), p.x + 32 - w / 2, p.y - 25, 20, RAYWHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
player.draw();
|
||||||
|
level.draw();
|
||||||
|
|
||||||
|
if (!entered) {
|
||||||
|
auto p = worldToScreen({71 * 64, -30 * 64 - 720});
|
||||||
|
DrawRectangle(p.x, p.y, 11 * 64, 6 * 64 + 720, {0, 0, 0, 255});
|
||||||
|
for (int y = -25; y > -40; y--) {
|
||||||
|
p = worldToScreen({70 * 64, y * 64.f});
|
||||||
|
DrawTexture(gradText, p.x, p.y, WHITE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DrawTextEx(myFont, "Нажми T, чтобы открыть чат!", worldToScreen({73.5f * 64.f - MeasureTextEx(myFont, "Нажми T, чтобы открыть чат!", 40, 1).x / 2.0f, -23 * 64.f}), 40,
|
||||||
|
1, RAYWHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DrawText((std::to_string(player.pos.x) + " " + std::to_string(player.pos.y)).c_str(), 0, 0, 20, RAYWHITE);
|
||||||
|
// DrawText(("Tile: " + std::to_string((int)player.pos.x / 64) + " " + std::to_string((int)player.pos.y / 64)).c_str(), 0, 20, 20, RAYWHITE);
|
||||||
|
// DrawText(("FPS: " + std::to_string(GetFPS())).c_str(), 0, 40, 20, RAYWHITE);
|
||||||
|
|
||||||
|
if (spawnPointChangedTime != 0) {
|
||||||
|
// printf("%i\n", (uint8_t)(255 - 255 * (GetTime() - spawnPointChangedTime) / 0.5f));
|
||||||
|
DrawText("Checkpoint!", 640 - MeasureText("Checkpoint!", 40) / 2, 500, 40, Color {245, 245, 245, (uint8_t)(255 - 255 * (GetTime() - spawnPointChangedTime) / 0.5f)});
|
||||||
|
}
|
||||||
|
|
||||||
|
int msgY = 720;
|
||||||
|
|
||||||
|
if (chatOpen) {
|
||||||
|
DrawRectangle(0, 720 - 30 - 4, 1280, 30 + 4, {0, 0, 0, 100});
|
||||||
|
|
||||||
|
// DrawText(("> " + chatMsg).c_str(), 10, 720 - 30 + 2, 30, RAYWHITE);
|
||||||
|
DrawTextEx(myFont, ("> " + chatMsg).c_str(), {10, 720 - 30 + 2}, 20, 1, RAYWHITE);
|
||||||
|
msgY -= 36;
|
||||||
|
|
||||||
|
// for (auto i = chatMessages.size(); i--;) {
|
||||||
|
// auto& msg = chatMessages[i];
|
||||||
|
// DrawTextEx(myFont, msg.text.c_str(), {0, (float)msgY - 20}, 20, 1, RAYWHITE);
|
||||||
|
// // DrawText(msg.c_str(), 0, msgY - 20, 20, RAYWHITE);
|
||||||
|
// msgY -= 22;
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
// for (auto i = chatMessages.size(); i--;) {
|
||||||
|
// auto& msg = chatMessages[i];
|
||||||
|
// if (GetTime() - msg.time <= 2) {
|
||||||
|
// DrawTextEx(myFont, msg.text.c_str(), {0, (float)msgY - 20}, 20, 1, {245, 245, 245, (uint8_t)(255 - (GetTime() - msg.time) / 2.f * 255.f)});
|
||||||
|
// // DrawText(msg.c_str(), 0, msgY - 20, 20, RAYWHITE);
|
||||||
|
// msgY -= 22;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for (auto i = chatMessages.size(); i--;) {
|
||||||
|
// auto& msg = chatMessages[i];
|
||||||
|
// DrawTextEx(myFont, msg.text.c_str(), {0, (float)msgY - 20}, 20, 1, RAYWHITE);
|
||||||
|
// // DrawText(msg.c_str(), 0, msgY - 20, 20, RAYWHITE);
|
||||||
|
// msgY -= 22;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i = chatMessages.size(); i--;) {
|
||||||
|
auto& msg = chatMessages[i];
|
||||||
|
DrawTextEx(myFont, msg.text.c_str(), {0, (float)msgY - 20}, 20, 1, RAYWHITE);
|
||||||
|
// DrawText(msg.c_str(), 0, msgY - 20, 20, RAYWHITE);
|
||||||
|
msgY -= 22;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DrawText((std::to_string(player.vel.x) + " " + std::to_string(player.vel.y)).c_str(), 0, 20, 20, RAYWHITE);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
|
||||||
|
lastTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseWindow();
|
||||||
|
}
|
||||||
62
src/Game.hpp
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "saferaylib.h"
|
||||||
|
#include "Player.hpp"
|
||||||
|
#include "Level.hpp"
|
||||||
|
#include "unordered_map"
|
||||||
|
#include "cmath"
|
||||||
|
#include "utf8.h"
|
||||||
|
#include "assets.hpp"
|
||||||
|
#include "algorithm"
|
||||||
|
|
||||||
|
inline Texture2D texFromMem(unsigned char* data, int size) {
|
||||||
|
return LoadTextureFromImage(LoadImageFromMemory(".png", data, size));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Texture2D skinFromName(std::string name) {
|
||||||
|
std::string lowerName = name;
|
||||||
|
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower);
|
||||||
|
|
||||||
|
if (lowerName == "citrim") {
|
||||||
|
return texFromMem(citrim_data, citrim_data_size);
|
||||||
|
} else if (lowerName == "danilka22ah") {
|
||||||
|
return texFromMem(danilka22ah_data, danilka22ah_data_size);
|
||||||
|
} else if (lowerName == "invisedivine") {
|
||||||
|
return texFromMem(invisedivine_data, invisedivine_data_size);
|
||||||
|
} else if (lowerName == "jaan") {
|
||||||
|
return texFromMem(jaan_data, jaan_data_size);
|
||||||
|
} else if (lowerName == "fullharmony") {
|
||||||
|
return texFromMem(fullharmony_data, fullharmony_data_size);
|
||||||
|
} else {
|
||||||
|
return texFromMem(kolyah35_data, kolyah35_data_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ChatMsg {
|
||||||
|
std::string text;
|
||||||
|
float time;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Game {
|
||||||
|
public:
|
||||||
|
inline static Game& get() {
|
||||||
|
static Game inst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start(std::string name);
|
||||||
|
inline Vector2 worldToScreen(const Vector2& p) { return Vector2 {p.x - camPos.x, p.y - camPos.y}; }
|
||||||
|
|
||||||
|
Vector2 camPos;
|
||||||
|
Level level;
|
||||||
|
Player player;
|
||||||
|
std::unordered_map<uint32_t, Player> otherPlayers;
|
||||||
|
std::string chatMsg;
|
||||||
|
std::vector<ChatMsg> chatMessages;
|
||||||
|
float spawnPointChangedTime;
|
||||||
|
float serverTime;
|
||||||
|
bool chatOpen;
|
||||||
|
bool entered;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Game();
|
||||||
|
};
|
||||||
363
src/Level.cpp
Normal file
@@ -0,0 +1,363 @@
|
|||||||
|
#include "Level.hpp"
|
||||||
|
|
||||||
|
#include "assets.hpp"
|
||||||
|
#include "Game.hpp"
|
||||||
|
|
||||||
|
Level::Level() {}
|
||||||
|
|
||||||
|
void Level::load() {
|
||||||
|
// tex = LoadTexture("assets/level.png");
|
||||||
|
tex = texFromMem(level_data, level_data_size);
|
||||||
|
|
||||||
|
for (short y = 4; y > -45; y--) {
|
||||||
|
for (short x = -10; x < 130; x++) {
|
||||||
|
background.push_back({BRICKGRAY, x, y, GRAY});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Start room
|
||||||
|
for (short i = -11; i < 10; i++) {
|
||||||
|
tiles.push_back({BRICKGRAY, i, -5});
|
||||||
|
}
|
||||||
|
for (short i = -6; i > -15; i--) {
|
||||||
|
tiles.push_back({BRICKGRAY, -11, i});
|
||||||
|
}
|
||||||
|
for (short i = -9; i > -17; i--) {
|
||||||
|
tiles.push_back({BRICKGRAY, 9, i});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (short y = -5; y < 15; y++) {
|
||||||
|
tiles.push_back({BRICKGRAY, 9, y});
|
||||||
|
tiles.push_back({BRICKGRAY, -11, y});
|
||||||
|
}
|
||||||
|
for (short x = -7; x < 6; x += 3) {
|
||||||
|
background.push_back({TORCH, x, -10});
|
||||||
|
}
|
||||||
|
background.push_back({SIGN, 6, -6});
|
||||||
|
background.push_back({BRICKGRAY, 9, -7, GRAY});
|
||||||
|
background.push_back({BRICKGRAY, 9, -6, GRAY});
|
||||||
|
background.push_back({BANNERBASEMENT, -10, -10});
|
||||||
|
background.push_back({BANNERBASEMENT, 8, -10});
|
||||||
|
|
||||||
|
// Main level
|
||||||
|
// First platforms
|
||||||
|
background.push_back({TORCH, 11, -8});
|
||||||
|
tiles.push_back({PLATFORMBIGLEFT, 11, -5});
|
||||||
|
tiles.push_back({PLATFORMBIGRIGHT, 12, -5});
|
||||||
|
|
||||||
|
background.push_back({TORCH, 15, -10});
|
||||||
|
tiles.push_back({PLATFORMBIGLEFT, 15, -7});
|
||||||
|
tiles.push_back({PLATFORMBIGRIGHT, 16, -7});
|
||||||
|
|
||||||
|
background.push_back({TORCH, 19, -6});
|
||||||
|
tiles.push_back({PLATFORMBIGLEFT, 19, -3});
|
||||||
|
tiles.push_back({PLATFORMBIGRIGHT, 20, -3});
|
||||||
|
|
||||||
|
background.push_back({TORCH, 24, -8});
|
||||||
|
tiles.push_back({PLATFORMBIGLEFT, 24, -5});
|
||||||
|
tiles.push_back({PLATFORMBIGRIGHT, 25, -5});
|
||||||
|
for (short x = 10; x < 30; x++) {
|
||||||
|
tiles.push_back({LAVA, x, 4});
|
||||||
|
}
|
||||||
|
// Checkpoint 1
|
||||||
|
background.push_back({BANNERSFF, 30, -10});
|
||||||
|
background.push_back({BANNERSFF, 36, -10});
|
||||||
|
checkpoints.push_back({CHECKPOINT, 33, -7});
|
||||||
|
background.push_back({TORCH, 33, -10});
|
||||||
|
|
||||||
|
for (short x = 30; x < 36; x++) {
|
||||||
|
tiles.push_back({BRICKGRAY, x, -6});
|
||||||
|
}
|
||||||
|
for (short y = -6; y < 15; y++) {
|
||||||
|
tiles.push_back({BRICKGRAY, 30, y});
|
||||||
|
tiles.push_back({BRICKGRAY, 36, y});
|
||||||
|
}
|
||||||
|
// Moving platforms
|
||||||
|
background.push_back({TORCH, 40, -9});
|
||||||
|
background.push_back({BANNERDOOMETERNAL, 41, -9});
|
||||||
|
background.push_back({TORCH, 42, -9});
|
||||||
|
|
||||||
|
background.push_back({TORCH, 45, -9});
|
||||||
|
background.push_back({BANNERDOOMETERNAL, 46, -9});
|
||||||
|
background.push_back({TORCH, 47, -9});
|
||||||
|
|
||||||
|
for (short x = 37; x < 53; x++) {
|
||||||
|
tiles.push_back({LAVA, x, 4});
|
||||||
|
}
|
||||||
|
// for (short x = 38; x < 49; x += 5) {
|
||||||
|
// tiles.push_back({PLATFORMBIGLEFT, x, -7});
|
||||||
|
// tiles.push_back({PLATFORMBIGRIGHT, static_cast<int16_t>(x + 1), -7});
|
||||||
|
// tiles.push_back({PLATFORMBIGLEFT, x, -10});
|
||||||
|
// tiles.push_back({PLATFORMBIGRIGHT, static_cast<int16_t>(x + 1), -10});
|
||||||
|
// tiles.push_back({PLATFORMBIGLEFT, x, -12});
|
||||||
|
// tiles.push_back({PLATFORMBIGRIGHT, static_cast<int16_t>(x + 1), -12});
|
||||||
|
// }
|
||||||
|
plats.push_back({{38 * 64.f, -12 * 64.f}, 0});
|
||||||
|
plats.push_back({{43 * 64.f, -12 * 64.f}, 1});
|
||||||
|
plats.push_back({{48 * 64.f, -12 * 64.f}, 0});
|
||||||
|
// Checkpoint 2
|
||||||
|
checkpoints.push_back({CHECKPOINT, 56, -7});
|
||||||
|
background.push_back({BANNERDOOMETERNAL, 53, -10});
|
||||||
|
background.push_back({BANNERDOOMETERNAL, 59, -10});
|
||||||
|
background.push_back({TORCH, 56, -10});
|
||||||
|
for (short x = 53; x < 60; x++) {
|
||||||
|
tiles.push_back({BRICKGRAY, x, -6});
|
||||||
|
}
|
||||||
|
for (short y = -6; y < 15; y++) {
|
||||||
|
tiles.push_back({BRICKGRAY, 53, y});
|
||||||
|
tiles.push_back({BRICKGRAY, 59, y});
|
||||||
|
}
|
||||||
|
// Way to upper platform
|
||||||
|
background.push_back({TORCH, 76, -9});
|
||||||
|
background.push_back({TORCH, 76, -8});
|
||||||
|
background.push_back({TORCH, 76, -7});
|
||||||
|
background.push_back({TORCH, 76, -6});
|
||||||
|
background.push_back({TORCH, 76, -5});
|
||||||
|
background.push_back({TORCH, 76, -4});
|
||||||
|
|
||||||
|
background.push_back({TORCH, 75, -8});
|
||||||
|
background.push_back({TORCH, 74, -7});
|
||||||
|
|
||||||
|
background.push_back({TORCH, 77, -8});
|
||||||
|
background.push_back({TORCH, 78, -7});
|
||||||
|
|
||||||
|
for (short x = 60; x < 80; x++) {
|
||||||
|
tiles.push_back({LAVA, x, 4});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (short y = 4; y > -40; y--) {
|
||||||
|
tiles.push_back({BRICKGRAY, 80, y});
|
||||||
|
}
|
||||||
|
background.push_back({TORCH, 67, -8});
|
||||||
|
background.push_back({TORCH, 62, -10});
|
||||||
|
background.push_back({TORCH, 58, -12});
|
||||||
|
|
||||||
|
tiles.push_back({PLATFORMBIGLEFT, 64, -6});
|
||||||
|
tiles.push_back({PLATFORMBIGRIGHT, 65, -6});
|
||||||
|
|
||||||
|
tiles.push_back({PLATFORMBIGLEFT, 69, -8});
|
||||||
|
tiles.push_back({PLATFORMBIGRIGHT, 70, -8});
|
||||||
|
|
||||||
|
tiles.push_back({PLATFORMBIGLEFT, 64, -10});
|
||||||
|
tiles.push_back({PLATFORMBIGRIGHT, 65, -10});
|
||||||
|
|
||||||
|
tiles.push_back({PLATFORMBIGLEFT, 60, -12});
|
||||||
|
tiles.push_back({PLATFORMBIGRIGHT, 61, -12});
|
||||||
|
|
||||||
|
tiles.push_back({PLATFORMBIGLEFT, 56, -14});
|
||||||
|
tiles.push_back({PLATFORMBIGRIGHT, 57, -14});
|
||||||
|
|
||||||
|
// Upper platform
|
||||||
|
for (short x = 54; x > 0; x--) {
|
||||||
|
tiles.push_back({BRICKGRAY, x, -15});
|
||||||
|
}
|
||||||
|
background.push_back({BANNBERHL, 54, -19});
|
||||||
|
checkpoints.push_back({CHECKPOINT, 52, -16});
|
||||||
|
background.push_back({BANNBERHL, 50, -19});
|
||||||
|
background.push_back({TORCH, 52, -19});
|
||||||
|
|
||||||
|
tiles.push_back({BRICKGRAY, 30, -16});
|
||||||
|
tiles.push_back({BRICKGRAY, 10, -16});
|
||||||
|
for (short x = 47; x > 34; x -= 2) {
|
||||||
|
// tiles.push_back({SAW, x, -19});
|
||||||
|
// Vector2 pos = {x * 64.f, -19 * 64.f + 3 * 64 * (x - 34) / 2 / 7.f};
|
||||||
|
// Vector2 pos = {x * 64.f, -19 * 64.f};
|
||||||
|
// saws.push_back({pos, pos});
|
||||||
|
saws.push_back({{x * 64.f, -19 * 64.f}, (x - 34) / 2 / 7.f});
|
||||||
|
}
|
||||||
|
for (short x = 46; x > 34; x -= 2) {
|
||||||
|
background.push_back({TORCH, x, -19});
|
||||||
|
}
|
||||||
|
// for (short x = 46; x > 33; x -= 4) {
|
||||||
|
// tiles.push_back({TORCH, x, -19});
|
||||||
|
// }
|
||||||
|
for (short x = 29; x > 10; x--) {
|
||||||
|
tiles.push_back({LAVA, x, -16});
|
||||||
|
}
|
||||||
|
background.push_back({BANNERNIRVANA, 31, -19});
|
||||||
|
background.push_back({BANNERNIRVANA, 33, -19});
|
||||||
|
background.push_back({TORCH, 32, -19});
|
||||||
|
checkpoints.push_back({CHECKPOINT, 32, -16});
|
||||||
|
|
||||||
|
// Way to final corridor
|
||||||
|
background.push_back({TORCH, 24, -26});
|
||||||
|
background.push_back({TORCH, 24, -25});
|
||||||
|
background.push_back({TORCH, 24, -24});
|
||||||
|
background.push_back({TORCH, 24, -23});
|
||||||
|
background.push_back({TORCH, 24, -22});
|
||||||
|
background.push_back({TORCH, 24, -21});
|
||||||
|
background.push_back({TORCH, 24, -20});
|
||||||
|
|
||||||
|
background.push_back({TORCH, 25, -25});
|
||||||
|
background.push_back({TORCH, 26, -24});
|
||||||
|
|
||||||
|
background.push_back({TORCH, 23, -25});
|
||||||
|
background.push_back({TORCH, 22, -24});
|
||||||
|
|
||||||
|
tiles.push_back({PLATFORM, 27, -18});
|
||||||
|
background.push_back({TORCH, 30, -22});
|
||||||
|
tiles.push_back({PLATFORM, 30, -20});
|
||||||
|
tiles.push_back({PLATFORM, 33, -22});
|
||||||
|
tiles.push_back({PLATFORM, 35, -23});
|
||||||
|
background.push_back({TORCH, 35, -25});
|
||||||
|
tiles.push_back({PLATFORM, 32, -25});
|
||||||
|
tiles.push_back({PLATFORM, 36, -27});
|
||||||
|
tiles.push_back({PLATFORM, 40, -25});
|
||||||
|
background.push_back({TORCH, 40, -27});
|
||||||
|
tiles.push_back({PLATFORM, 44, -27});
|
||||||
|
tiles.push_back({PLATFORM, 48, -23});
|
||||||
|
background.push_back({TORCH, 48, -25});
|
||||||
|
tiles.push_back({PLATFORM, 52, -25});
|
||||||
|
|
||||||
|
// final corridor
|
||||||
|
for (short x = 56; x < 81; x++) {
|
||||||
|
tiles.push_back({BRICKGRAY, x, -25});
|
||||||
|
}
|
||||||
|
background.push_back({BANNERBASEMENT, 56, -28});
|
||||||
|
background.push_back({TORCH, 57, -28});
|
||||||
|
background.push_back({TORCH, 58, -28});
|
||||||
|
background.push_back({BANNERSFF, 59, -28});
|
||||||
|
background.push_back({TORCH, 60, -28});
|
||||||
|
background.push_back({TORCH, 61, -28});
|
||||||
|
background.push_back({BANNERDOOMETERNAL, 62, -28});
|
||||||
|
background.push_back({TORCH, 63, -28});
|
||||||
|
background.push_back({TORCH, 64, -28});
|
||||||
|
background.push_back({BANNBERHL, 65, -28});
|
||||||
|
background.push_back({TORCH, 66, -28});
|
||||||
|
background.push_back({TORCH, 67, -28});
|
||||||
|
background.push_back({BANNERNIRVANA, 68, -28});
|
||||||
|
checkpoints.push_back({CHECKPOINT, 68, -26});
|
||||||
|
|
||||||
|
// tiles.push_back({BRICKGRAY, 70, -28});
|
||||||
|
// tiles.push_back({BRICKGRAY, 70, -29});
|
||||||
|
for (short y = -28; y > -40; y--) {
|
||||||
|
tiles.push_back({BRICKGRAY, 70, y});
|
||||||
|
}
|
||||||
|
for (short x = 71; x < 80; x++) {
|
||||||
|
tiles.push_back({BRICKGRAY, x, -31});
|
||||||
|
}
|
||||||
|
tiles.push_back({TABLELEFT, 75, -26});
|
||||||
|
tiles.push_back({TABLERIGHT, 76, -26});
|
||||||
|
|
||||||
|
background.push_back({TORCH, 71, -29});
|
||||||
|
background.push_back({BALOON1, 72, -29});
|
||||||
|
background.push_back({BALOON2, 77, -30});
|
||||||
|
background.push_back({BALOON3, 73, -28});
|
||||||
|
background.push_back({TORCH, 79, -29});
|
||||||
|
background.push_back({BALOON4, 78, -29});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::update(float dt) {
|
||||||
|
for (auto& saw : saws) {
|
||||||
|
saw.pos.y = -19 * 64.f + 3 * 64.f * (sinf(Game::get().serverTime * 2.2f + saw.offset * 2.f) / 2.f + 0.5f);
|
||||||
|
}
|
||||||
|
for (auto& plat : plats) {
|
||||||
|
plat.pos.y = -12 * 64.f + 4 * 64.f * (sinf((Game::get().serverTime + plat.offset * PI / 2) * 2.2f) / 2.f + 0.5f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #define ROUND_POS(x) (float)((int)(x))
|
||||||
|
#define ROUND_POS(x) floorf(x)
|
||||||
|
|
||||||
|
void Level::drawBack() {
|
||||||
|
// Behind player
|
||||||
|
for (const auto& tile : background) {
|
||||||
|
auto p = Game::get().worldToScreen({(float)tile.x * 64, (float)tile.y * 64});
|
||||||
|
if (p.x < -64.f || p.y < -64.f || p.x > 1280 || p.y > 720) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto tid = tile.id;
|
||||||
|
if (Game::get().entered && tile.id == BRICKGRAY) {
|
||||||
|
tid = WOOD;
|
||||||
|
}
|
||||||
|
DrawTexturePro(tex, {32.0f * (tid % 10), 32.0f * (tid / 10), 32.0f, 32.0f}, {ROUND_POS(p.x), ROUND_POS(p.y), 64.0f, 64.0f}, {0, 0}, 0, tile.col);
|
||||||
|
}
|
||||||
|
for (const auto& tile : checkpoints) {
|
||||||
|
auto p = Game::get().worldToScreen({(float)tile.x * 64, (float)tile.y * 64});
|
||||||
|
if (p.x < -64.f || p.y < -64.f || p.x > 1280 || p.y > 720) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DrawTexturePro(tex, {32.0f * (tile.id % 10), 32.0f * (tile.id / 10), 32.0f, 32.0f}, {ROUND_POS(p.x), ROUND_POS(p.y), 64.0f, 64.0f}, {0, 0}, 0, tile.col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::draw() {
|
||||||
|
for (const auto& tile : tiles) {
|
||||||
|
auto p = Game::get().worldToScreen({(float)tile.x * 64, (float)tile.y * 64});
|
||||||
|
if (p.x < -64.f || p.y < -64.f || p.x > 1280 || p.y > 720) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// DrawTexturePro(tex, {32.0f * (tile.id % 10), 32.0f * (tile.id / 10), 32.0f, 32.0f}, {ROUND_POS(p.x), ROUND_POS(p.y), 64.0f, 64.0f}, {0, 0}, 0, tile.col);
|
||||||
|
auto tid = tile.id;
|
||||||
|
if (Game::get().entered && tile.id == BRICKGRAY) {
|
||||||
|
tid = WOOD;
|
||||||
|
}
|
||||||
|
DrawTexturePro(tex, {32.0f * (tid % 10), 32.0f * (tid / 10), 32.0f, 32.0f}, {ROUND_POS(p.x), ROUND_POS(p.y), 64.0f, 64.0f}, {0, 0}, 0, tile.col);
|
||||||
|
}
|
||||||
|
for (const auto& saw : saws) {
|
||||||
|
auto p = Game::get().worldToScreen(saw.pos);
|
||||||
|
DrawTexturePro(tex, {32.0f * (SAW % 10), 32.0f * (SAW / 10), 32.0f, 32.0f}, {ROUND_POS(p.x), ROUND_POS(p.y), 64.0f, 64.0f}, {0, 0}, 0, WHITE);
|
||||||
|
}
|
||||||
|
auto c = Game::get().worldToScreen({4810, -1690});
|
||||||
|
|
||||||
|
DrawTexturePro(tex, {32.0f * (CAKE % 10), 32.0f * (CAKE / 10), 32.0f, 32.0f}, {ROUND_POS(c.x), ROUND_POS(c.y), 64.0f, 64.0f}, {0, 0}, 0, WHITE);
|
||||||
|
for (const auto& plat : plats) {
|
||||||
|
auto p = Game::get().worldToScreen(plat.pos);
|
||||||
|
DrawTexturePro(tex, {32.0f * (PLATFORMBIGLEFT % 10), 32.0f * (PLATFORMBIGLEFT / 10), 32.0f, 32.0f}, {ROUND_POS(p.x), ROUND_POS(p.y), 64.0f, 64.0f}, {0, 0}, 0, WHITE);
|
||||||
|
DrawTexturePro(tex, {32.0f * (PLATFORMBIGRIGHT % 10), 32.0f * (PLATFORMBIGRIGHT / 10), 32.0f, 32.0f}, {ROUND_POS(p.x + 64.f), ROUND_POS(p.y), 64.0f, 64.0f}, {0, 0}, 0,
|
||||||
|
WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float Level::collides(const Rectangle& rect, bool y) {
|
||||||
|
for (const auto& plat : plats) {
|
||||||
|
Rectangle tileRect = Rectangle {plat.pos.x, plat.pos.y + 44.f, 96.f, 64.f - 44.f};
|
||||||
|
|
||||||
|
if (CheckCollisionRecs(rect, tileRect)) {
|
||||||
|
auto colRect = GetCollisionRec(rect, tileRect);
|
||||||
|
if (colRect.height > 0 && y) {
|
||||||
|
return colRect.height;
|
||||||
|
}
|
||||||
|
if (colRect.width > 0 && !y) {
|
||||||
|
return colRect.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& tile : tiles) {
|
||||||
|
Rectangle tileRect = Rectangle {tile.x * 64.0f, tile.y * 64.0f, 64.0, 64.0f};
|
||||||
|
if (tile.id == TABLELEFT) {
|
||||||
|
tileRect.y += 26.f;
|
||||||
|
tileRect.height -= 26.f;
|
||||||
|
} else if (tile.id == TABLERIGHT) {
|
||||||
|
tileRect.y += 26.f;
|
||||||
|
tileRect.height -= 26.f;
|
||||||
|
tileRect.width -= 32.f;
|
||||||
|
} else if (tile.id == PLATFORM) {
|
||||||
|
tileRect.y += 44.f;
|
||||||
|
tileRect.height -= 44.f;
|
||||||
|
tileRect.width -= 32.f;
|
||||||
|
} else if (tile.id == PLATFORMBIGLEFT) {
|
||||||
|
tileRect.y += 44.f;
|
||||||
|
tileRect.height -= 44.f;
|
||||||
|
} else if (tile.id == PLATFORMBIGRIGHT) {
|
||||||
|
tileRect.y += 44.f;
|
||||||
|
tileRect.height -= 44.f;
|
||||||
|
// tileRect.width -= 32.f;
|
||||||
|
} else if (tile.id == LAVA) {
|
||||||
|
tileRect.y += 24.f;
|
||||||
|
tileRect.height -= 24.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CheckCollisionRecs(rect, tileRect)) {
|
||||||
|
auto colRect = GetCollisionRec(rect, tileRect);
|
||||||
|
if (colRect.height > 0 && y) {
|
||||||
|
return colRect.height;
|
||||||
|
}
|
||||||
|
if (colRect.width > 0 && !y) {
|
||||||
|
return colRect.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
78
src/Level.hpp
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "saferaylib.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
enum TextureTilePos {
|
||||||
|
BRICKGRAY = 0,
|
||||||
|
BRICKRED,
|
||||||
|
TORCH,
|
||||||
|
SAW,
|
||||||
|
CAKE,
|
||||||
|
|
||||||
|
TABLELEFT,
|
||||||
|
TABLERIGHT,
|
||||||
|
|
||||||
|
PLATFORMBIGLEFT,
|
||||||
|
PLATFORMBIGRIGHT,
|
||||||
|
|
||||||
|
PLATFORM,
|
||||||
|
CHECKPOINT,
|
||||||
|
BANNERBASEMENT,
|
||||||
|
BANNERSFF,
|
||||||
|
BANNERDOOMETERNAL,
|
||||||
|
SIGN,
|
||||||
|
BANNBERHL,
|
||||||
|
BANNERNIRVANA,
|
||||||
|
LAVA,
|
||||||
|
|
||||||
|
WHITEBRICKS,
|
||||||
|
BALOON1,
|
||||||
|
BALOON2,
|
||||||
|
BALOON3,
|
||||||
|
BALOON4,
|
||||||
|
|
||||||
|
WOOD
|
||||||
|
};
|
||||||
|
|
||||||
|
// 64x64 pxl
|
||||||
|
struct Tile {
|
||||||
|
uint8_t id;
|
||||||
|
int16_t x;
|
||||||
|
int16_t y;
|
||||||
|
Color col = WHITE;
|
||||||
|
// Vector2 size = {0, 0};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Saw {
|
||||||
|
// Vector2 startPos;
|
||||||
|
Vector2 pos;
|
||||||
|
float offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Platform {
|
||||||
|
// Vector2 startPos;
|
||||||
|
Vector2 pos;
|
||||||
|
float offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Level {
|
||||||
|
public:
|
||||||
|
Level();
|
||||||
|
|
||||||
|
void load();
|
||||||
|
float collides(const Rectangle& rect, bool y);
|
||||||
|
void update(float dt);
|
||||||
|
void draw();
|
||||||
|
void drawBack();
|
||||||
|
|
||||||
|
std::vector<Tile> checkpoints;
|
||||||
|
std::vector<Tile> background;
|
||||||
|
std::vector<Tile> tiles;
|
||||||
|
std::vector<Saw> saws;
|
||||||
|
std::vector<Platform> plats;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Texture2D tex;
|
||||||
|
// std::vector<Tile> tilesBig;
|
||||||
|
};
|
||||||
247
src/Multiplayer.cpp
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
#include "Multiplayer.hpp"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cctype>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "Game.hpp"
|
||||||
|
|
||||||
|
// #define SERVER_ADDRESS "127.0.0.1"
|
||||||
|
#define SERVER_ADDRESS "sffnetwork.su"
|
||||||
|
|
||||||
|
void Multiplayer::connect(const char* name) {
|
||||||
|
printf("name %s\n", name);
|
||||||
|
m_name = name;
|
||||||
|
|
||||||
|
m_state = MultiplayerState::CONNECTING;
|
||||||
|
|
||||||
|
client = enet_host_create(nullptr, 1, LAST_CHANNEL, 0, 0);
|
||||||
|
if (!client) {
|
||||||
|
printf("client null\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENetAddress address;
|
||||||
|
enet_address_set_host(&address, SERVER_ADDRESS);
|
||||||
|
address.port = 7777;
|
||||||
|
|
||||||
|
peer = enet_host_connect(client, &address, LAST_CHANNEL, 0);
|
||||||
|
if (peer == nullptr) {
|
||||||
|
printf("peer null\n");
|
||||||
|
enet_host_destroy(client);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENetEvent event;
|
||||||
|
auto res = enet_host_service(client, &event, 5000);
|
||||||
|
|
||||||
|
if (res <= 0 || event.type != ENET_EVENT_TYPE_CONNECT) {
|
||||||
|
enet_peer_reset(peer);
|
||||||
|
printf("Failed to connect to server!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto packet_size = 1 + 2 + strlen(name);
|
||||||
|
auto login_packet = new char[packet_size];
|
||||||
|
login_packet[0] = Header::IDENTIFICATION;
|
||||||
|
*(uint16_t*)(login_packet + 1) = strlen(name);
|
||||||
|
memcpy(login_packet + 3, name, strlen(name));
|
||||||
|
|
||||||
|
if (sendPacket(login_packet, packet_size)) {
|
||||||
|
printf("trying to reg!!\n");
|
||||||
|
m_state = MultiplayerState::LOGGING_IN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Multiplayer::sendPacket(char* data, int size, Channel channel, bool reliable) {
|
||||||
|
auto enetPacket = enet_packet_create(data, size, reliable ? ENET_PACKET_FLAG_RELIABLE : ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT);
|
||||||
|
|
||||||
|
return enet_peer_send(peer, channel, enetPacket) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Multiplayer::update(float dt) {
|
||||||
|
ENetEvent event;
|
||||||
|
while (enet_host_service(client, &event, 0) > 0) {
|
||||||
|
switch (event.type) {
|
||||||
|
case ENET_EVENT_TYPE_RECEIVE: {
|
||||||
|
// printf("packet received\n");
|
||||||
|
|
||||||
|
auto bytes = event.packet->data;
|
||||||
|
|
||||||
|
// for (int i = 0; i < event.packet->dataLength; i++) {
|
||||||
|
// printf("%02X ", bytes[i]);
|
||||||
|
// }
|
||||||
|
// printf("\n");
|
||||||
|
|
||||||
|
switch (bytes[0]) {
|
||||||
|
case LOAD_PLAYER: { // all players get this when a new player connects
|
||||||
|
bytes++;
|
||||||
|
|
||||||
|
uint16_t nameLen = *(uint16_t*)bytes;
|
||||||
|
bytes += 2;
|
||||||
|
|
||||||
|
auto name = new char[nameLen + 1];
|
||||||
|
memcpy(name, bytes, nameLen);
|
||||||
|
bytes += nameLen;
|
||||||
|
name[nameLen] = 0;
|
||||||
|
|
||||||
|
uint32_t playerID = *(uint32_t*)bytes;
|
||||||
|
bytes += 4;
|
||||||
|
float serverTime = *(float*)bytes;
|
||||||
|
|
||||||
|
printf("- load player name %s id %i server time %f\n", name, playerID, serverTime);
|
||||||
|
|
||||||
|
Game::get().chatMessages.push_back({"Player " + std::string(name) + " has joined.", (float)GetTime()});
|
||||||
|
|
||||||
|
if (m_name == name) {
|
||||||
|
printf("- its me!\n");
|
||||||
|
m_id = playerID;
|
||||||
|
m_state = MultiplayerState::PLAYING;
|
||||||
|
Game::get().serverTime = serverTime;
|
||||||
|
|
||||||
|
char packet = Header::LOAD_PLAYERS;
|
||||||
|
|
||||||
|
sendPacket(&packet, 1);
|
||||||
|
} else {
|
||||||
|
// std::string texture = "assets/";
|
||||||
|
// std::string nicknamee = name;
|
||||||
|
// std::transform(nicknamee.begin(), nicknamee.end(), nicknamee.begin(), ::tolower);
|
||||||
|
// texture.append(nicknamee).append(".png");
|
||||||
|
|
||||||
|
auto p = Player(skinFromName(name), name);
|
||||||
|
p.pos.y = -400;
|
||||||
|
Game::get().otherPlayers[playerID] = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LOAD_PLAYERS: { // get list of all players on server with their id,pos,name
|
||||||
|
printf("- load players packet size %i\n", event.packet->dataLength);
|
||||||
|
|
||||||
|
bytes++;
|
||||||
|
|
||||||
|
auto num = *bytes;
|
||||||
|
bytes++;
|
||||||
|
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
auto id = *(uint32_t*)bytes;
|
||||||
|
bytes += 4;
|
||||||
|
auto x = *(float*)bytes;
|
||||||
|
bytes += 4;
|
||||||
|
auto y = *(float*)bytes;
|
||||||
|
bytes += 4;
|
||||||
|
|
||||||
|
auto nameLen = *(uint16_t*)bytes;
|
||||||
|
bytes += 2;
|
||||||
|
|
||||||
|
auto name = new char[nameLen + 1];
|
||||||
|
name[nameLen] = 0;
|
||||||
|
memcpy(name, bytes, nameLen);
|
||||||
|
bytes += nameLen;
|
||||||
|
|
||||||
|
printf("- - player: x %f y %f name %s id %i\n", x, y, name, id);
|
||||||
|
// std::string texture = "assets/";
|
||||||
|
// std::string nicknamee = name;
|
||||||
|
// std::transform(nicknamee.begin(), nicknamee.end(), nicknamee.begin(), ::tolower);
|
||||||
|
// texture.append(nicknamee).append(".png");
|
||||||
|
|
||||||
|
auto p = Player(skinFromName(name), name);
|
||||||
|
// auto p = Player(texture.c_str(), name);
|
||||||
|
p.pos = {x, y};
|
||||||
|
Game::get().otherPlayers[id] = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PLAYER: { // pos of all players
|
||||||
|
bytes++;
|
||||||
|
|
||||||
|
auto num = *bytes;
|
||||||
|
bytes++;
|
||||||
|
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
auto id = *(uint32_t*)bytes;
|
||||||
|
bytes += 4;
|
||||||
|
auto x = *(float*)bytes;
|
||||||
|
bytes += 4;
|
||||||
|
auto y = *(float*)bytes;
|
||||||
|
bytes += 4;
|
||||||
|
|
||||||
|
if (id == peer->connectID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Game::get().otherPlayers.contains(id)) {
|
||||||
|
auto& p = Game::get().otherPlayers[id];
|
||||||
|
// Game::get().otherPlayers[id].pos = {x, y};
|
||||||
|
auto delta_x = x - p.pos.x;
|
||||||
|
p.pos = {x, y};
|
||||||
|
p.vel.x = delta_x;
|
||||||
|
// p.walkRight = delta_x > 0;
|
||||||
|
if (delta_x > 0) {
|
||||||
|
p.walkRight = true;
|
||||||
|
} else if (delta_x < 0) {
|
||||||
|
p.walkRight = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MESSAGE: {
|
||||||
|
bytes++;
|
||||||
|
|
||||||
|
auto len = *(uint16_t*)bytes;
|
||||||
|
bytes += 2;
|
||||||
|
|
||||||
|
auto msg = new char[len + 1];
|
||||||
|
msg[len] = 0;
|
||||||
|
|
||||||
|
memcpy(msg, bytes, len);
|
||||||
|
|
||||||
|
Game::get().chatMessages.push_back({msg, (float)GetTime()});
|
||||||
|
|
||||||
|
delete[] msg;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
printf("- unk packet %i\n", bytes[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ENET_EVENT_TYPE_DISCONNECT: {
|
||||||
|
printf("Connection closed.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_updateTime += dt;
|
||||||
|
|
||||||
|
const auto POS_TIME = 1 / 30.f;
|
||||||
|
if (m_updateTime > POS_TIME) {
|
||||||
|
// printf("sending pos\n");
|
||||||
|
m_updateTime -= POS_TIME;
|
||||||
|
|
||||||
|
auto data = new char[1 + 4 + 4];
|
||||||
|
|
||||||
|
data[0] = Header::PLAYER;
|
||||||
|
*(float*)(data + 1) = Game::get().player.pos.x;
|
||||||
|
*(float*)(data + 1 + 4) = Game::get().player.pos.y;
|
||||||
|
|
||||||
|
sendPacket(data, 1 + 4 + 4);
|
||||||
|
|
||||||
|
delete[] data;
|
||||||
|
}
|
||||||
|
}
|
||||||
98
src/Multiplayer.hpp
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "saferaylib.h"
|
||||||
|
#include "cstdio"
|
||||||
|
#include "cstdint"
|
||||||
|
#include "string"
|
||||||
|
|
||||||
|
enum Channel : uint8_t {
|
||||||
|
EVERYTHING,
|
||||||
|
BLOCKS,
|
||||||
|
LAST_CHANNEL
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Header : uint8_t {
|
||||||
|
// World headers (also uses in mp)
|
||||||
|
PLAYER,
|
||||||
|
BLOCK,
|
||||||
|
CHUNK,
|
||||||
|
WORLD,
|
||||||
|
ENTITY,
|
||||||
|
INVENTORY_ITEM,
|
||||||
|
|
||||||
|
// Multiplayer headers
|
||||||
|
IDENTIFICATION,
|
||||||
|
DISCONNECT,
|
||||||
|
LOAD_CHUNK,
|
||||||
|
UNLOAD_CHUNK,
|
||||||
|
LOAD_PLAYER,
|
||||||
|
UNLOAD_PLAYER,
|
||||||
|
BLOCK_PLACE,
|
||||||
|
BLOCK_DESTROY,
|
||||||
|
|
||||||
|
NETWORK_ERROR,
|
||||||
|
ARRAY,
|
||||||
|
TERRAIN,
|
||||||
|
LOAD_TERRAIN,
|
||||||
|
LOAD_PLAYERS,
|
||||||
|
MESSAGE,
|
||||||
|
LOAD_MESSAGE,
|
||||||
|
NULL_PACKET = 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MultiplayerState {
|
||||||
|
CONNECTING,
|
||||||
|
LOGGING_IN,
|
||||||
|
LOADING_TERRAIN,
|
||||||
|
PLAYING,
|
||||||
|
ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
class Multiplayer {
|
||||||
|
public:
|
||||||
|
static Multiplayer& get() {
|
||||||
|
static Multiplayer inst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~Multiplayer() {
|
||||||
|
// printf("MP distr\n");
|
||||||
|
|
||||||
|
// char data = Header::DISCONNECT;
|
||||||
|
|
||||||
|
// sendPacket(&data, 1);
|
||||||
|
|
||||||
|
// if (peer) {
|
||||||
|
// enet_peer_reset(peer);
|
||||||
|
// peer = nullptr;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (client) {
|
||||||
|
// enet_host_destroy(client);
|
||||||
|
// client = nullptr;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
Multiplayer() : m_state(MultiplayerState::CONNECTING), client(nullptr), peer(nullptr), m_updateTime(0) {
|
||||||
|
printf("MP constr\n");
|
||||||
|
if (enet_initialize() != 0) {
|
||||||
|
printf("An error occurred while initializing ENet.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
atexit(enet_deinitialize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void connect(const char* name);
|
||||||
|
|
||||||
|
int sendPacket(char* data, int size, Channel channel = EVERYTHING, bool reliable = true);
|
||||||
|
void update(float dt);
|
||||||
|
|
||||||
|
MultiplayerState m_state;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ENetHost* client;
|
||||||
|
ENetPeer* peer;
|
||||||
|
std::string m_name;
|
||||||
|
uint32_t m_id;
|
||||||
|
float m_updateTime;
|
||||||
|
bool connected = false;
|
||||||
|
};
|
||||||
131
src/Player.cpp
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#include "Player.hpp"
|
||||||
|
#include "Game.hpp"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
Player::Player(const char* texName, std::string name, const Vector2& frameSize, int fps) : Player(LoadTexture(texName), name, frameSize, fps) {}
|
||||||
|
|
||||||
|
Player::Player(Texture2D tex, std::string name, const Vector2& frameSize, int fps)
|
||||||
|
: pos(0, 0), animTime(0), targetFrameTime(1.0f / fps), curFrame(0), vel(0, 0), onGround(false), walkRight(true), name(name), tex(tex) {
|
||||||
|
totalFrames = (int)(tex.width / frameSize.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::update(float dt) {
|
||||||
|
bool co = Game::get().chatOpen;
|
||||||
|
|
||||||
|
// // Should be removed from release build
|
||||||
|
// if (IsKeyDown(KEY_R) && !co) {
|
||||||
|
// // pos = {-66, -400};
|
||||||
|
// pos = spawnPoint;
|
||||||
|
// }
|
||||||
|
if (IsKeyDown(KEY_A) && !co) {
|
||||||
|
vel.x = -500;
|
||||||
|
walkRight = false;
|
||||||
|
} else if (IsKeyDown(KEY_D) && !co) {
|
||||||
|
vel.x = 500;
|
||||||
|
walkRight = true;
|
||||||
|
} else {
|
||||||
|
vel.x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((IsKeyDown(KEY_SPACE) || IsKeyDown(KEY_W)) && !co
|
||||||
|
#if 1
|
||||||
|
&& onGround
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
onGround = false;
|
||||||
|
// vel.y = -47000 * dt;
|
||||||
|
// vel.y = -(47000 * (1.f / 60));
|
||||||
|
vel.y = -(49000 * (1.f / 60));
|
||||||
|
}
|
||||||
|
|
||||||
|
// vel.y += 2000 * dt;
|
||||||
|
vel.y += 2300 * dt;
|
||||||
|
|
||||||
|
pos.y += vel.y * dt;
|
||||||
|
auto playerRect = Rectangle {pos.x + 10, pos.y, 64 - 20, 128};
|
||||||
|
auto colY = Game::get().level.collides(playerRect, true);
|
||||||
|
if (colY != 0) {
|
||||||
|
pos.y -= colY * (vel.y > 0 ? 1 : -1);
|
||||||
|
if (vel.y > 0) {
|
||||||
|
onGround = true;
|
||||||
|
}
|
||||||
|
vel.y = 0;
|
||||||
|
} else {
|
||||||
|
onGround = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos.x += vel.x * dt;
|
||||||
|
playerRect = Rectangle {pos.x + 10, pos.y, 64 - 20, 128};
|
||||||
|
auto colX = Game::get().level.collides(playerRect, false);
|
||||||
|
pos.x -= colX * (vel.x > 0 ? 1 : -1);
|
||||||
|
if (vel.x != 0) {
|
||||||
|
animTime += dt;
|
||||||
|
if (animTime >= targetFrameTime) {
|
||||||
|
animTime -= targetFrameTime;
|
||||||
|
curFrame = (curFrame + 1) % (totalFrames - 1);
|
||||||
|
// printf("%i\n", curFrame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vel.x == 0) {
|
||||||
|
curFrame = 0;
|
||||||
|
animTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
playerRect = Rectangle {pos.x + 10, pos.y, 64 - 20, 128};
|
||||||
|
|
||||||
|
for (auto& tile : Game::get().level.checkpoints) {
|
||||||
|
Rectangle tileRect = Rectangle {tile.x * 64.0f, tile.y * 64.0f, 64.0, 64.0f};
|
||||||
|
|
||||||
|
if (CheckCollisionRecs(playerRect, tileRect) && Game::get().spawnPointChangedTime == 0) {
|
||||||
|
spawnPoint = {tile.x * 64.0f - 32.f, tile.y * 64.0f};
|
||||||
|
Game::get().spawnPointChangedTime = GetTime();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& tile : Game::get().level.tiles) {
|
||||||
|
if (tile.id == LAVA) {
|
||||||
|
Rectangle tileRect = Rectangle {tile.x * 64.0f - 2, tile.y * 64.0f - 2, 64.0 + 4, 64.0f + 4};
|
||||||
|
tileRect.x += 2;
|
||||||
|
tileRect.width -= 4;
|
||||||
|
tileRect.y += 24.f;
|
||||||
|
tileRect.height -= 24.f;
|
||||||
|
if (CheckCollisionRecs(tileRect, playerRect)) {
|
||||||
|
pos = spawnPoint;
|
||||||
|
vel = {0, 0};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& saw : Game::get().level.saws) {
|
||||||
|
Rectangle tileRect = Rectangle {saw.pos.x + 2, saw.pos.y + 2, 64.0 - 4, 64.0f - 4};
|
||||||
|
if (CheckCollisionRecs(tileRect, playerRect)) {
|
||||||
|
pos = spawnPoint;
|
||||||
|
vel = {0, 0};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos.y > -1900 && pos.y < -1700 && pos.x > 4500) {
|
||||||
|
Game::get().entered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Game::get().camPos.x = fmax(pos.x - 640 + 32, -11 * 64.f);
|
||||||
|
Game::get().camPos.x = std::clamp(pos.x - 640 + 32, -11 * 64.f, 81 * 64.f - 1280);
|
||||||
|
Game::get().camPos.y = fmin(pos.y - 360 + 64, 4 * 64.f - 720 + 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::draw() {
|
||||||
|
// DrawTextureRec(tex, {(float)tex.width / totalFrames * curFrame, 0, (float)tex.width / totalFrames, (float)tex.height}, pos, WHITE);
|
||||||
|
auto p = Game::get().worldToScreen(pos);
|
||||||
|
auto ffframe = (vel.x != 0) ? curFrame + 1 : curFrame;
|
||||||
|
if (walkRight) {
|
||||||
|
DrawTexturePro(tex, {(float)tex.width / totalFrames * ffframe, 0, (float)tex.width / totalFrames, (float)tex.height},
|
||||||
|
{p.x, p.y, (float)tex.width / totalFrames * 2, (float)tex.height * 2}, {0, 0}, 0, WHITE);
|
||||||
|
} else {
|
||||||
|
DrawTexturePro(tex, {(float)tex.width / totalFrames * (ffframe), 0, -(float)tex.width / totalFrames, (float)tex.height},
|
||||||
|
{p.x, p.y, (float)tex.width / totalFrames * 2, (float)tex.height * 2}, {0, 0}, 0, WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/Player.hpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "saferaylib.h"
|
||||||
|
#include "string"
|
||||||
|
|
||||||
|
class Player {
|
||||||
|
public:
|
||||||
|
Player() {}
|
||||||
|
Player(const char* texName, std::string name, const Vector2& frameSize = {32, 64}, int fps = 7);
|
||||||
|
Player(Texture2D tex, std::string name, const Vector2& frameSize = {32, 64}, int fps = 7);
|
||||||
|
|
||||||
|
void update(float dt);
|
||||||
|
void draw();
|
||||||
|
|
||||||
|
Vector2 pos;
|
||||||
|
Vector2 vel;
|
||||||
|
std::string name;
|
||||||
|
Vector2 spawnPoint;
|
||||||
|
bool walkRight;
|
||||||
|
float animTime;
|
||||||
|
int curFrame;
|
||||||
|
int totalFrames;
|
||||||
|
float targetFrameTime;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Texture2D tex;
|
||||||
|
bool onGround;
|
||||||
|
};
|
||||||
1528
src/assets.hpp
Normal file
31
src/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include "Game.hpp"
|
||||||
|
#include "Multiplayer.hpp"
|
||||||
|
#include "thread"
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
auto& mp = Multiplayer::get();
|
||||||
|
|
||||||
|
#if KOLYAH_MODE
|
||||||
|
// std::thread(&Multiplayer::connect, &mp, "Kolyah35").detach();
|
||||||
|
std::string name = "Kolyah35";
|
||||||
|
#else
|
||||||
|
if (argc != 2) {
|
||||||
|
printf("specify ur name in args\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// std::thread(&Multiplayer::connect, &mp, argv[1]).detach();
|
||||||
|
std::string name = argv[1];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::thread(&Multiplayer::connect, &mp, name.c_str()).detach();
|
||||||
|
|
||||||
|
Game::get().start(name);
|
||||||
|
|
||||||
|
// printf("hi!\n");
|
||||||
|
|
||||||
|
// char data = Header::DISCONNECT;
|
||||||
|
|
||||||
|
// Multiplayer::get().sendPacket(&data, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
103
src/saferaylib.h
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
// To avoid conflicting windows.h symbols with raylib, some flags are defined
|
||||||
|
// WARNING: Those flags avoid inclusion of some Win32 headers that could be required
|
||||||
|
// by user at some point and won't be included...
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// If defined, the following flags inhibit definition of the indicated items.
|
||||||
|
#define NOGDICAPMASKS // CC_*, LC_*, PC_*, CP_*, TC_*, RC_
|
||||||
|
#define NOVIRTUALKEYCODES // VK_*
|
||||||
|
#define NOWINMESSAGES // WM_*, EM_*, LB_*, CB_*
|
||||||
|
#define NOWINSTYLES // WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_*
|
||||||
|
#define NOSYSMETRICS // SM_*
|
||||||
|
#define NOMENUS // MF_*
|
||||||
|
#define NOICONS // IDI_*
|
||||||
|
#define NOKEYSTATES // MK_*
|
||||||
|
#define NOSYSCOMMANDS // SC_*
|
||||||
|
#define NORASTEROPS // Binary and Tertiary raster ops
|
||||||
|
#define NOSHOWWINDOW // SW_*
|
||||||
|
#define OEMRESOURCE // OEM Resource values
|
||||||
|
#define NOATOM // Atom Manager routines
|
||||||
|
#define NOCLIPBOARD // Clipboard routines
|
||||||
|
#define NOCOLOR // Screen colors
|
||||||
|
#define NOCTLMGR // Control and Dialog routines
|
||||||
|
#define NODRAWTEXT // DrawText() and DT_*
|
||||||
|
#define NOGDI // All GDI defines and routines
|
||||||
|
#define NOKERNEL // All KERNEL defines and routines
|
||||||
|
#define NOUSER // All USER defines and routines
|
||||||
|
// #define NONLS // All NLS defines and routines
|
||||||
|
#define NOMB // MB_* and MessageBox()
|
||||||
|
#define NOMEMMGR // GMEM_*, LMEM_*, GHND, LHND, associated routines
|
||||||
|
#define NOMETAFILE // typedef METAFILEPICT
|
||||||
|
#define NOMINMAX // Macros min(a,b) and max(a,b)
|
||||||
|
#define NOMSG // typedef MSG and associated routines
|
||||||
|
#define NOOPENFILE // OpenFile(), OemToAnsi, AnsiToOem, and OF_*
|
||||||
|
#define NOSCROLL // SB_* and scrolling routines
|
||||||
|
#define NOSERVICE // All Service Controller routines, SERVICE_ equates, etc.
|
||||||
|
#define NOSOUND // Sound driver routines
|
||||||
|
#define NOTEXTMETRIC // typedef TEXTMETRIC and associated routines
|
||||||
|
#define NOWH // SetWindowsHook and WH_*
|
||||||
|
#define NOWINOFFSETS // GWL_*, GCL_*, associated routines
|
||||||
|
#define NOCOMM // COMM driver routines
|
||||||
|
#define NOKANJI // Kanji support stuff.
|
||||||
|
#define NOHELP // Help engine interface.
|
||||||
|
#define NOPROFILER // Profiler interface.
|
||||||
|
#define NODEFERWINDOWPOS // DeferWindowPos routines
|
||||||
|
#define NOMCX // Modem Configuration Extensions
|
||||||
|
|
||||||
|
#define MMNOSOUND
|
||||||
|
|
||||||
|
// Type required before windows.h inclusion
|
||||||
|
typedef struct tagMSG* LPMSG;
|
||||||
|
|
||||||
|
#include <enet/enet.h> // Now windows.h won't define CloseWindow, DrawText, etc.
|
||||||
|
// #include <windows.h>
|
||||||
|
|
||||||
|
// Type required by some unused function...
|
||||||
|
typedef struct tagBITMAPINFOHEADER {
|
||||||
|
DWORD biSize;
|
||||||
|
LONG biWidth;
|
||||||
|
LONG biHeight;
|
||||||
|
WORD biPlanes;
|
||||||
|
WORD biBitCount;
|
||||||
|
DWORD biCompression;
|
||||||
|
DWORD biSizeImage;
|
||||||
|
LONG biXPelsPerMeter;
|
||||||
|
LONG biYPelsPerMeter;
|
||||||
|
DWORD biClrUsed;
|
||||||
|
DWORD biClrImportant;
|
||||||
|
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
|
||||||
|
|
||||||
|
#include <objbase.h>
|
||||||
|
#include <mmreg.h>
|
||||||
|
#include <mmsystem.h>
|
||||||
|
|
||||||
|
// Some required types defined for MSVC/TinyC compiler
|
||||||
|
#if defined(_MSC_VER) || defined(__TINYC__)
|
||||||
|
#include "propidl.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// #define WIN32_LEAN_AND_MEAN
|
||||||
|
// #define NOMINMAX
|
||||||
|
// #define NOGDI
|
||||||
|
#if defined(__linux__)
|
||||||
|
#include <enet/enet.h> // Now windows.h won't define CloseWindow, DrawText, etc.
|
||||||
|
#endif
|
||||||
|
// // Explicitly undefine remaining problematic macros
|
||||||
|
// #ifdef CloseWindow
|
||||||
|
// #undef CloseWindow
|
||||||
|
// #endif
|
||||||
|
// #ifdef DrawText
|
||||||
|
// #undef DrawText
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define KOLYAH_MODE 0
|
||||||