Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 7

### Part 1: `main.

py` (Game File)


- **`__init__()`**: Initializes the game, sets up the display, and starts a new
game.
- **`new_game()`**: Resets the game by initializing all the components like map,
player, etc.
- **`update()`**: Updates the game logic every frame, including player movement,
raycasting calculations, object updates, and weapon actions.
- **`draw()`**: Draws the game frame by rendering objects and weapons.
- **`check_events()`**: Handles input events like keyboard presses and mouse
movement.
- **`run()`**: The main game loop that continually checks events, updates game
state, and draws the frame.

### Part 2: `object_handler.py` (Object Handler File)


- **`__init__()`**: Initializes the object handler, sets up NPC and sprite lists,
and spawns NPCs.
- **`spawn_npc()`**: Randomly places NPCs in the game world, avoiding certain areas
and obstacles.
- **`check_win()`**: Checks if the win condition is met (no NPCs left).
- **`update()`**: Updates the state of all NPCs and sprites each frame, also checks
for win condition.
- **`add_npc()`**: Adds an NPC to the npc list.
- **`add_sprite()`**: Adds a sprite to the sprite list.

### Part 3: `object_render.py` (Object Renderer File)


- **`__init__()`**: Loads textures and initializes rendering-related variables.
- **`draw()`**: Calls methods to draw background, game objects, and player health.
- **`win()`**: Displays the win image when the game is won.
- **`game_over()`**: Displays the game over image when the player dies.
- **`draw_player_health()`**: Draws the player's health bar on the screen.
- **`player_damage()`**: Displays the damage effect on the player's screen.
- **`draw_background()`**: Draws the sky and floor background.
- **`render_game_objects()`**: Sorts and renders all game objects based on their
depth.
- **`get_texture()`**: Helper method to load and scale textures.
- **`load_wall_textures()`**: Loads wall textures from files.

### Part 4: `pathfinding.py` (Pathfinding File)


- **`__init__()`**: Initializes the pathfinding system and creates a graph of the
game map.
- **`get_path()`**: Uses BFS to find the shortest path from start to goal.
- **`bfs()`**: Breadth-first search algorithm to find the shortest path in a graph.
- **`get_next_nodes()`**: Gets adjacent nodes for pathfinding.
- **`get_graph()`**: Creates a graph representation of the game world for
pathfinding.

### Part 5: `player.py` (Player File)


- **`__init__()`**: Sets up the player with initial position, angle, and health.
- **`recover_health()`**: Gradually increases player health over time until max
health is reached.
- **`check_health_recovery_delay()`**: Checks if enough time has passed to recover
health.
- **`check_game_over()`**: Checks if the player's health has dropped to zero and
ends the game.
- **`get_damage()`**: Reduces player health when taking damage and checks for game
over.
- **`single_fire_event()`**: Handles the event of the player firing their weapon.
- **`movement()`**: Updates player position based on input keys for movement.
- **`check_wall()`**: Checks if the player's new position would collide with a
wall.
- **`check_wall_collision()`**: Prevents the player from moving through walls.
- **`draw()`**: Debugging tool to draw the player's position and view direction.
- **`mouse_control()`**: Handles mouse movement for player view direction.
- **`update()`**: Calls methods to handle movement, mouse control, and health
recovery.

### Part 6: `raycasting.py` (Raycasting File)


- **`__init__()`**: Initializes raycasting related variables.
- **`get_objects_to_render()`**: Prepares the objects that need to be rendered on
the screen, along with their depth information.
- **`ray_cast()`**: Calculates ray collision with walls to determine what is
visible to the player.
- **`update()`**: Calls `ray_cast()` and `get_objects_to_render()` to update the
objects to be rendered.

### Part 7: `sprite_object.py` (Sprite Object File)


- **`__init__()`**: Initializes a static sprite object with a position and an
image.
- **`get_sprite_projection()`**: Calculates the projection of the sprite on the
screen.
- **`get_sprite()`**: Calculates sprite position and distance from the player.
- **`update()`**: Updates the sprite's position and

rendering.

**For AnimatedSprite subclass**:


- **`__init__()`**: Sets up an animated sprite.
- **`update()`**: Updates the animated sprite and handles the animation.
- **`animate()`**: Changes the sprite image to the next in the sequence for
animation.
- **`check_animation_time()`**: Determines if it's time to update the animation
frame.
- **`get_images()`**: Loads a sequence of images for animation.

### Part 8: `weapon.py` (Weapon File)


- **`__init__()`**: Initializes the weapon, its position, and its animation.
- **`animate_shot()`**: Handles the animation of the weapon being fired and
reloaded.
- **`draw()`**: Draws the current weapon sprite on the screen.
- **`update()`**: Updates the weapon's state, including its animation.

### Part 9: `npc.py` (NPC File)


- **`__init__()`**: Sets up an NPC with health, attack range, and animations.
- **`update()`**: Updates NPC behavior, including movement and attacks.
- **`check_wall()`**: Checks for wall collisions.
- **`check_wall_collision()`**: Handles NPC movement and wall collision logic.
- **`movement()`**: Moves the NPC based on pathfinding results.
- **`attack()`**: Handles NPC attacks on the player.
- **`animate_death()`**: Animates NPC death.
- **`animate_pain()`**: Animates NPC taking damage.
- **`check_hit_in_npc()`**: Checks if the NPC is hit by a player's attack.
- **`check_health()`**: Checks NPC's health and handles its death.
- **`run_logic()`**: Handles the NPC's behavior logic.
- **`ray_cast_player_npc()`**: Determines if the NPC has a line of sight to the
player.
- **`draw_ray_cast()`**: Debugging tool to draw a line between the NPC and player
when in line of sight.

Each subclass of `NPC` (SoldierNPC, CacoDemonNPC, CyberDemonNPC) has an


`__init__()` method that initializes the NPC with specific parameters like path,
position, scale, and animation timing.

These concise descriptions provide an overview of the functions and methods in each
file, offering insight into their purpose within the game's structure.

TEXTURE ON WALL EXPLANATION:

Alright, imagine you're creating a virtual world in your game, and you want to make
the walls look realistic. This piece of code is like a painter's tool that helps
you draw each wall exactly where it should be and with the right size and texture
so it looks good from where the player is standing.

Here's what each part does:

- `self.objects_to_render = []`: This is your blank canvas. It's a list where


you're going to keep all the wall pieces you need to draw.

- `for ray, values in enumerate(self.ray_casting_result)`: Think of "raycasting"


like shooting invisible lasers from the player's eyes to figure out where the walls
are. This line goes through each laser (or "ray") and looks at what it hit.

- `depth, proj_height, texture, offset = values`: This unpacks the details of what
each laser hit. 'depth' is how far away the wall is, 'proj_height' is how tall the
wall should appear on the screen, 'texture' is which picture to paste on the wall,
and 'offset' is where on the picture to start.

- The `if` statement checks if the wall is too big to fit on the screen
(`proj_height < HEIGHT`). If it is, we only show the part that fits.

- Inside the `if`, `self.textures[texture].subsurface()`: This is like taking


scissors and cutting out the part of the wall picture (texture) we want to show.

- `pg.transform.scale(wall_column, (SCALE, proj_height))`: This is like stretching


or shrinking the picture to make sure it fits right into the space on the wall
we're drawing.

- `wall_pos = (ray * SCALE, HALF_HEIGHT - proj_height // 2)`: This decides where on


the screen to put the wall piece.

- The `else` part is for when the wall piece is really big, and we need to be smart
about which part of the picture to show so it still looks like a real wall.

- `self.objects_to_render.append((depth, wall_column, wall_pos))`: Finally, we take


the piece of the wall we've prepared and put it on our list, so we remember to draw
it when we're ready.

So basically, this code is all about making the walls in your game look as if
they're at the right place, with the right size and the right part of the texture
showing, no matter where the player moves or looks. It's a clever trick to make a
flat screen look like a 3D space!

---------------->RAY CASTING EXPLANATION


Alright, let's dive into what this code is doing. This is a ray casting function
that's used in creating a 3D effect in a 2D space, like in old-school first-person
shooter games.

Here's the logic, step by step:

1. **Initialization**:
- `self.ray_casting_result = []`: We start with an empty list that will later be
filled with the results of our ray casting.
- `texture_vert, texture_hor = 1, 1`: These are default texture values for
vertical and horizontal surfaces hit by the rays.
- `ox, oy`: The player's current position in the game world.
- `x_map, y_map`: The grid position of the player in the map.
- `ray_angle`: The starting angle for the first ray, calculated from the
player's current viewing angle minus half the field of view.

2. **Casting Rays**:
- A loop starts that will send out a number of rays (`NUM_RAYS`) across the
field of view. Each ray will check for walls in the scene.

3. **Horizontal Intersections**:
- The code first checks horizontal grid lines for intersections with the ray. It
calculates where the ray hits the first horizontal line (`y_hor`) and adjusts the
y-coordinate depending on whether the ray is facing up or down.
- `depth_hor` is how far the ray travels to hit the first horizontal wall.
- `x_hor` is where on the horizontal line the ray hits.
- The inner loop then steps the ray along, checking each new position (`x_hor`,
`y_hor`) against the game's map to see if it's hit a wall.

4. **Vertical Intersections**:
- Next, it checks vertical grid lines in a similar way. It finds where the ray
would hit the first vertical line and then steps along, checking each new position
against the map to find wall hits.

5. **Comparing Intersections**:
- After checking both horizontal and vertical intersections, the code compares
which hit a wall first (`depth_hor` vs. `depth_vert`). The one that's closer is the
actual hit point.
- `offset` is calculated to know which part of the texture to display for that
wall slice. It wraps the position along the wall to a range between 0 and 1,
essentially finding where on the texture the ray hit.

6. **Fishbowl Effect Correction**:


- `depth *= math.cos(self.game.player.angle - ray_angle)`: This line corrects
the "fishbowl effect," which is a distortion that happens because the rays at the
edges of the field of view travel a longer distance. By using the cosine of the
angle difference, it scales the depth to be more representative of straight
distances.

7. **Projection Height Calculation**:


- `proj_height = SCREEN_DIST / (depth + 0.0001)`: This calculates how tall the
wall slice should be drawn on the screen based on its distance. The further away
the wall, the shorter it appears.

8. **Storing Results**:
- The calculated values are then stored in `self.ray_casting_result`, including
the depth (corrected for the fishbowl effect), the projected height of the wall
slice, the texture that should be displayed, and the offset where the texture
should start.

9. **Next Ray**:
- Finally, `ray_angle += DELTA_ANGLE` increases the angle for the next ray,
spreading the rays across the field of view.

This function is central to creating the illusion of 3D in the game. It tells you
which walls are visible and how they should look from the player's current position
and view direction, which gets translated into what you see on the screen.

----------->NPC EXPLAINATION

Alright, this is a chunk of code that defines the behavior of non-player characters
(NPCs) in a game, such as enemies or other interactive characters. Let's break it
down:

### NPC Class

#### `__init__` Method


- This is the constructor that creates an NPC. It sets up the NPC's animations,
stats, and state.
- It loads different animation images for the NPC like attacking, dying, being
idle, in pain, or walking.
- `attack_dist` is a random distance within which the NPC will start attacking the
player.
- `speed` is how fast the NPC moves in the game world.
- `size` could be used for collision detection or visual representation.
- `health` is how much damage the NPC can take before dying.
- `attack_damage` is how much damage the NPC does to the player.
- `accuracy` is the chance of an attack successfully hitting the player.
- `alive` is a flag to check if the NPC is alive.
- `pain` indicates if the NPC is currently in pain (recently hit).
- `ray_cast_value` is a boolean that will later determine if the NPC has line of
sight to the player.
- `frame_counter` is used for tracking animation frames.
- `player_search_trigger` indicates if the NPC is actively seeking the player.

#### `update` Method


- This method updates the NPC's state every frame. It's called repeatedly in the
game loop.
- It checks the time to update animations, calculates the sprite's position, and
runs the NPC's logic.

#### `check_wall` and `check_wall_collision` Methods


- These methods prevent the NPC from walking through walls. They calculate the
NPC's next position and check if it's inside a wall.

#### `movement` Method


- Determines the next step in the NPC's path towards the player using pathfinding.
It then moves the NPC towards the player if the path is clear.

#### `attack` Method


- This is called when the NPC is close enough to attack. It plays a sound and has a
chance to damage the player based on the NPC's accuracy.

#### `animate_death` and `animate_pain` Methods


- These handle the animation for when the NPC is dying or in pain.

#### `check_hit_in_npc` Method


- It checks if the player's shot hit the NPC. If so, it plays a sound, sets the NPC
to a 'pain' state, and reduces its health.

#### `check_health` Method


- This checks the NPC's health. If it drops to zero, the NPC is marked as dead, and
a death sound is played.

#### `run_logic` Method


- This contains the decision-making logic of the NPC. Depending on various
conditions (like whether it's alive, in pain, or has a clear line of sight to the
player), it chooses to attack, move, or play idle animations.

#### `map_pos` Property


- This is a convenience property that returns the NPC's position on the map as
integer grid coordinates.

#### `ray_cast_player_npc` Method


- This checks if there's a direct line of sight from the NPC to the player, which
is essential for determining whether the NPC can see and therefore attack the
player.

#### `draw_ray_cast` Method


- This is likely a debugging method used to visually represent the line of sight
from the NPC to the player.

### SoldierNPC, CacoDemonNPC, CyberDemonNPC Classes


- These are specific types of NPCs that inherit from the base `NPC` class. They
have their own initialization methods that set up their unique properties like path
to their sprites, position, scale of their sprites, and animation timing. They also
have different stats like health, attack distance, damage, speed, and accuracy,
making each type of NPC behave differently.

This code is pretty sophisticated—it simulates intelligent behavior in the game,


making the NPCs seem like they're thinking and acting on their own. They can wander
around, follow the player, react to getting hit, and die. All of this contributes
to a dynamic and engaging game environment.

------------->PATHFINDING
This is a Python class for pathfinding in a game, which helps NPCs or other
entities navigate through the game world. Let's break down what each part does:

### PathFinding Class

#### `__init__` Method


- When you create a new `PathFinding` object, this method sets it up. It takes the
game's current state and makes a smaller version of the game map that's easier to
work with for pathfinding.
- `self.ways` lists all the possible directions an entity can move in the game,
including diagonals.
- `self.graph` is going to be a big map of all the places you can go from every
point on the map.
- `self.get_graph()` fills in that graph with actual data from the game's map.

#### `get_path` Method (Decorated with `lru_cache`)


- This is the method you call when you want to find a path from one point to
another.
- `lru_cache` is a decorator that saves recent calls to this method. If you ask for
the same path again, it can give you the answer instantly instead of calculating it
all over again.
- It uses the `bfs` (Breadth-First Search) method to figure out how to get from
`start` to `goal`.
- It then traces the path back from the goal to the start and returns the first
step on that path.

#### `bfs` Method


- This is a method for searching through the map to find the shortest path between
two points.
- It uses a `queue` to keep track of where it's searching and a `visited`
dictionary to remember where it's been.
- It looks at each place it can go from the current location (`cur_node`), and if
it hasn't been there before, and it's not where an NPC is, it adds that to the
places to visit next.
- It stops when it reaches the goal and returns the `visited` dictionary, which
records how it got to each place.

#### `get_next_nodes` Method


- This method is used to find all the adjacent places you can move to from a given
point `(x, y)` on the map.
- It looks in all the possible `ways` to move and only returns the ones that aren't
blocked by walls.

#### `get_graph` Method


- This method fills in the `self.graph` with all the possible moves from every
point.
- It goes through every spot on the map and, if that spot isn't a wall, it uses
`get_next_nodes` to find all the adjacent places you can go to from there and adds
them to the graph.

This `PathFinding` class is like the game's GPS. It figures out where you can go on
the map and the fastest way to get from one place to another, considering where
walls and NPCs are. It's crucial for making NPCs move around in a smart way, like
chasing the player or walking along a patrol route.

You might also like