import random import time import pygame import sys import pyaudio import wave import glob import os import ast from configobj import ConfigObj from itertools import cycle class Game: def __init__(self, o): self.o = o self.last_frame_time = time.perf_counter() self.bullets = [] self.bullet_speed = 80 self.delta = 0.00001 self.sidebar_width = 80 self.gw = o.width - self.sidebar_width self.score = 0 self.time = 0 self.player = Player(o, self) self.enemies = [] self.birth = pygame.time.get_ticks() self.last_enemy_spawn = pygame.time.get_ticks() self.enemy_spawn_delay = 2000 self.explodes = [] self.explode_speed = 80 self.hs_name = "" self.speed_mult = 1.0 self.speed_mult_inc = .1 self.mult_state = 3 self.load_highscore() self.game_over = False def update(self): self.delta = time.perf_counter() - self.last_frame_time self.last_frame_time = time.perf_counter() self.o.draw.rectangle((0, 0, self.o.width, self.o.height), outline=0, fill=self.o.blue) self.mstime = (pygame.time.get_ticks() - self.birth) self.time = int(self.mstime * .001) if self.time > self.mult_state: self.mult_state += 3 if self.speed_mult < 2.5: self.speed_mult += self.speed_mult_inc if self.enemy_spawn_delay > 1000: self.enemy_spawn_delay -= 50 self.enemy_spawner() self.draw_bullets() self.draw_enemies() self.draw_explodes() self.player.update(self.delta) self.draw_sidebar() self.o.update_display(self.o) def draw_bullets(self): for x in self.bullets: x.check_collision() x.update() x.draw() def draw_enemies(self): for x in self.enemies: x.check_collision() x.update() x.draw() def draw_explodes(self): for x in self.explodes: x.update() x.draw() def draw_sidebar(self): w = self.o.width - self.sidebar_width self.o.draw.rectangle((w, 0, self.o.width, self.o.height), outline=0, fill=self.o.light_grey) inc = 40 h = 10 self.o.center_block("Score", self.o.h2, [w, h, self.o.width, h + 10], self.o.blue) h += inc self.o.center_block(str(self.score), self.o.h2, [w, 15, self.o.width, h + 10], self.o.blue) h += (inc * 2) self.o.center_block("Time", self.o.h2, [w, 30, self.o.width, h + 10], self.o.blue) h += inc self.o.center_block(str(self.time), self.o.h2, [w, 40, self.o.width, h + 10], self.o.blue) def enemy_spawner(self): sl = pygame.time.get_ticks() - self.last_enemy_spawn if len(self.enemies) < 1 or sl > self.enemy_spawn_delay: new_e = Enemy(self.o, self) self.enemies.append(new_e) self.last_enemy_spawn = pygame.time.get_ticks() def save_highscore(self): base_dir = "/home/pi/zpc_ct/" title = "defender_scores" fname = base_dir + title + '.sco' if os.path.exists(fname): os.utime(fname, None) else: open(fname, 'a').close() self.sconf = ConfigObj(fname) self.sconf['name1'] = self.hs_n1 self.sconf['name2'] = self.hs_n2 self.sconf['name3'] = self.hs_n3 self.sconf['score1'] = self.hs_s1 self.sconf['score2'] = self.hs_s2 self.sconf['score3'] = self.hs_s3 self.sconf.write() def load_highscore(self): base_dir = "/home/pi/zpc_ct/" self.sconf = ConfigObj(base_dir + 'defender_scores.sco') self.hs_n1 = self.sconf['name1'] self.hs_n2 = self.sconf['name2'] self.hs_n3 = self.sconf['name3'] self.hs_s1 = self.sconf.as_int('score1') self.hs_s2 = self.sconf.as_int('score2') self.hs_s3 = self.sconf.as_int('score3') class Player: def __init__(self, o, game): self.o = o self.game = game self.width = 28 self.height = 12 self.speed = 80 self.posx = game.gw / 2 self.posy = o.height - self.height def update(self, delta): self.check_keys(delta) self.draw_player() def draw_player(self): hw = self.width / 2 hh = self.height / 2 self.o.draw.rectangle(((self.posx - hw), (self.posy - hh), (self.posx + hw), (self.posy + hh)), outline=self.o.light_grey, fill=self.o.light_grey) self.o.draw.rectangle(((self.posx - (hw/4)), (self.posy - self.height), (self.posx + (hw/4)), (self.posy + hh)), outline=self.o.light_grey, fill=self.o.light_grey) def check_keys(self, delta): if self.o.keyState[0] == 2: if self.posx > 0: self.posx -= self.speed * delta elif self.o.keyState[3] == 2: if self.posx < self.o.width: self.posx += self.speed * delta elif self.o.keyState[1] == 1 or self.o.keyState[2] == 1: self.game.bullets.append(Bullet(self.o, self.game, self.posx)) self.o.defender_sounds[0].set_volume(self.o.volume / 16) pygame.mixer.Sound.play(self.o.defender_sounds[0]) # if self.file != None: # if vol != 0: # vol = (vol / 16) * (self.volume / 16) * (self.o.volume / 16) # self.mixerSound.set_volume(vol) # pygame.mixer.Sound.play(self.mixerSound) class Bullet: def __init__(self, o, game, x): self.o = o self.game = game self.posx = x self.posy = 110 self.width = 3 self.height = 10 def draw(self): hw = self.width / 2 hh = self.height / 2 self.o.draw.rectangle(((self.posx - hw), (self.posy - hh), (self.posx + hw), (self.posy + hh)), outline=0, fill=self.o.light_grey) def update(self): self.posy -= self.game.bullet_speed * self.game.delta if self.posy < 0: self.game.bullets.remove(self) self.draw() def check_collision(self): pass class Enemy: def __init__(self, o, game): self.o = o self.game = game self.posx = game.gw / 2 self.posy = -20 self.width = 20 self.height = 15 self.speed = random.randrange(15, 30) * game.speed_mult self.xspeed = random.randrange(0, 30) * game.speed_mult self.point_value = 50 self.ydir = random.choice([-1, 1]) def draw(self): hw = self.width / 2 hh = self.height / 2 self.o.draw.rectangle(((self.posx - hw), (self.posy - hh), (self.posx + hw), (self.posy + hh)), outline=self.o.light_grey, fill=self.o.light_grey) self.o.draw.rectangle(((self.posx - hw + 5), (self.posy - hh + 10), (self.posx + hw - 5), (self.posy + hh)), outline=self.o.blue, fill=self.o.blue) self.o.draw.rectangle(((self.posx - 8), (self.posy - 4), (self.posx - 2), (self.posy - 3)), outline=self.o.blue, fill=self.o.blue) self.o.draw.rectangle(((self.posx + 8), (self.posy - 4), (self.posx + 2), (self.posy - 3)), outline=self.o.blue, fill=self.o.blue) def update(self): self.posy += self.speed * self.game.delta self.posx += (self.xspeed * self.ydir * self.game.delta) self.check_collision() if self.posy > self.o.height: self.game.enemies.remove(self) self.o.defender_sounds[2].set_volume(self.o.volume / 16) pygame.mixer.Sound.play(self.o.defender_sounds[2]) self.game.game_over = True if self.posx > (self.game.gw - (self.width / 2)): self.ydir = -1 elif self.posx < (0 + (self.width / 2)): self.ydir = 1 self.draw() def check_collision(self): for b in self.game.bullets: xdist = abs(b.posx - self.posx) if xdist < self.width / 2: ydist = abs(b.posy - self.posy) if ydist < self.height / 2: #print('hit ', xdist) self.game.score += self.point_value if b in self.game.bullets: self.game.bullets.remove(b) self.die() self.o.defender_sounds[1].set_volume(self.o.volume / 16) pygame.mixer.Sound.play(self.o.defender_sounds[1]) def die(self): if self in self.game.enemies: self.game.enemies.remove(self) self.game.explodes.append(Explode(self.o, self.game, self.posx, self.posy)) class Explode: def __init__(self, o, game, x, y): self.o = o self.game = game self.posx = x self.posy = y self.width = 16 self.height = 14 self.gap = 5 self.scale_speed = 80 def draw(self): hw = self.width / 2 hh = self.height / 2 c1 = [self.posx + self.gap, self.posy - self.gap] c2 = [self.posx - self.gap, self.posy - self.gap] c3 = [self.posx + self.gap, self.posy + self.gap] c4 = [self.posx - self.gap, self.posy + self.gap] self.o.draw.rectangle(((c1[0] - hw), (c1[1] - hh), (c1[0] + hw), (c1[1] + hh)), outline=0, fill=self.o.light_grey) self.o.draw.rectangle(((c2[0] - hw), (c2[1] - hh), (c2[0] + hw), (c2[1] + hh)), outline=0, fill=self.o.light_grey) self.o.draw.rectangle(((c3[0] - hw), (c3[1] - hh), (c3[0] + hw), (c3[1] + hh)), outline=0, fill=self.o.light_grey) self.o.draw.rectangle(((c4[0] - hw), (c4[1] - hh), (c4[0] + hw), (c4[1] + hh)), outline=0, fill=self.o.light_grey) def update(self): #self.posy -= self.game.bullet_speed * self.game.delta self.gap += self.game.explode_speed * self.game.delta self.width -= self.scale_speed * self.game.delta self.height -= self.scale_speed * self.game.delta if self.gap > 20: self.game.explodes.remove(self) print('killing explosion ', len(self.game.explodes)) self.draw() def check_collision(self): pass #==================================== State = type("State", (object,), {}) #==================================== class State(object): def __init__(self, FSM): self.FSM = FSM self.timer = 0 self.startTime = 0 def Enter(self): self.timer = 0 self.startTime = 0 def Execute(self): print('Executing') def Exit(self): print('Exiting') #==================================== class Example(State): def __init__(self,FSM): super(Example, self).__init__(FSM) def Enter(self): self.FSM.stateLife = 1 super(Example, self).Enter() def Execute(self): self.FSM.stateLife += 1 def Exit(self): pass #==================================== class Startup(State): def __init__(self,FSM): super(Startup, self).__init__(FSM) def Enter(self): self.FSM.stateLife = 1 self.birth = time.perf_counter() super(Startup, self).Enter() def Execute(self): print('defender startup state') self.FSM.ToTransition('toIntro') def Exit(self): pass #==================================== class Intro(State): def __init__(self,FSM): super(Intro, self).__init__(FSM) def Enter(self): self.birth = time.perf_counter() o = self.FSM.owner o.draw.rectangle((0, 0, o.width, o.height), outline=0, fill=o.blue) o.center_block("Welcome To Defender", o.h2, [0, 0, o.width, o.height], o.light_grey) o.update_display(0) super(Intro, self).Enter() def Execute(self): if (time.perf_counter() - self.birth) > 2: print('time is up') self.FSM.queued_state = "toMain" self.FSM.ToTransition('toBlueFade') def Exit(self): pass #==================================== #==================================== class Main(State): def __init__(self,FSM): super(Main, self).__init__(FSM) def Enter(self): print('hello defender main') o = self.FSM.owner o.draw.rectangle((0, 0, o.width, o.height), outline=0, fill=o.blue) o.update_display(0) self.game = Game(o) o.game = self.game super(Main, self).Enter() def Execute(self): self.game.update() if self.game.game_over: self.FSM.queued_state = "toGameOver" self.FSM.ToTransition('toBlueFade') def Exit(self): pass #==================================== class BlueFade(State): def __init__(self,FSM): super(BlueFade, self).__init__(FSM) def Enter(self): self.FSM.stateLife = 1 self.birth = pygame.time.get_ticks() self.last_frame_time = time.perf_counter() self.o = self.FSM.owner self.x = self.o.width / 2 self.y = self.o.height / 2 self.xsize = 0.0 self.ysize = 0.0 super(BlueFade, self).Enter() def Execute(self): self.FSM.stateLife += 1 self.delta = time.perf_counter() - self.last_frame_time self.last_frame_time = time.perf_counter() self.o.draw.rectangle((self.x - self.xsize, self.y - self.ysize, self.x + self.xsize, self.y + self.ysize), outline=self.o.blue, fill=self.o.blue) self.o.update_display(self.o) self.xsize += self.delta * 150 self.ysize += self.delta * 125 if (pygame.time.get_ticks() - self.birth > 1000): if self.FSM.queued_state != None: ns = self.FSM.queued_state self.FSM.queued_state = None self.FSM.ToTransition(ns) def Exit(self): pass #==================================== class GreyFade(State): def __init__(self,FSM): super(GreyFade, self).__init__(FSM) def Enter(self): self.FSM.stateLife = 1 self.birth = pygame.time.get_ticks() self.last_frame_time = time.perf_counter() self.o = self.FSM.owner self.x = self.o.width / 2 self.y = self.o.height / 2 self.xsize = 0.0 self.ysize = 0.0 super(GreyFade, self).Enter() def Execute(self): self.FSM.stateLife += 1 self.delta = time.perf_counter() - self.last_frame_time self.last_frame_time = time.perf_counter() self.o.draw.rectangle((self.x - self.xsize, self.y - self.ysize, self.x + self.xsize, self.y + self.ysize), outline=self.o.light_grey, fill=self.o.light_grey) self.o.update_display(self.o) self.xsize += self.delta * 150 self.ysize += self.delta * 125 if (pygame.time.get_ticks() - self.birth > 1000): print('get outta fade') if self.FSM.queued_state != None: ns = self.FSM.queued_state self.FSM.queued_state = "toMain" self.FSM.ToTransition(ns) def Exit(self): pass #==================================== class GameOver(State): def __init__(self,FSM): super(GameOver, self).__init__(FSM) def Enter(self): self.FSM.stateLife = 1 self.o = self.FSM.owner self.birth = pygame.time.get_ticks() self.o.draw.rectangle((0, 0, self.o.width, self.o.height), outline=0, fill=self.o.blue) self.o.center_block("Game Over", self.o.h2, [0, 0, self.o.width, self.o.height], self.o.light_grey) self.o.center_block("Score: " + str(self.o.game.score), self.o.h2, [0, 20, self.o.width, self.o.height + 20], self.o.light_grey) self.o.update_display(0) super(GameOver, self).Enter() def Execute(self): if self.o.keyState[0] == 1: self.FSM.queued_state = "toMain" self.FSM.ToTransition('toBlueFade') if (pygame.time.get_ticks() - self.birth) > 3000: if self.o.game.score > self.o.game.hs_s1: print('this is a new high score') self.FSM.queued_state = "toNewHighScore" else: print('not a new high score') self.FSM.queued_state = "toHighScore" self.FSM.ToTransition('toBlueFade') def Exit(self): pass #==================================== class HighScore(State): def __init__(self,FSM): super(HighScore, self).__init__(FSM) def Enter(self): self.o = self.FSM.owner self.o.draw.rectangle((0, 0, self.o.width, self.o.height), outline=0, fill=self.o.blue) self.o.center_text("HIGH SCORES", self.o.h1, self.o.width, 25, self.o.light_grey) self.o.center_text("----------------------", self.o.h2, self.o.width, 55, self.o.light_grey) self.o.center_block(self.o.game.hs_n3 + ': ' + str(self.o.game.hs_s3), self.o.h2, [0, -20, self.o.width, self.o.height-20], self.o.light_grey) self.o.center_block(self.o.game.hs_n2 + ': ' + str(self.o.game.hs_s2), self.o.h2, [0, 0, self.o.width, self.o.height], self.o.light_grey) self.o.center_block(self.o.game.hs_n1 + ': ' + str(self.o.game.hs_s1), self.o.h2, [0, 20, self.o.width, self.o.height+20], self.o.light_grey) self.o.center_block("restart", self.o.h2, [0, 50, self.o.width, self.o.height + 50], self.o.light_grey) self.o.update_display(0) super(HighScore, self).Enter() def Execute(self): if self.o.keyState[0] == 1 or self.o.keyState[1] == 1 or self.o.keyState[2] == 1 or self.o.keyState[3] == 1: self.FSM.queued_state = "toMain" self.FSM.ToTransition('toBlueFade') def Exit(self): pass #==================================== class NewHighScore(State): def __init__(self,FSM): super(NewHighScore, self).__init__(FSM) def Enter(self): self.birth = time.perf_counter() o = self.FSM.owner o.draw.rectangle((0, 0, o.width, o.height), outline=0, fill=o.blue) o.center_block("NEW HIGH SCORE!", o.h2, [0, 0, o.width, o.height], o.light_grey) o.update_display(0) super(NewHighScore, self).Enter() def Execute(self): if (time.perf_counter() - self.birth) > 2: self.FSM.queued_state = "toEnterText" self.FSM.ToTransition('toBlueFade') def Exit(self): pass #==================================== class EnterText(State): def __init__(self,FSM): super(EnterText, self).__init__(FSM) def Enter(self): o = self.FSM.owner self.input_string = "" self.last_action = pygame.time.get_ticks() self.caps = False self.cur_but = 18 self.cur_letter = "" self.skips = [7, 3, 11, 12, 13, 14, 15] self.lc_labels = [["p", "q", "r", "s"], ["t", "u", "v"], ["w", "x", "y", "z"], ["C", "A", "P", "S"], ["g", "h", "i"], ["j", "k", "l"], ["m", "n", "o"], ["D", "E", "L"], ["_", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-"], ["a", "b", "c"], ["d", "e", "f"], ["O", "K"], [], [], [], []] self.uc_labels = [["P", "Q", "R", "S"], ["T", "U", "V"], ["W", "X", "Y", "Z"], ["C", "A", "P", "S"], ["G", "H", "I"], ["J", "K", "L"], ["M", "N", "O"], ["D", "E", "L"], ["_", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-"], ["A", "B", "C"], ["D", "E", "F"], ["O", "K"], [], [], [], []] self.labels = self.lc_labels self.cycles = [] for l in self.labels: self.cycles.append(cycle(l)) self.draw(o) o.update_display(0) super(EnterText, self).Enter() def Execute(self): o = self.FSM.owner y_size = o.height / 4 if o.keyState[11] == 1: if self.input_string != 'blank': o.game.hs_name = self.input_string if o.game.score > o.game.hs_s3: print('new first') o.game.hs_s1 = o.game.hs_s2 o.game.hs_n1 = o.game.hs_n2 o.game.hs_s2 = o.game.hs_s3 o.game.hs_n2 = o.game.hs_n3 o.game.hs_s3 = o.game.score o.game.hs_n3 = o.game.hs_name elif o.game.score > o.game.hs_s2: print('new second') o.game.hs_s1 = o.game.hs_s2 o.game.hs_n1 = o.game.hs_n2 o.game.hs_s2 = o.game.score o.game.hs_n2 = o.game.hs_name else: print('new third') o.game.hs_s1 = o.game.score o.game.hs_n1 = o.game.hs_name print('new high score saving') self.FSM.queued_state = 'toHighScore' self.FSM.ToTransition('toBlueFade') o.game.save_highscore() if o.keyState[16] > 0 and o.keyState[17] > 0: pass else: _iter = 0 for k in o.keyState: if k == 1: cur_time = pygame.time.get_ticks() if _iter not in self.skips: self.last_action = cur_time self.cur_letter = next(self.cycles[_iter]) self.cur_but = _iter self.draw(o) o.center_block(self.input_string + self.cur_letter, o.h2, [0, 0, o.width, y_size], o.light_grey) if _iter == 7: self.input_string = self.input_string[:-1] print('deleting') self.last_action = 100000000 self.draw(o) o.center_block(self.input_string, o.h2, [0, 0, o.width, y_size], o.light_grey) elif _iter == 3: print('caps') if self.caps: self.caps = False self.labels = self.lc_labels else: self.caps = True self.labels = self.uc_labels self.draw(o) o.center_block(self.input_string, o.h2, [0, 0, o.width, y_size], o.light_grey) self.cycles = [] for l in self.labels: self.cycles.append(cycle(l)) o.update_display(0) _iter += 1 cur_time = pygame.time.get_ticks() delay = cur_time - self.last_action if delay > 1000 and delay < 100000: self.input_string += self.cur_letter self.last_action = 100000000 self.reset_cycles() self.draw(o) o.center_block(self.input_string, o.h2, [0, 0, o.width, y_size], o.light_grey) o.update_display(0) def draw(self, o): x_size = o.width / 4 y_size = o.height / 4 og_x = 0 o_x = og_x o_y = o.height text_padding = 6 _id = 0 while _id < 16: lab = "" for i in self.labels[_id]: lab += i if _id == 8: lab = "_12" o.draw.rectangle((o_x, o_y, o_x + x_size, o_y - y_size), outline=0, fill=o.blue) o.center_block(lab, o.h2, [o_x, o_y, o_x + x_size, o_y - y_size], o.light_grey) o_x = o_x + x_size _id += 1 if _id % 4 == 0: o_y -= y_size o_x = og_x o.draw.rectangle((0, 0, o.width, y_size), outline=0, fill=o.blue) def reset_cycles(self): self.cycles = [] for l in self.labels: self.cycles.append(cycle(l)) def Exit(self): pass #==================================== def timer_event(): pass