Created
November 16, 2019 15:42
-
-
Save ntabris/1b51e8f9e58b5a13098d93cb958a06c3 to your computer and use it in GitHub Desktop.
python text astroids game
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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