Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Street Fighter #312

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions Street Fighter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Shadow Fight

**Shadow Fight** is an engaging two-player fighting game built with Python and Pygame. This project features exciting gameplay mechanics, unique characters, and dynamic animations, making it a perfect choice for retro game enthusiasts and developers interested in Python-based game development.



## Features
- **Two Distinct Fighters**:
- **Warrior**: A melee combatant with powerful sword attacks.
- **Wizard**: A magic wielder with spell-based attacks.
- **Gameplay Mechanics**:
- Health bars for each fighter.
- Smooth animations for idle, run, jump, attack, hit, and death actions.
- Scoring system to track player victories.
- **Dynamic Background**:
- Blurred background effects during the main menu for a cinematic feel.
- **Sound Effects and Music**:
- Immersive soundtracks and attack effects.
- **Responsive UI**:
- Main menu with start, score, and exit options.
- Victory screen for the winning fighter.
- **Custom Controls** for two players.



## 📋 Table of Contents
- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Gameplay Instructions](#gameplay-instructions)
- [Screenshots](#screenshots)
- [Demo](#demo)
- [License](#license)
- [Credits](#credits)
- [Contributing](#contributing)
- [Contact](#contact)



## Requirements
- Python 3.7 or higher
- Required Python libraries:
- `pygame`
- `numpy`
- `opencv-python`



## Installation

Follow these steps to install and run the game:

1. **Clone the Repository**:
```bash
git clone https://github.com/AadityaPanda/Shadow-Fight.git
cd Shadow-Fight
```

2. **Install Dependencies**:
```bash
pip install -r requirements.txt
```

3. **Run the Game**:
```bash
python src/main.py
```



## Gameplay Instructions

### Player Controls:
- **Player 1**:
- Move: `A` (Left), `D` (Right)
- Jump: `W`
- Attack: `R` (Attack 1), `T` (Attack 2)

- **Player 2**:
- Move: Left Arrow (`←`), Right Arrow (`→`)
- Jump: Up Arrow (`↑`)
- Attack: `M` (Attack 1), `N` (Attack 2)

**Objective**: Reduce your opponent's health to zero to win the round. Victory is celebrated with a dynamic win screen!



## Screenshots
![Screenshot (2)](https://github.com/user-attachments/assets/82b289ab-5da7-4331-a1b4-dd264ee77707)
![Screenshot (3)](https://github.com/user-attachments/assets/c72256a3-c637-4b2f-8605-57a7c39093de)
![Screenshot (4)](https://github.com/user-attachments/assets/1e747407-7887-4bc3-87c1-751b6d27eb5c)



## Demo


https://github.com/user-attachments/assets/fe990e99-b59e-4ef3-9d2a-80ba7a7e7601





## License

This project is licensed under the [MIT License](LICENSE). Feel free to use, modify, and distribute it in your projects.



## Credits

- **Developer**: Aaditya Panda
- **Assets**:
- Background music and sound effects: [Free Music Archive](https://freemusicarchive.org/)
- Fonts: [Turok Font](https://www.fontspace.com/turok-font)
- Sprites: Custom-designed and modified from open-source assets.



## Contributing

Contributions are welcome! Here's how you can help:
1. Fork the repository.
2. Create a new branch:
```bash
git checkout -b feature/YourFeatureName
```
3. Commit your changes:
```bash
git commit -m "Add YourFeatureName"
```
4. Push to the branch:
```bash
git push origin feature/YourFeatureName
```
5. Open a pull request.

Check the [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.



## Contact

- **Developer**: Aaditya Panda
- **Email**: [[email protected]](mailto:[email protected])
- **GitHub**: [AadityaPanda](https://github.com/AadityaPanda)
Binary file added Street Fighter/assets/audio/magic.wav
Binary file not shown.
Binary file added Street Fighter/assets/audio/music.mp3
Binary file not shown.
Binary file added Street Fighter/assets/audio/sword.wav
Binary file not shown.
Binary file added Street Fighter/assets/fonts/turok.ttf
Binary file not shown.
Binary file added Street Fighter/assets/icon/sficon.ico
Binary file not shown.
Binary file added Street Fighter/assets/images/bg.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Street Fighter/assets/images/bg1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Street Fighter/assets/images/bg2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Street Fighter/assets/images/victory.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Street Fighter/assets/images/warrior.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Street Fighter/assets/images/wizard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
191 changes: 191 additions & 0 deletions Street Fighter/src/fighter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
import pygame

class Fighter:
def __init__(self, player, x, y, flip, data, sprite_sheet, animation_steps, sound):
self.player = player
self.size = data[0]
self.image_scale = data[1]
self.offset = data[2]
self.flip = flip
self.animation_list = self.load_images(sprite_sheet, animation_steps)
self.action = 0 # 0:idle #1:run #2:jump #3:attack1 #4: attack2 #5:hit #6:death
self.frame_index = 0
self.image = self.animation_list[self.action][self.frame_index]
self.update_time = pygame.time.get_ticks()
self.rect = pygame.Rect((x, y, 80, 180))
self.vel_y = 0
self.running = False
self.jump = False
self.attacking = False
self.attack_type = 0
self.attack_cooldown = 0
self.attack_sound = sound
self.hit = False
self.health = 100
self.alive = True

def load_images(self, sprite_sheet, animation_steps):
# extract images from spritesheet
animation_list = []
for y, animation in enumerate(animation_steps):
temp_img_list = []
for x in range(animation):
temp_img = sprite_sheet.subsurface(x * self.size, y * self.size, self.size, self.size)
temp_img_list.append(
pygame.transform.scale(temp_img, (self.size * self.image_scale, self.size * self.image_scale)))
animation_list.append(temp_img_list)
return animation_list

def move(self, screen_width, screen_height, target, round_over):
SPEED = 10
GRAVITY = 2
dx = 0
dy = 0
self.running = False
self.attack_type = 0

# get keypresses
key = pygame.key.get_pressed()

# can only perform other actions if not currently attacking
if self.attacking == False and self.alive == True and round_over == False:
# check player 1 controls
if self.player == 1:
# movement
if key[pygame.K_a]:
dx = -SPEED
self.running = True
if key[pygame.K_d]:
dx = SPEED
self.running = True
# jump
if key[pygame.K_w] and self.jump == False:
self.vel_y = -30
self.jump = True
# attack
if key[pygame.K_r] or key[pygame.K_t]:
self.attack(target)
# determine which attack type was used
if key[pygame.K_r]:
self.attack_type = 1
if key[pygame.K_t]:
self.attack_type = 2

# check player 2 controls
if self.player == 2:
# movement
if key[pygame.K_LEFT]:
dx = -SPEED
self.running = True
if key[pygame.K_RIGHT]:
dx = SPEED
self.running = True
# jump
if key[pygame.K_UP] and self.jump == False:
self.vel_y = -30
self.jump = True
# attack
if key[pygame.K_m] or key[pygame.K_n]:
self.attack(target)
# determine which attack type was used
if key[pygame.K_m]:
self.attack_type = 1
if key[pygame.K_n]:
self.attack_type = 2

# apply gravity
self.vel_y += GRAVITY
dy += self.vel_y

# ensure player stays on screen
if self.rect.left + dx < 0:
dx = -self.rect.left
if self.rect.right + dx > screen_width:
dx = screen_width - self.rect.right
if self.rect.bottom + dy > screen_height - 110:
self.vel_y = 0
self.jump = False
dy = screen_height - 110 - self.rect.bottom

# ensure players face each other
if target.rect.centerx > self.rect.centerx:
self.flip = False
else:
self.flip = True

# apply attack cooldown
if self.attack_cooldown > 0:
self.attack_cooldown -= 1

# update player position
self.rect.x += dx
self.rect.y += dy

# handle animation updates
def update(self):
# check what action the player is performing
if self.health <= 0:
self.health = 0
self.alive = False
self.update_action(6) # 6:death
elif self.hit:
self.update_action(5) # 5:hit
elif self.attacking:
if self.attack_type == 1:
self.update_action(3) # 3:attack1
elif self.attack_type == 2:
self.update_action(4) # 4:attack2
elif self.jump:
self.update_action(2) # 2:jump
elif self.running:
self.update_action(1) # 1:run
else:
self.update_action(0) # 0:idle

animation_cooldown = 50
# update image
self.image = self.animation_list[self.action][self.frame_index]
# check if enough time has passed since the last update
if pygame.time.get_ticks() - self.update_time > animation_cooldown:
self.frame_index += 1
self.update_time = pygame.time.get_ticks()
# check if the animation has finished
if self.frame_index >= len(self.animation_list[self.action]):
# if the player is dead then end the animation
if not self.alive:
self.frame_index = len(self.animation_list[self.action]) - 1
else:
self.frame_index = 0
# check if an attack was executed
if self.action == 3 or self.action == 4:
self.attacking = False
self.attack_cooldown = 20
# check if damage was taken
if self.action == 5:
self.hit = False
# if the player was in the middle of an attack, then the attack is stopped
self.attacking = False
self.attack_cooldown = 20

def attack(self, target):
if self.attack_cooldown == 0:
# execute attack
self.attacking = True
self.attack_sound.play()
attacking_rect = pygame.Rect(self.rect.centerx - (2 * self.rect.width * self.flip), self.rect.y,
2 * self.rect.width, self.rect.height)
if attacking_rect.colliderect(target.rect):
target.health -= 10
target.hit = True

def update_action(self, new_action):
# check if the new action is different to the previous one
if new_action != self.action:
self.action = new_action
# update the animation settings
self.frame_index = 0
self.update_time = pygame.time.get_ticks()

def draw(self, surface):
img = pygame.transform.flip(self.image, self.flip, False)
surface.blit(img, (self.rect.x - (self.offset[0] * self.image_scale), self.rect.y - (self.offset[1] * self.image_scale)))
Loading