This commit is contained in:
Waylon Walker 2023-06-29 16:38:05 -05:00
parent f0f1ce5018
commit d0b3712f17
No known key found for this signature in database
GPG key ID: 66E2BF2B4190EFE4
18 changed files with 568 additions and 23 deletions

View file

@ -1,13 +1,13 @@
from fastapi import APIRouter, Depends, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse
from rich.console import Console
from sqlmodel import Session
from sqlmodel import Session, select
from websockets.exceptions import ConnectionClosed
from learn_sql_model.api.websocket_connection_manager import manager
from learn_sql_model.config import get_session
from learn_sql_model.console import console
from learn_sql_model.models.hero import HeroDelete, HeroUpdate, Heros
from learn_sql_model.models.hero import Hero, HeroDelete, HeroUpdate, Heros
web_socket_router = APIRouter()
@ -46,7 +46,9 @@ async def websocket_endpoint_connect(
):
Console().log(f"Client #{id} connecting")
await manager.connect(websocket, channel)
heros = Heros.list(session=session)
statement = select(Hero)
heros = session.exec(statement).all()
heros = Heros(__root__=heros)
await websocket.send_text(heros.json())
try:
@ -83,11 +85,18 @@ async def websocket_endpoint_hero_echo(
while True:
data = await websocket.receive_text()
hero = HeroUpdate.parse_raw(data)
heros = Heros.list(session=session)
statement = select(Hero)
heros = session.exec(statement).all()
heros = Heros(__root__=heros)
if heros != last_heros:
await manager.broadcast(heros.json(), "heros")
last_heros = heros
hero.update(session=session)
db_hero = session.get(Hero, hero.id)
for key, value in hero.dict(exclude_unset=True).items():
setattr(db_hero, key, value)
session.add(db_hero)
session.commit()
session.refresh(db_hero)
console.print(heros)
await websocket.send_text(heros.json())
@ -96,7 +105,9 @@ async def websocket_endpoint_hero_echo(
HeroDelete(id=hero.id).delete(session=session)
except Exception:
...
heros = Heros.list(session=session)
statement = select(Hero)
heros = session.exec(statement).all()
heros = Heros(__root__=heros)
await manager.broadcast(heros.json(), "heros")
print("disconnected")
except ConnectionClosed:
@ -104,6 +115,8 @@ async def websocket_endpoint_hero_echo(
HeroDelete(id=hero.id).delete(session=session)
except Exception:
...
heros = Heros.list(session=session)
statement = select(Hero)
heros = session.exec(statement).all()
heros = Heros(__root__=heros)
await manager.broadcast(heros.json(), "heros")
print("connection closed")

View file

@ -29,8 +29,6 @@ def run(
help="show the log messages",
),
):
import uvicorn
uvicorn.run(**get_config().api_server.dict())

View file

@ -5,10 +5,10 @@ from websocket import create_connection
from learn_sql_model.config import get_config
from learn_sql_model.console import console
from learn_sql_model.game.light import Light
from learn_sql_model.game.map import Map
from learn_sql_model.game.menu import Menu
from learn_sql_model.game.player import Player
from learn_sql_model.game.light import Light
from learn_sql_model.optional import _optional_import_
pygame = _optional_import_("pygame", group="game")
@ -37,15 +37,22 @@ class Client:
self.light = Light(self)
self.font = pygame.font.SysFont("", 50)
self.joysticks = {}
self.darkness = pygame.Surface(
(self.screen.get_width(), self.screen.get_height())
)
atexit.register(self.quit)
@property
def ws(self):
def connect():
self._ws = create_connection(
f"wss://{config.api_client.url.replace('https://', '')}/wsecho"
)
if "https" in config.api_client.url:
url = f"wss://{config.api_client.url.replace('https://', '')}/wsecho"
elif "http" in config.api_client.url:
url = f"ws://{config.api_client.url.replace('http://', '')}/wsecho"
else:
url = f"ws://{config.api_client.url}/wsecho"
self._ws = create_connection(url)
if not hasattr(self, "_ws"):
connect()
@ -80,6 +87,19 @@ class Client:
self.screen.fill((0, 0, 0))
self.map.render()
self.player.render()
light_level = 0
self.darkness.fill((light_level, light_level, light_level))
# self.darkness.blit(
# pygame.transform.smoothscale(
# self.spot, [self.light_power, self.light_power]
# ),
# (self.x - self.light_power / 2, self.y - self.light_power / 2),
# )
self.screen.blit(
pygame.transform.scale(self.darkness, self.screen.get_size()).convert(),
(0, 0),
special_flags=pygame.BLEND_MULT,
)
self.light.render()
# update the screen

View file

@ -6,15 +6,41 @@ pygame = _optional_import_("pygame", group="game")
class Light:
def __init__(self, game):
self.game = game
self.surf = pygame.Surface((1000, 100))
# pil_image = Image.new("RGBA", (1000, 500))
# pil_draw = ImageDraw.Draw(pil_image)
# pil_draw.pieslice((-1500, -100, 1000, 600), 340, 20, fill=(255, 250, 205))
# pil_image = pil_image.filter(ImageFilter.GaussianBlur(radius=5))
# mode = pil_image.mode
# size = pil_image.size
# data = pil_image.tobytes()
# self.image = pygame.image.fromstring(data, size, mode)
# for r in range(-25, 25):
# _v = v.rotate(r)
# pygame.draw.line(
# self.game.screen,
# (255, 250, 205),
# (0, 50),
# (0 + _v.x, self.game.player.hero.y + _v.y),
# 50,
# )
def render(self):
mx, my = pygame.mouse.get_pos()
v = pygame.math.Vector2(
mx - self.game.player.hero.x, my - self.game.player.hero.y
)
v.scale_to_length(1000)
v.scale_to_length(self.game.player.hero.flashlight_strength)
self.game.player.hero.flashlight_angle = v.angle_to(pygame.math.Vector2(0, 0))
# self.game.screen.blit(
# pygame.transform.rotate(self.image, pygame.math.Vector2(0, 0).angle_to(v)),
# (self.game.player.hero.x, self.game.player.hero.y - 250),
# )
for r in range(0, 360):
for r in range(-25, 25):
_v = v.rotate(r)
pygame.draw.line(
self.game.screen,
@ -23,3 +49,29 @@ class Light:
(self.game.player.hero.x + _v.x, self.game.player.hero.y + _v.y),
50,
)
# draw a circle
pygame.draw.circle(
self.game.screen,
(255, 250, 205),
(self.game.player.hero.x, self.game.player.hero.y),
self.game.player.hero.lanturn_strength,
)
def render_flashlight(light, strength, angle):
# self.darkness.blit(
# pygame.transform.smoothscale(
# self.spot, [self.light_power, self.light_power]
# ),
# (self.x - self.light_power / 2, self.y - self.light_power / 2),
# )
for r in range(-25, 25):
_v = v.rotate(r)
pygame.draw.line(
light,
(255, 250, 205),
(self.game.player.hero.x, self.game.player.hero.y),
(self.game.player.hero.x + _v.x, self.game.player.hero.y + _v.y),
50,
)

View file

@ -1,5 +1,6 @@
from learn_sql_model.config import get_config
from learn_sql_model.console import console
from learn_sql_model.models.hero import HeroCreate, HeroDelete, HeroUpdate, Heros
from learn_sql_model.models.hero import Hero, HeroCreate, HeroUpdate, Heros
from learn_sql_model.optional import _optional_import_
pygame = _optional_import_("pygame", group="game")
@ -12,11 +13,18 @@ HeroFactory = _optional_import_(
class Player:
def __init__(self, game):
hero = HeroFactory().build(size=25, x=100, y=100)
hero = HeroFactory().build(
size=25,
x=100,
y=100,
flashlight_strength=1000,
lanturn_strength=100,
flashlight_angle=0,
)
self.hero = HeroCreate(**hero.dict()).post()
self.game = game
self.others = [] #Heros(heros=[])
self.others = [] # Heros(heros=[])
self.width = 16
self.height = 16
self.white = (255, 255, 255)
@ -42,13 +50,21 @@ class Player:
def rename_hero(self):
old_hero = self.hero
hero = HeroFactory().build(
size=self.hero.size, x=self.hero.x, y=self.hero.y, id=old_hero.id
size=self.hero.size,
x=self.hero.x,
y=self.hero.y,
id=old_hero.id,
flashlight_strength=self.hero.flashlight_strength,
lanturn_strength=self.hero.lanturn_strength,
)
self.hero = HeroCreate(**hero.dict()).post()
def quit(self):
try:
HeroDelete(id=self.hero.id).delete()
session = get_config().database.session
hero = session.get(Hero, self.hero.id)
session.delete(hero)
session.commit()
except RuntimeError:
pass
@ -158,6 +174,10 @@ class Player:
movement_vector = end_pos - start_pos
try:
movement_direction = movement_vector.normalize()
except ValueError:
end_pos = pygame.math.Vector2(self.hero.x + 128, self.hero.y + 128)
movement_vector = end_pos - start_pos
movement_direction = movement_vector.normalize()
except ZeroDivisionError:
end_pos = pygame.math.Vector2(self.hero.x + 128, self.hero.y + 128)
movement_vector = end_pos - start_pos
@ -200,7 +220,7 @@ class Player:
)
def render(self):
for other in self.others.heros:
for other in self.others.__root__:
if other.id != self.hero.id:
pygame.draw.circle(
self.game.screen, (255, 0, 0), (other.x, other.y), other.size

View file

@ -1,6 +1,7 @@
from typing import Dict
from typing import Dict, Optional
import httpx
import pydantic
from pydantic import BaseModel
from sqlmodel import Field, SQLModel
@ -13,13 +14,24 @@ class HeroBase(SQLModel, table=False):
secret_name: str
x: int
y: int
# size: int
size: Optional[int]
flashlight_strength: Optional[int] = 1000
flashlight_angle: Optional[int] = 0
lanturn_strength: Optional[int] = 100
# age: Optional[int] = None
# shoe_size: Optional[int] = None
# pet_id: Optional[int] = Field(default=None, foreign_key="pet.id")
# pet: Optional[Pet] = Relationship(back_populates="hero")
@pydantic.validator("size", pre=True, always=True)
def validate_size(cls, v):
if v is None:
return 50
if v <= 0:
raise ValueError("size must be > 0")
return v
class Hero(HeroBase, table=True):
id: int = Field(default=None, primary_key=True)