Last active
August 29, 2015 14:06
-
-
Save abner-math/05364c4b67d5ed265871 to your computer and use it in GitHub Desktop.
This file contains 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
#!/usr/bin/python | |
# -*-coding=utf-8 -*- | |
#----------------------------------------------------------- | |
# PyInvaders v3.1 | |
# Created by: Abner Matheus | |
# E-mail: [email protected] | |
# Github: http://github.com/picoledelimao | |
#----------------------------------------------------------- | |
import time, os, platform, random, sys, select | |
class GameObject(object): | |
def __init__(self, life, x, y, char): | |
self.life = life | |
self.x = x | |
self.y = y | |
self.char = char | |
def getX(self): | |
return self.x | |
def getY(self): | |
return self.y | |
def getChar(self): | |
return self.char | |
def getLife(self): | |
return self.life | |
def setX(self, x): | |
self.x = x | |
def setY(self, y): | |
self.y = y | |
def damage(self): | |
self.life -= 1 | |
def dead(self): | |
return self.life <= 0 | |
class Game(object): | |
def __init__(self): | |
self.new_game() | |
def new_game(self): | |
self.spacecraft = GameObject(3, 13, 8, "^") | |
self.aliens = [] | |
self.create_aliens() | |
self.walls = [] | |
self.create_walls() | |
self.shoots = [] | |
self.shoots_aliens = [] | |
self.terrain = [] | |
self.create_terrain() | |
self.score = 0 | |
self.cooldown = False | |
self.start_screen = False | |
self.mode_screen = False | |
self.difficulty = 0 | |
def create_aliens(self): | |
for x in range(5): | |
for y in range(10): | |
alien = GameObject(5-x, x+1, 4+y, "@") | |
self.aliens.append(alien) | |
def create_walls(self): | |
for i in range(4): | |
wall = GameObject(1, 12, 3+i*3, "~") | |
self.walls.append(wall) | |
def create_terrain(self): | |
for x in range(15): | |
self.terrain.append([]) | |
for y in range(15): | |
self.terrain[-1].append(" ") | |
def clear_terrain(self): | |
for x in range(15): | |
for y in range(15): | |
self.terrain[x][y] = " " | |
def draw_spacecraft(self): | |
self.terrain[self.spacecraft.getX()][self.spacecraft.getY()] = self.spacecraft.getChar() | |
def find_alien(self, x, y): | |
for i in range(len(self.aliens)): | |
alien = self.aliens[i] | |
if alien.getX() == x and alien.getY() == y: | |
return i | |
def find_wall(self, x, y): | |
for i in range(len(self.walls)): | |
wall = self.walls[i] | |
if wall.getX() == x and wall.getY() == y: | |
return i | |
def destroy_shoot(self, i): | |
self.shoots.pop(i) | |
def draw_shoots(self): | |
for i in range(len(self.shoots) - 1, -1, -1): | |
shoot = self.shoots[i] | |
x = shoot.getX() | |
y = shoot.getY() | |
a = self.find_alien(x, y) | |
if a != None: | |
self.aliens[a].damage() | |
if self.aliens[a].dead(): | |
self.aliens.pop(a) | |
self.score += 10 | |
self.destroy_shoot(i) | |
else: | |
if x > 0: | |
shoot.setX(x - 1) | |
else: | |
self.destroy_shoot(i) | |
for shoot in self.shoots: | |
self.terrain[shoot.getX()][shoot.getY()] = shoot.getChar() | |
def destroy_shoot_aliens(self, i): | |
self.shoots_aliens.pop(i) | |
def alien_shoot(self): | |
x = random.randint(0, len(self.aliens)-1) | |
alien = self.aliens[x] | |
shoot = GameObject(1, alien.getX()+1, alien.getY(), ":") | |
self.shoots_aliens.append(shoot) | |
def draw_shoots_aliens(self): | |
if int(time.localtime().tm_sec) % (4-self.difficulty) == 0: | |
self.alien_shoot() | |
for i in range(len(self.shoots_aliens) - 1, -1, -1): | |
shoot = self.shoots_aliens[i] | |
x = shoot.getX() | |
y = shoot.getY() | |
m = self.find_wall(x, y) | |
if m != None: | |
self.walls[m].damage() | |
if self.walls[m].dead(): | |
self.walls.pop(m) | |
self.destroy_shoot_aliens(i) | |
elif x == self.spacecraft.getX() and y == self.spacecraft.getY(): | |
self.spacecraft.damage() | |
if self.spacecraft.dead(): | |
self.game_over() | |
self.destroy_shoot_aliens(i) | |
else: | |
if x < 14: | |
shoot.setX(x + 1) | |
else: | |
self.destroy_shoot_aliens(i) | |
for shoot in self.shoots_aliens: | |
self.terrain[shoot.getX()][shoot.getY()] = shoot.getChar() | |
def draw_aliens(self): | |
for alien in self.aliens: | |
self.terrain[alien.getX()][alien.getY()] = alien.getChar() | |
def draw_walls(self): | |
for wall in self.walls: | |
self.terrain[wall.getX()][wall.getY()] = wall.getChar() | |
def draw_terrain(self): | |
for x in range(15): | |
print "".join(self.terrain[x]) | |
def update(self): | |
if int(time.localtime().tm_sec) % self.difficulty == 0: | |
self.cooldown = False | |
print ("SCORE<%d>" % self.score).center(20) | |
self.clear_terrain() | |
self.draw_spacecraft() | |
self.draw_shoots() | |
self.draw_shoots_aliens() | |
self.draw_aliens() | |
self.draw_walls() | |
self.draw_terrain() | |
print ("LIVES: %d" % self.spacecraft.getLife()).center(20) | |
if len(self.aliens) == 0: | |
self.win() | |
return False | |
elif self.spacecraft.dead(): | |
return False | |
return True | |
def move_right(self): | |
if self.spacecraft.getY() < 14: | |
self.spacecraft.setY(self.spacecraft.getY() + 1) | |
def move_left(self): | |
if self.spacecraft.getY() > 0: | |
self.spacecraft.setY(self.spacecraft.getY() - 1) | |
def shoot(self): | |
if not self.cooldown: | |
shoot = GameObject(1, 12, self.spacecraft.getY(), "|") | |
self.shoots.append(shoot) | |
self.cooldown = True | |
def game_over(self): | |
clear_screen() | |
print "GAME OVER!!" | |
time.sleep(3) | |
def win(self): | |
clear_screen() | |
print "YOU ROCK!!" | |
time.sleep(3) | |
def is_start_screen(self): | |
return self.start_screen | |
def start(self): | |
if not self.mode_screen: | |
print """ | |
## ## | |
## ## | |
############## | |
#### ###### #### | |
###################### | |
## ############## ## | |
## ## ## ## | |
#### #### | |
## | |
## | |
## | |
## | |
## | |
## | |
## """ | |
print "\n" | |
print "PYINVADERS".center(70) | |
print "========= CREATED BY: =========".center(70) | |
print "ABNER MATHEUS ([email protected])".center(70) | |
print "\n" | |
print "PRESS 'N' TO START A NEW GAME OR 'ESC' TO EXIT GAME.".center(70) | |
else: | |
if self.difficulty == 0: | |
print """DIFFICULTY: | |
1. EASY | |
2. AVERAGE | |
3. HARD | |
=================================== | |
GAME CONTROLS: | |
=================================== | |
'A' AND 'D' TO MOVE THE SPACECRAFT. | |
'S' TO SHOOT. | |
""" | |
else: | |
self.start_screen = True | |
def new(self): | |
self.mode_screen = True | |
def set_difficulty(self, n): | |
self.difficulty = n | |
def clear_screen(): | |
if platform.system() == "Windows": os.system("cls") | |
else: os.system("clear") | |
#------------------------------- | |
# IO MANAGER | |
#-------------------------------- | |
def controller_windows(): | |
import Tkinter | |
class Controller: | |
def __init__(self): | |
self.game = Game() | |
self.start_game() | |
def press_key(self, key): | |
event = key.keysym.lower() | |
if event == "escape": | |
self.console.destroy() | |
elif event == "d": | |
self.game.move_right() | |
elif event == "a": | |
self.game.move_left() | |
elif event == "s": | |
self.game.shoot() | |
elif event == "n": | |
self.game.new() | |
elif event == "1": | |
self.game.set_difficulty(1) | |
elif event == "2": | |
self.game.set_difficulty(2) | |
elif event == "3": | |
self.game.set_difficulty(3) | |
return True | |
def loop(self): | |
clear_screen() | |
if not self.game.is_start_screen(): | |
self.game.start() | |
else: | |
if not self.game.update(): | |
self.game = Game() | |
self.console.after(250, self.loop) | |
def start_game(self): | |
self.game.start() | |
self.console = Tkinter.Tk() | |
self.console.bind_all('<Key>', self.press_key) | |
self.console.withdraw() | |
try: | |
self.console.after(250, self.loop) | |
self.console.mainloop() | |
except KeyboardInterrupt: pass | |
Controller() | |
def controller_unix(): | |
import termios, tty, thread | |
class NonBlockingConsole(object): | |
def __enter__(self): | |
self.old_settings = termios.tcgetattr(sys.stdin) | |
tty.setcbreak(sys.stdin.fileno()) | |
return self | |
def __exit__(self, type, value, traceback): | |
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.old_settings) | |
def get_data(self): | |
if select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], []): | |
return sys.stdin.read(1) | |
return False | |
class Controller: | |
def __init__(self): | |
self.game = Game() | |
self.start_game() | |
def press_key(self, nbc): | |
event = str(nbc.get_data()) | |
if event == '\x1b': | |
return False | |
elif event == "d": | |
self.game.move_right() | |
elif event == "a": | |
self.game.move_left() | |
elif event == "s": | |
self.game.shoot() | |
elif event == "n": | |
self.game.new() | |
elif event == "1": | |
self.game.set_difficulty(1) | |
elif event == "2": | |
self.game.set_difficulty(2) | |
elif event == "3": | |
self.game.set_difficulty(3) | |
return True | |
def loop(self, threadName): | |
while self.running: | |
time.sleep(250/1000.0) | |
clear_screen() | |
if not self.game.is_start_screen(): | |
self.game.start() | |
else: | |
if not self.game.update(): | |
self.game = Game() | |
def start_game(self): | |
self.running = True | |
thread.start_new_thread(self.loop, ("Thread-1",)) | |
try: | |
with NonBlockingConsole() as nbc: | |
while self.press_key(nbc): pass | |
except KeyboardInterrupt: pass | |
self.running = False | |
Controller() | |
if __name__ == '__main__': | |
if platform.system() == "Windows": | |
controller_windows() | |
else: | |
controller_unix() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment