make a game
This commit is contained in:
parent
53d878c75a
commit
dab0697f45
4 changed files with 227 additions and 11 deletions
|
|
@ -81,7 +81,8 @@ def get_config(overrides: dict = {}) -> Config:
|
|||
return config
|
||||
|
||||
|
||||
def get_session(config: Config = None) -> "Session":
|
||||
def get_session() -> "Session":
|
||||
config = get_config()
|
||||
with Session(config.database.engine) as session:
|
||||
yield session
|
||||
|
||||
|
|
|
|||
165
learn_sql_model/game/game.py
Normal file
165
learn_sql_model/game/game.py
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
# using pygame make a game using Hero
|
||||
# it should be gamepad and mouse compatible
|
||||
# it should have a server that keeps track of the game logic
|
||||
# it should have a renderer that renders the game
|
||||
# it should have a client that sends commands to the server
|
||||
#
|
||||
|
||||
|
||||
import atexit
|
||||
|
||||
import pygame
|
||||
from rich.console import Console
|
||||
import typer
|
||||
from typer import Typer
|
||||
|
||||
from learn_sql_model.models.hero import (
|
||||
Hero,
|
||||
HeroCreate,
|
||||
HeroDelete,
|
||||
HeroRead,
|
||||
HeroUpdate,
|
||||
)
|
||||
|
||||
speed = 10
|
||||
|
||||
pygame.font.init() # you have to call this at the start,
|
||||
# if you want to use this module.
|
||||
my_font = pygame.font.SysFont("Comic Sans MS", 30)
|
||||
|
||||
|
||||
class Client:
|
||||
def __init__(self, name, secret_name):
|
||||
self.hero = Hero(name=name, secret_name=secret_name, x=400, y=300, size=50)
|
||||
self.hero = HeroCreate(**self.hero.dict()).post()
|
||||
|
||||
self.screen = pygame.display.set_mode((800, 600))
|
||||
self.clock = pygame.time.Clock()
|
||||
self.running = True
|
||||
self.screen.fill((0, 0, 0))
|
||||
|
||||
self.moving_up = False
|
||||
self.moving_down = False
|
||||
self.moving_left = False
|
||||
self.moving_right = False
|
||||
|
||||
self.others = HeroRead.list()
|
||||
|
||||
atexit.register(self.quit)
|
||||
|
||||
def run(self):
|
||||
while self.running:
|
||||
self.handle_events()
|
||||
self.update()
|
||||
self.render()
|
||||
self.clock.tick(60)
|
||||
self.quit()
|
||||
|
||||
def quit(self):
|
||||
HeroDelete(id=self.hero.id).delete()
|
||||
|
||||
def update(self):
|
||||
if self.moving_up:
|
||||
self.hero.y -= speed
|
||||
if self.moving_down:
|
||||
self.hero.y += speed
|
||||
if self.moving_left:
|
||||
self.hero.x -= speed
|
||||
if self.moving_right:
|
||||
self.hero.x += speed
|
||||
|
||||
HeroUpdate(
|
||||
**{k: v for k, v in self.hero.dict().items() if v is not None}
|
||||
).update()
|
||||
|
||||
self.others = HeroRead.list()
|
||||
|
||||
def render(self):
|
||||
Console().print(self.hero)
|
||||
self.screen.fill((0, 0, 0))
|
||||
|
||||
for other in self.others:
|
||||
pygame.draw.circle(self.screen, (255, 0, 0), (other.x, other.y), other.size)
|
||||
self.screen.blit(
|
||||
my_font.render(other.name, False, (255, 255, 255), 1),
|
||||
(other.x, other.y),
|
||||
)
|
||||
|
||||
pygame.draw.circle(
|
||||
self.screen, (0, 0, 255), (self.hero.x, self.hero.y), self.hero.size
|
||||
)
|
||||
self.screen.blit(
|
||||
my_font.render(self.hero.name, False, (255, 255, 255)),
|
||||
(self.hero.x, self.hero.y),
|
||||
)
|
||||
|
||||
# update the screen
|
||||
pygame.display.flip()
|
||||
|
||||
def handle_events(self):
|
||||
self.events = pygame.event.get()
|
||||
for event in self.events:
|
||||
if event.type == pygame.QUIT:
|
||||
self.running = False
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_ESCAPE:
|
||||
self.running = False
|
||||
if event.key == pygame.K_LEFT:
|
||||
self.moving_left = True
|
||||
if event.key == pygame.K_RIGHT:
|
||||
self.moving_right = True
|
||||
if event.key == pygame.K_UP:
|
||||
self.moving_up = True
|
||||
if event.key == pygame.K_DOWN:
|
||||
self.moving_down = True
|
||||
# wasd
|
||||
if event.key == pygame.K_w:
|
||||
self.moving_up = True
|
||||
if event.key == pygame.K_s:
|
||||
self.moving_down = True
|
||||
if event.key == pygame.K_a:
|
||||
self.moving_left = True
|
||||
if event.key == pygame.K_d:
|
||||
self.moving_right = True
|
||||
# controller left joystick
|
||||
|
||||
if event.type == pygame.KEYUP:
|
||||
if event.key == pygame.K_LEFT:
|
||||
self.moving_left = False
|
||||
if event.key == pygame.K_RIGHT:
|
||||
self.moving_right = False
|
||||
if event.key == pygame.K_UP:
|
||||
self.moving_up = False
|
||||
if event.key == pygame.K_DOWN:
|
||||
self.moving_down = False
|
||||
# wasd
|
||||
if event.key == pygame.K_w:
|
||||
self.moving_up = False
|
||||
if event.key == pygame.K_s:
|
||||
self.moving_down = False
|
||||
if event.key == pygame.K_a:
|
||||
self.moving_left = False
|
||||
if event.key == pygame.K_d:
|
||||
self.moving_right = False
|
||||
|
||||
def check_events(self):
|
||||
pass
|
||||
|
||||
def check_collisions(self):
|
||||
pass
|
||||
|
||||
|
||||
app = Typer()
|
||||
|
||||
|
||||
@app.command()
|
||||
def run(
|
||||
name: str = typer.Option(...),
|
||||
secret_name: str = typer.Option(...),
|
||||
):
|
||||
client = Client(name, secret_name)
|
||||
client.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app()
|
||||
|
|
@ -12,6 +12,9 @@ from learn_sql_model.models.pet import Pet
|
|||
class HeroBase(SQLModel, table=False):
|
||||
name: str
|
||||
secret_name: str
|
||||
x: int
|
||||
y: int
|
||||
size: int
|
||||
age: Optional[int] = None
|
||||
shoe_size: Optional[int] = None
|
||||
|
||||
|
|
@ -34,6 +37,8 @@ class HeroCreate(HeroBase):
|
|||
if r.status_code != 200:
|
||||
raise RuntimeError(f"{r.status_code}:\n {r.text}")
|
||||
|
||||
return Hero.parse_obj(r.json())
|
||||
|
||||
|
||||
class HeroRead(HeroBase):
|
||||
id: int
|
||||
|
|
@ -80,6 +85,8 @@ class HeroUpdate(SQLModel):
|
|||
secret_name: Optional[str] = None
|
||||
age: Optional[int] = None
|
||||
shoe_size: Optional[int] = None
|
||||
x: int
|
||||
y: int
|
||||
|
||||
pet_id: Optional[int] = Field(default=None, foreign_key="pet.id")
|
||||
pet: Optional[Pet] = Relationship(back_populates="hero")
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from learn_sql_model.api.app import app
|
|||
from learn_sql_model.cli.hero import hero_app
|
||||
from learn_sql_model.config import get_config, get_session
|
||||
from learn_sql_model.factories.hero import HeroFactory
|
||||
from learn_sql_model.models.hero import Hero
|
||||
from learn_sql_model.models.hero import Hero, HeroCreate, HeroRead
|
||||
|
||||
runner = CliRunner()
|
||||
client = TestClient(app)
|
||||
|
|
@ -76,15 +76,6 @@ def test_api_read_hero(session: Session, client: TestClient):
|
|||
session.add(hero_1)
|
||||
session.commit()
|
||||
|
||||
response = client.get(f"/hero/999")
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_api_read_hero_404(session: Session, client: TestClient):
|
||||
hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
|
||||
session.add(hero_1)
|
||||
session.commit()
|
||||
|
||||
response = client.get(f"/hero/{hero_1.id}")
|
||||
data = response.json()
|
||||
|
||||
|
|
@ -95,6 +86,15 @@ def test_api_read_hero_404(session: Session, client: TestClient):
|
|||
assert data["id"] == hero_1.id
|
||||
|
||||
|
||||
def test_api_read_hero_404(session: Session, client: TestClient):
|
||||
hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
|
||||
session.add(hero_1)
|
||||
session.commit()
|
||||
|
||||
response = client.get(f"/hero/999")
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_api_update_hero(session: Session, client: TestClient):
|
||||
hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
|
||||
session.add(hero_1)
|
||||
|
|
@ -233,3 +233,46 @@ def test_cli_list(mocker):
|
|||
assert f"secret_name='{hero_1.secret_name}'" in result.stdout
|
||||
assert f"name='{hero_2.name}'" in result.stdout
|
||||
assert f"secret_name='{hero_2.secret_name}'" in result.stdout
|
||||
|
||||
|
||||
def test_model_post(mocker):
|
||||
patch_httpx_post = mocker.patch(
|
||||
"httpx.post", return_value=mocker.Mock(status_code=200)
|
||||
)
|
||||
hero = HeroFactory().build(name="Steelman", age=25)
|
||||
hero_create = HeroCreate(**hero.dict())
|
||||
hero_create.post()
|
||||
assert patch_httpx_post.call_count == 1
|
||||
|
||||
|
||||
def test_model_post_500(mocker):
|
||||
patch_httpx_post = mocker.patch(
|
||||
"httpx.post", return_value=mocker.Mock(status_code=500)
|
||||
)
|
||||
hero = HeroFactory().build(name="Steelman", age=25)
|
||||
hero_create = HeroCreate(**hero.dict())
|
||||
with pytest.raises(RuntimeError):
|
||||
hero_create.post()
|
||||
assert patch_httpx_post.call_count == 1
|
||||
|
||||
|
||||
def test_model_read_hero(mocker, session: Session, client: TestClient):
|
||||
mocker.patch(
|
||||
"learn_sql_model.config.Database.engine",
|
||||
new_callable=lambda: create_engine(
|
||||
"sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool
|
||||
),
|
||||
)
|
||||
|
||||
config = get_config()
|
||||
SQLModel.metadata.create_all(config.database.engine)
|
||||
|
||||
hero = Hero(name="Deadpond", secret_name="Dive Wilson")
|
||||
session = config.database.session
|
||||
session.add(hero)
|
||||
session.commit()
|
||||
session.refresh(hero)
|
||||
|
||||
hero_read = HeroRead.get(id=hero.id)
|
||||
assert hero_read.name == "Deadpond"
|
||||
assert hero_read.secret_name == "Dive Wilson"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue