~ubuntu-branches/ubuntu/warty/pygame/warty

« back to all changes in this revision

Viewing changes to examples/uberball.py

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-09-17 17:09:53 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040917170953-caomeukd8awvvpwv
Tags: 1.6-0.2ubuntu1
Add missing build-depends: python

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#/usr/bin/env python
 
2
"""
 
3
�berBall python source by Geoff Howland.  04-28-02
 
4
 
 
5
All rights to this code and source and name are placed in the public domain.
 
6
 
 
7
This is meant to be an example of how to use Python for creating games, and being my first project
 
8
in Python could have some things that could have been organized better, but I think it handles most
 
9
of the situations pretty elegantly.  The code was originally based on the 'chimp.py' example that
 
10
with PyGame examples as it was the most basic example to do full drawing/events.  Most, but not all,
 
11
of that code has been rewriten though so it probably wont be much to compare.
 
12
 
 
13
If you're interested in independent game development you can take a look at my website Ludum Dare:
 
14
http://ludumdare.com/
 
15
 
 
16
Hope this helps some people!
 
17
 
 
18
-Geoff Howland
 
19
ghowland@lupinegames.com
 
20
 
 
21
 
 
22
On May 21, 2002, this was slightly cleaned up to be included with the pygame
 
23
examples. Changes mainly include better use of the pygame.sprite module. All
 
24
graphic resources are now rendered during runtime instead of loaded from disk.
 
25
"""
 
26
 
 
27
 
 
28
#Import Modules
 
29
import os, pygame
 
30
from pygame.locals import *
 
31
from random import randint
 
32
 
 
33
if not pygame.font: raise SystemExit, "Requires pygame.font module"
 
34
if not pygame.mixer: print 'Warning, sound disabled'
 
35
 
 
36
 
 
37
#functions to create our resources
 
38
 
 
39
def load_sound(name):
 
40
        class NoneSound:
 
41
                def play(self): pass
 
42
        if not pygame.mixer or not pygame.mixer.get_init():
 
43
                return NoneSound()
 
44
        fullname = os.path.join('data', name)
 
45
        try:
 
46
                sound = pygame.mixer.Sound(fullname)
 
47
        except pygame.error, message:
 
48
                print 'Cannot load sound:', fullname
 
49
                raise SystemExit, message
 
50
        return sound
 
51
 
 
52
def render_block(size, color, width=1):
 
53
        hicolor = map(lambda x: x+40, color)
 
54
        locolor = map(lambda x: x-20, color)
 
55
        surf = pygame.Surface(size)
 
56
        r = surf.get_rect()
 
57
        smallr = r.inflate(-width-1, -width-1)
 
58
        surf.fill(color)
 
59
        pygame.draw.lines(surf, locolor, 0, (smallr.topright, smallr.bottomright, smallr.bottomleft), width)
 
60
        pygame.draw.lines(surf, hicolor, 0, (r.bottomleft, r.topleft, r.topright), width)
 
61
        return surf, r
 
62
 
 
63
def render_ball(radius, color):
 
64
        hicolor = map(lambda x: x+50, color)
 
65
        radius = radius
 
66
        size = radius * 2
 
67
        surf = pygame.Surface((size, size))
 
68
        pygame.draw.circle(surf, color, (radius, radius), radius)
 
69
        half = radius/2
 
70
        surf.set_at((half, half+1), hicolor)
 
71
        surf.set_at((half+1, half), hicolor)
 
72
        surf.set_colorkey(0)
 
73
        return surf, surf.get_rect()
 
74
        
 
75
 
 
76
def render_powerup(color):
 
77
        if not pygame.font:
 
78
            surf = pygame.Surface((30, 30))
 
79
            surf.fill(color)
 
80
            return surf, surf.get_rect()
 
81
        
 
82
        font = pygame.font.Font(None, 15)
 
83
        font.set_bold(1)
 
84
        surf = font.render(":-)", 0, color)
 
85
        surf2 = pygame.transform.rotate(surf, -90)
 
86
        r = surf2.get_rect()
 
87
        pygame.draw.rect(surf2, color, r, 1)
 
88
        return surf2, r
 
89
 
 
90
 
 
91
class PlayGameState:
 
92
        "Class for the game's play state variables and control functions."
 
93
        def __init__(self):
 
94
                self.menuMode = 0
 
95
                self.score = 0
 
96
                self.level = 1
 
97
                self.effectCurrent = 0
 
98
                self.effectDuration = 0
 
99
 
 
100
        def NewGame(self):
 
101
                self.menuMode = 2 # Game
 
102
                self.score = 0
 
103
                self.level = 1
 
104
                self.effectCurrent = 0
 
105
                self.effectDuration = 0
 
106
                
 
107
                # Load level
 
108
 
 
109
        def ScoreAdd(self, scoreAdd):
 
110
                self.score = self.score + scoreAdd
 
111
 
 
112
#classes for our game objects
 
113
class Paddle(pygame.sprite.Sprite):
 
114
        """moves a clenched paddle on the screen, following the mouse"""
 
115
        def __init__(self):
 
116
                pygame.sprite.Sprite.__init__(self) #call Sprite initializer
 
117
                self.image, self.rect = render_block((50, 15), (200, 180, 120), 2)
 
118
 
 
119
        def update(self):
 
120
                "move the paddle based on the mouse position"
 
121
                pos = pygame.mouse.get_pos()    # This should really be passed the mouse position
 
122
                self.rect.midtop = pos
 
123
                self.rect.bottom = 440          # Lock Paddle at the bottom of the screen
 
124
 
 
125
 
 
126
#classes for our game objects
 
127
class Brick(pygame.sprite.Sprite):
 
128
        """moves a clenched paddle on the screen, following the mouse"""
 
129
        colors = (200, 50, 50),  (50, 200, 50), (50, 50, 200), (200, 200, 50)
 
130
        def __init__(self, type, x, y):
 
131
                pygame.sprite.Sprite.__init__(self) #call Sprite initializer
 
132
                self.type = type
 
133
                self.image, self.rect = render_block((30, 10), Brick.colors[type])
 
134
                self.active = 1
 
135
                self.rect.left = (x * self.rect.width) + 5
 
136
                self.rect.top = y * self.rect.height
 
137
                self.posX = x
 
138
                self.posY = y
 
139
 
 
140
#classes for our game objects
 
141
class PowerUp(pygame.sprite.Sprite):
 
142
        """moves a clenched paddle on the screen, following the mouse"""
 
143
        colors = (150, 50, 50), (50, 150, 50)
 
144
        def __init__(self, type, speed, x, y):
 
145
                pygame.sprite.Sprite.__init__(self) #call Sprite initializer
 
146
                self.type = type
 
147
                self.speed = speed
 
148
                self.image, self.rect = render_powerup(PowerUp.colors[type])
 
149
                self.rect.left = x
 
150
                self.rect.top = y
 
151
 
 
152
        def update(self):
 
153
                # Fall
 
154
                self.rect.top = self.rect.top + self.speed
 
155
 
 
156
        def collide (self, test):
 
157
                if self.rect.colliderect (test.rect):
 
158
                        return 1
 
159
 
 
160
                return 0
 
161
                        
 
162
class Ball(pygame.sprite.Sprite):
 
163
        """moves a monkey critter across the screen. it can spin the
 
164
           monkey when it is punched."""
 
165
        radii = 8, 4
 
166
        def __init__(self, size,x=300,y=200):
 
167
                pygame.sprite.Sprite.__init__(self) #call Sprite intializer
 
168
                self.size = size
 
169
                self.image, self.rect = render_ball(Ball.radii[size], (50, 200, 200))
 
170
                screen = pygame.display.get_surface()
 
171
                self.area = screen.get_rect()
 
172
                self.area.left = self.area.left - 5
 
173
                
 
174
                self.rect.centerx = x
 
175
                self.rect.centery = y
 
176
                self.moveX = 4 + (2 * size)
 
177
                self.moveY = 4 + (2 * size)
 
178
                self.lastRect = self.rect
 
179
 
 
180
        def changeType(self):
 
181
                size = not self.size
 
182
                self.size = size
 
183
                x = self.rect.centerx
 
184
                y = self.rect.centery
 
185
                self.image, self.rect = render_ball(Ball.radii[size], (50, 200, 200))
 
186
                self.rect.centerx = x
 
187
                self.rect.centery = y
 
188
                
 
189
                # Set the speed based on the size, and keep its direction
 
190
                if size:
 
191
                        self.moveX = self.moveX * 2
 
192
                        self.moveY = self.moveY * 2
 
193
                else:
 
194
                        self.moveX = self.moveX / 2
 
195
                        self.moveY = self.moveY / 2
 
196
 
 
197
        def update(self):
 
198
                self.lastRect = self.rect
 
199
                newpos = self.rect.move((self.moveX, self.moveY))
 
200
                if not self.area.contains(newpos):
 
201
                        if self.rect.centerx < 0 or self.rect.centerx > self.area.right:
 
202
                                self.moveX = -self.moveX
 
203
                        if self.rect.centery < 0 or self.rect.centery > self.area.bottom:
 
204
                                self.moveY = -self.moveY
 
205
                        newpos = self.rect.move((self.moveX, self.moveY))
 
206
 
 
207
                self.rect = newpos
 
208
 
 
209
        def collidePaddle (self, test):
 
210
                horReverse = 0
 
211
                ## Collision from right
 
212
                if self.lastRect.right < test.rect.left and self.lastRect.bottom > test.rect.top:
 
213
                        self.rect.right = test.rect.left
 
214
                        self.moveX = -self.moveX
 
215
                        horReverse = 1
 
216
                        
 
217
                ## Collision from left                  
 
218
                if self.lastRect.left > test.rect.right and self.lastRect.bottom > test.rect.top:
 
219
                        self.rect.left = test.rect.right
 
220
                        self.moveX = -self.moveX
 
221
                        horReverse = 1
 
222
 
 
223
                ## Collision from above                 
 
224
                if not horReverse and self.moveY > 0:
 
225
                        self.rect.bottom = test.rect.top
 
226
                        # If we haven't done a horizontal reverse then do a gradient angle change
 
227
                        if not horReverse:
 
228
                                if self.rect.centerx < test.rect.centerx:
 
229
                                        self.moveX = ((self.rect.centerx - test.rect.centerx) / (test.rect.width / 2.0)) * 4.0
 
230
                                        if self.moveX >= -1:
 
231
                                                self.moveX = -1
 
232
                                else:
 
233
                                        self.moveX = ((self.rect.centerx - test.rect.centerx) / (test.rect.width / 2.0)) * 4.0
 
234
                                        if self.moveX <= 1:
 
235
                                                self.moveX = 1
 
236
                
 
237
                        self.moveY = -self.moveY
 
238
 
 
239
        def collide (self, test):
 
240
                horReverse = 0
 
241
                # Collision from right
 
242
                if self.lastRect.right < test.rect.left and self.lastRect.bottom > test.rect.top:
 
243
                        self.rect.right = test.rect.left-1
 
244
                        self.moveX = -self.moveX
 
245
                        horReverse = 1
 
246
                        
 
247
                # Collision from left                   
 
248
                if self.lastRect.left > test.rect.right and self.lastRect.bottom > test.rect.top:
 
249
                        self.rect.left = test.rect.right+1
 
250
                        self.moveX = -self.moveX
 
251
                        horReverse = 1
 
252
 
 
253
                # Collision from above                  
 
254
                if not horReverse and self.moveY > 0:
 
255
                        self.rect.bottom = test.rect.top
 
256
                        self.moveY = -self.moveY
 
257
 
 
258
                # Collision from below                  
 
259
                if not horReverse and self.moveY < 0:
 
260
                        self.rect.top = test.rect.bottom
 
261
                        self.moveY = -self.moveY
 
262
 
 
263
 
 
264
class GameMode:
 
265
        """This handles all the game mode activities, playing, scoring, dying, drawing, etc."""
 
266
        def __init__(self, gameControlObj, screenRect):
 
267
                self.gameControl = gameControlObj       # Mode can change to another mode by itself
 
268
                
 
269
                # Create rect bonudaries for the screen
 
270
                self.screenBoundary = screenRect
 
271
                self.powerchance = 3
 
272
                
 
273
                # Create fonts
 
274
                self.fontScore = pygame.font.Font(None, 26)
 
275
                self.fontLives = pygame.font.Font(None, 26)
 
276
                
 
277
                # Create sounds
 
278
                self.bong_sound = load_sound('bong.wav')
 
279
                
 
280
                self.reset ()
 
281
 
 
282
        def reset(self):
 
283
                # Create and clear the gameState
 
284
                self.gameState = PlayGameState()
 
285
                
 
286
                # Create paddle for player
 
287
                self.paddle = Paddle()
 
288
                self.allsprites = pygame.sprite.RenderUpdates(self.paddle)
 
289
 
 
290
                # Create balls
 
291
                self.allballs = pygame.sprite.Group((Ball(1), Ball(0)))
 
292
                self.allsprites.add(self.allballs)
 
293
 
 
294
                # Create bricks
 
295
                self.allbricks = pygame.sprite.Group()
 
296
                for y in range(8):
 
297
                        for x in range(21):
 
298
                                type = randint(0,3)
 
299
                                brick = Brick(type, x, y)
 
300
                                brick.add((self.allbricks, self.allsprites))
 
301
 
 
302
                # Power ups
 
303
                self.allpowerups = pygame.sprite.Group()
 
304
 
 
305
        def eventHandle(self):
 
306
                if self.gameControl.gameEvent.keystate[K_ESCAPE]:
 
307
                        self.gameControl.setMode (0)
 
308
                return 0
 
309
                
 
310
        def update(self):
 
311
                # Update all the sprite objects we've added to this comprehensive list
 
312
                self.allsprites.update()
 
313
 
 
314
                # If we're under the paddle
 
315
                bottom = self.screenBoundary.bottom
 
316
                for powerUp in self.allpowerups.sprites():
 
317
                        if powerUp.rect.bottom > bottom:
 
318
                                powerUp.kill()
 
319
                for ball in self.allballs.sprites():
 
320
                        if ball.rect.bottom > bottom:
 
321
                                ball.kill()
 
322
 
 
323
                # Check balls against blocks
 
324
                collisiondict = pygame.sprite.groupcollide(self.allballs, self.allbricks, 0, 1)
 
325
                for ball,bricks in collisiondict.items():
 
326
                        for brick in bricks:
 
327
                                ball.collide(brick)
 
328
                                self.bong_sound.play()
 
329
                                self.gameState.ScoreAdd (10)
 
330
                                # Randomly create a power up
 
331
                                if not randint(0, self.powerchance):
 
332
                                        self.powerchance = len(self.allballs) * 2
 
333
                                        center = brick.rect.center
 
334
                                        powerUp = PowerUp(randint(0,1), randint(3,7), center[0], center[1])
 
335
                                        powerUp.add((self.allpowerups, self.allsprites))
 
336
                                else:
 
337
                                        self.powerchance = self.powerchance - 1
 
338
 
 
339
                # Check balls against paddle
 
340
                for ball in pygame.sprite.spritecollide(self.paddle, self.allballs, 0):
 
341
                        ball.collidePaddle(self.paddle)
 
342
                        self.bong_sound.play()
 
343
                        self.gameState.ScoreAdd(10)
 
344
 
 
345
                # Check powerups against paddle
 
346
                for powerUp in pygame.sprite.spritecollide(self.paddle, self.allpowerups, 1):
 
347
                        ball.collidePaddle(self.paddle)
 
348
                        self.bong_sound.play()
 
349
                        if powerUp.type == 1: # Double the balls
 
350
                                for ball in self.allballs.sprites():
 
351
                                        newBall = Ball (ball.size, ball.rect.centerx, ball.rect.centery)
 
352
                                        newBall.moveX = -ball.moveX
 
353
                                        newBall.moveY = -ball.moveY
 
354
                                        newBall.add((self.allballs, self.allsprites))
 
355
                        else: # Convert the balls
 
356
                                for ball in self.allballs.sprites():
 
357
                                        ball.changeType()
 
358
 
 
359
                # If all the balls are gone
 
360
                if not self.allballs:
 
361
                        self.gameControl.setMode(0)     # Back to the main menu
 
362
 
 
363
        def draw(self, background, screen):
 
364
                #Draw Everything
 
365
                screen.blit(background, (0, 0))
 
366
                self.allsprites.draw(screen)
 
367
                
 
368
                # Draw score
 
369
                textScore = self.fontScore.render(str(self.gameState.score), 1, (255, 255, 255))
 
370
                textposScore = textScore.get_rect()
 
371
                textposScore.bottom = background.get_rect().bottom - 5
 
372
                textposScore.left = background.get_rect().left + 10
 
373
                screen.blit(textScore, textposScore)
 
374
 
 
375
                # Draw balls
 
376
                textLives = self.fontLives.render(str(len(self.allballs)), 1, (255, 255, 255))
 
377
                textposLives = textLives.get_rect()
 
378
                textposLives.bottom = background.get_rect().bottom - 5
 
379
                textposLives.right = background.get_rect().right - 10
 
380
                screen.blit(textLives, textposLives)
 
381
 
 
382
class MainMenuMode:
 
383
        """This handles all the main menu activities of quitting, or starting a game, checking high score"""
 
384
        def __init__(self, gameControlObj, screenRect):
 
385
                self.gameControl = gameControlObj       # Mode can change to another mode by itself
 
386
                self.screenBoundary = screenRect
 
387
                self.menuSelect = 0
 
388
                self.menuMax = 3
 
389
 
 
390
                # Create fonts
 
391
                self.fontMenu = pygame.font.Font(None, 30)
 
392
 
 
393
        def reset(self):
 
394
                return
 
395
 
 
396
        def eventHandle(self):
 
397
                # Check for quit
 
398
                if self.gameControl.gameEvent.keystate[K_ESCAPE]:
 
399
                        self.gameControl.setMode (-1)   # -1 is exit the game
 
400
        
 
401
                # Move selection up and down
 
402
                if self.gameControl.gameEvent.newkeys[K_DOWN] and self.menuSelect < self.menuMax-1:
 
403
                        self.menuSelect = self.menuSelect + 1
 
404
                        
 
405
                if self.gameControl.gameEvent.newkeys[K_UP] and self.menuSelect > 0:
 
406
                        self.menuSelect = self.menuSelect - 1
 
407
                
 
408
                # Process current selection
 
409
                if self.gameControl.gameEvent.newkeys[K_RETURN]:
 
410
                        if self.menuSelect == 0:
 
411
                                self.gameControl.setMode (2)
 
412
                        if self.menuSelect == 1:
 
413
                                self.gameControl.setMode (1)
 
414
                        if self.menuSelect == 2:
 
415
                                self.gameControl.setMode (-1)   # -1 is exit the game
 
416
                
 
417
        def update(self):
 
418
                return
 
419
 
 
420
        def draw(self, background, screen):
 
421
                #Draw Everything
 
422
                screen.blit(background, (0, 0))
 
423
                
 
424
                # Draw options - New Game
 
425
                color = (255, 255, 255)
 
426
                if self.menuSelect == 0:
 
427
                        color = (0, 255, 0)
 
428
                textMenu = self.fontMenu.render("New Game", 1, color)
 
429
                textPosMenu = textMenu.get_rect()
 
430
                textPosMenu.bottom = background.get_rect().centery - textPosMenu.height
 
431
                textPosMenu.left = background.get_rect().centerx - textPosMenu.width/2
 
432
                screen.blit(textMenu, textPosMenu)
 
433
                lastBottom = textPosMenu.bottom
 
434
 
 
435
                # Draw options - High Score
 
436
                color = (255, 255, 255)
 
437
                if self.menuSelect == 1:
 
438
                        color = (0, 255, 0)
 
439
                textMenu = self.fontMenu.render("High Scores", 1, color)
 
440
                textPosMenu = textMenu.get_rect()
 
441
                textPosMenu.top = lastBottom+10
 
442
                textPosMenu.left = background.get_rect().centerx - textPosMenu.width/2
 
443
                screen.blit(textMenu, textPosMenu)
 
444
                lastBottom = textPosMenu.bottom
 
445
 
 
446
                # Draw options - Quit
 
447
                color = (255, 255, 255)
 
448
                if self.menuSelect == 2:
 
449
                        color = (0, 255, 0)
 
450
                textMenu = self.fontMenu.render("Quit", 1, color)
 
451
                textPosMenu = textMenu.get_rect()
 
452
                textPosMenu.top = lastBottom+10
 
453
                textPosMenu.left = background.get_rect().centerx - textPosMenu.width/2
 
454
                screen.blit(textMenu, textPosMenu)
 
455
 
 
456
class HighScoreMenuMode:
 
457
        """This handles all the main menu activities of quitting, or starting a game, checking high score"""
 
458
        def __init__(self, gameControlObj, screenRect):
 
459
                self.gameControl = gameControlObj       # Mode can change to another mode by itself
 
460
                self.screenBoundary = screenRect
 
461
 
 
462
                # Create fonts
 
463
                self.fontMenu = pygame.font.Font(None, 30)
 
464
 
 
465
        def reset(self):
 
466
                return
 
467
 
 
468
        def eventHandle(self):
 
469
                # Quit on any keys
 
470
                if self.gameControl.gameEvent.keystate[K_RETURN]:
 
471
                        self.gameControl.setMode (0)
 
472
                if self.gameControl.gameEvent.keystate[K_SPACE]:
 
473
                        self.gameControl.setMode (0)
 
474
                
 
475
        def update(self):
 
476
                return
 
477
 
 
478
        def draw(self, background, screen):
 
479
                #Draw Everything
 
480
                screen.blit(background, (0, 0))
 
481
                
 
482
                # This could be more dynamic and function, but I dont really feel like it right now.
 
483
                
 
484
                # Draw options - New Game
 
485
                color = (255, 255, 255)
 
486
                textMenu = self.fontMenu.render("High Scores", 1, color)
 
487
                textPosMenu = textMenu.get_rect()
 
488
                textPosMenu.bottom = background.get_rect().centery - textPosMenu.height
 
489
                textPosMenu.left = background.get_rect().centerx - textPosMenu.width/2
 
490
                screen.blit(textMenu, textPosMenu)
 
491
                lastBottom = textPosMenu.bottom
 
492
 
 
493
                # Draw options - High Score
 
494
                color = (255, 255, 255)
 
495
                textMenu = self.fontMenu.render("----", 1, color)
 
496
                textPosMenu = textMenu.get_rect()
 
497
                textPosMenu.top = lastBottom+10
 
498
                textPosMenu.left = background.get_rect().centerx - textPosMenu.width/2
 
499
                screen.blit(textMenu, textPosMenu)
 
500
                lastBottom = textPosMenu.bottom
 
501
 
 
502
                # Draw options - Quit
 
503
                color = (255, 255, 255)
 
504
                textMenu = self.fontMenu.render("----", 1, color)
 
505
                textPosMenu = textMenu.get_rect()
 
506
                textPosMenu.top = lastBottom+10
 
507
                textPosMenu.left = background.get_rect().centerx - textPosMenu.width/2
 
508
                screen.blit(textMenu, textPosMenu)
 
509
 
 
510
class GameEvent:
 
511
        """Event system wrapped so that it is based on time things were pressed.  
 
512
                Otherwise repeats occur that we dont desire."""
 
513
                
 
514
        def __init__(self):
 
515
                # Run update to init all the variables
 
516
                self.keystate = None
 
517
                self.update()
 
518
 
 
519
        def update(self):
 
520
                pygame.event.pump() #keep messages alive
 
521
 
 
522
                # Get the key state
 
523
                if self.keystate:
 
524
                        oldstate = self.keystate
 
525
                        self.keystate = pygame.key.get_pressed()
 
526
                        self.newkeys = map(lambda o,c: c and not o, oldstate, self.keystate)
 
527
                else:
 
528
                        self.keystate = pygame.key.get_pressed()
 
529
                        self.newkeys = self.keystate
 
530
 
 
531
                # Get the mouse data
 
532
                self.mousePos = pygame.mouse.get_pos()
 
533
                self.mouseButtons = pygame.mouse.get_pressed()
 
534
 
 
535
                # Get the time
 
536
                self.ticks = pygame.time.get_ticks()
 
537
 
 
538
class GameControl:
 
539
        """This saves the state that the game is in: what mode we're in, etc.  
 
540
                This is different than GameState because it deals with the play state."""
 
541
        def __init__(self):
 
542
                self.gameEvent = GameEvent()
 
543
                self.modeCur = 0
 
544
                self.modes = []
 
545
                return
 
546
                
 
547
        def addMode(self, newMode):
 
548
                """Insert the new mode into the modes list"""
 
549
                self.modes.insert (len(self.modes), newMode)
 
550
                
 
551
        def setMode(self, newMode):
 
552
                """Set the new mode, and reset it"""
 
553
                self.modeCur = newMode
 
554
                
 
555
                # If we didn't set the mode to exit
 
556
                if self.modeCur != -1:
 
557
                        self.modes[self.modeCur].reset()                
 
558
 
 
559
        def update(self):
 
560
                """Update the current mode and events"""
 
561
                self.gameEvent.update()
 
562
                
 
563
                if self.modeCur != -1:
 
564
                        self.modes[self.modeCur].eventHandle()
 
565
                        
 
566
                if self.modeCur != -1:
 
567
                        self.modes[self.modeCur].update()
 
568
 
 
569
        def draw(self, background, screen):
 
570
                if self.modeCur != -1:
 
571
                        self.modes[self.modeCur].draw(background, screen)
 
572
 
 
573
 
 
574
def main():
 
575
        """this function is called when the program starts.
 
576
           it initializes everything it needs, then runs in
 
577
           a loop until the function returns."""
 
578
           
 
579
        #Initialize Everything
 
580
        pygame.init()
 
581
        screen = pygame.display.set_mode((640, 480))
 
582
        pygame.display.set_caption('�berBall')
 
583
        pygame.mouse.set_visible(0)
 
584
        pygame.event.set_grab(1)
 
585
        
 
586
        #Create The Backgound
 
587
        background = pygame.Surface(screen.get_size())
 
588
        background = background.convert()
 
589
        background.fill((0, 0, 0))
 
590
        
 
591
        #Put Text On The Background, Centered
 
592
        if pygame.font:
 
593
                font = pygame.font.Font(None, 36)
 
594
                text = font.render("�berBall", 1, (255, 255, 255))
 
595
                textpos = text.get_rect()
 
596
                textpos.centerx = background.get_rect().centerx
 
597
                background.blit(text, textpos)
 
598
                lastBot = textpos.bottom
 
599
                
 
600
                font = pygame.font.Font(None, 20)
 
601
                text = font.render("by Geoff Howland", 1, (255, 255, 255))
 
602
                textpos = text.get_rect()
 
603
                textpos.centerx = background.get_rect().centerx
 
604
                textpos.top = lastBot + 10
 
605
                background.blit(text, textpos)
 
606
 
 
607
 
 
608
        # Create clock to lock framerate
 
609
        clock = pygame.time.Clock()
 
610
 
 
611
        # Create the game control object and add the game modes
 
612
        gameControl = GameControl()
 
613
        gameControl.addMode( MainMenuMode (gameControl, screen.get_rect()) )
 
614
        gameControl.addMode( HighScoreMenuMode (gameControl, screen.get_rect()) )
 
615
        gameControl.addMode( GameMode (gameControl, screen.get_rect()) )
 
616
 
 
617
        # Main Loop
 
618
        while 1:
 
619
                # Lock the framerate
 
620
                clock.tick(60)
 
621
        
 
622
                # Handle the modes
 
623
                gameControl.update()
 
624
                gameControl.draw(background, screen)
 
625
 
 
626
                # Handle game exit
 
627
                if gameControl.modeCur == -1:
 
628
                        return
 
629
 
 
630
                # Flip to front
 
631
                pygame.display.flip()
 
632
 
 
633
 
 
634
#this calls the 'main' function when this script is executed
 
635
if __name__ == '__main__': main()