Skip to content

Instantly share code, notes, and snippets.

@ntabris
Created November 16, 2019 15:42
Show Gist options
  • Save ntabris/1b51e8f9e58b5a13098d93cb958a06c3 to your computer and use it in GitHub Desktop.
Save ntabris/1b51e8f9e58b5a13098d93cb958a06c3 to your computer and use it in GitHub Desktop.
python text astroids game
import attr
import os
import curses
from math import pi, cos, sin
import time
import random
@attr.s(auto_attribs=True)
class Board(object):
height: int = 60
width: int = 100
things: list = attr.ib(factory=list)
def draw(self, win):
win.noutrefresh()
win.erase()
win.addstr("+" + "-" * self.width + "+\n")
for h in range(self.height):
line = "|"
for w in range(self.width):
mark = " "
for thing in self.things:
if h == int(thing.down) and w == int(thing.over):
mark = thing.mark
line += mark
line += "|\n"
win.addstr(line)
win.addstr("+" + "-" * self.width + "+\n")
win.refresh()
# win.addstr(f"{things['guy'].direction / pi}\n")
def update(self):
self.move_things()
self.check_collisions()
self.remove_dead_things()
if self.astroid_count() == 0:
for _ in range(10):
self.add_astroid()
def move_things(self):
for thing in self.things:
# apply movement
thing.move()
# wrap around edges of board
thing.down = thing.down % self.height
thing.over = thing.over % self.width
def check_collisions(self):
for thing_a in self.things:
for thing_b in self.things:
if thing_a != thing_b:
if abs(thing_a.down - thing_b.down) < 1 and abs(
thing_a.over - thing_b.over) < 1:
thing_a.collision(thing_b)
def remove_dead_things(self):
self.things = [thing for thing in self.things
if thing.health > 0]
def add_astroid(self):
astroid = Thing(mark="#", thing_type="astroid")
astroid.down = random.randint(0, self.height)
astroid.over = random.randint(0, self.width)
astroid.speed = random.random()
astroid.direction = random.random() * pi * 2
self.things.append(astroid)
def astroid_count(self):
return len([1 for thing in self.things if thing.thing_type == "astroid"])
@attr.s(auto_attribs=True, slots=True, eq=False)
class Thing(object):
down: float = 0
over: float = 0
mark: str = ""
speed: float = 0
direction: int = 0
thing_type: str = ""
health: int = 1
@property
def move_down(self):
return self.speed * cos(self.direction)
@property
def move_over(self):
return self.speed * sin(self.direction)
def move(self):
self.down += self.move_down
self.over += self.move_over
if self.thing_type == "bullet":
self.health = self.health - 1
def collision(self, other_thing):
if self.thing_type == "bullet" and other_thing.thing_type != "guy":
self.health = 0
other_thing.health = other_thing.health - 1
def main(win):
curses.curs_set(0)
win.nodelay(True)
board = Board(height=40, width=80)
guy = Thing(down=10, over=10, mark="*", thing_type="guy")
board.things.append(guy)
board.draw(win)
MAX_GUY_SPEED = 1.5
GUY_ACCELERATION = .3
GUY_ROTATION = pi / 2
while True:
key = win.getch()
if key:
if key == ord("q"):
break
if key == ord(" "):
bullet = Thing(
down=guy.down,
over=guy.over,
mark=".",
speed=2.5,
direction=guy.direction,
thing_type="bullet",
health=20,
)
board.things.append(bullet)
if key == curses.KEY_DOWN:
guy.speed = guy.speed - GUY_ACCELERATION
if guy.speed < 0:
guy.speed = 0
if key == curses.KEY_UP:
guy.speed = guy.speed + GUY_ACCELERATION
if guy.speed > MAX_GUY_SPEED:
guy.speed = MAX_GUY_SPEED
if key == curses.KEY_LEFT:
guy.direction = guy.direction + GUY_ROTATION
guy.direction = guy.direction % (pi * 2)
if key == curses.KEY_RIGHT:
guy.direction = guy.direction - GUY_ROTATION
guy.direction = guy.direction % (pi * 2)
if guy.direction > (7/4)*pi or guy.direction <= (1/4)*pi:
guy.mark = "v"
elif (1/4)*pi < guy.direction <= (3/4)*pi:
guy.mark = ">"
elif (3/4)*pi < guy.direction <= (5/4)*pi:
guy.mark = "^"
elif (5/4)*pi < guy.direction <= (7/4)*pi:
guy.mark = "<"
board.update()
board.draw(win)
time.sleep(0.05)
if __name__ == "__main__":
curses.wrapper(main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment