Прикреплённый файл «2014-02-07-flyword.py»

Загрузка

   1 #!/usr/bin/env python
   2 # coding: utf
   3 '''
   4 Задача: написать на клавиатуре или показать мышкой все буквы слова в верном порядке
   5 Каждый успех увеличивает скорость и бонусы, каждый промах — штраф
   6 Если штрвф зашкаливает — конец игры 
   7 '''
   8 
   9 import pygame, random, sys
  10 
  11 # откроем первый попавшийся файл со словами
  12 for w in "words", "/usr/share/dict/words":
  13     try:
  14         words = file(w).read().split()
  15         break
  16     except:
  17         pass
  18 else:
  19     print "No 'words' file"
  20     sys.exit(1)
  21 
  22 size = 600,600
  23 pygame.init()
  24 scr = pygame.display.set_mode(size)
  25 font = pygame.font.Font(None, 72)
  26 white = pygame.Color("white")
  27 light = pygame.Color("tan")
  28 black = pygame.Color("black")
  29 red = pygame.Color("tomato")
  30 green = pygame.Color("limegreen")
  31 noevent=pygame.event.Event(pygame.NOEVENT)
  32 
  33 class Letter:
  34     '''Изображение-буква'''
  35     def __init__(self, c, font, color):
  36         self.char = c
  37         self.font = font
  38         self.color = color
  39         self.speed = random.random()*2-1,random.random()*2-1
  40         self.pos = 0,0
  41         self.refresh()
  42 
  43     def refresh(self, **attrs):
  44         '''Перерисовать букву'''
  45         for a,v in attrs.items():
  46             if hasattr(self, a):
  47                 setattr(self, a, v)
  48             else:
  49                 print >> sys.stderr, "Warning: unknown Letter attribute:",a
  50         self.surface = self.font.render(self.char,True,self.color)
  51 
  52 def int2(seq): return int(seq[0]), int(seq[1])
  53 
  54 class Game:
  55     '''Игровой процесс. Класс используется как контейнер глобальных имён'''
  56     NEWGAMEBONUS = 100
  57     def __init__(self):
  58         self.bg = black
  59         self.fg = white
  60         self.sg = red
  61         self.bonus = 0
  62         self.rounds = 1
  63 
  64     def __make_letters__(self, word, font, color):
  65         '''Внутренняя функция: сгенерировать список букв-картинок из слова'''
  66         self.word = word
  67         self.letters = [Letter(c, font, color) for c in self.word]
  68         w = sum(l.surface.get_width() for l in self.letters)
  69         x,y = (scr.get_width()-w)/2,(scr.get_height()-font.get_height())/2
  70         for l in self.letters:
  71             l.pos=x,y
  72             x+=l.surface.get_width()
  73 
  74     def start(self, state, word, font, color, timer=50, speed=3.):
  75         '''Начать очередную игру'''
  76         self.__make_letters__(word, font, color)
  77         self.stopped_letters=[]
  78         self.state = state
  79         self.timer = timer
  80         self.speed = speed
  81         self.again = True
  82         self.journal = []
  83         self.bonus += self.NEWGAMEBONUS
  84         pygame.time.set_timer(pygame.USEREVENT, self.timer)
  85 
  86     def stop(self):
  87         '''Остановить игру'''
  88         pygame.time.set_timer(pygame.USEREVENT, 0)
  89 
  90 game = Game()
  91 
  92 class BasicState:
  93     '''Игровое состояние: общие методы'''
  94     def __init__(self):
  95         self.font = pygame.font.Font(None, 36)
  96         self.c_bonus = light
  97         self.c_letter = white
  98         self.c_catch = green
  99         self.c_miss = red
 100         self.border = 2
 101 
 102     def redraw(self):
 103         '''Отобразить состояние игры'''
 104         scr.fill(game.bg)
 105         for l in game.letters+game.stopped_letters:
 106             scr.blit(l.surface, int2(l.pos))
 107         score = self.font.render(str(game.bonus), True, self.c_bonus)
 108         scr.blit(score, (self.border, self.border))
 109         score = self.font.render(str(game.rounds), True, self.c_bonus)
 110         scr.blit(score, (scr.get_width()-score.get_width()-self.border, self.border))
 111 
 112     def loop(self, event):
 113         '''Обработка событий'''
 114         if event.type == pygame.QUIT:
 115             game.again = False
 116         else:
 117             return event
 118         return noevent
 119 
 120     def recalc(self):
 121         '''Пересчёт игрового мира'''
 122         for l in game.letters:
 123             if not scr.get_rect().colliderect(int2(l.pos),l.surface.get_size()):
 124                 game.journal.append(("away",l))
 125 
 126     def logic(self):
 127         '''Изменить игровой мир'''
 128         for act, l in game.journal:
 129             if act == "away":
 130                 game.letters.remove(l)
 131         if not game.letters:
 132             game.again = False
 133         game.journal=[]
 134 
 135 def locate(ls,pos):
 136     '''Найти элемент списка букв по позиции или по букве'''
 137     if type(pos) is unicode:    # буква
 138         for l in ls:
 139             if l.char == pos:
 140                 return l
 141     else:                       # координаты
 142         for l in ls:
 143             if pygame.Rect(l.pos,l.surface.get_size()).collidepoint(pos):
 144                 return l
 145     return None
 146 
 147 class GameState(BasicState):
 148     '''Игровое состояние'''
 149 
 150     def loop(self, event):
 151         event = BasicState.loop(self, event)
 152         l = None
 153         if event.type == pygame.MOUSEBUTTONDOWN:
 154             l = locate(game.letters, event.pos)
 155             if l: game.journal.append(("catch", l))
 156         elif event.type == pygame.KEYDOWN and event.unicode:
 157             l = locate(game.letters, event.unicode)
 158             game.journal.append(("catch", l))
 159         else:
 160             return event
 161         return noevent
 162 
 163     def recalc(self):
 164         '''Пересчитать игровой мир'''
 165         for l in game.letters:
 166             l.pos = l.pos[0]+game.speed*l.speed[0],l.pos[1]+game.speed*l.speed[1]
 167         BasicState.recalc(self)
 168 
 169     def logic(self):
 170         for act, l in game.journal:
 171             if act == "catch":
 172                 if not l:
 173                     # TODO штраф 1
 174                     pass
 175                 else:
 176                     if l.char==game.letters[0].char:
 177                         # TODO бонус 1
 178                         l=game.letters.pop(0)
 179                         l.refresh(color=self.c_catch)
 180                     else:
 181                         # TODO штраф 2
 182                         game.letters.remove(l)
 183                         l.refresh(color=self.c_miss)
 184                     game.stopped_letters.append(l)
 185         BasicState.logic(self)
 186         # TODO: change state
 187         if not game.letters:
 188             game.again = False
 189 
 190 gen = GameState()
 191 game.start(gen, random.choice(words), font, white, speed=1.5)
 192 while game.again:
 193     bang = None
 194     event = game.state.loop(pygame.event.wait())
 195     if event.type == pygame.USEREVENT:
 196         game.state.recalc()
 197     game.state.logic()
 198     game.state.redraw()
 199     pygame.display.flip()

Прикреплённые файлы

Для ссылки на прикреплённый файл в тексте страницы напишите attachment:имяфайла, как показано ниже в списке файлов. Не используйте URL из ссылки «[получить]», так как он чисто внутренний и может измениться.

Вам нельзя прикреплять файлы к этой странице.