Прикреплённый файл «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 из ссылки «[получить]», так как он чисто внутренний и может измениться.- [получить | показать] (2014-02-21 14:06:47, 6.6 KB) [[attachment:2014-02-07-flyword.py]]
- [получить | показать] (2014-02-21 14:06:35, 1.3 KB) [[attachment:2014-02-07-safeinput.py]]
Вам нельзя прикреплять файлы к этой странице.