0% found this document useful (0 votes)
13 views23 pages

Python 2D Shooter Game with Pygame

Uploaded by

srilasri.sg
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views23 pages

Python 2D Shooter Game with Pygame

Uploaded by

srilasri.sg
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

TABLE OF CONTENT (TOC)

Serial
Sub-topic Page
number
number
1 ACKNOWLEDGEMENT

2 INTRODUCTION

3 AIM

4 SOURCE CODE

5 OUTPUT

6 BIBLIOGRAPHY
Introduction

The project titled “2D Shooter Game” is a Python-based arcade-style shooting game developed using the
Pygame library. This game simulates a battle scenario in a 2D top-down environment, where the player
competes against multiple computer-controlled bots in a map filled with obstacles such as houses and vehicles.

The game begins with a lobby, where the player can start the match by clicking a button. Upon starting, the
player is spawned into the map along with 29 AI-controlled bots, making a total of 30 participants in the
battle. The player has 200 health points and can navigate using WASD keys, aim with the mouse, and shoot
enemies to eliminate them. Each enemy kill rewards the player with 10 coins, and the last player standing
receives a bonus of 100 coins.

The game features basic AI mechanics, where bots can wander, chase the player, and shoot if they are within
range. The map contains houses and vehicles that serve as cover and obstacles, adding strategic depth to
gameplay. The player’s perspective is centered on the character, providing a first-person-style experience in a
2D environment.

This project demonstrates key concepts of game development, including player and enemy mechanics,
collision detection, health and scoring systems, and the creation of interactive game environments. It also
serves as a foundation for further enhancements, such as improved AI, additional weapons, or multiplayer
functionality.
AIM

The aim of this project is to design and develop


an interactive 2D shooting game that allows
players to control a character, navigate a map,
and engage in combat scenarios. The game
focuses on enhancing problem-solving skills,
hand-eye coordination, and strategic thinking
while providing an entertaining and immersive
gaming experience. Additionally, this project
aims to demonstrate practical knowledge of
Python programming, game development
concepts, and the use of libraries such as
Pygame for creating engaging visual and
interactive content.
SOURCE CODE

2D Shooter Game (Pygame)

Features:

- Lobby with Start button

- Map with houses (rectangles) and vehicles (rectangles)

- Player (centered camera) and 29 bot enemies

- Player has 200 health

- Each kill awards player 10 coins; if player is last one standing, award 100 coins

- When player dies, returns to lobby and resets

- Simple bot AI: wander, detect player within range to chase and shoot

- Basic bullets, collisions, respawn to lobby

Controls:

- WASD: move

- Mouse: aim

- Left click: shoot

- R: reload (not strictly necessary)

- Esc: quit

Save this file as 2D_Shooter_Game.py and run with `python 2D_Shooter_Game.py`

Requires: pygame (pip install pygame)

This is a compact, single-file prototype. It is NOT a full production game but provides

the requested mechanics and a good base for further development.

"""

import math
import random

import pygame

from [Link] import Vector2

# --- Config ---

SCREEN_W, SCREEN_H = 1280, 720

MAP_W, MAP_H = 3000, 2000

FPS = 60

NUM_BOTS = 29

PLAYER_MAX_HEALTH = 200

BULLET_SPEED = 900.0

BULLET_LIFETIME = 1.8

BOT_BULLET_SPEED = 700.0

KILL_COINS = 10

WIN_BONUS = 100

# Colors

WHITE = (255,255,255)

BLACK = (0,0,0)

RED = (200,30,30)

GREEN = (30,200,30)

BLUE = (30,144,255)

YELLOW = (240,200,20)

GRAY = (120,120,120)

[Link]()

FONT = [Link]('Arial', 20)

BIGFONT = [Link]('Arial', 48)

screen = [Link].set_mode((SCREEN_W, SCREEN_H))

clock = [Link]()
# --- Utility ---

def clamp(v, a, b):

return max(a, min(b, v))

# --- Entities ---

class Bullet:

def __init__(self, pos, vel, owner, damage=20, life=BULLET_LIFETIME):

[Link] = Vector2(pos)

[Link] = Vector2(vel)

[Link] = owner # 'player' or Bot instance

[Link] = damage

[Link] = life

def update(self, dt):

[Link] += [Link] * dt

[Link] -= dt

return [Link] > 0 and 0 <= [Link].x <= MAP_W and 0 <= [Link].y <= MAP_H

def draw(self, surf, cam):

p = world_to_screen([Link], cam)

[Link](surf, YELLOW, (int(p.x), int(p.y)), 4)

class Actor:

def __init__(self, pos, color, health=100):

[Link] = Vector2(pos)

[Link] = Vector2(0,0)

[Link] = color

[Link] = health
self.max_health = health

[Link] = 18

[Link] = True

def take_damage(self, d, attacker=None):

if not [Link]: return

[Link] -= d

if [Link] <= 0:

[Link] = False

def draw_healthbar(self, surf, cam):

p = world_to_screen([Link] + Vector2(0,-30), cam)

w = 40

h=6

rect_bg = [Link](p.x - w//2, p.y - h//2, w, h)

rect_fg = [Link](p.x - w//2, p.y - h//2, w * ([Link]/self.max_health), h)

[Link](surf, RED, rect_bg)

[Link](surf, GREEN, rect_fg)

class Player(Actor):

def __init__(self, pos):

super().__init__(pos, BLUE, health=PLAYER_MAX_HEALTH)

[Link] = 0

[Link] = 0

[Link] = 340

self.fire_rate = 0.15

self.time_since_shot = 0

def update(self, dt, keys, mouse_world):

# Movement
dir = Vector2(0,0)

if keys[pygame.K_w]: dir.y -= 1

if keys[pygame.K_s]: dir.y += 1

if keys[pygame.K_a]: dir.x -= 1

if keys[pygame.K_d]: dir.x += 1

if dir.length_squared() > 0:

dir = [Link]()

[Link] = dir * [Link]

[Link] += [Link] * dt

[Link].x = clamp([Link].x, 0, MAP_W)

[Link].y = clamp([Link].y, 0, MAP_H)

self.time_since_shot += dt

def can_shoot(self):

return self.time_since_shot >= self.fire_rate

def shoot(self, target):

if not self.can_shoot(): return None

self.time_since_shot = 0

dir = (Vector2(target) - [Link])

if dir.length_squared() == 0: dir = Vector2(1,0)

dir = [Link]()

vel = dir * BULLET_SPEED

b = Bullet([Link] + dir*28, vel, 'player', damage=35)

return b

def draw(self, surf, cam, mouse_world):

p = world_to_screen([Link], cam)

# body

[Link](surf, [Link], (int(p.x), int(p.y)), [Link])


# direction line (aim)

dir = (Vector2(mouse_world) - [Link])

if dir.length_squared()>0:

dir = [Link]()

end = p + Vector2(dir.x, dir.y)*30

[Link](surf, WHITE, (p.x,p.y),(end.x,end.y),3)

self.draw_healthbar(surf, cam)

class Bot(Actor):

def __init__(self, pos):

super().__init__(pos, RED, health=120)

[Link] = [Link](120,220)

self.fire_rate = [Link](0.6,1.6)

self.time_since_shot = [Link](0, self.fire_rate)

[Link] = None

self.wander_dir = Vector2([Link](-1,1), [Link](-1,1))

if self.wander_dir.length_squared() == 0:

self.wander_dir = Vector2(1,0)

self.wander_dir = self.wander_dir.normalize()

def update(self, dt, player):

if not [Link]: return

# Simple AI: if close to player chase; if very close shoot

to_player = [Link] - [Link]

dist = to_player.length()

if dist < 450:

# chase

if dist>60:

[Link] = to_player.normalize() * [Link]

else:
[Link] = Vector2(0,0)

# shooting

self.time_since_shot += dt

if self.time_since_shot >= self.fire_rate and dist < 520:

self.time_since_shot = 0

dir = to_player.normalize() if dist>0 else Vector2(1,0)

vel = dir * BOT_BULLET_SPEED

return Bullet([Link] + dir*22, vel, self, damage=20)

else:

# wander

self.time_since_shot += dt

if [Link]() < 0.01:

self.wander_dir = Vector2([Link](-1,1), [Link](-1,1))

if self.wander_dir.length_squared()>0:

self.wander_dir = self.wander_dir.normalize()

[Link] = self.wander_dir * [Link] * 0.6

[Link] += [Link] * dt

# stay inside map

[Link].x = clamp([Link].x, 0, MAP_W)

[Link].y = clamp([Link].y, 0, MAP_H)

return None

def draw(self, surf, cam):

p = world_to_screen([Link], cam)

[Link](surf, [Link], (int(p.x), int(p.y)), [Link])

self.draw_healthbar(surf, cam)

# --- Map and world ---

HOUSES = []

VEHICLES = []
def generate_map():

global HOUSES, VEHICLES

HOUSES = []

VEHICLES = []

# create houses as rectangles randomly positioned

for i in range(30):

w = [Link](90,220)

h = [Link](80,180)

x = [Link](50, MAP_W - 50 - w)

y = [Link](50, MAP_H - 50 - h)

[Link]([Link](x,y,w,h))

# vehicles as small rectangles

for i in range(40):

w = [Link](30,70)

h = [Link](20,40)

x = [Link](20, MAP_W - 20 - w)

y = [Link](20, MAP_H - 20 - h)

[Link]([Link](x,y,w,h))

# --- Camera ---

def world_to_screen(pos, cam):

return Vector2(pos.x - cam.x + SCREEN_W/2, pos.y - cam.y + SCREEN_H/2)

def screen_to_world(pos, cam):

return Vector2(pos[0] + cam.x - SCREEN_W/2, pos[1] + cam.y - SCREEN_H/2)

# --- Game state ---

class GameState:
def __init__(self):

self.in_lobby = True

[Link] = Player(Vector2(MAP_W/2, MAP_H/2))

[Link] = []

[Link] = []

self.spawn_points = []

self.coins_display = 0

def start_match(self):

# reset things

self.in_lobby = False

generate_map()

[Link] = Player(Vector2([Link](100, MAP_W-100), [Link](100, MAP_H-100)))

[Link] = []

[Link] = []

# create spawn points away from player

self.spawn_points = []

for i in range(NUM_BOTS+20):

x = [Link](50, MAP_W-50)

y = [Link](50, MAP_H-50)

if Vector2(x,y).distance_to([Link]) > 300:

self.spawn_points.append(Vector2(x,y))

[Link](self.spawn_points)

# spawn NUM_BOTS bots

for i in range(NUM_BOTS):

if i < len(self.spawn_points):

pos = self.spawn_points[i]

else:

pos = Vector2([Link](50,MAP_W-50), [Link](50,MAP_H-50))

b = Bot(pos)
[Link](b)

def end_round_to_lobby(self, player_won=False):

if player_won:

[Link] += WIN_BONUS

# tiny delay handled by caller

self.in_lobby = True

def update(self, dt, keys, mouse_world, mouse_pressed):

if self.in_lobby:

return

if not [Link]:

# return to lobby

self.end_round_to_lobby(player_won=False)

return

# update player

[Link](dt, keys, mouse_world)

# shooting

if mouse_pressed[0]:

b = [Link](mouse_world)

if b:

[Link](b)

# update bots

for bot in [Link]:

if not [Link]: continue

newb = [Link](dt, [Link])

if newb:

[Link](newb)

# update bullets

to_remove = []
for bullet in [Link]:

alive = [Link](dt)

if not alive:

to_remove.append(bullet)

continue

# collision against bots and player

if [Link] == 'player':

for bot in [Link]:

if not [Link]: continue

if [Link].distance_to([Link]) < [Link]+6:

bot.take_damage([Link], attacker=[Link])

to_remove.append(bullet)

if not [Link]:

[Link] += KILL_COINS

[Link] += 1

break

else:

# owner is Bot instance

if [Link].distance_to([Link]) < [Link]+6 and [Link]:

[Link].take_damage([Link], attacker=[Link])

to_remove.append(bullet)

if not [Link]:

# player eliminated

# award coins to killer bot? specs ask only player coins so skip

pass

for r in to_remove:

if r in [Link]:

[Link](r)

# check win condition: is the player last alive among actors?

others_alive = sum(1 for b in [Link] if [Link])


if others_alive == 0:

# player won

self.end_round_to_lobby(player_won=True)

def draw_world(self, surf, cam, mouse_world):

# draw ground

[Link]((50,130,50))

# Houses (as rectangles)

for rect in HOUSES:

r = [Link](rect.x - cam.x + SCREEN_W/2, rect.y - cam.y + SCREEN_H/2, [Link], [Link])

[Link](surf, (170,120,100), r)

[Link](surf, (100,60,40), r, 3)

# Vehicles

for rect in VEHICLES:

r = [Link](rect.x - cam.x + SCREEN_W/2, rect.y - cam.y + SCREEN_H/2, [Link], [Link])

[Link](surf, (50,50,120), r)

[Link](surf, (10,10,40), r, 2)

# bots

for bot in [Link]:

if [Link]:

[Link](surf, cam)

# bullets

for bullet in [Link]:

[Link](surf, cam)

# player

if [Link]:

[Link](surf, cam, mouse_world)

def draw_hud(self, surf):

# top-left: health, coins, kills


health_surf = [Link](f'Health: {int([Link])}/{[Link].max_health}', True, WHITE)

coins_surf = [Link](f'Coins: {[Link]}', True, YELLOW)

kills_surf = [Link](f'Kills: {[Link]}', True, WHITE)

[Link](health_surf, (12,12))

[Link](coins_surf, (12,40))

[Link](kills_surf, (12,68))

# --- UI / Lobby ---

def draw_lobby(surf):

[Link]((20,30,50))

title = [Link]('Lobby - 2D Shooter Prototype', True, WHITE)

info = [Link]('Click START to spawn player + 29 bots. Each kill = 10 coins. Last player standing =
+100 coins.', True, WHITE)

[Link](title, (SCREEN_W//2 - title.get_width()//2, 120))

[Link](info, (SCREEN_W//2 - info.get_width()//2, 200))

# start button

btn_rect = [Link](SCREEN_W//2 - 120, 300, 240, 70)

[Link](surf, (80,200,100), btn_rect)

[Link](surf, WHITE, btn_rect, 3)

txt = [Link]('START', True, BLACK)

[Link](txt, (btn_rect.x + btn_rect.width//2 - txt.get_width()//2, btn_rect.y + btn_rect.height//2 -


txt.get_height()//2))

return btn_rect

# --- Main Loop ---

game = GameState()

def main():

running = True
respawn_timer = 0.0

while running:

dt = [Link](FPS) / 1000.0

for event in [Link]():

if [Link] == [Link]:

running = False

if [Link] == [Link]:

if [Link] == pygame.K_ESCAPE:

running = False

keys = [Link].get_pressed()

mouse_pressed = [Link].get_pressed()

mouse_screen = [Link].get_pos()

if game.in_lobby:

btn = draw_lobby(screen)

[Link]()

# handle clicks

for evt in [Link]():

if [Link] == [Link]:

running = False

if [Link] == [Link] and [Link] == 1:

if [Link]([Link]):

game.start_match()

continue

# camera centers on player

cam = Vector2([Link].x, [Link].y)

mouse_world = screen_to_world(mouse_screen, cam)

# update game
[Link](dt, keys, mouse_world, mouse_pressed)

# draw world

game.draw_world(screen, cam, mouse_world)

# HUD

game.draw_hud(screen)

# Crosshair

[Link](screen, WHITE, mouse_screen, 6, 2)

[Link]()

[Link]()

if __name__ == '__main__':

main()
MY SQL CATALOUGE
-- Database creation

CREATE DATABASE IF NOT EXISTS GameDB;

USE GameDB;

-- Players Table

CREATE TABLE Players (

player_id INT AUTO_INCREMENT PRIMARY KEY,

username VARCHAR(50) UNIQUE NOT NULL,

password VARCHAR(255) NOT NULL,

email VARCHAR(100),

created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

);

-- Characters Table

CREATE TABLE Characters (

character_id INT AUTO_INCREMENT PRIMARY KEY,

player_id INT,

character_name VARCHAR(50),

level INT DEFAULT 1,

health INT DEFAULT 100,

experience INT DEFAULT 0,

FOREIGN KEY (player_id) REFERENCES Players(player_id)

);

-- Inventory Table

CREATE TABLE Inventory (


inventory_id INT AUTO_INCREMENT PRIMARY KEY,

player_id INT,

item_name VARCHAR(50),

quantity INT DEFAULT 1,

FOREIGN KEY (player_id) REFERENCES Players(player_id)

);

-- Matches Table

CREATE TABLE Matches (

match_id INT AUTO_INCREMENT PRIMARY KEY,

player_id INT,

kills INT DEFAULT 0,

deaths INT DEFAULT 0,

score INT DEFAULT 0,

match_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

FOREIGN KEY (player_id) REFERENCES Players(player_id)

);

-- Shop Table

CREATE TABLE Shop (

item_id INT AUTO_INCREMENT PRIMARY KEY,

item_name VARCHAR(50),

item_type VARCHAR(50),

price INT

);
BIBLIGRAPHY

1. COMPUTER SCIENCE WITH PYTHON [ CLASS


11 ].
2. COMPUTER SCIENCE WITH PYTHON CLASS [
12 ]

You might also like