dong
This commit is contained in:
commit
c1099cd16c
160
.gitignore
vendored
Normal file
160
.gitignore
vendored
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/#use-with-ide
|
||||||
|
.pdm.toml
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
409
main.py
Normal file
409
main.py
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
import pygame
|
||||||
|
import math
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
# import pprint
|
||||||
|
# from pygame import gfxdraw
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
SIZE = (1000, 1000)
|
||||||
|
|
||||||
|
LEFT_COLOR = "#606858"
|
||||||
|
RIGHT_COLOR = "#F7F9F6"
|
||||||
|
|
||||||
|
BLOCKS_SIZE = 10
|
||||||
|
|
||||||
|
PADDLE_LENGTH = 100
|
||||||
|
|
||||||
|
HALF_SPEED = 250
|
||||||
|
|
||||||
|
|
||||||
|
def draw_circle(surface, x, y, radius, color):
|
||||||
|
pygame.draw.circle(surface, color, (x, y), radius)
|
||||||
|
# AA Drawing
|
||||||
|
# gfxdraw.aacircle(surface, x, y, radius, color)
|
||||||
|
# gfxdraw.filled_circle(surface, x, y, radius, color)
|
||||||
|
|
||||||
|
|
||||||
|
def draw_rect(surface, topL, topT, width, height, color, corner_radius=0):
|
||||||
|
pygame.draw.rect(
|
||||||
|
surface,
|
||||||
|
color,
|
||||||
|
pygame.Rect(topL, topT, width, height),
|
||||||
|
border_radius=corner_radius,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def angle_arccos(v1, v2):
|
||||||
|
y_diff = v2[1] - v1[1]
|
||||||
|
x_diff = v2[0] - v1[0]
|
||||||
|
angle = math.atan2(y_diff, x_diff)
|
||||||
|
return angle
|
||||||
|
|
||||||
|
|
||||||
|
def intersects(rect, r, center):
|
||||||
|
circle_distance_x = abs(center[0] - rect.centerx)
|
||||||
|
circle_distance_y = abs(center[1] - rect.centery)
|
||||||
|
if circle_distance_x > rect.w / 2.0 + r or circle_distance_y > rect.h / 2.0 + r:
|
||||||
|
return False
|
||||||
|
if circle_distance_x <= rect.w / 2.0 or circle_distance_y <= rect.h / 2.0:
|
||||||
|
return True
|
||||||
|
corner_x = circle_distance_x - rect.w / 2.0
|
||||||
|
corner_y = circle_distance_y - rect.h / 2.0
|
||||||
|
corner_distance_sq = corner_x**2.0 + corner_y**2.0
|
||||||
|
return corner_distance_sq <= r**2.0
|
||||||
|
|
||||||
|
|
||||||
|
class TileType(Enum):
|
||||||
|
PLAYER = 1
|
||||||
|
CPU = 2
|
||||||
|
|
||||||
|
|
||||||
|
class ObjectType(Enum):
|
||||||
|
PLAYER = 1
|
||||||
|
CPU = 2
|
||||||
|
|
||||||
|
|
||||||
|
class Tile:
|
||||||
|
|
||||||
|
def __init__(self, positionx, positiony, sidelength, color, tileType) -> None:
|
||||||
|
self.x = positionx
|
||||||
|
self.y = positiony
|
||||||
|
self.length = sidelength
|
||||||
|
self.rect = pygame.Rect(positionx, positiony, sidelength, sidelength)
|
||||||
|
self.color = color
|
||||||
|
self.tileType = tileType
|
||||||
|
|
||||||
|
|
||||||
|
class Paddle:
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, startx, starty, length, depth, color, radius, initial_vel=300
|
||||||
|
) -> None:
|
||||||
|
self.x = startx
|
||||||
|
self.y = starty
|
||||||
|
self.length = length
|
||||||
|
self.depth = depth
|
||||||
|
self.vy = initial_vel
|
||||||
|
self.color = color
|
||||||
|
self.radius = radius
|
||||||
|
self.elasticity = 0.08
|
||||||
|
|
||||||
|
def draw(self, screen):
|
||||||
|
draw_rect(
|
||||||
|
screen,
|
||||||
|
self.x - (self.depth / 2),
|
||||||
|
self.y - (self.length / 2),
|
||||||
|
self.depth,
|
||||||
|
self.length,
|
||||||
|
self.color,
|
||||||
|
corner_radius=self.radius,
|
||||||
|
)
|
||||||
|
|
||||||
|
def move(self, dt):
|
||||||
|
newy = self.y + (self.vy * dt)
|
||||||
|
if (newy - self.length / 2 <= 0) or (newy + self.length / 2 >= SIZE[0]):
|
||||||
|
return
|
||||||
|
self.y = newy
|
||||||
|
|
||||||
|
def set_vel(self, vel):
|
||||||
|
self.vy = vel
|
||||||
|
|
||||||
|
|
||||||
|
class Ball:
|
||||||
|
|
||||||
|
def __init__(self, startx, starty, size, color, charType) -> None:
|
||||||
|
self.x = startx
|
||||||
|
self.y = starty
|
||||||
|
self.radius = size
|
||||||
|
self.color = pygame.Color(color)
|
||||||
|
self.mass = 0.25
|
||||||
|
self.vx = 0
|
||||||
|
self.vy = 0
|
||||||
|
self.charType = charType
|
||||||
|
self.speed = HALF_SPEED
|
||||||
|
|
||||||
|
def draw(self, screen):
|
||||||
|
draw_circle(screen, self.x, self.y, self.radius, self.color)
|
||||||
|
|
||||||
|
def set_speed(self, speed):
|
||||||
|
self.speed = speed
|
||||||
|
|
||||||
|
def move(self, grid, object_grid, dt):
|
||||||
|
# Pretend to move to new location
|
||||||
|
newx = self.x + (self.vx * dt)
|
||||||
|
newy = self.y + (self.vy * dt)
|
||||||
|
|
||||||
|
# If we are at the top/bottom edge of the board, flip Y velocity
|
||||||
|
if newy + self.radius >= SIZE[0] or newy - self.radius <= 0:
|
||||||
|
self.vy = self.vy * -1.0
|
||||||
|
|
||||||
|
# Back wall
|
||||||
|
# TODO: Make this a life or lose condition
|
||||||
|
if newx + self.radius >= SIZE[0] or newx - self.radius <= 0:
|
||||||
|
self.vx = self.vx * -1.0
|
||||||
|
|
||||||
|
grid_x = math.floor(newx / 100)
|
||||||
|
grid_y = math.floor(newy / 100)
|
||||||
|
|
||||||
|
candidates = []
|
||||||
|
if (
|
||||||
|
grid[grid_y][grid_x] == TileType.CPU and self.charType == ObjectType.PLAYER
|
||||||
|
) or (
|
||||||
|
grid[grid_y][grid_x] == TileType.PLAYER and self.charType == ObjectType.CPU
|
||||||
|
):
|
||||||
|
candidates.append(object_grid[grid_y][grid_x])
|
||||||
|
if grid_x + 1 < BLOCKS_SIZE:
|
||||||
|
if self.vx > 0:
|
||||||
|
if (
|
||||||
|
grid[grid_y][grid_x + 1] == TileType.CPU
|
||||||
|
and self.charType == ObjectType.PLAYER
|
||||||
|
) or (
|
||||||
|
grid[grid_y][grid_x + 1] == TileType.PLAYER
|
||||||
|
and self.charType == ObjectType.CPU
|
||||||
|
):
|
||||||
|
candidates.append(object_grid[grid_y][grid_x + 1])
|
||||||
|
if grid_x - 1 >= 0:
|
||||||
|
if self.vx <= 0:
|
||||||
|
if (
|
||||||
|
grid[grid_y][grid_x - 1] == TileType.CPU
|
||||||
|
and self.charType == ObjectType.PLAYER
|
||||||
|
) or (
|
||||||
|
grid[grid_y][grid_x - 1] == TileType.PLAYER
|
||||||
|
and self.charType == ObjectType.CPU
|
||||||
|
):
|
||||||
|
candidates.append(object_grid[grid_y][grid_x - 1])
|
||||||
|
if grid_y + 1 < BLOCKS_SIZE:
|
||||||
|
if self.vy > 0:
|
||||||
|
if (
|
||||||
|
grid[grid_y + 1][grid_x] == TileType.CPU
|
||||||
|
and self.charType == ObjectType.PLAYER
|
||||||
|
) or (
|
||||||
|
grid[grid_y + 1][grid_x] == TileType.PLAYER
|
||||||
|
and self.charType == ObjectType.CPU
|
||||||
|
):
|
||||||
|
candidates.append(object_grid[grid_y + 1][grid_x])
|
||||||
|
if grid_y - 1 >= 0:
|
||||||
|
if self.vy <= 0:
|
||||||
|
if (
|
||||||
|
grid[grid_y - 1][grid_x] == TileType.CPU
|
||||||
|
and self.charType == ObjectType.PLAYER
|
||||||
|
) or (
|
||||||
|
grid[grid_y - 1][grid_x] == TileType.PLAYER
|
||||||
|
and self.charType == ObjectType.CPU
|
||||||
|
):
|
||||||
|
candidates.append(object_grid[grid_y - 1][grid_x])
|
||||||
|
|
||||||
|
for candidate in candidates:
|
||||||
|
if intersects(candidate.rect, self.radius, (self.x, self.y)):
|
||||||
|
|
||||||
|
if self.x >= candidate.x and self.x <= (candidate.x + candidate.length):
|
||||||
|
if (candidate.y + candidate.length) < self.y:
|
||||||
|
self.vy = self.vy * -1
|
||||||
|
if self.y < candidate.y:
|
||||||
|
self.vy = self.vy * -1
|
||||||
|
|
||||||
|
if candidate.x > self.x:
|
||||||
|
self.vx = self.vx * -1.0
|
||||||
|
|
||||||
|
if (candidate.x + candidate.length) < self.x:
|
||||||
|
self.vx = self.vx * -1.0
|
||||||
|
|
||||||
|
if candidate.tileType == TileType.PLAYER:
|
||||||
|
candidate.tileType = TileType.CPU
|
||||||
|
candidate.color = RIGHT_COLOR
|
||||||
|
else:
|
||||||
|
candidate.tileType = TileType.PLAYER
|
||||||
|
candidate.color = LEFT_COLOR
|
||||||
|
|
||||||
|
tgrid_x = int(candidate.x / 100)
|
||||||
|
tgrid_y = int(candidate.y / 100)
|
||||||
|
if grid[tgrid_y][tgrid_x] == TileType.PLAYER:
|
||||||
|
grid[tgrid_y][tgrid_x] = TileType.CPU
|
||||||
|
else:
|
||||||
|
grid[tgrid_y][tgrid_x] = TileType.PLAYER
|
||||||
|
break
|
||||||
|
|
||||||
|
self.x = self.x + (self.vx * dt)
|
||||||
|
self.y = self.y + (self.vy * dt)
|
||||||
|
|
||||||
|
# Fix speed if necessary:
|
||||||
|
if abs(self.vx) < 3:
|
||||||
|
if self.vx < 0:
|
||||||
|
self.vx = -5
|
||||||
|
else:
|
||||||
|
self.vx = 5
|
||||||
|
|
||||||
|
# Normalize to speed
|
||||||
|
mag = math.sqrt((self.vx * self.vx) + (self.vy * self.vy))
|
||||||
|
if mag != 0:
|
||||||
|
self.vx = (self.vx / mag) * self.speed
|
||||||
|
self.vy = (self.vy / mag) * self.speed
|
||||||
|
|
||||||
|
def perform_spawn_hit(self):
|
||||||
|
forceX = np.random.uniform(low=-50.0, high=50.0)
|
||||||
|
forceY = np.random.uniform(low=-50.0, high=50.0)
|
||||||
|
|
||||||
|
# Impulse dv = (f * dt)/m
|
||||||
|
# Assuming dt = 1
|
||||||
|
self.vx = (forceX) / self.mass
|
||||||
|
self.vy = (forceY) / self.mass
|
||||||
|
|
||||||
|
|
||||||
|
def ball_paddle_collide(ball: Ball, paddle: Paddle):
|
||||||
|
pRect = pygame.Rect(
|
||||||
|
paddle.x - paddle.depth / 2,
|
||||||
|
paddle.y - paddle.length / 2,
|
||||||
|
paddle.depth,
|
||||||
|
paddle.length,
|
||||||
|
)
|
||||||
|
|
||||||
|
collide = intersects(pRect, ball.radius, (ball.x, ball.y))
|
||||||
|
|
||||||
|
if collide:
|
||||||
|
ball.vx = (ball.vx * -1)
|
||||||
|
|
||||||
|
# Depending on where the ball hit on the paddle
|
||||||
|
# relative to the center, add more or less vy
|
||||||
|
mag = (ball.y - paddle.y) / (paddle.length * 1.25)
|
||||||
|
|
||||||
|
ball.vy = ball.vy + (mag * 50)
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
pygame.init()
|
||||||
|
screen = pygame.display.set_mode(SIZE)
|
||||||
|
clock = pygame.time.Clock()
|
||||||
|
|
||||||
|
running = True
|
||||||
|
dt = 0
|
||||||
|
|
||||||
|
ball_pos_left = pygame.Vector2(screen.get_width() / 4, screen.get_height() / 2)
|
||||||
|
ball_pos_right = pygame.Vector2((screen.get_width() / 4) * 3, screen.get_height() / 2)
|
||||||
|
left_ball = Ball(ball_pos_left.x, ball_pos_left.y, 10, RIGHT_COLOR, ObjectType.PLAYER)
|
||||||
|
right_ball = Ball(ball_pos_right.x, ball_pos_right.y, 10, LEFT_COLOR, ObjectType.CPU)
|
||||||
|
|
||||||
|
p1 = Paddle(20, screen.get_height() / 2, PADDLE_LENGTH, 20, RIGHT_COLOR, 5, 300)
|
||||||
|
p2 = Paddle(
|
||||||
|
screen.get_width() - 20,
|
||||||
|
screen.get_height() / 2,
|
||||||
|
PADDLE_LENGTH,
|
||||||
|
20,
|
||||||
|
LEFT_COLOR,
|
||||||
|
5,
|
||||||
|
300,
|
||||||
|
)
|
||||||
|
|
||||||
|
p1score = 0
|
||||||
|
p2score = 0
|
||||||
|
|
||||||
|
grid = [[] * BLOCKS_SIZE]
|
||||||
|
|
||||||
|
LENGTH = BLOCKS_SIZE
|
||||||
|
|
||||||
|
A = TileType.PLAYER
|
||||||
|
B = TileType.CPU
|
||||||
|
|
||||||
|
# Initialize the 2D array with zeros
|
||||||
|
grid = [[0 for _ in range(LENGTH)] for _ in range(LENGTH)]
|
||||||
|
|
||||||
|
# Determine the midpoint of the array
|
||||||
|
midpoint = LENGTH // 2
|
||||||
|
|
||||||
|
# Fill the first half of the array with value A
|
||||||
|
for i in range(midpoint):
|
||||||
|
for j in range(LENGTH):
|
||||||
|
grid[j][i] = A
|
||||||
|
|
||||||
|
# Fill the second half of the grid with value B
|
||||||
|
for i in range(midpoint, LENGTH):
|
||||||
|
for j in range(LENGTH):
|
||||||
|
grid[j][i] = B
|
||||||
|
|
||||||
|
|
||||||
|
object_grid = [[0 for _ in range(LENGTH)] for _ in range(LENGTH)]
|
||||||
|
|
||||||
|
for i in range(LENGTH):
|
||||||
|
for j in range(LENGTH):
|
||||||
|
if grid[j][i] == TileType.PLAYER:
|
||||||
|
object_grid[j][i] = Tile(i * 100, j * 100, 100, LEFT_COLOR, TileType.PLAYER)
|
||||||
|
else:
|
||||||
|
object_grid[j][i] = Tile(i * 100, j * 100, 100, RIGHT_COLOR, TileType.CPU)
|
||||||
|
|
||||||
|
|
||||||
|
BACKGROUND_RIGHT = pygame.Rect(
|
||||||
|
screen.get_width() / 2, 0, screen.get_width() / 2, screen.get_height()
|
||||||
|
)
|
||||||
|
|
||||||
|
while running:
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
running = False
|
||||||
|
|
||||||
|
# Render grid
|
||||||
|
for i in range(LENGTH):
|
||||||
|
for j in range(LENGTH):
|
||||||
|
t = object_grid[j][i]
|
||||||
|
draw_rect(screen, t.rect.x, t.rect.y, t.rect.width, t.rect.height, t.color)
|
||||||
|
|
||||||
|
# Draw ball
|
||||||
|
left_ball.draw(screen)
|
||||||
|
right_ball.draw(screen)
|
||||||
|
p1.draw(screen)
|
||||||
|
p2.draw(screen)
|
||||||
|
|
||||||
|
# input handling
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
running = False
|
||||||
|
p1.set_vel(0)
|
||||||
|
p2.set_vel(0)
|
||||||
|
keys = pygame.key.get_pressed()
|
||||||
|
if keys[pygame.K_w]:
|
||||||
|
p1.set_vel(-300.0)
|
||||||
|
if keys[pygame.K_s]:
|
||||||
|
p1.set_vel(300.0)
|
||||||
|
if keys[pygame.K_i]:
|
||||||
|
p2.set_vel(-300.0)
|
||||||
|
if keys[pygame.K_k]:
|
||||||
|
p2.set_vel(300.0)
|
||||||
|
if keys[pygame.K_h]:
|
||||||
|
left_ball.perform_spawn_hit()
|
||||||
|
right_ball.perform_spawn_hit()
|
||||||
|
if keys[pygame.K_q]:
|
||||||
|
running = False
|
||||||
|
|
||||||
|
# Movement and physics
|
||||||
|
left_ball.move(grid, object_grid, dt)
|
||||||
|
right_ball.move(grid, object_grid, dt)
|
||||||
|
p1.move(dt)
|
||||||
|
p2.move(dt)
|
||||||
|
|
||||||
|
ball_paddle_collide(left_ball, p1)
|
||||||
|
ball_paddle_collide(right_ball, p2)
|
||||||
|
|
||||||
|
# Compute Score
|
||||||
|
|
||||||
|
p1score = 0
|
||||||
|
p2score = 0
|
||||||
|
for i in grid:
|
||||||
|
for j in i:
|
||||||
|
if j == TileType.PLAYER:
|
||||||
|
p1score += 1
|
||||||
|
else:
|
||||||
|
p2score += 1
|
||||||
|
|
||||||
|
# if your score is higher, your ball is faster
|
||||||
|
left_ball.set_speed(HALF_SPEED * (p1score/50.0))
|
||||||
|
right_ball.set_speed(HALF_SPEED * (p2score/50.0))
|
||||||
|
|
||||||
|
|
||||||
|
pygame.display.flip()
|
||||||
|
dt = clock.tick(60) / 1000
|
||||||
|
print("\x1b[1A\x1b[2K", end="")
|
||||||
|
print(f"scores -> \t {p1score} ({left_ball.speed}, ({left_ball.vx}, {left_ball.vy}) \t {p2score} ({right_ball.speed}, {right_ball.vx})")
|
||||||
|
|
||||||
|
pygame.quit()
|
8
pyvenv.cfg
Normal file
8
pyvenv.cfg
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
home = /Library/Developer/CommandLineTools/usr/bin
|
||||||
|
implementation = CPython
|
||||||
|
version_info = 3.9.6.final.0
|
||||||
|
virtualenv = 20.25.0
|
||||||
|
include-system-site-packages = false
|
||||||
|
base-prefix = /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9
|
||||||
|
base-exec-prefix = /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9
|
||||||
|
base-executable = /Library/Developer/CommandLineTools/usr/bin/python3
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
imgui==2.0.0
|
||||||
|
pygame==2.5.2
|
Loading…
x
Reference in New Issue
Block a user