Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 867 lines (740 sloc) 31.123 kb
b68496b4 »
2012-07-03 first commit
1 #!/usr/bin/env python
2 # a snakey clone using pygame
3
4 import random, pygame, sys
5 from pygame.locals import *
6
7 FPS = 12
8 WINDOWWIDTH = 640
9 WINDOWHEIGHT = 480
10 CELLSIZE = 20
11 assert WINDOWWIDTH % CELLSIZE == 0, "Window width must be a multiple of cell size."
12 assert WINDOWHEIGHT % CELLSIZE == 0, "Window height must be a multiple of cell size."
13 CELLWIDTH = int(WINDOWWIDTH / CELLSIZE)
14 CELLHEIGHT = int(WINDOWHEIGHT / CELLSIZE)
15
16 #colors
17 WHITE = (255, 255, 255)
18 BLACK = (0, 0, 0)
19 RED = (255, 0, 0)
20 GREEN = (0, 255, 0)
21 BLUE = (0, 0, 255)
22 DARKGRAY = (40, 40, 40)
23
24 #snake colors
25 HONEYDEW = (240, 255, 240)
26 MINTGREEN = (189, 252, 201)
27 SEAGREEN = (84, 255, 159)
28 EMERALDGREEN = (0, 201, 87)
29 FORESTGREEN = (34, 139, 34)
30 COBALTGREEN = (61, 145, 64)
31 GREENYELLOW = (173, 255, 47)
32 OLIVEGREEN = (107, 142, 35)
33 IVORY = (205, 205, 193)
34 LIGHTYELLOW = (238, 238, 209)
35 YELLOW = (238, 238, 0)
36 KHAKI = (255, 246, 143)
37 GOLDENROD = (218, 165, 32)
38 CORAL = (255, 127, 80)
39 SIENNA = (255, 130, 71)
40
41 #other
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
42 ORANGE = (255, 127, 0)
b68496b4 »
2012-07-03 first commit
43 PURPLE = (142, 56, 142)
44 MAROON = (255, 52, 179)
45
46 BGCOLOR = BLACK
47
48 UP = 'up'
49 DOWN = 'down'
50 LEFT = 'left'
51 RIGHT = 'right'
52
53 HEAD = 0 #index of snake's head
54
55 # fruit time remains on screen
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
56 POISONTIMER = (100,200)
57 ORANGETIMER = (35,65)
58 RASPBERRYTIMER = (30,45)
59 BLUEBERRYTIMER = (20,40)
60 LEMONTIMER = (100,100)
61
62 POISONBONUS = 7
63 ORANGEBONUS = 8
64 RASPBERRYBONUS = 9
65 BLUEBERRYBONUS = 10
66 LEMONBONUS = 11
b68496b4 »
2012-07-03 first commit
67
68
69 class Snake:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
70 """
71 Snake class houses all information for a particular snake.
72 player - if snake is the player. Player snake is also referenced directly when player snake object is created.
73 alive - if snake is alive. Rather than delete, this allows snake to slowly shrink to the point of where it died.
74 coords - a list of dictionaries containing coordinates 'x' and 'y'. A special global variable HEAD (0).
75 direction - where snake moves for every game iteration ('left', 'up', etc).
76 color - body of snake's color.
77 colorBorder - outline of body.
78 growth - when a snake is to grow, this is stored in this buffer so that every game iteration can add one growth, only.
79 multiplier - all fruit eaten which cause points to be scored are multiplied by this.
80 multipliertimer - number of game iterations multiplier stays in effect.
81 score - the number of points snake has accumulated.
82 """
b68496b4 »
2012-07-03 first commit
83 def __init__(self, c=[{'x':5, 'y':5},{'x':4, 'y':5},{'x':3, 'y':5}], d=RIGHT, sc=GREEN, sb=COBALTGREEN):
84 self.player = False
85 self.alive = True
86 self.coords = c
87 # ensure snake length
88 assert len(self.coords) > 1
89 self.direction = d
90 self.color = sc
91 self.colorBorder = sb
92 self.growth = 0
93 self.multiplier = 1
94 self.multipliertimer = 0
95 self.score = 0
96
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
97 def updateDirection(self, direction_input):
98 """
99 This helps filter direction input to help ignore garbage direction input.
100 """
101 if direction_input == UP:
102 self.direction = UP
103 elif direction_input == DOWN:
104 self.direction = DOWN
105 elif direction_input == LEFT:
106 self.direction = LEFT
107 elif direction_input == RIGHT:
108 self.direction = RIGHT
109
110 def updateScore(self, points_input):
111 """
112 This updates score of snake, factoring multiplier.
113 """
114 self.score = self.score + (points_input * self.multiplier)
115
116 def updateGrowth(self, growth_input):
117 """
118 This updates growth "owed" to snake, allowing amount to stack.
119 """
120 self.growth = self.growth + growth_input
121
122 def updateMultiplier(self, multiplier_input, timer_input):
123 """
124 This updates multiplier value and time (game iterations) multiplier is active. Only time stacks.
125 """
126 # multiplier value does not stack, but time does
127 self.multiplier = multiplier_input
128 self.multipliertimer = self.multipliertimer + timer_input
129
130 def boundsCollision(self):
131 """
132 This returns True if snake (head) is ever out of grid parameters.
133 """
134 # check if out of bounds
135 if self.coords[HEAD]['x'] == -1 or self.coords[HEAD]['x'] == CELLWIDTH or self.coords[HEAD]['y'] == -1 or self.coords[HEAD]['y'] == CELLHEIGHT:
136 return True
137 else:
138 return False
139
140 def snakeCollision(self, snake):
141 """
142 This returns True if snake (head) collides with any part of a given snake (outside of own head if checking against self).
143 """
144 if self is snake:
145 # exclude head if checked against self
146 for snakebody in snake.coords[1:]:
147 if snakebody['x'] == self.coords[HEAD]['x'] and snakebody['y'] == self.coords[HEAD]['y']:
148 return True
149 else:
150 for snakebody in snake.coords:
151 if snakebody['x'] == self.coords[HEAD]['x'] and snakebody['y'] == self.coords[HEAD]['y']:
152 return True
153 # no collision
154 return False
155
156 def fruitCollision(self, fruit):
157 """
158 This returns True if snake (head) has collided with a given fruit.
159 """
160 if self.coords[HEAD]['x'] == fruit.coords['x'] and self.coords[HEAD]['y'] == fruit.coords['y']:
161 return True
162 else:
163 return False
164
165 def move(self):
166 """
167 This will update coords for snake, moving it one cell in given direction.
168 It also factors in and updates growth if any growth is "owed" snake (one per game iteration).
169 If snake is dead, will only remove the last segment of snake and ignore direction / not move snake.
170 """
171 if self.alive:
172 # delete last segment first.
173 if self.growth < 0:
174 self.growth = self.growth + 1
175 if len(self.coords) > 3:
176 # implement negative growth by removing last two segments
177 del self.coords[-2:]
178 else:
179 # snake is too short -- remove last segment as normal
180 del self.coords[-1]
181 elif self.growth > 0:
182 self.growth = self.growth - 1
183 # implement positive growth by not deleting last segment
184 else:
185 # no growth factor, delete last segment
186 del self.coords[-1]
187
188 # determine new head coordinates by direction
189 if self.direction == UP:
190 newhead = {'x': self.coords[HEAD]['x'], 'y': self.coords[HEAD]['y'] - 1}
191 elif self.direction == DOWN:
192 newhead = {'x': self.coords[HEAD]['x'], 'y': self.coords[HEAD]['y'] + 1}
193 elif self.direction == LEFT:
194 newhead = {'x': self.coords[HEAD]['x'] - 1, 'y': self.coords[HEAD]['y']}
195 elif self.direction == RIGHT:
196 newhead = {'x': self.coords[HEAD]['x'] + 1, 'y': self.coords[HEAD]['y']}
197
198 # insert new head segment
199 self.coords.insert(HEAD, newhead)
200
201 # dead snake -- remove last segment as long as it isn't the last
202 elif len(self.coords) > 1:
203 del self.coords[-1]
204
205 def drawSnake(self):
206 """
207 Responsible for drawing snake image to screen.
208 """
209 for coord in self.coords:
210 x = coord['x'] * CELLSIZE
211 y = coord['y'] * CELLSIZE
212 snakeSegmentRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
213 pygame.draw.rect(DISPLAYSURF, self.colorBorder, snakeSegmentRect)
214 snakeInnerSegmentRect = pygame.Rect(x + 4, y + 4, CELLSIZE - 8, CELLSIZE - 8)
215 pygame.draw.rect(DISPLAYSURF, self.color, snakeInnerSegmentRect)
216
b68496b4 »
2012-07-03 first commit
217
218 class Fruit:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
219 """
220 Fruit class houses all information for fruit objects. Base class is not meant to be instantiated, but rather provide base methods shared by all fruit.
221 """
222 def __init__(self):
223 self.timer = 0
224
225 def getRandomLocation(self, allfruit, allsnake, gametally):
226 """
227 Returns random coordinates (for fruit to be placed). Ensures that coordinates are not occupied by fruit or snake head.
228 Will keep fruit away from edges (outside 20%) if in an "easy mode" determined in Tally object.
229 """
b68496b4 »
2012-07-03 first commit
230 while True:
231 conflict = False
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
232 if gametally.checkEasyTrigger():
b68496b4 »
2012-07-03 first commit
233 x = random.randint(int(CELLWIDTH/5), CELLWIDTH - int(CELLWIDTH/5) - 1)
234 y = random.randint(int(CELLHEIGHT/5), CELLHEIGHT - int(CELLHEIGHT/5) - 1)
235 else:
236 x = random.randint(0, CELLWIDTH - 1)
237 y = random.randint(0, CELLHEIGHT - 1)
238 # ensure coordinates are not already occupied by fruit
239 for fruit in allfruit:
240 if fruit.coords['x'] == x and fruit.coords['y'] == y:
241 conflict = True
242 # ensure coordinates are not already occupied by snake head
243 for snake in allsnake:
244 if snake.coords[HEAD]['x'] == x and snake.coords[HEAD]['y'] == y:
245 conflict = True
246 if conflict == False:
247 return {'x':x, 'y':y}
248
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
249 def updateTimer(self):
250 """
251 Returns true and decrements if there is still time left for fruit to be on screen.
252 """
b68496b4 »
2012-07-03 first commit
253 if self.timer > 0:
254 self.timer = self.timer - 1
255 return True
256 else:
257 return False
258
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
259 def drawFruit(self):
260 """
261 Responsible for drawing fruit image to screen.
262 """
263 x = self.coords['x'] * CELLSIZE
264 y = self.coords['y'] * CELLSIZE
265 fruitRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
266 pygame.draw.rect(DISPLAYSURF, self.color, fruitRect)
267
268
269 class Apple(Fruit):
270 """
271 Apples are a unique fruit in that they never leave the screen and once one is eaten, it is always replaced with another.
272 They also add points and one growth
273 """
274 def __init__(self, allfruit, allsnake, gametally):
275 self.coords = Fruit.getRandomLocation(self, allfruit, allsnake, gametally)
276 self.color = RED
277 self.points = 10
278 self.growth = 1
279
280 def isEaten(self, snake, gametally):
281 gametally.fruitEaten['apple'] = gametally.fruitEaten['apple'] + 1
282 snake.updateScore(self.points)
283 snake.updateGrowth(self.growth)
284
285 def drawFruit(self):
286 Fruit.drawFruit(self)
287
288
289 class Poison(Fruit):
290 """
291 Poison will shorten a snake (by adding a negative growth value) and reduce points.
292 """
293 def __init__(self, allfruit, allsnake, gametally):
294 self.coords = Fruit.getRandomLocation(self, allfruit, allsnake, gametally)
295 self.timer = random.randint(POISONTIMER[0], POISONTIMER[1])
296 self.color = GREEN
297 self.points = -25
298 self.growth = -3
299
300 def isEaten(self, snake, gametally):
301 gametally.fruitEaten['poison'] = gametally.fruitEaten['poison'] + 1
302 snake.updateScore(self.points)
303 snake.updateGrowth(self.growth)
304
305 def updateTimer(self):
306 return Fruit.updateTimer(self)
307
308 def drawFruit(self):
309 Fruit.drawFruit(self)
310
311
312 class Orange(Fruit):
313 """
314 Orange will grow snake substantially and are worth points.
315 """
316 def __init__(self, allfruit, allsnake, gametally):
317 self.coords = Fruit.getRandomLocation(self, allfruit, allsnake, gametally)
318 self.timer = random.randint(ORANGETIMER[0], ORANGETIMER[1])
319 self.color = ORANGE
320 self.points = 50
321 self.growth = 3
322
323 def isEaten(self, snake, gametally):
324 gametally.fruitEaten['orange'] = gametally.fruitEaten['orange'] + 1
325 snake.updateScore(self.points)
326 snake.updateGrowth(self.growth)
327
328 def updateTimer(self):
329 return Fruit.updateTimer(self)
330
331 def drawFruit(self):
332 Fruit.drawFruit(self)
333
334
335 class Raspberry(Fruit):
336 """
337 Raspberry will set snake's multiplier to two for a period of time.
338 """
339 def __init__(self, allfruit, allsnake, gametally):
340 self.coords = Fruit.getRandomLocation(self, allfruit, allsnake, gametally)
341 self.timer = random.randint(RASPBERRYTIMER[0], RASPBERRYTIMER[1])
342 self.color = PURPLE
343 self.multiplier = 2
344 self.multipliertimer = 100
345
346 def isEaten(self, snake, gametally):
347 gametally.fruitEaten['raspberry'] = gametally.fruitEaten['raspberry'] + 1
348 snake.updateMultiplier(self.multiplier, self.multipliertimer)
349
350 def updateTimer(self):
351 return Fruit.updateTimer(self)
352
353 def drawFruit(self):
354 Fruit.drawFruit(self)
355
356
357 class Blueberry(Fruit):
358 """
359 Blueberry will reduce the frame rate (slowing down game iterations) for a period of time.
360 It is also worth a lot of points.
361 """
362 def __init__(self, allfruit, allsnake, gametally):
363 self.coords = Fruit.getRandomLocation(self, allfruit, allsnake, gametally)
364 self.timer = random.randint(BLUEBERRYTIMER[0], BLUEBERRYTIMER[1])
365 self.color = BLUE
366 self.score = 100
367 self.slowtimer = 120
368
369 def isEaten(self, snake, gametally):
370 gametally.fruitEaten['blueberry'] = gametally.fruitEaten['blueberry'] + 1
371 snake.updateScore(self.score)
372
373 def updateTimer(self):
374 return Fruit.updateTimer(self)
375
376 def drawFruit(self):
377 Fruit.drawFruit(self)
378
379
380 class Lemon(Fruit):
381 def __init__(self, allfruit, allsnake, gametally):
382 self.coords = Fruit.getRandomLocation(self, allfruit, allsnake, gametally)
383 self.timer = random.randint(LEMONTIMER[0], LEMONTIMER[1])
384 self.color = YELLOW
385 self.score = 1000
386
387 def isEaten(self, snake, gametally):
388 gametally.fruitEaten['lemon'] = gametally.fruitEaten['lemon'] + 1
389 snake.updateScore(self.score)
390
391 def updateTimer(self):
392 return Fruit.updateTimer(self)
393
394 def drawFruit(self):
395 Fruit.drawFruit(self)
396
397
398 class Tally:
399 """
400 Responsible for dynamics relating to the accumulation of fruits in a given game.
401 fruitEaten - a dictionary containing a numeric tally of each fruit eaten.
402 speedTrigger - the frequency (based on apples consumed) in which gamespeed is increased by one.
403 bonusTrigger - the frequency (based on apples consumed) in which a bonus game - runBonus() - is launched.
404 easyTrigger - a threshold (apples consumed); once reached fruit can be placed anywhere on screen (as opposed to away from edges).
405 typeMin - the minimum value in determining bonus game type.
406 typeMax - the maximum value in determining bonus game type.
407 """
408 def __init__(self, st=20, bt=10, et=20, tmin=1, tmax=10):
409 self.fruitEaten = {'apple':0, 'poison':0, 'orange':0, 'raspberry':0, 'blueberry':0, 'lemon':0}
410 self.speedTrigger = st
411 self.bonusTrigger = bt
412 self.easyTrigger = et
413 self.typeMin = tmin
414 self.typeMax = tmax
415
416 def checkSpeedTrigger(self):
417 """
418 Returns true if number of apples consumed modulo speedTrigger equals zero.
419 """
420 if self.fruitEaten['apple'] % self.speedTrigger == 0:
421 return True
422 else:
423 return False
424
425 def checkBonusTrigger(self):
426 """
427 Returns true if number of apples consumed modulo bonusTrigger equals zero.
428 """
429 if self.fruitEaten['apple'] % self.bonusTrigger == 0:
430 return True
431 else:
432 return False
433
434 def checkEasyTrigger(self):
435 """
436 Returns true if number of apples consumed is less than or equal to easyTrigger.
437 """
438 if self.fruitEaten['apple'] <= self.easyTrigger:
439 return True
440 else:
441 return False
442
443 def runBonus(self):
444 """
445 Returns a list containing fruit (as strings) to be added to game from bonus game.
446 An integer (determined randomly between typeMin and typeMax) corresponds to bonus game run.
447 A basic set-up would randomly choose between 1 and 10; 6 through 10 initiating a fruit specific bonus.
448 Default will contain an assortment of fruit.
449 """
450 bonus = []
451 type = random.randint(self.typeMin, self.typeMax)
452 if type == LEMONBONUS:
453 bonus.append('lemon')
454 elif type == POISONBONUS:
455 counter = random.randint(20,35)
456 while counter > 0:
457 bonus.append('poison')
458 counter = counter - 1
459 elif type == ORANGEBONUS:
460 counter = random.randint(20,35)
461 while counter > 0:
462 bonus.append('orange')
463 counter = counter - 1
464 elif type == RASPBERRYBONUS:
465 counter = random.randint(20,35)
466 while counter > 0:
467 bonus.append('raspberry')
468 counter = counter - 1
469 elif type == BLUEBERRYBONUS:
470 counter = random.randint(20,30)
471 while counter > 0:
472 bonus.append('blueberry')
473 counter = counter - 1
474 else: # default bonus
475 counter = random.randint(0,3)
476 while counter > 0:
477 bonus.append('poison')
478 counter = counter - 1
479 counter = random.randint(5,20)
480 while counter > 0:
481 bonus.append('orange')
482 counter = counter - 1
483 counter = random.randint(1,4)
484 while counter > 0:
485 bonus.append('raspberry')
486 counter = counter - 1
487 counter = random.randint(0,2)
488 while counter > 0:
489 bonus.append('blueberry')
490 counter = counter - 1
491 return bonus
492
b68496b4 »
2012-07-03 first commit
493
494 class Button():
495 def __init__(self, text, x, y):
496 self.text = text
497 startSurf = BUTTONFONT.render(self.text, True, GREEN, DARKGRAY)
498 self.rect = startSurf.get_rect()
499 self.rect.center = x,y
500
501 def display(self):
502 startSurf = BUTTONFONT.render(self.text, True, GREEN, DARKGRAY)
503 DISPLAYSURF.blit(startSurf, self.rect)
504
505 def pressed(self,mouse):
506 if mouse[0] > self.rect.topleft[0]:
507 if mouse[1] > self.rect.topleft[1]:
508 if mouse[0] < self.rect.bottomright[0]:
509 if mouse[1] < self.rect.bottomright[1]:
510 return True
511 else: return False
512 else: return False
513 else: return False
514 else: return False
515
516
517 def main():
518 global FPSCLOCK, DISPLAYSURF, BASICFONT, BUTTONFONT
519
520 pygame.init()
521 FPSCLOCK = pygame.time.Clock()
522 DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
523 BASICFONT = pygame.font.Font('freesansbold.ttf', 18)
524 BUTTONFONT = pygame.font.Font('freesansbold.ttf', 48)
525 pygame.display.set_caption('Snakey!')
526
527 showStartScreen()
528
529 while True:
530 runGame()
531 showGameOverScreen()
532
533
534 def runGame():
535
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
536 # set up globals
537 #global allsnake, allfruit, fruiteaten
538 allsnake = []
539 allfruit = []
540 gametally = Tally(20, 10, 19)
541
b68496b4 »
2012-07-03 first commit
542 # create player snake and add to all snakes
543 player = Snake([{'x':5, 'y':5},{'x':4, 'y':5},{'x':3, 'y':5}], RIGHT, GREEN, COBALTGREEN)
544 allsnake.append(player)
545
546 # set beginning variables
547 player.player = True
548 player.score = 10
549 basespeed = FPS
550 currentspeed = basespeed
551 slowtimer = 0
552
553 # create initial fruit
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
554 a = Apple(allfruit, allsnake, gametally)
b68496b4 »
2012-07-03 first commit
555 allfruit.append(a)
556
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
557 # main game loop
558 while True:
b68496b4 »
2012-07-03 first commit
559 stop = False
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
560 # event handling loop
561 for event in pygame.event.get():
b68496b4 »
2012-07-03 first commit
562 if event.type == QUIT:
563 terminate()
564 elif event.type == KEYDOWN and stop == False:
565 if (event.key == K_LEFT or event.key == K_a) and player.direction != RIGHT:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
566 player.updateDirection(LEFT)
b68496b4 »
2012-07-03 first commit
567 stop = True
568 elif (event.key == K_RIGHT or event.key == K_d) and player.direction != LEFT:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
569 player.updateDirection(RIGHT)
b68496b4 »
2012-07-03 first commit
570 stop = True
571 elif (event.key == K_UP or event.key == K_w) and player.direction != DOWN:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
572 player.updateDirection(UP)
b68496b4 »
2012-07-03 first commit
573 stop = True
574 elif (event.key == K_DOWN or event.key == K_s) and player.direction != UP:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
575 player.updateDirection(DOWN)
b68496b4 »
2012-07-03 first commit
576 stop = True
577 elif event.key == K_ESCAPE or event.key == K_q:
578 terminate()
579
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
580 # check if the snake has hit boundary
b68496b4 »
2012-07-03 first commit
581 for snake in allsnake:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
582 if snake.alive and snake.boundsCollision():
b68496b4 »
2012-07-03 first commit
583 snake.alive = False
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
584 # check if snake has hit another snake
585 for othersnake in allsnake:
586 if snake.alive and snake.snakeCollision(othersnake):
b68496b4 »
2012-07-03 first commit
587 snake.alive = False
588
589 # check score - change color accordingly
590 # only looks at player snake
591 if player.score > 2000:
592 player.color = SIENNA
593 player.colorBorder = CORAL
594 elif player.score > 1500:
595 player.color = CORAL
596 player.colorBorder = GOLDENROD
597 elif player.score > 1250:
598 player.color = GOLDENROD
599 player.colorBorder = EMERALDGREEN
600 elif player.score > 1000:
601 player.color = KHAKI
602 player.colorBorder = LIGHTYELLOW
603 elif player.score > 750:
604 player.color = YELLOW
605 player.colorBorder = GREEN
606 elif player.score > 500:
607 player.color = LIGHTYELLOW
608 player.colorBorder = FORESTGREEN
609 elif player.score > 400:
610 player.color = IVORY #change this
611 player.colorBorder = FORESTGREEN
612 elif player.score > 300:
613 player.color = GREENYELLOW
614 player.colorBorder = OLIVEGREEN
615 elif player.score > 200:
616 player.color = HONEYDEW
617 player.colorBorder = SEAGREEN
618 elif player.score > 100:
619 player.color = SEAGREEN
620 player.colorBorder = EMERALDGREEN
621 else:
622 player.color = GREEN
623 player.colorBorder = COBALTGREEN
624
625 # check if fruit has been eaten by a snake
626 for snake in allsnake:
627 for fruit in allfruit:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
628 if snake.alive and snake.fruitCollision(fruit):
629 fruit.isEaten(snake, gametally)
630 # apples have special adding properties
631 if fruit.__class__ == Apple:
b68496b4 »
2012-07-03 first commit
632 # check for speed increase
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
633 if gametally.checkSpeedTrigger():
b68496b4 »
2012-07-03 first commit
634 basespeed = basespeed + 1
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
635 # check for bonus drop
636 if gametally.checkBonusTrigger():
637 bonus = gametally.runBonus()
638 for bonusfruit in bonus: ##if this works, maybe try f = fruit.__class__()
639 if bonusfruit == 'poison':
640 f = Poison(allfruit, allsnake, gametally)
641 elif bonusfruit == 'orange':
642 f = Orange(allfruit, allsnake, gametally)
643 elif bonusfruit == 'raspberry':
644 f = Raspberry(allfruit, allsnake, gametally)
645 elif bonusfruit == 'blueberry':
646 f = Blueberry(allfruit, allsnake, gametally)
647 else:
648 f = Lemon(allfruit, allsnake, gametally)
649 allfruit.append(f)
650 # chance of poison drop
b68496b4 »
2012-07-03 first commit
651 if random.randint(1,4) == 1:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
652 p = Poison(allfruit, allsnake, gametally)
b68496b4 »
2012-07-03 first commit
653 allfruit.append(p)
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
654 # chance of orange drop
b68496b4 »
2012-07-03 first commit
655 if random.randint(1,5) == 1:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
656 o = Orange(allfruit, allsnake, gametally)
b68496b4 »
2012-07-03 first commit
657 allfruit.append(o)
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
658 # chance of raspberry drop
b68496b4 »
2012-07-03 first commit
659 if random.randint(1,6) == 1:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
660 r = Raspberry(allfruit, allsnake, gametally)
b68496b4 »
2012-07-03 first commit
661 allfruit.append(r)
662 # create new apple
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
663 a = Apple(allfruit, allsnake, gametally)
b68496b4 »
2012-07-03 first commit
664 allfruit.append(a)
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
665 elif fruit.__class__ == Blueberry:
666 # update speed
b68496b4 »
2012-07-03 first commit
667 slowtimer = slowtimer + currentspeed * 12 # add 12 seconds
668 # remove fruit
669 allfruit.remove(fruit)
670
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
671 # check for snake death
b68496b4 »
2012-07-03 first commit
672 for snake in allsnake:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
673 if snake.alive == False:
674 if snake.player == True:
675 return 1
676
677 # check for size changes / move snake
678 for snake in allsnake:
679 snake.move()
b68496b4 »
2012-07-03 first commit
680
681 # check multiplier and adjust color and multiplier as needed
682 for snake in allsnake:
683 if snake.multipliertimer > 0:
684 snake.multipliertimer = snake.multipliertimer - 1
685 snake.colorBorder = PURPLE
686 else:
687 snake.multiplier = 1
688
689 # check slow and adjust color and fps as needed
690 if slowtimer > 0:
691 slowtimer = slowtimer - 1
692 for snake in allsnake:
693 snake.color = BLUE
694 if currentspeed > 8:
695 currentspeed = currentspeed - 1
696 else:
697 if currentspeed < basespeed:
698 currentspeed = currentspeed + 1
699
700 # update timers on fruits, remove if necessary
701 for fruit in allfruit:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
702 if fruit.__class__ != Apple:
703 if fruit.updateTimer() == False:
b68496b4 »
2012-07-03 first commit
704 allfruit.remove(fruit)
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
705
b68496b4 »
2012-07-03 first commit
706 DISPLAYSURF.fill(BGCOLOR)
707 drawGrid()
708 for fruit in allfruit:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
709 fruit.drawFruit()
b68496b4 »
2012-07-03 first commit
710 for snake in allsnake:
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
711 snake.drawSnake()
b68496b4 »
2012-07-03 first commit
712 drawScore(player.score)
713 pygame.display.update()
714 FPSCLOCK.tick(currentspeed)
715
716
717 def drawPressKeyMsg():
718 pressKeySurf = BASICFONT.render('Press a key to play.', True, DARKGRAY)
719 pressKeyRect = pressKeySurf.get_rect()
720 pressKeyRect.topleft = (WINDOWWIDTH - 200, WINDOWHEIGHT - 30)
721 DISPLAYSURF.blit(pressKeySurf, pressKeyRect)
722
723
724 def checkForKeyPress():
725 if len(pygame.event.get(QUIT)) > 0:
726 terminate()
727
728 keyUpEvents = pygame.event.get(KEYUP)
729 if len(keyUpEvents) == 0:
730 return None
731 if keyUpEvents[0].key == K_ESCAPE or keyUpEvents[0].key == K_q:
732 terminate()
733 return keyUpEvents[0].key
734
735
736 def showStartScreen():
737 titleFont = pygame.font.Font('freesansbold.ttf', 100)
738 titleSurf1 = titleFont.render('Snakey!', True, WHITE, FORESTGREEN)
739 titleSurf2 = titleFont.render('Snakey!', True, GREEN)
740
741 degrees1 = 0
742 degrees2 = 0
743
744 startbutton = Button('(s)tart game', WINDOWWIDTH / 2, WINDOWHEIGHT * 3/5)
745 instructbutton = Button('(i)nstructions', WINDOWWIDTH / 2, WINDOWHEIGHT * 4/5)
746
747 while True:
748
749 DISPLAYSURF.fill(BGCOLOR)
750 rotatedSurf1 = pygame.transform.rotate(titleSurf1, degrees1)
751 rotatedRect1 = rotatedSurf1.get_rect()
752 rotatedRect1.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2)
753 DISPLAYSURF.blit(rotatedSurf1, rotatedRect1)
754
755 rotatedSurf2 = pygame.transform.rotate(titleSurf2, degrees2)
756 rotatedRect2 = rotatedSurf2.get_rect()
757 rotatedRect2.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2)
758 DISPLAYSURF.blit(rotatedSurf2, rotatedRect2)
759
760 startbutton.display()
761 instructbutton.display()
762
763 for event in pygame.event.get():
764 if event.type == QUIT:
765 terminate()
766 elif event.type == MOUSEBUTTONDOWN:
767 mouse = pygame.mouse.get_pos()
768 if startbutton.pressed(mouse):
769 pygame.event.get()
770 return
771 elif instructbutton.pressed(mouse):
772 showInstructScreen()
773 elif event.type == KEYDOWN:
774 if event.key == K_s:
775 pygame.event.get()
776 return
777 elif event.key == K_i:
778 showInstructScreen()
779 elif event.key == K_ESCAPE or event.key == K_q:
780 terminate()
781
782 pygame.display.update()
783 FPSCLOCK.tick(FPS)
784 degrees1 += 3 # rotate by 3 degrees each frame
785 degrees2 += 7 # rotate by 7 degrees each frame
786
787
788 def showInstructScreen():
789
790 endinstructbutton = Button('(e)xit', WINDOWWIDTH / 2, WINDOWHEIGHT - 40)
791
792 while True:
793
794 instruct = pygame.image.load('snakey_party_instructions.png').convert()
795
796 DISPLAYSURF.blit(instruct, (54, 10))
797
798 endinstructbutton.display()
799
800 for event in pygame.event.get():
801 if event.type == QUIT:
802 terminate()
803 elif event.type == MOUSEBUTTONDOWN:
804 mouse = pygame.mouse.get_pos()
805 if endinstructbutton.pressed(mouse):
806 pygame.event.get()
807 return
808 elif event.type == KEYDOWN:
809 if event.key == K_e or event.key == K_i:
810 pygame.event.get()
811 return
812 elif event.key == K_ESCAPE or event.key == K_q:
813 terminate()
814
815 pygame.display.update()
816
817
818 def terminate():
819 pygame.quit()
820 sys.exit()
821
822
823 def showGameOverScreen():
824 gameOverFont = pygame.font.Font('freesansbold.ttf', 150)
825 gameSurf = gameOverFont.render('Game', True, WHITE)
826 overSurf = gameOverFont.render('Over', True, WHITE)
827 gameRect = gameSurf.get_rect()
828 overRect = overSurf.get_rect()
829 gameRect.midtop = (WINDOWWIDTH / 2, 10)
830 overRect.midtop = (WINDOWWIDTH / 2, gameRect.height + 10 + 25)
831
832 DISPLAYSURF.blit(gameSurf, gameRect)
833 DISPLAYSURF.blit(overSurf, overRect)
834 drawPressKeyMsg()
835 pygame.display.update()
836 pygame.time.wait(500)
837 checkForKeyPress() # clear out any key presses in the event queue
838
839 while True:
840 if checkForKeyPress():
841 pygame.event.get() # clear event queue
842 return
843
844
845 def drawScore(score):
846 scoreSurf = BASICFONT.render('Score: %s' % (score), True, WHITE)
847 scoreRect = scoreSurf.get_rect()
848 scoreRect.topleft = (WINDOWWIDTH - 120, 10)
849 DISPLAYSURF.blit(scoreSurf, scoreRect)
850
851
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
852 def drawPoints(score, x=1, y=1, color=WHITE):
b68496b4 »
2012-07-03 first commit
853 scoreSurf = BASICFONT.render('%s!' % (score), True, color)
854 scoreRect = scoreSurf.get_rect()
faa87d1f »
2012-07-12 added Snake, Fruit, Tally classes
855 scoreRect.topleft = (x, y)
b68496b4 »
2012-07-03 first commit
856 DISPLAYSURF.blit(scoreSurf, scoreRect)
857
858
859 def drawGrid():
860 for x in range(0, WINDOWWIDTH, CELLSIZE): # draw vertical lines
861 pygame.draw.line(DISPLAYSURF, DARKGRAY, (x, 0), (x, WINDOWHEIGHT))
862 for y in range(0, WINDOWHEIGHT, CELLSIZE): # draw horizontal lines
863 pygame.draw.line(DISPLAYSURF, DARKGRAY, (0, y), (WINDOWWIDTH, y))
864
865
866 if __name__ == '__main__':
867 main()
868
Something went wrong with that request. Please try again.