Skip to content
Snippets Groups Projects
Commit bf2a2608 authored by Felix Agner's avatar Felix Agner
Browse files

Initial commit

parents
Branches
No related tags found
No related merge requests found
# Virtual Environment
venv/
__pycache__/
# Other common Python ignores
*.pyc
*.pyo
*.egg-info/
*.log
*.sqlite # if using SQLite databases
MIT License
Copyright (c) 2023 Felix Agner
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.
# TOP SECRET
Stay out of here for now please.
\ No newline at end of file
numpy==1.26.0
pygame==2.5.2
# Define dimensions
SCREEN_WIDTH = 1920
SCREEN_HEIGHT = 1080
ARENA_RADIUS = int(SCREEN_HEIGHT / 2.5)
ARENA_CENTER = (int(SCREEN_HEIGHT / 2), int(SCREEN_HEIGHT / 2))
# Tank and shot sizes
TANK_SIZE = 20
TURRET_LENGTH = 30
TURRET_WIDTH = 8
SHOT_SIZE = 5
# Define base colors
DARK_BLUE = (0, 0, 128)
EGGSHELL = (240, 234, 214)
BLACK = (0, 0, 0)
# Define colors
BACKGROUND_COLOR = DARK_BLUE
ARENA_COLOR = EGGSHELL
OVERLAY_COLOR = EGGSHELL
# Physics parameters
DRAG = 0.1
ACCELERATION = 30
TURN_SPEED = 3
SHOT_SPEED = 100
\ No newline at end of file
from config import *
from tanks.tank import Tank
from shot import Shot
class PhysicsManager:
def __init__(self):
self.tanks = []
self.shots = []
def add_tank(self, tank):
self.tanks.append(tank)
def add_shot(self, shot):
self.shots.append(shot)
def update(self, dt, time):
# Update tanks
for tank in self.tanks:
u = tank.control(self.tanks, self.shots, dt, time)
tank.update(u, dt)
if tank.has_ammunition() and tank.should_fire(self.tanks):
tank.fire()
self.add_shot(Shot(tank.x, tank.y, tank.theta, tank))
# Update shots
for shot in self.shots:
shot.update(dt)
# Check for collisions
self.check_collisions()
import pygame
from config import *
from math import cos, sin, radians
def draw_arena(screen):
pygame.draw.circle(screen, ARENA_COLOR, ARENA_CENTER, ARENA_RADIUS)
def draw_info_panel(screen, tanks, time):
pygame.draw.rect(screen, OVERLAY_COLOR, (ARENA_CENTER[0] + ARENA_RADIUS + 10, 0, SCREEN_WIDTH - ARENA_RADIUS, SCREEN_HEIGHT))
# display current time
font = pygame.font.SysFont(None, 32)
time_surf = font.render("Time: " + str(int(time)), True, (0, 0, 0))
screen.blit(time_surf, (ARENA_CENTER[0] + ARENA_RADIUS + 50, 30))
# Display tank information
y_offset = 100 # initial vertical offset
for tank in tanks:
# Draw tank's color circle
pygame.draw.circle(screen, tank.color, (ARENA_CENTER[0] + ARENA_RADIUS + 30, y_offset), 10)
# Display tank's name
font = pygame.font.SysFont(None, 24)
name_surf = font.render(tank.name, True, (0, 0, 0))
screen.blit(name_surf, (ARENA_CENTER[0] + ARENA_RADIUS + 50, y_offset - 12))
y_offset += 40
def draw_tanks(screen, tanks):
for tank in tanks:
draw_tank(screen, tank)
def draw_tank(screen, tank):
# Draw the tank body
tank_pos = (int(ARENA_CENTER[0] + tank.x), int(ARENA_CENTER[1] + tank.y))
pygame.draw.circle(screen, tank.color, tank_pos, TANK_SIZE)
# Calculate the end point for the turret based on the tank's angle
turret_end_x = ARENA_CENTER[0] + tank.x + TURRET_LENGTH * cos(radians(tank.theta))
turret_end_y = ARENA_CENTER[1] + tank.y + TURRET_LENGTH * sin(radians(tank.theta))
turret_end = (int(turret_end_x), int(turret_end_y))
pygame.draw.line(screen, BLACK, tank_pos, turret_end, TURRET_WIDTH)
# Draw the tank name above the tank
font = pygame.font.SysFont(None, 24)
name_surf = font.render(tank.name, True, BLACK)
name_rect = name_surf.get_rect(center=(tank_pos[0], tank_pos[1] - TANK_SIZE - 10))
screen.blit(name_surf, name_rect)
def draw_shots(screen, shots):
for shot in shots:
draw_shot(screen, shot)
def draw_shot(screen, shot):
shot_pos = (int(ARENA_CENTER[0] + shot.x), int(ARENA_CENTER[1] + shot.y))
pygame.draw.circle(screen, shot.color, shot_pos, SHOT_SIZE)
\ No newline at end of file
from math import sin, cos, radians
from config import *
class Shot:
def __init__(self, x, y, theta, shooter):
"""Initialize a shot with position and angle.
Parameters:
- x (int/float): The x-coordinate of the shot.
- y (int/float): The y-coordinate of the shot.
- theta (int/float): The angle (in degrees) at which the shot is oriented.
"""
self.x = x
self.y = y
self.theta = theta
self.shooter = shooter
self.color = shooter.color
def update(self, dt):
"""Update the shot's state based on the control input u.
Parameters:
- dt (float): The time (in seconds) since the last frame.
"""
self.move_forward(dt)
def move_forward(self, dt):
"""Move the shot forward by a specified distance based on its current angle."""
# Using basic trigonometry to calculate the new x and y coordinates
self.x += SHOT_SPEED * cos(radians(self.theta)) * dt
self.y += SHOT_SPEED * sin(radians(self.theta)) * dt
\ No newline at end of file
# Example file showing a circle moving on screen
import pygame
from rendering import draw_arena, draw_info_panel, draw_tanks
from config import *
from tanks.tank import Tank
def main():
# Initialize pygame
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Tank Wars')
clock = pygame.time.Clock()
running = True
time = 0
dt = 0
# For now, let's use sample tanks
tank1 = Tank(100, 100, 0, (255, 0, 0), "RedTank")
tank2 = Tank(200, 200, 0, (0, 255, 0), "GreenTank")
tanks = [tank1, tank2]
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Run physics update
for tank in tanks:
u = tank.control(tanks, [], dt, time)
tank.update(u, dt)
screen.fill(DARK_BLUE)
draw_arena(screen)
draw_info_panel(screen, tanks, time)
draw_tanks(screen, tanks)
# Later, you can draw tanks and handle movements here
pygame.display.flip()
# limits FPS to 60
# dt is delta time in seconds since last frame, used for framerate-
# independent physics.
dt = clock.tick(60) / 1000
time += dt
pygame.quit()
if __name__ == "__main__":
main()
\ No newline at end of file
from math import sin, cos, radians
from config import *
class Tank:
def __init__(self, x, y, theta, color, name):
"""Initialize a tank with position, angle, color, and name.
Parameters:
- x (int/float): The x-coordinate of the tank.
- y (int/float): The y-coordinate of the tank.
- theta (int/float): The angle (in degrees) at which the tank is oriented.
- color (tuple): A tuple representing the RGB color of the tank (e.g., (255, 0, 0) for red).
- name (str): The name of the tank.
"""
self.x = x
self.y = y
self.speed = 0.0
self.theta = theta
self.ammunition = 1
self.alive = True
self.give_me_a_color(color)
self.give_me_a_name(name)
self.kill_count = 0
self.kill_list = []
def give_me_a_name(self, suggestion):
"""Give the tank a name."""
self.name = suggestion
def give_me_a_color(self, suggestion):
"""Give the tank a color."""
self.color = suggestion
def control(self, tanks, shots, dt, time):
"""Control the tank's movement and firing.
Parameters:
- tanks (list): A list of all tanks in the arena.
- shots (list): A list of all shots in the arena.
- dt (float): The time (in seconds) since the last frame.
- time (float): The total time (in seconds) since the start of the game.
"""
# For now, let's just move forward and turn randomly
return (1, -1)
def update(self, u, dt):
"""Update the tank's state based on the control input u.
Parameters:
- u (tuple): A tuple containing the acceleration and turn rate of the tank.
"""
a = ACCELERATION * max(-1, min(u[0], 1))
r = TURN_SPEED * max(-1, min(u[1], 1))
self.speed = self.speed - self.speed * dt * DRAG + a * dt
self.move_forward(dt)
self.turn(r)
def move_forward(self, dt):
"""Move the tank forward by a specified distance based on its current angle."""
# Using basic trigonometry to calculate the new x and y coordinates
self.x += self.speed * cos(radians(self.theta)) * dt
self.y += self.speed * sin(radians(self.theta)) * dt
def turn(self, angle_change):
"""Turn the tank by a specified angle (positive values turn clockwise, negative values turn counter-clockwise)."""
self.theta += angle_change
# Ensure theta remains between 0 and 360
self.theta %= 360
def __str__(self):
"""Return a string representation of the tank."""
return self.name
def get_state(self):
"""Return a tuple containing the tank's position and angle"""
return (self.x, self.y, self.theta)
def is_alive(self):
"""Return True if the tank is alive, False otherwise."""
return self.alive
def has_ammunition(self):
"""Return True if the tank has ammunition, False otherwise."""
return self.ammunition > 0
def shoot(self):
"""Shoot a projectile from the tank."""
self.ammunition -= 1
def replenish_ammunition(self):
"""Replenish the tank's ammunition."""
self.ammunition = 1
def should_shoot(self):
"""Return True if the tank should shoot, False otherwise."""
return self.has_ammunition()
def __eq__(self, other):
# Check if 'other' is an instance of Tank before comparing
if isinstance(other, Tank):
# Here, for simplicity, we're using the name of the tank as the unique identifier for comparison.
# You can use any unique attribute(s) for your use case.
return self.name == other.name
return False
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment