tempsdedl
This commit is contained in:
parent
8c26c84821
commit
39b998d62b
290
idea/chaosDungeon.md
Normal file
290
idea/chaosDungeon.md
Normal file
@ -0,0 +1,290 @@
|
||||
# World of Chaos : Dungeon and Knowledge
|
||||
|
||||
First level should be a very hard wave defense where you need to lose, but the difficulty go higher until the player cannot defend it anymore.
|
||||
|
||||
Add effect for item drop or mob drop for rarity with special sound and effect for legendary one.
|
||||
|
||||
___
|
||||
|
||||
## 1. Game Overview
|
||||
|
||||
- Name-> World of Chaos : Dungeon and Knowledge
|
||||
|
||||
- Genre-> Real-time Survival Base-Builder & Defense with Sandbox Construction, Tech-Tree Progression, Wave Survival, Dungeon-Crawl
|
||||
- Platform-> Desktop (Windows, Linux)
|
||||
- Perspective-> 2D Top-Down, Tile-Based
|
||||
- Core Experience-> Fast-paced, responsive building + combat (akin to MOBA/RTS), layered loops reward both planning (base, tech) and moment-to-moment skill (aim, positioning).
|
||||
|
||||
___
|
||||
|
||||
## 2. High-Level Concept
|
||||
|
||||
- MVP Vision:
|
||||
|
||||
- Sandbox Build Mode: Place walls, turrets, resource-gatherers on a grid.
|
||||
|
||||
- Defense Loop: Survive waves of enemies attacking your base.
|
||||
|
||||
- Round Survival Loop: Fixed-arena rounds with escalating difficulty.
|
||||
|
||||
- Dungeon Crawl Loop: Enter procedural dungeon, defeat boss; failure sends boss to assault your base in next wave.
|
||||
|
||||
|
||||
|
||||
- USP (Unique Selling Points):
|
||||
|
||||
- Four interlocking loops: your dungeon success directly impacts base defense.
|
||||
|
||||
- Deep tech-tree: unlock new defenses, units, dungeon skills.
|
||||
|
||||
- Responsive, omnidirectional movement & aiming—skill matters.
|
||||
|
||||
___
|
||||
|
||||
## 3. Core Gameplay Mechanics
|
||||
|
||||
- Movement & Combat:
|
||||
- 8-directional movement.
|
||||
- real-time aiming with mouse.
|
||||
- instant feedback on attacks & blocks.
|
||||
- Building:
|
||||
- Grid-snapping placement.
|
||||
- rotate/flip tiles.
|
||||
- undo/redo.
|
||||
- resource cost preview.
|
||||
- Resources:
|
||||
- Wood, Stone, Metal.
|
||||
- gathered via structures or dungeon pickups.
|
||||
- Tech Tree:
|
||||
- Multi-branch:
|
||||
- Base Defense.
|
||||
- Resource Efficiency.
|
||||
- Dungeon Skills.
|
||||
- Elite Units.
|
||||
- Enemy Waves:
|
||||
- Scripted + procedural mix.
|
||||
- includes fast scouts, heavy brutes, flying units.
|
||||
- Dungeon:
|
||||
- Procedural rooms.
|
||||
- puzzles.
|
||||
- minibosses.
|
||||
- culminates in boss fight with unique mechanics.
|
||||
|
||||
___
|
||||
|
||||
## 4. Game Loops
|
||||
|
||||
- Sandbox Build (Persistent): Place/upgrade structures; plan defenses.
|
||||
|
||||
- Defense Wave (Dynamic): Enemies pathfind toward base; survive until timer.
|
||||
|
||||
- Round Survival (Arena): Fixed map, randomized spawn points; earn bonus resources per round.
|
||||
|
||||
- Dungeon Crawl: Voluntary loop—risk vs. reward. Dungeon boss grants tech unlock on success; on failure, boss invades next wave.
|
||||
|
||||
- Opinion: Prioritize implementing the Defense Wave & Sandbox Build first—they form the spine of player engagement. Then layer in Round Survival. Dungeon Crawl can initially be a single hand-crafted level to prove the loop.
|
||||
|
||||
___
|
||||
|
||||
## 5. MVP Feature List
|
||||
|
||||
- A. Core Systems (Week 1–3)
|
||||
|
||||
- Tilemap rendering & collision (raylib tilemap module)
|
||||
|
||||
- Player movement/aim/shoot
|
||||
|
||||
- Basic enemy AI (pathfinding to base)
|
||||
|
||||
- B. Building & Resources (Week 4–6)
|
||||
|
||||
- Place/destroy grid-aligned buildings
|
||||
|
||||
- Resource spawn & collection
|
||||
|
||||
- C. Wave Defense Loop (Week 7–9)
|
||||
|
||||
- Wave spawner, UI timer, win/lose conditions
|
||||
|
||||
- D. Tech Tree UI & Data (Week 10–11)
|
||||
|
||||
- Data-driven tech nodes, unlock logic, simple UI
|
||||
|
||||
- E. Round Survival & Score (Week 12–13)
|
||||
|
||||
- F. Dungeon Prototype (Week 14–16)
|
||||
|
||||
___
|
||||
|
||||
## 6. Tech-Tree Design
|
||||
|
||||
```
|
||||
[Resource Efficiency]──┐
|
||||
├─[Advanced Turrets]──[Energy Shield]
|
||||
[Base Armor]───────────┘ │
|
||||
├─[Boss Summon Tech]
|
||||
[Trap Mastery]─────────┐ │
|
||||
├─[Dungeon Vision]─────┘
|
||||
[Spellcraft]───────────┘
|
||||
```
|
||||
|
||||
- Node Details:
|
||||
|
||||
- Cost in tech-points (earned per wave/dungeon).
|
||||
|
||||
- Prerequisites enforce meaningful choices.
|
||||
|
||||
- Strong opinion: cap tech depth to 15–20 nodes for MVP.
|
||||
|
||||
___
|
||||
|
||||
## 7. Systems Architecture
|
||||
|
||||
- Language: C99
|
||||
|
||||
- Engine: raylib (windowing, input, 2D rendering, audio)
|
||||
|
||||
- Modules:
|
||||
|
||||
```
|
||||
tilemap.c/h (grid, pathfinding)
|
||||
|
||||
player.c/h (movement, input)
|
||||
|
||||
entity.c/h (enemies, projectiles)
|
||||
|
||||
buildings.c/h (construction, upgrades)
|
||||
|
||||
waves.c/h (spawn logic)
|
||||
|
||||
dungeon.c/h (room gen, boss logic)
|
||||
|
||||
tech.c/h (tech-tree data & UI)
|
||||
|
||||
ui.c/h (HUD, menus)
|
||||
```
|
||||
|
||||
- Data: JSON or simple CSV for wave definitions, tech nodes, tile properties.
|
||||
|
||||
___
|
||||
|
||||
## 8. Controls & UI
|
||||
|
||||
- Controls:
|
||||
|
||||
- WASD or arrows: Move
|
||||
|
||||
- Mouse: Aim & shoot
|
||||
|
||||
- 1–5: Hotkeys for building types
|
||||
|
||||
- T: Open Tech Tree
|
||||
|
||||
- Esc: Menu/Pause
|
||||
|
||||
- UI Layout:
|
||||
|
||||
- Top-center: Wave timer & round
|
||||
|
||||
- Bottom-left: Resource counters
|
||||
|
||||
- Bottom-right: Build hotkeys
|
||||
|
||||
- Center-right: Tech-tree button
|
||||
|
||||
___
|
||||
|
||||
## 9. Art & Audio (MVP)
|
||||
|
||||
- Art Style: Simple, high-contrast tiles; clear readability over detail.
|
||||
|
||||
- Animations: 4-frame loops for player/enemies.
|
||||
|
||||
- Audio:
|
||||
- Looping ambient track
|
||||
|
||||
- SFX: construction, shooting, enemy death
|
||||
|
||||
- Opinion: Defer polish art until gameplay is locked; use placeholders but ensure clarity.
|
||||
|
||||
___
|
||||
|
||||
## 10. Success Metrics & KPIs
|
||||
|
||||
- Playtest Goal: Survive at least 5 waves with basic defenses.
|
||||
|
||||
- Performance: Stable 60 FPS on moderate hardware (Intel i5, integrated GPU).
|
||||
|
||||
- Engagement: Test loop—players should face meaningful choices every 30 s.
|
||||
|
||||
___
|
||||
|
||||
## 11. Risks & Mitigations
|
||||
|
||||
```
|
||||
Risk->Mitigation:
|
||||
|
||||
Pathfinding stalls on large maps->Limit map size; use A* with node caching
|
||||
Feature creep (dungeon complexity)->Lock dungeon to 3 room types for MVP
|
||||
Balancing tech-tree overpowered->Data-driven values; expose easy tuning parameters
|
||||
```
|
||||
|
||||
___
|
||||
|
||||
## 12. Roadmap & Milestones
|
||||
|
||||
- Prototype (Weeks 1–3): Movement, tilemap, enemy pathfind.
|
||||
|
||||
- Alpha (Weeks 4–9): Building, resources, first 3 waves.
|
||||
|
||||
- Beta (Weeks 10–14): Tech tree, survival rounds, basic dungeon.
|
||||
|
||||
- MVP Release (Week 16): All loops functional; placeholder assets.
|
||||
|
||||
___
|
||||
|
||||
## 13. Next Steps
|
||||
|
||||
- Review GDD—prioritize any missing “must-have.”
|
||||
|
||||
- Scaffold C modules & basic raylib window.
|
||||
|
||||
- Implement tilemap + player movement immediately.
|
||||
|
||||
- Schedule weekly playtest to validate loops.
|
||||
|
||||
___
|
||||
|
||||
## how it started
|
||||
|
||||
I give myself 2 mounth to finish this project, the roadmap can be seen in roguelike_projecct_roadmap.md
|
||||
|
||||
the point is to challenge myself to finish a simple commercial game
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
int height, width;
|
||||
float rotation;
|
||||
} obstacle_hitbox;
|
||||
```
|
||||
___
|
||||
|
||||
## idea
|
||||
|
||||
- base building and defense (kinda more like terraria)
|
||||
- dungeon exploration
|
||||
- wave survival
|
||||
- exploration ?
|
||||
- hand crafted world no procedural (only dungeon using presets parts)
|
||||
- using advanced shader using normal texture and depth of object top down 2D
|
||||
|
||||
- load level from tiled xml
|
||||
- use tile in a 3D world, but only one layer with cartoon texture
|
||||
|
||||
___
|
||||
|
||||
### refs art:
|
||||
|
||||
- https://www.youtube.com/watch?v=R6vQ9VmMz2w
|
||||
- https://www.youtube.com/watch?v=YVUPgiyB6iM
|
||||
- https://www.youtube.com/watch?v=HsOKwUwL1bE
|
||||
97
idea/roguelike_project_roadmap.md
Normal file
97
idea/roguelike_project_roadmap.md
Normal file
@ -0,0 +1,97 @@
|
||||
# 2D Roguelike with Dual Game Loops: Roadmap & Deadline
|
||||
|
||||
This document outlines a detailed plan to create a simple 2D roguelike in C using raylib, featuring two distinct game loops: defending your base against hordes and pillaging a dungeon.
|
||||
|
||||
---
|
||||
|
||||
## 1. Realistic Deadline Estimate
|
||||
|
||||
- **Overall Estimate:** **80–120 hours** of focused development time
|
||||
*(This can be spread over several weeks if you’re working part time.)*
|
||||
|
||||
> **Note:**
|
||||
> If you’re new to C/game development or raylib, you may want to extend this timeline by an additional 50% or more to cover learning curves and extra debugging.
|
||||
|
||||
---
|
||||
|
||||
## 2. Roadmap / To-Do List
|
||||
|
||||
### A. Pre-Production and Planning (8–12 hours)
|
||||
- **Concept Design:**
|
||||
- Define the core mechanics for both game loops:
|
||||
- **Base Defense Mode:** Determine horde attack wave system, enemy behavior, and defensive structure mechanics.
|
||||
- **Dungeon Pillaging Mode:** Decide on dungeon layout, exploration dynamics, enemy encounters, and reward systems.
|
||||
- Sketch out game flow diagrams and state transitions between modes.
|
||||
- **Feature List & Scope:**
|
||||
- Create a brief design document outlining gameplay, UI, and any score/progression systems.
|
||||
- Prioritize features (MVP vs. additional polish) to ensure core gameplay is functional.
|
||||
- **Tool Setup:**
|
||||
- Install and configure raylib.
|
||||
- Set up your development environment (IDE, version control, build scripts).
|
||||
|
||||
### B. Prototyping Basic Framework (15–20 hours)
|
||||
- **Project Setup:**
|
||||
- Initialize a basic C project structure and integrate raylib.
|
||||
- Create a main game loop with a game state manager to switch between modes.
|
||||
- **Basic Game Loop Implementation:**
|
||||
- Implement a splash screen or main menu for mode selection.
|
||||
- Add stubs for each mode (base defense and dungeon) to verify mode switching.
|
||||
- **Input and Rendering:**
|
||||
- Set up event handling using raylib for keyboard/mouse input.
|
||||
- Render simple shapes or sprites as placeholders for the player, enemies, and bases.
|
||||
|
||||
### C. Base Defense Mode Development (25–30 hours)
|
||||
- **Game Mechanics:**
|
||||
- Code enemy spawning and implement wave mechanics for base defense.
|
||||
- Develop basic AI for enemy movement and targeting the base.
|
||||
- **Player & Base Interactions:**
|
||||
- Create defensive structures or player-controlled defenses.
|
||||
- Implement collision detection between enemies and the base.
|
||||
- **Visual Feedback:**
|
||||
- Display base health/integrity.
|
||||
- Include simple animations or state feedback (damage effects, score updates).
|
||||
- **Testing and Iteration:**
|
||||
- Continuously test and tweak enemy behavior, spawn rates, and difficulty.
|
||||
|
||||
### D. Dungeon Pillaging Mode Development (25–30 hours)
|
||||
- **Dungeon Generation:**
|
||||
- Design a simple procedural (or pre-defined) dungeon layout.
|
||||
- Implement room transitions, corridors, or tile-based map structure.
|
||||
- **Player Mechanics:**
|
||||
- Code player movement, attacks, and possibly a simple inventory or item system.
|
||||
- Define enemy encounters with a basic combat system and AI.
|
||||
- **Environment Interactions:**
|
||||
- Add interactive elements such as doors, traps, or treasure chests.
|
||||
- Implement transitions between rooms or levels.
|
||||
- **Basic Story/Progression Elements:**
|
||||
- Integrate objectives like reaching a goal or collecting treasures.
|
||||
- Consider power-ups or enhancements to influence later base defense rounds.
|
||||
- **Testing and Iteration:**
|
||||
- Playtest exploration, tweak enemy difficulty, and adjust dungeon layouts to ensure engagement.
|
||||
|
||||
### E. Integration, Polish, and Debugging (10–20 hours)
|
||||
- **Integration:**
|
||||
- Seamlessly connect the two modes so that players can transition between them.
|
||||
- Implement transitions (e.g., carrying over score or narrative cues).
|
||||
- **Polish:**
|
||||
- Refine graphics and animations (using temporary assets if necessary).
|
||||
- Add sound effects and background music for an improved player experience.
|
||||
- **Debugging & Optimization:**
|
||||
- Thoroughly playtest for bugs and balance gameplay.
|
||||
- Optimize performance, particularly when managing multiple on-screen entities.
|
||||
- **Final Touches:**
|
||||
- Develop a simple scoring or progression system, if desired.
|
||||
- Implement a basic UI for health, score, and game mode transitions.
|
||||
|
||||
### F. Buffer and Extra Time
|
||||
- **Extra Time (Optional):** Reserve an additional **10–20%** of the total planned hours for unforeseen challenges or potential extra features.
|
||||
|
||||
---
|
||||
|
||||
## 3. Final Considerations
|
||||
|
||||
- **Iteration:** Game development is iterative. Be prepared to revisit and refine early stages as new challenges or ideas arise.
|
||||
- **Scope Management:** Focus initially on a minimal viable product (MVP) that covers both game modes. Additional features can be added once core gameplay is solid.
|
||||
- **Learning Curve:** If you are less experienced with raylib or game development in C, consider using online tutorials and community forums for additional guidance.
|
||||
|
||||
Good luck with your project!
|
||||
@ -7,6 +7,26 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "entity.h"
|
||||
typedef enum {
|
||||
STATE_RUNNING = 1 << 0,
|
||||
STATE_CLOSING = 1 << 1,
|
||||
} ENGINE_STATE_ENUM;
|
||||
|
||||
typedef enum {
|
||||
CAM_FP,
|
||||
CAM_TP,
|
||||
CAM_FREE
|
||||
} ENGINE_CAMERA_ENUM;
|
||||
|
||||
#define ENGINE_CAMERA_NUMBER 3
|
||||
|
||||
typedef struct {
|
||||
uint32_t w_height;
|
||||
uint32_t w_width;
|
||||
uint16_t state;
|
||||
Camera3D camera[ENGINE_CAMERA_NUMBER];
|
||||
uint8_t current_cam;
|
||||
} context;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
1
source/engine/ecs.c
Normal file
1
source/engine/ecs.c
Normal file
@ -0,0 +1 @@
|
||||
#include "ecs.h"
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef ENTITY_H
|
||||
# define ENTITY_H
|
||||
#ifndef ENGINE_ECS_H
|
||||
# define ENGINE_ECS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@ -13,7 +13,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
int current[MAX_ENTITY];
|
||||
int max{MAX_ENTITY};
|
||||
int max[MAX_ENTITY];
|
||||
} health_array;
|
||||
|
||||
typedef struct {
|
||||
19
source/engine/game_state.c
Normal file
19
source/engine/game_state.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include "game_state.h"
|
||||
|
||||
void initialize_game(GameState *state) {
|
||||
initialize_player(&state->localPlayer);
|
||||
state->remoteCount = 0;
|
||||
}
|
||||
|
||||
void update_game(GameState *state, InputState *input, float delta) {
|
||||
update_player_movement(&state->localPlayer, input, delta);
|
||||
|
||||
PlayerNetState netState = {
|
||||
.id = 0,
|
||||
.position = state->localPlayer.position,
|
||||
.velocity = state->localPlayer.velocity,
|
||||
.yaw = state->localPlayer.yaw
|
||||
};
|
||||
send_player_state(&netState);
|
||||
receive_remote_players(state->remotePlayers, &state->remoteCount);
|
||||
}
|
||||
18
source/engine/game_state.h
Normal file
18
source/engine/game_state.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef ENGINE_GAME_STATE_H
|
||||
# define ENGINE_GAME_STATE_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "player_controller.h"
|
||||
#include "net_sync.h"
|
||||
|
||||
typedef struct {
|
||||
PlayerState localPlayer;
|
||||
PlayerNetState remotePlayers[MAX_REMOTE_PLAYERS];
|
||||
int remoteCount;
|
||||
} GameState;
|
||||
|
||||
void initialize_game(GameState *state);
|
||||
void update_game(GameState *state, InputState *input, float delta);
|
||||
|
||||
#endif
|
||||
9
source/engine/net_sync.c
Normal file
9
source/engine/net_sync.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include "net_sync.h"
|
||||
|
||||
void send_player_state(PlayerNetState *state) {
|
||||
// TODO: Serialize + UDP send
|
||||
}
|
||||
|
||||
void receive_remote_players(PlayerNetState *players, int *count) {
|
||||
// TODO: Receive + deserialize state
|
||||
}
|
||||
20
source/engine/net_sync.h
Normal file
20
source/engine/net_sync.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef ENGINE_NET_H
|
||||
# define ENGINE_NET_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vector_math.h"
|
||||
|
||||
#define MAX_REMOTE_PLAYERS 16
|
||||
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
Vector3 position;
|
||||
Vector3 velocity;
|
||||
float yaw;
|
||||
} PlayerNetState;
|
||||
|
||||
void send_player_state(PlayerNetState *state);
|
||||
void receive_remote_players(PlayerNetState *players, int *count);
|
||||
|
||||
#endif
|
||||
38
source/engine/physic.c
Normal file
38
source/engine/physic.c
Normal file
@ -0,0 +1,38 @@
|
||||
#include "physics.h"
|
||||
#include <math.h>
|
||||
|
||||
Vector3 apply_gravity(Vector3 velocity, float delta) {
|
||||
velocity.y += GRAVITY * delta;
|
||||
return velocity;
|
||||
}
|
||||
|
||||
Vector3 apply_friction(Vector3 velocity, float delta, bool grounded) {
|
||||
if (!grounded) return velocity;
|
||||
velocity.x *= 1.0f - delta * 6.0f;
|
||||
velocity.z *= 1.0f - delta * 6.0f;
|
||||
return velocity;
|
||||
}
|
||||
|
||||
Vector3 ground_accelerate(Vector3 velocity, Vector3 wishDir, float wishSpeed, float delta) {
|
||||
float accel = 10.0f;
|
||||
Vector3 change = Vector3Scale(wishDir, accel * delta);
|
||||
return Vector3Add(velocity, change);
|
||||
}
|
||||
|
||||
Vector3 air_accelerate(Vector3 velocity, Vector3 wishDir, float wishSpeed, float delta) {
|
||||
float accel = 2.5f;
|
||||
Vector3 change = Vector3Scale(wishDir, accel * delta);
|
||||
return Vector3Add(velocity, change);
|
||||
}
|
||||
|
||||
Vector3 calculate_wish_direction(InputState *input, float yaw) {
|
||||
Vector3 forward = { sinf(yaw), 0, cosf(yaw) };
|
||||
Vector3 right = { -forward.z, 0, forward.x };
|
||||
Vector3 wish = {0};
|
||||
|
||||
if (input->forward) wish = Vector3Add(wish, forward);
|
||||
if (input->backward) wish = Vector3Subtract(wish, forward);
|
||||
if (input->left) wish = Vector3Subtract(wish, right);
|
||||
if (input->right) wish = Vector3Add(wish, right);
|
||||
return Vector3Normalize(wish);
|
||||
}
|
||||
20
source/engine/physic.h
Normal file
20
source/engine/physic.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef ENGINE_PHYSIC_H
|
||||
# define ENGINE_PHYSIC_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vector_math.h"
|
||||
|
||||
#define GROUND_Y 0.0f
|
||||
#define GRAVITY -9.81f
|
||||
#define PLAYER_JUMP_VELOCITY 8.0f
|
||||
#define PLAYER_WALK_SPEED 5.0f
|
||||
#define PLAYER_SPRINT_SPEED 8.5f
|
||||
|
||||
Vector3 apply_gravity(Vector3 velocity, float delta);
|
||||
Vector3 apply_friction(Vector3 velocity, float delta, bool grounded);
|
||||
Vector3 ground_accelerate(Vector3 velocity, Vector3 wishDir, float wishSpeed, float delta);
|
||||
Vector3 air_accelerate(Vector3 velocity, Vector3 wishDir, float wishSpeed, float delta);
|
||||
Vector3 calculate_wish_direction(InputState *input, float yaw);
|
||||
|
||||
#endif
|
||||
33
source/engine/player_controller.c
Normal file
33
source/engine/player_controller.c
Normal file
@ -0,0 +1,33 @@
|
||||
#include "player_controller.h"
|
||||
#include "physics.h"
|
||||
|
||||
void initialize_player(PlayerState *player) {
|
||||
player->position = (Vector3){0};
|
||||
player->velocity = (Vector3){0};
|
||||
player->acceleration = (Vector3){0};
|
||||
player->yaw = 0.0f;
|
||||
player->pitch = 0.0f;
|
||||
player->isGrounded = false;
|
||||
player->isSprinting = false;
|
||||
player->isSliding = false;
|
||||
}
|
||||
|
||||
void update_player_movement(PlayerState *player, InputState *input, float delta) {
|
||||
Vector3 wishDir = calculate_wish_direction(input, player->yaw);
|
||||
float wishSpeed = player->isSprinting ? PLAYER_SPRINT_SPEED : PLAYER_WALK_SPEED;
|
||||
|
||||
if (player->isGrounded) {
|
||||
if (input->jump) {
|
||||
player->velocity.y = PLAYER_JUMP_VELOCITY;
|
||||
player->isGrounded = false;
|
||||
}
|
||||
player->velocity = ground_accelerate(player->velocity, wishDir, wishSpeed, delta);
|
||||
if (input->crouch) player->isSliding = true;
|
||||
} else {
|
||||
player->velocity = air_accelerate(player->velocity, wishDir, wishSpeed, delta);
|
||||
}
|
||||
|
||||
player->velocity = apply_friction(player->velocity, delta, player->isGrounded);
|
||||
player->velocity = apply_gravity(player->velocity, delta);
|
||||
player->position = Vector3Add(player->position, Vector3Scale(player->velocity, delta));
|
||||
}
|
||||
18
source/engine/player_controller.h
Normal file
18
source/engine/player_controller.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "vector_math.h"
|
||||
#include "input_state.h"
|
||||
|
||||
typedef struct {
|
||||
Vector3 position;
|
||||
Vector3 velocity;
|
||||
Vector3 acceleration;
|
||||
float yaw;
|
||||
float pitch;
|
||||
bool isGrounded;
|
||||
bool isSprinting;
|
||||
bool isSliding;
|
||||
} PlayerState;
|
||||
|
||||
void initialize_player(PlayerState *player);
|
||||
void update_player_movement(PlayerState *player, InputState *input, float delta);
|
||||
1
source/engine/ui.c
Normal file
1
source/engine/ui.c
Normal file
@ -0,0 +1 @@
|
||||
#include "ui.h"
|
||||
24
source/engine/ui.h
Normal file
24
source/engine/ui.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef ENGINE_UI_H
|
||||
# define ENGINE_UI_H
|
||||
|
||||
/* input */
|
||||
typedef struct {
|
||||
bool is_mouse;
|
||||
bool repeat;
|
||||
int bind;
|
||||
} keybind_t;
|
||||
|
||||
|
||||
/* gui */
|
||||
typedef struct {
|
||||
Texture2D tex;
|
||||
Rectangle rec;
|
||||
char* str;
|
||||
} button;
|
||||
|
||||
bool mouse_inbound(const Rectangle bound, const Vector2 mouse_pos);
|
||||
button create_button(Vector2 pos, char* tex_path, char* str);
|
||||
void destroy_button(button b);
|
||||
bool gui_button(button b);
|
||||
|
||||
#endif
|
||||
0
source/engine/world.c
Normal file
0
source/engine/world.c
Normal file
2392
source/extern/toml.c
vendored
Normal file
2392
source/extern/toml.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
175
source/extern/toml.h
vendored
Normal file
175
source/extern/toml.h
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) CK Tan
|
||||
https://github.com/cktan/tomlc99
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef TOML_H
|
||||
#define TOML_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define TOML_EXTERN extern "C"
|
||||
#else
|
||||
#define TOML_EXTERN extern
|
||||
#endif
|
||||
|
||||
typedef struct toml_timestamp_t toml_timestamp_t;
|
||||
typedef struct toml_table_t toml_table_t;
|
||||
typedef struct toml_array_t toml_array_t;
|
||||
typedef struct toml_datum_t toml_datum_t;
|
||||
|
||||
/* Parse a file. Return a table on success, or 0 otherwise.
|
||||
* Caller must toml_free(the-return-value) after use.
|
||||
*/
|
||||
TOML_EXTERN toml_table_t *toml_parse_file(FILE *fp, char *errbuf, int errbufsz);
|
||||
|
||||
/* Parse a string containing the full config.
|
||||
* Return a table on success, or 0 otherwise.
|
||||
* Caller must toml_free(the-return-value) after use.
|
||||
*/
|
||||
TOML_EXTERN toml_table_t *toml_parse(char *conf, /* NUL terminated, please. */
|
||||
char *errbuf, int errbufsz);
|
||||
|
||||
/* Free the table returned by toml_parse() or toml_parse_file(). Once
|
||||
* this function is called, any handles accessed through this tab
|
||||
* directly or indirectly are no longer valid.
|
||||
*/
|
||||
TOML_EXTERN void toml_free(toml_table_t *tab);
|
||||
|
||||
/* Timestamp types. The year, month, day, hour, minute, second, z
|
||||
* fields may be NULL if they are not relevant. e.g. In a DATE
|
||||
* type, the hour, minute, second and z fields will be NULLs.
|
||||
*/
|
||||
struct toml_timestamp_t {
|
||||
struct { /* internal. do not use. */
|
||||
int year, month, day;
|
||||
int hour, minute, second, millisec;
|
||||
char z[10];
|
||||
} __buffer;
|
||||
int *year, *month, *day;
|
||||
int *hour, *minute, *second, *millisec;
|
||||
char *z;
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
* Enhanced access methods
|
||||
*/
|
||||
struct toml_datum_t {
|
||||
int ok;
|
||||
union {
|
||||
toml_timestamp_t *ts; /* ts must be freed after use */
|
||||
char *s; /* string value. s must be freed after use */
|
||||
int b; /* bool value */
|
||||
int64_t i; /* int value */
|
||||
double d; /* double value */
|
||||
} u;
|
||||
};
|
||||
|
||||
/* on arrays: */
|
||||
/* ... retrieve size of array. */
|
||||
TOML_EXTERN int toml_array_nelem(const toml_array_t *arr);
|
||||
/* ... retrieve values using index. */
|
||||
TOML_EXTERN toml_datum_t toml_string_at(const toml_array_t *arr, int idx);
|
||||
TOML_EXTERN toml_datum_t toml_bool_at(const toml_array_t *arr, int idx);
|
||||
TOML_EXTERN toml_datum_t toml_int_at(const toml_array_t *arr, int idx);
|
||||
TOML_EXTERN toml_datum_t toml_double_at(const toml_array_t *arr, int idx);
|
||||
TOML_EXTERN toml_datum_t toml_timestamp_at(const toml_array_t *arr, int idx);
|
||||
/* ... retrieve array or table using index. */
|
||||
TOML_EXTERN toml_array_t *toml_array_at(const toml_array_t *arr, int idx);
|
||||
TOML_EXTERN toml_table_t *toml_table_at(const toml_array_t *arr, int idx);
|
||||
|
||||
/* on tables: */
|
||||
/* ... retrieve the key in table at keyidx. Return 0 if out of range. */
|
||||
TOML_EXTERN const char *toml_key_in(const toml_table_t *tab, int keyidx);
|
||||
/* ... returns 1 if key exists in tab, 0 otherwise */
|
||||
TOML_EXTERN int toml_key_exists(const toml_table_t *tab, const char *key);
|
||||
/* ... retrieve values using key. */
|
||||
TOML_EXTERN toml_datum_t toml_string_in(const toml_table_t *arr,
|
||||
const char *key);
|
||||
TOML_EXTERN toml_datum_t toml_bool_in(const toml_table_t *arr, const char *key);
|
||||
TOML_EXTERN toml_datum_t toml_int_in(const toml_table_t *arr, const char *key);
|
||||
TOML_EXTERN toml_datum_t toml_double_in(const toml_table_t *arr,
|
||||
const char *key);
|
||||
TOML_EXTERN toml_datum_t toml_timestamp_in(const toml_table_t *arr,
|
||||
const char *key);
|
||||
/* .. retrieve array or table using key. */
|
||||
TOML_EXTERN toml_array_t *toml_array_in(const toml_table_t *tab,
|
||||
const char *key);
|
||||
TOML_EXTERN toml_table_t *toml_table_in(const toml_table_t *tab,
|
||||
const char *key);
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
* lesser used
|
||||
*/
|
||||
/* Return the array kind: 't'able, 'a'rray, 'v'alue, 'm'ixed */
|
||||
TOML_EXTERN char toml_array_kind(const toml_array_t *arr);
|
||||
|
||||
/* For array kind 'v'alue, return the type of values
|
||||
i:int, d:double, b:bool, s:string, t:time, D:date, T:timestamp, 'm'ixed
|
||||
0 if unknown
|
||||
*/
|
||||
TOML_EXTERN char toml_array_type(const toml_array_t *arr);
|
||||
|
||||
/* Return the key of an array */
|
||||
TOML_EXTERN const char *toml_array_key(const toml_array_t *arr);
|
||||
|
||||
/* Return the number of key-values in a table */
|
||||
TOML_EXTERN int toml_table_nkval(const toml_table_t *tab);
|
||||
|
||||
/* Return the number of arrays in a table */
|
||||
TOML_EXTERN int toml_table_narr(const toml_table_t *tab);
|
||||
|
||||
/* Return the number of sub-tables in a table */
|
||||
TOML_EXTERN int toml_table_ntab(const toml_table_t *tab);
|
||||
|
||||
/* Return the key of a table*/
|
||||
TOML_EXTERN const char *toml_table_key(const toml_table_t *tab);
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* misc
|
||||
*/
|
||||
TOML_EXTERN int toml_utf8_to_ucs(const char *orig, int len, int64_t *ret);
|
||||
TOML_EXTERN int toml_ucs_to_utf8(int64_t code, char buf[6]);
|
||||
TOML_EXTERN void toml_set_memutil(void *(*xxmalloc)(size_t),
|
||||
void (*xxfree)(void *));
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* deprecated
|
||||
*/
|
||||
/* A raw value, must be processed by toml_rto* before using. */
|
||||
typedef const char *toml_raw_t;
|
||||
TOML_EXTERN toml_raw_t toml_raw_in(const toml_table_t *tab, const char *key);
|
||||
TOML_EXTERN toml_raw_t toml_raw_at(const toml_array_t *arr, int idx);
|
||||
TOML_EXTERN int toml_rtos(toml_raw_t s, char **ret);
|
||||
TOML_EXTERN int toml_rtob(toml_raw_t s, int *ret);
|
||||
TOML_EXTERN int toml_rtoi(toml_raw_t s, int64_t *ret);
|
||||
TOML_EXTERN int toml_rtod(toml_raw_t s, double *ret);
|
||||
TOML_EXTERN int toml_rtod_ex(toml_raw_t s, double *ret, char *buf, int buflen);
|
||||
TOML_EXTERN int toml_rtots(toml_raw_t s, toml_timestamp_t *ret);
|
||||
|
||||
#endif /* TOML_H */
|
||||
@ -1,4 +1,4 @@
|
||||
#include "engine.h"
|
||||
#include <engine.h>
|
||||
|
||||
struct {
|
||||
int width;
|
||||
@ -9,17 +9,26 @@ int main(void) {
|
||||
context.height = 600;
|
||||
context.width = 800;
|
||||
Vector2 position = (Vector2){0, 0};
|
||||
|
||||
Camera2D cam = {0};
|
||||
|
||||
InitWindow(context.width, context.height, "Game");
|
||||
|
||||
SetTargetFPS(120);
|
||||
while (!WindowShouldClose()) {
|
||||
float delta = GetFrameTime();
|
||||
process_input(&input);
|
||||
update_player_movement(&localPlayer, &input, delta);
|
||||
apply_ground_snap(&localPlayer);
|
||||
|
||||
send_player_state(&localPlayerNet);
|
||||
receive_remote_players(remotePlayers, &remoteCount);
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(BLACK);
|
||||
DrawFPS(10, 10);
|
||||
EndDrawing();
|
||||
begin_drawing_frame();
|
||||
draw_world();
|
||||
draw_player(&localPlayer);
|
||||
draw_remote_players(remotePlayers, remoteCount);
|
||||
draw_gui();
|
||||
end_drawing_frame();
|
||||
}
|
||||
|
||||
CloseWindow();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user