Initial commit from version 1e-99
[beatscape.git] / keygraph.py
1 import pygame
2 from bmevent import *
3 from keyhandler import *
4 from keyfile import BMEListIter
5 from fx import ColumnPulse
6 from constants import *
7
8 red = (255,30,30)
9 offwhite = (245,245,245)
10 blue = (30,30,255)
11 black = (0,0,0)
12 darkgray = (20,20,20)
13
14 class KeyGraph:
15         keyfile = None
16         t = 0
17         b = 0
18         velocity = 150.0
19         li = None
20         bordercolor = (255,255,255)
21         judgemapping = {JUDGE_FGREAT: ["gfx/great.png","gfx/fgreat.png"],
22                         JUDGE_GREAT: ["gfx/great.png"],
23                         JUDGE_GOOD: ["gfx/good.png"],
24                         JUDGE_BAD: ["gfx/bad.png"],
25                         JUDGE_POOR: ["gfx/poor.png"],
26                         JUDGE_NA: []}
27         colmarkmap = {JUDGE_FGREAT: "gfx/dcircle.png",
28                       JUDGE_GREAT: "gfx/circle.png",
29                       JUDGE_GOOD: "gfx/triangle.png",
30                       JUDGE_BAD: "gfx/cross.png",
31                       JUDGE_POOR: "gfx/cross.png",
32                       JUDGE_NA: None}
33         numberfiles = ["gfx/glyph/0.png","gfx/glyph/1.png","gfx/glyph/2.png","gfx/glyph/3.png","gfx/glyph/4.png","gfx/glyph/5.png","gfx/glyph/6.png","gfx/glyph/7.png","gfx/glyph/8.png","gfx/glyph/9.png"]
34         
35         def __init__(self, kf, keystyle, player, disprect):
36                 self.numkeys = len(keystyle)
37                 self.keyfile = kf
38                 self.screen = pygame.display.get_surface()
39                 self.disprect = disprect
40                 self.vheight = disprect.height - 5;
41                 self.barrect = pygame.Rect(disprect.left,
42                                            disprect.bottom - 4,
43                                            disprect.width,
44                                            5)
45                 if player == 1:
46                         self.notefilter = BME_NOTE1
47                 elif player == 2:
48                         self.notefilter = BME_NOTE2
49                 else:
50                         print "Invalid player given to keygraph: " + kf
51                         exit(1)
52                 self.t = 0
53                 self.b = 0
54                 self.li = BMEListIter(self.keyfile.bmelist)
55                 self.keystyle = []
56
57                 w = 0
58                 tw = sum(map(lambda x: x[0],keystyle))
59                 for x in keystyle:
60                         self.keystyle.append((int(w),x[1],x[2]))
61                         w += (x[0] / tw) * (disprect.width - 1)
62                 self.keystyle.append((int(w),None,None))
63
64                 # Load gfx
65                 self.judgeimg = {}
66                 for k in self.judgemapping.keys():
67                         self.judgeimg[k] = map(lambda y: pygame.image.load(y).convert_alpha(),self.judgemapping[k])
68                 self.colmarkimg = {}
69                 for k in self.colmarkmap.keys():
70                         if self.colmarkmap[k]:
71                                 self.colmarkimg[k] = pygame.image.load(self.colmarkmap[k]).convert_alpha()
72                         else:
73                                 self.colmarkimg[k] = None
74                 self.colmarkimg[0] = None
75                 self.numberimg = map(lambda y: pygame.image.load(y).convert_alpha(),self.numberfiles)
76                 self.judgement = 0
77                 self.kjudgement = [0 for x in range(0,self.numkeys)]
78                 self.judgetime = 0
79                 self.kjudgetime = [0 for x in range(0,self.numkeys)]
80                 self.combo = 0
81
82                 # Initialize keypulses (they are neat)
83                 self.pulse = []
84                 for n in range(0,len(keystyle)):
85                         x = self.keystyle[n][0] + 1
86                         y = self.disprect.top + 0.3 * self.disprect.height
87                         w = self.keystyle[n+1][0] - self.keystyle[n][0] - 1
88                         h = 0.7 * self.disprect.height - 4
89                         self.pulse.append(ColumnPulse(pygame.Rect(x,y,w,h),keystyle[n][3]))
90                 self.accuracy = 0
91                 self.key = 0
92
93         def setproperties(self,properties):
94                 try:
95                         ud = properties['ud']
96                         k = properties['key']
97                         if ud == 1:
98                                 self.pulse[k].down()
99                         else:
100                                 self.pulse[k].up()
101                         self.key = k
102                 except KeyError:
103                         pass
104
105                 try:
106                         self.judgement = properties['judgement']
107                         self.kjudgement[self.key] = properties['judgement']
108                         self.judgetime = self.t
109                         self.kjudgetime[self.key] = self.t
110                         if self.judgement <= JUDGE_GOOD:
111                                 self.combo += 1
112                         else:
113                                 self.combo = 0
114                 except KeyError:
115                         pass
116
117                 try:
118                         self.accuracy = properties['accuracy']
119                 except KeyError:
120                         pass
121
122         def numimgs(self,n):
123                 imgs = []
124                 while n:
125                         imgs.append(self.numberimg[n % 10])
126                         n = n / 10
127                 imgs.reverse()
128                 return imgs
129
130         def draw(self):
131                 self.b = self.keyfile.eval_beatfunc(self.t)
132                 for n in range(0,self.numkeys):
133                         x = self.disprect.left + self.keystyle[n][0]
134                         w = self.keystyle[n+1][0] - self.keystyle[n][0]
135                         self.screen.fill(self.keystyle[n][2],
136                                 (x,self.disprect.top,w,self.disprect.height))
137                 for n in range(0,self.numkeys+1):
138                         pygame.draw.line(self.screen, self.bordercolor,
139                                 (self.disprect.left + self.keystyle[n][0], self.disprect.top),
140                                 (self.disprect.left + self.keystyle[n][0], self.disprect.bottom - 1) )
141
142                 self.li.goto(self.b)
143                 keylist = self.li.window(self.vheight / self.velocity, self.notefilter)
144                 pygame.draw.rect(self.screen, (255,0,0), self.barrect)
145                 distortion = 1.0
146                 for k in keylist:
147                         y = self.disprect.top + self.vheight - int((k.beat - self.b) * (self.velocity / distortion))
148                         x = self.disprect.left + self.keystyle[k.key][0] + 1
149                         w = self.keystyle[k.key+1][0] - self.keystyle[k.key][0] - 1
150                         pygame.draw.rect(self.screen, self.keystyle[k.key][1], (x,y,w,5) )
151                 for n in self.pulse:
152                         n.draw()
153
154                 if self.judgement:
155                         if self.t - self.judgetime > 500:
156                                 self.judgement = 0
157                         elif len(self.judgeimg[self.judgement]) == 0:
158                                 pass
159                         else:
160                                 z = (self.t / 60) % len(self.judgeimg[self.judgement])
161                                 w = self.judgeimg[self.judgement][z].get_width()
162                                 x = self.disprect.left + (self.disprect.width / 2) - (w / 2)
163                                 y = self.disprect.top + self.disprect.height * 0.7
164                                 if self.combo >= 2:
165                                         imgs = self.numimgs(self.combo)
166                                         x -= 2
167                                         w += 4
168                                         for i in imgs:
169                                                 x -= i.get_width() / 2
170                                         for i in imgs:
171                                                 self.screen.blit(i,(x + w,y))
172                                                 w += i.get_width()
173                                 self.screen.blit(self.judgeimg[self.judgement][z],(x,y))
174                                 # Draw accuracy bar
175                                 x = self.disprect.left + self.disprect.width / 2
176                                 y += 50
177                                 dx = self.accuracy
178                                 if dx < 0:
179                                         x += dx
180                                         dx = -dx
181                                 self.screen.fill((255,0,0), (x,y,dx,3))
182                 for i in range(0,self.numkeys):
183                         if self.t - self.kjudgetime[i] > 300:
184                                 self.kjudgement[i] = 0
185                         else:
186                                 x = self.disprect.left + self.keystyle[i][0] + (self.keystyle[i+1][0] - self.keystyle[i][0] - 24) / 2
187                                 y = self.disprect.bottom - 30
188                                 if self.colmarkimg[self.kjudgement[i]]:
189                                         self.screen.blit(self.colmarkimg[self.kjudgement[i]],(x,y))