├── README.md ├── brickout-game ├── README.md ├── classDiagram.png └── game.py ├── lunarlander.py ├── lunarlander ├── lander.ai ├── lander.jpg └── lander_flame.jpg ├── snake.py └── snake2.py /README.md: -------------------------------------------------------------------------------- 1 | # Pygame Examples 2 | 3 | I always learn better from examples -- a long tutorial explaining the 4 | background doesn't do it for me. To that end, here's a collection of 5 | [PyGame](http://pygame.org) example games I've developed in the 6 | process of learning PyGame. 7 | 8 | Right now there's: 9 | 10 | - `snake.py`: a simple ~100-line version of Snake. 11 | - `lunarlander.py`: a slightly-more-complicated Lunar Lander game. 12 | 13 | Happy coding! 14 | -------------------------------------------------------------------------------- /brickout-game/README.md: -------------------------------------------------------------------------------- 1 | # Brickout-Game in pygame 2 | 3 | This is a simple brickout-game. It's includes ball, paddle, brick wall 4 | and additional collision detection between this objects. Furthermore logic for winning and losing and 5 | scoring. The game is written in **Python 2**. 6 | 7 | You start the game with ```python game.py``` 8 | 9 | The game runs with 60 frames per second. 10 | 11 | I used a code sample for the basic structure of pygame from this site [http://programarcadegames.com/](http://programarcadegames.com/) 12 | The site contains a comprehensive introduction in Python and Pygame. In addition many many examples. 13 | 14 | -------------------------------------------------------------------------------- /brickout-game/classDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ternus/pygame-examples/6649f4e0362622841a5408d8a55cb18ec4376ad8/brickout-game/classDiagram.png -------------------------------------------------------------------------------- /brickout-game/game.py: -------------------------------------------------------------------------------- 1 | """ 2 | Pygame base template for opening a window 3 | 4 | Sample Python/Pygame Programs 5 | Simpson College Computer Science 6 | http://programarcadegames.com/ 7 | http://simpson.edu/computer-science/ 8 | 9 | Explanation video: http://youtu.be/vRB_983kUMc 10 | 11 | ------------------------------------------------- 12 | 13 | Author for the Brickout game is Christian Bender 14 | That includes the classes Ball, Paddle, Brick, and BrickWall. 15 | 16 | """ 17 | 18 | import pygame 19 | 20 | 21 | # Define some colors 22 | BLACK = (0, 0, 0) 23 | WHITE = (255, 255, 255) 24 | GREEN = (0, 255, 0) 25 | RED = (255, 0, 0) 26 | 27 | pygame.init() 28 | 29 | # Set the width and height of the screen [width, height] 30 | size = (700, 500) 31 | screen = pygame.display.set_mode(size) 32 | 33 | """ 34 | This is a simple Ball class for respresenting a ball 35 | in the game. 36 | """ 37 | class Ball(object): 38 | def __init__ (self, screen, radius,x,y): 39 | self.__screen = screen 40 | self._radius = radius 41 | self._xLoc = x 42 | self._yLoc = y 43 | self.__xVel = 5 44 | self.__yVel = -3 45 | w, h = pygame.display.get_surface().get_size() 46 | self.__width = w 47 | self.__height = h 48 | def draw(self): 49 | """ 50 | draws the ball onto screen. 51 | """ 52 | pygame.draw.circle(screen,(255, 0, 0) , (self._xLoc,self._yLoc), self._radius) 53 | def update(self, paddle, brickwall): 54 | """ 55 | moves the ball at the screen. 56 | contains some collision detection. 57 | """ 58 | self._xLoc += self.__xVel 59 | self._yLoc += self.__yVel 60 | if self._xLoc == self._radius: 61 | self.__xVel *= -1 62 | elif self._xLoc >= self.__width - self._radius: 63 | self.__xVel *= -1 64 | if self._yLoc == self._radius: 65 | self.__yVel *= -1 66 | elif self._yLoc >= self.__height - self._radius: 67 | return True 68 | 69 | # for bouncing off the bricks. 70 | if brickwall.collide(self): 71 | self.__yVel *= -1 72 | 73 | # collision deection between ball and paddle 74 | paddleX = paddle._xLoc 75 | paddleY = paddle._yLoc 76 | paddleW = paddle._width 77 | paddleH = paddle._height 78 | ballX = self._xLoc 79 | ballY = self._yLoc 80 | 81 | if ((ballX + self._radius) >= paddleX and ballX <= (paddleX + paddleW)) \ 82 | and ((ballY + self._radius) >= paddleY and ballY <= (paddleY + paddleH)): 83 | self.__yVel *= -1 84 | 85 | return False 86 | 87 | 88 | """ 89 | Simple class for representing a paddle 90 | """ 91 | class Paddle (object): 92 | def __init__ (self, screen, width, height,x,y): 93 | self.__screen = screen 94 | self._width = width 95 | self._height = height 96 | self._xLoc = x 97 | self._yLoc = y 98 | w, h = pygame.display.get_surface().get_size() 99 | self.__W = w 100 | self.__H = h 101 | def draw(self): 102 | """ 103 | draws the paddle onto screen. 104 | """ 105 | pygame.draw.rect(screen, (0,0,0), (self._xLoc,self._yLoc,self._width,self._height),0) 106 | def update(self): 107 | """ 108 | moves the paddle at the screen via mouse 109 | """ 110 | x,y = pygame.mouse.get_pos() 111 | if x >= 0 and x <= (self.__W - self._width): 112 | self._xLoc = x 113 | 114 | """ 115 | This class represents a simple Brick class. 116 | For representing bricks onto screen. 117 | """ 118 | class Brick (pygame.sprite.Sprite): 119 | def __init__(self, screen, width, height, x,y): 120 | self.__screen = screen 121 | self._width = width 122 | self._height = height 123 | self._xLoc = x 124 | self._yLoc = y 125 | w, h = pygame.display.get_surface().get_size() 126 | self.__W = w 127 | self.__H = h 128 | self.__isInGroup = False 129 | def draw(self): 130 | """ 131 | draws the brick onto screen. 132 | color: rgb(56, 177, 237) 133 | """ 134 | pygame.draw.rect(screen, (56, 177, 237), (self._xLoc,self._yLoc,self._width,self._height),0) 135 | def add (self, group): 136 | """ 137 | adds this brick to a given group. 138 | """ 139 | group.add(self) 140 | self.__isInGroup = True 141 | def remove(self, group): 142 | """ 143 | removes this brick from the given group. 144 | """ 145 | group.remove(self) 146 | self.__isInGroup = False 147 | def alive(self): 148 | """ 149 | returns true when this brick is belong to the brick wall. 150 | otherwise false 151 | """ 152 | return self.__isInGroup 153 | 154 | def collide(self, ball): 155 | """ 156 | collision deection between ball and this brick 157 | """ 158 | brickX = self._xLoc 159 | brickY = self._yLoc 160 | brickW = self._width 161 | brickH = self._height 162 | ballX = ball._xLoc 163 | ballY = ball._yLoc 164 | radius = ball._radius 165 | 166 | if ((ballX + radius) >= brickX and ballX <= (brickX + brickW)) \ 167 | and ((ballY + radius) >= brickY and ballY <= (brickY + brickH)): 168 | return True 169 | 170 | return False 171 | 172 | 173 | """ 174 | This is a simple class for representing a 175 | brick wall. 176 | """ 177 | class BrickWall (pygame.sprite.Group): 178 | def __init__ (self,screen, x, y, width, height): 179 | self.__screen = screen 180 | self._x = x 181 | self._y = y 182 | self._width = width 183 | self._height = height 184 | self._bricks = [] 185 | 186 | X = x 187 | Y = y 188 | for i in range(3): 189 | for j in range(4): 190 | self._bricks.append(Brick(screen,width,height,X,Y)) 191 | X += width + (width/ 7.0) 192 | Y += height + (height / 7.0) 193 | X = x 194 | 195 | def add(self,brick): 196 | """ 197 | adds a brick to this BrickWall (group) 198 | """ 199 | self._bricks.append(brick) 200 | def remove(self,brick): 201 | """ 202 | removes a brick from this BrickWall (group) 203 | """ 204 | self._bricks.remove(brick) 205 | def draw(self): 206 | """ 207 | draws all bricks onto screen. 208 | """ 209 | for brick in self._bricks: 210 | if brick != None: 211 | brick.draw() 212 | def update(self, ball): 213 | """ 214 | checks collision between ball and bricks. 215 | """ 216 | for i in range(len(self._bricks)): 217 | if ((self._bricks[i] != None) and self._bricks[i].collide(ball)): 218 | self._bricks[i] = None 219 | 220 | # removes the None-elements from the brick list. 221 | for brick in self._bricks: 222 | if brick == None: 223 | self._bricks.remove(brick) 224 | def hasWin(self): 225 | """ 226 | Has player win the game? 227 | """ 228 | return len(self._bricks) == 0 229 | def collide (self, ball): 230 | """ 231 | check collisions between the ball and 232 | any of the bricks. 233 | """ 234 | for brick in self._bricks: 235 | if brick.collide(ball): 236 | return True 237 | return False 238 | 239 | # The game objects ball, paddle and brick wall 240 | ball = Ball(screen,25,350,250) 241 | paddle = Paddle(screen,100,20,250,450) 242 | brickWall = BrickWall(screen,25,25,150,50) 243 | 244 | isGameOver = False # determines whether game is lose 245 | gameStatus = True # game is still running 246 | 247 | score = 0 # score for the game. 248 | 249 | pygame.display.set_caption("Brickout-game") 250 | 251 | # Loop until the user clicks the close button. 252 | done = False 253 | 254 | # Used to manage how fast the screen updates 255 | clock = pygame.time.Clock() 256 | 257 | # for displaying text in the game 258 | pygame.font.init() # you have to call this at the start, 259 | # if you want to use this module. 260 | 261 | # message for game over 262 | mgGameOver = pygame.font.SysFont('Comic Sans MS', 60) 263 | 264 | # message for winning the game. 265 | mgWin = pygame.font.SysFont('Comic Sans MS', 60) 266 | 267 | # message for score 268 | mgScore = pygame.font.SysFont('Comic Sans MS', 60) 269 | 270 | textsurfaceGameOver = mgGameOver.render('Game Over!', False, (0, 0, 0)) 271 | textsurfaceWin = mgWin.render("You win!",False,(0,0,0)) 272 | textsurfaceScore = mgScore.render("score: "+str(score),False,(0,0,0)) 273 | 274 | 275 | # -------- Main Program Loop ----------- 276 | while not done: 277 | # --- Main event loop 278 | for event in pygame.event.get(): 279 | if event.type == pygame.QUIT: 280 | done = True 281 | 282 | # --- Game logic should go here 283 | 284 | # --- Screen-clearing code goes here 285 | 286 | # Here, we clear the screen to white. Don't put other drawing commands 287 | # above this, or they will be erased with this command. 288 | 289 | # If you want a background image, replace this clear with blit'ing the 290 | # background image. 291 | screen.fill(WHITE) 292 | 293 | # --- Drawing code should go here 294 | 295 | """ 296 | Because I use OOP in the game logic and the drawing code, 297 | are both in the same section. 298 | """ 299 | if gameStatus: 300 | 301 | # first draws ball for appropriate displaying the score. 302 | brickWall.draw() 303 | 304 | # for counting and displaying the score 305 | if brickWall.collide(ball): 306 | score += 10 307 | textsurfaceScore = mgScore.render("score: "+str(score),False,(0,0,0)) 308 | screen.blit(textsurfaceScore,(300,0)) 309 | 310 | # after scoring. because hit bricks are removed in the update-method 311 | brickWall.update(ball) 312 | 313 | paddle.draw() 314 | paddle.update() 315 | 316 | if ball.update(paddle, brickWall): 317 | isGameOver = True 318 | gameStatus = False 319 | 320 | if brickWall.hasWin(): 321 | gameStatus = False 322 | 323 | ball.draw() 324 | 325 | else: # game isn't running. 326 | if isGameOver: # player lose 327 | screen.blit(textsurfaceGameOver,(0,0)) 328 | textsurfaceScore = mgScore.render("score: "+str(score),False,(0,0,0)) 329 | screen.blit(textsurfaceScore,(300,0)) 330 | elif brickWall.hasWin(): # player win 331 | screen.blit(textsurfaceWin,(0,0)) 332 | textsurfaceScore = mgScore.render("score: "+str(score),False,(0,0,0)) 333 | screen.blit(textsurfaceScore,(300,0)) 334 | 335 | # --- Go ahead and update the screen with what we've drawn. 336 | pygame.display.flip() 337 | 338 | # --- Limit to 60 frames per second 339 | clock.tick(60) 340 | 341 | # Close the window and quit. 342 | pygame.quit() -------------------------------------------------------------------------------- /lunarlander.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import pygame 4 | import sys 5 | import time 6 | import os 7 | import random 8 | import math 9 | 10 | from pygame.locals import RLEACCEL, QUIT, K_r, K_SPACE, K_UP, K_LEFT, K_RIGHT 11 | #from pygame.locals import * 12 | 13 | FPS = 80 14 | 15 | pygame.init() 16 | 17 | fpsClock=pygame.time.Clock() 18 | 19 | SCREEN_WIDTH, SCREEN_HEIGHT = 800, 600 20 | ARENA_WIDTH, ARENA_HEIGHT = 10 * SCREEN_WIDTH, 10 * SCREEN_HEIGHT 21 | 22 | screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32) 23 | surface = pygame.Surface(screen.get_size()) 24 | surface = surface.convert() 25 | surface.fill((255,255,255)) 26 | clock = pygame.time.Clock() 27 | 28 | pygame.key.set_repeat(1, 1) 29 | 30 | def load_image(name, colorkey=None): 31 | fullname = os.path.join('lunarlander', name) 32 | try: 33 | image = pygame.image.load(fullname) 34 | except pygame.error, message: 35 | print 'Cannot load image:', fullname 36 | raise SystemExit(message) 37 | image = image.convert() 38 | if colorkey is not None: 39 | if colorkey is -1: 40 | colorkey = image.get_at((0,0)) 41 | image.set_colorkey(colorkey, RLEACCEL) 42 | return image, image.get_rect() 43 | 44 | class V(object): 45 | """ 46 | A simple class to keep track of vectors, including initializing 47 | from Cartesian and polar forms. 48 | """ 49 | def __init__(self, x=0, y=0, angle=None, magnitude=None): 50 | self.x = x 51 | self.y = y 52 | 53 | if (angle is not None and magnitude is not None): 54 | self.x = magnitude * math.sin(math.radians(angle)) 55 | self.y = magnitude * math.cos(math.radians(angle)) 56 | 57 | @property 58 | def magnitude(self): 59 | return math.sqrt(self.x ** 2 + self.y ** 2) 60 | 61 | @property 62 | def angle(self): 63 | if self.y == 0: 64 | if self.x > 0: 65 | return 90.0 66 | else: 67 | return 270.0 68 | if math.floor(self.x) == 0: 69 | if self.y < 0: 70 | return 180.0 71 | return math.degrees(math.atan(self.x / float(self.y))) 72 | 73 | def __add__(self, other): 74 | return V(x=(self.x + other.x), y=(self.y + other.y)) 75 | 76 | def rotate(self, angle): 77 | c = math.cos(math.radians(angle)) 78 | s = math.sin(math.radians(angle)) 79 | self.x = self.x * c - self.y * s 80 | self.y = self.x * s + self.y * c 81 | 82 | def __str__(self): 83 | return "X: %.3d Y: %.3d Angle: %.3d degrees Magnitude: %.3d" % (self.x, self.y, self.angle, self.magnitude) 84 | 85 | class Lander(pygame.sprite.DirtySprite): 86 | """ 87 | Our intrepid lunar lander! 88 | """ 89 | def __init__(self): 90 | self.image, self.rect = load_image('lander.jpg', -1) 91 | 92 | self.original = self.image 93 | self.original_flame, self.flame_rect = load_image('lander_flame.jpg', -1) 94 | 95 | self.mass = 10 96 | self.orientation = 0.0 # 97 | self.rect.topleft = ((SCREEN_WIDTH / 2), 20) # The starting point. 98 | self.engine_power = 2 # The power of the engine. 99 | self.velocity = V(0.0,0.0) # Starting velocity. 100 | self.landed = False # Have we landed yet? 101 | self.intact = True # Is the ship still shipshape? 102 | self.fuel = 100 # Units of fuel 103 | self.boosting = 0 # Are we in "boost" mode? (show the flame graphic) 104 | return super(pygame.sprite.DirtySprite, self).__init__() 105 | 106 | def update_image(self): 107 | """ 108 | Update our image based on orientation and engine state of the craft. 109 | """ 110 | img = self.original_flame if self.boosting else self.original 111 | center = self.rect.center 112 | self.image = pygame.transform.rotate(img, -1 * self.orientation) 113 | self.rect = self.image.get_rect(center=center) 114 | 115 | def rotate(self, angle): 116 | """ 117 | Rotate the craft. 118 | """ 119 | self.orientation += angle 120 | 121 | def boost(self): 122 | """ 123 | Provide a boost to our craft's velocity in whatever orientation we're currently facing. 124 | """ 125 | if not self.fuel: return 126 | self.velocity += V(magnitude=self.engine_power, angle=self.orientation) 127 | self.fuel -= 1 128 | if self.landed: 129 | self.landed = False 130 | np = self.rect.move(0, -5) 131 | self.rect = np 132 | self.boosting = 3 133 | 134 | def physics_update(self): 135 | if not self.landed: 136 | self.velocity += V(magnitude=.5, angle=180) 137 | 138 | def ok_to_land(self): 139 | return (self.orientation < 10 or self.orientation > 350) and self.velocity.magnitude < 5 140 | 141 | def check_landed(self, surface): 142 | if self.landed: return 143 | if hasattr(surface, "radius"): 144 | collision = pygame.sprite.collide_circle(self, surface) 145 | else: 146 | collision = pygame.sprite.collide_rect(self, surface) 147 | if collision: 148 | self.landed = True 149 | if self.ok_to_land() and surface.landing_ok: 150 | self.intact = True 151 | else: 152 | # Hard landing, kaboom! 153 | self.intact = False 154 | self.velocity = V(0.0,0.0) # In any case, we stop moving. 155 | 156 | def update(self): 157 | self.physics_update() # Iterate physics 158 | if self.boosting: 159 | self.boosting -= 1 # Tick over engine time 160 | self.update_image() 161 | np = self.rect.move(self.velocity.x, -1 * self.velocity.y) 162 | self.rect = np 163 | self.dirty = True 164 | 165 | def explode(self, screen): 166 | for i in range(random.randint(20,40)): 167 | pygame.draw.line(screen, 168 | (random.randint(190, 255), 169 | random.randint(0,100), 170 | random.randint(0,100)), 171 | self.rect.center, 172 | (random.randint(0, SCREEN_WIDTH), 173 | random.randint(0, SCREEN_HEIGHT)), 174 | random.randint(1,3)) 175 | 176 | def stats(self): 177 | return "Position: [%.2d,%.2d] Velocity: %.2f m/s at %.3d degrees Orientation: %.3d degrees Fuel: %d Status: [%s]" % (self.rect.top, self.rect.left, self.velocity.magnitude, self.velocity.angle, self.orientation, self.fuel, ("Crashed" if not self.intact else ("Landed" if self.landed else ("OK to Land" if self.ok_to_land() else "Not OK")))) 178 | 179 | 180 | class Moon(pygame.sprite.DirtySprite): 181 | def __init__(self): 182 | self.width = SCREEN_WIDTH+20 183 | self.height = 20 184 | self.image = pygame.Surface((self.width, self.height)) 185 | self.rect = pygame.Rect(-10, SCREEN_HEIGHT - 20, SCREEN_WIDTH + 20, 20) 186 | self.landing_ok = True 187 | return super(pygame.sprite.DirtySprite, self).__init__() 188 | 189 | 190 | class Boulder(pygame.sprite.DirtySprite): 191 | def __init__(self): 192 | self.diameter = random.randint(2, 300) 193 | self.radius = self.diameter / 2 194 | self.x_pos = random.randint(0, SCREEN_WIDTH) 195 | self.image = pygame.Surface((self.diameter, self.diameter)) 196 | #self.image.fill((255,255,255,128)) 197 | pygame.draw.circle(self.image, (128,128,128), (self.radius, self.radius), self.radius) 198 | self.rect = pygame.Rect(self.x_pos, SCREEN_HEIGHT - (20 + self.radius), 199 | self.diameter, self.diameter) 200 | self.image = self.image.convert() 201 | self.landing_ok = False 202 | self.dirty = False 203 | return super(pygame.sprite.DirtySprite, self).__init__() 204 | 205 | 206 | def initialize(): 207 | lander = Lander() 208 | moon = Moon() 209 | sprites = [lander] 210 | boulders = [Boulder() for i in range(random.randint(2,5))] 211 | sprites.extend(boulders) 212 | sprites.append(moon) 213 | return lander, moon, boulders, pygame.sprite.RenderPlain(sprites) 214 | 215 | 216 | if __name__ == '__main__': 217 | 218 | lander, moon, boulders, allsprites = initialize() 219 | 220 | while True: 221 | 222 | pygame.event.pump() 223 | keys = pygame.key.get_pressed() 224 | 225 | for event in pygame.event.get(): 226 | 227 | if event.type == QUIT: 228 | pygame.quit() 229 | sys.exit() 230 | 231 | if keys[K_r]: 232 | lander, moon, boulders, allsprites = initialize() 233 | elif keys[K_SPACE] or keys[K_UP]: 234 | lander.boost() 235 | elif keys[K_LEFT]: 236 | lander.rotate(-5) 237 | elif keys[K_RIGHT]: 238 | lander.rotate(5) 239 | 240 | lander.check_landed(moon) 241 | for boulder in boulders: 242 | lander.check_landed(boulder) 243 | 244 | surface.fill((255,255,255)) 245 | 246 | font = pygame.font.Font(None, 14) 247 | 248 | text = font.render(lander.stats(), 1, (10, 10, 10)) 249 | textpos = text.get_rect() 250 | textpos.centerx = SCREEN_WIDTH / 2 251 | surface.blit(text, textpos) 252 | screen.blit(surface, (0,0)) 253 | allsprites.update() 254 | allsprites.draw(screen) 255 | 256 | def render_center_text(surface, screen, txt, color): 257 | font2 = pygame.font.Font(None, 36) 258 | text = font2.render(txt, 1, color) 259 | textpos = text.get_rect() 260 | textpos.centerx = SCREEN_WIDTH / 2 261 | textpos.centery = SCREEN_HEIGHT / 2 262 | surface.blit(text, textpos) 263 | screen.blit(surface, (0,0)) 264 | 265 | if lander.landed: 266 | if not lander.intact: 267 | lander.explode(screen) 268 | #render_center_text(surface, screen, "Kaboom! Your craft is destroyed.", (255,0,0)) 269 | else: 270 | render_center_text(surface, screen, "You landed successfully!", (0,255,0)) 271 | 272 | pygame.display.flip() 273 | pygame.display.update() 274 | time.sleep(1) 275 | lander, moon, boulders, allsprites = initialize() 276 | else: 277 | pygame.display.flip() 278 | pygame.display.update() 279 | 280 | fpsClock.tick(FPS) # and tick the clock. 281 | -------------------------------------------------------------------------------- /lunarlander/lander.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ternus/pygame-examples/6649f4e0362622841a5408d8a55cb18ec4376ad8/lunarlander/lander.ai -------------------------------------------------------------------------------- /lunarlander/lander.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ternus/pygame-examples/6649f4e0362622841a5408d8a55cb18ec4376ad8/lunarlander/lander.jpg -------------------------------------------------------------------------------- /lunarlander/lander_flame.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ternus/pygame-examples/6649f4e0362622841a5408d8a55cb18ec4376ad8/lunarlander/lander_flame.jpg -------------------------------------------------------------------------------- /snake.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import pygame 4 | import sys 5 | import time 6 | import random 7 | 8 | from pygame.locals import * 9 | 10 | FPS = 15 11 | pygame.init() 12 | fpsClock=pygame.time.Clock() 13 | 14 | SCREEN_WIDTH, SCREEN_HEIGHT = 640, 480 15 | screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32) 16 | surface = pygame.Surface(screen.get_size()) 17 | surface = surface.convert() 18 | surface.fill((255,255,255)) 19 | clock = pygame.time.Clock() 20 | 21 | pygame.key.set_repeat(1, 40) 22 | 23 | GRIDSIZE=10 24 | GRID_WIDTH = SCREEN_WIDTH / GRIDSIZE 25 | GRID_HEIGHT = SCREEN_HEIGHT / GRIDSIZE 26 | UP = (0, -1) 27 | DOWN = (0, 1) 28 | LEFT = (-1, 0) 29 | RIGHT = (1, 0) 30 | 31 | screen.blit(surface, (0,0)) 32 | 33 | def draw_box(surf, color, pos): 34 | r = pygame.Rect((pos[0], pos[1]), (GRIDSIZE, GRIDSIZE)) 35 | pygame.draw.rect(surf, color, r) 36 | 37 | class Snake(object): 38 | def __init__(self): 39 | self.lose() 40 | self.color = (0,0,0) 41 | 42 | def get_head_position(self): 43 | return self.positions[0] 44 | 45 | def lose(self): 46 | self.length = 1 47 | self.positions = [((SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2))] 48 | self.direction = random.choice([UP, DOWN, LEFT, RIGHT]) 49 | 50 | def point(self, pt): 51 | if self.length > 1 and (pt[0] * -1, pt[1] * -1) == self.direction: 52 | return 53 | else: 54 | self.direction = pt 55 | 56 | def move(self): 57 | cur = self.positions[0] 58 | x, y = self.direction 59 | new = (((cur[0]+(x*GRIDSIZE)) % SCREEN_WIDTH), (cur[1]+(y*GRIDSIZE)) % SCREEN_HEIGHT) 60 | if len(self.positions) > 2 and new in self.positions[2:]: 61 | self.lose() 62 | else: 63 | self.positions.insert(0, new) 64 | if len(self.positions) > self.length: 65 | self.positions.pop() 66 | 67 | def draw(self, surf): 68 | for p in self.positions: 69 | draw_box(surf, self.color, p) 70 | 71 | class Apple(object): 72 | def __init__(self): 73 | self.position = (0,0) 74 | self.color = (255,0,0) 75 | self.randomize() 76 | 77 | def randomize(self): 78 | self.position = (random.randint(0, GRID_WIDTH-1) * GRIDSIZE, random.randint(0, GRID_HEIGHT-1) * GRIDSIZE) 79 | 80 | def draw(self, surf): 81 | draw_box(surf, self.color, self.position) 82 | 83 | def check_eat(snake, apple): 84 | if snake.get_head_position() == apple.position: 85 | snake.length += 1 86 | apple.randomize() 87 | 88 | 89 | class Rock (object): 90 | def __init__(self): 91 | self.position = (0,0) 92 | self.color = (160,80,30) 93 | self.randomize() 94 | 95 | def randomize(self): 96 | self.position = (random.randint(0, GRID_WIDTH-1) * GRIDSIZE, random.randint(0, GRID_HEIGHT-1) * GRIDSIZE) 97 | 98 | def draw(self, surf): 99 | draw_box(surf, self.color, self.position) 100 | 101 | def check_smash(snake, rock): 102 | if snake.get_head_position() == rock.position: 103 | snake.lose() 104 | 105 | 106 | 107 | if __name__ == '__main__': 108 | snake = Snake() 109 | apple = Apple() 110 | rock = Rock() 111 | while True: 112 | 113 | for event in pygame.event.get(): 114 | if event.type == QUIT: 115 | pygame.quit() 116 | sys.exit() 117 | elif event.type == KEYDOWN: 118 | if event.key == K_UP: 119 | snake.point(UP) 120 | elif event.key == K_DOWN: 121 | snake.point(DOWN) 122 | elif event.key == K_LEFT: 123 | snake.point(LEFT) 124 | elif event.key == K_RIGHT: 125 | snake.point(RIGHT) 126 | 127 | 128 | surface.fill((255,255,255)) 129 | snake.move() 130 | check_eat(snake, apple) 131 | check_smash(snake, rock) 132 | snake.draw(surface) 133 | apple.draw(surface) 134 | rock.draw(surface) 135 | font = pygame.font.Font(None, 36) 136 | text = font.render(str(snake.length), 1, (10, 10, 10)) 137 | textpos = text.get_rect() 138 | textpos.centerx = 20 139 | surface.blit(text, textpos) 140 | screen.blit(surface, (0,0)) 141 | 142 | pygame.display.flip() 143 | pygame.display.update() 144 | fpsClock.tick(FPS + snake.length/3) 145 | -------------------------------------------------------------------------------- /snake2.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import sys 3 | import time 4 | import random 5 | 6 | from pygame.locals import * 7 | 8 | snap_time = 0 9 | #rainbow_berry_effects = 0 10 | FPS = 15 11 | pygame.init() 12 | fpsClock=pygame.time.Clock() 13 | 14 | SCREEN_WIDTH, SCREEN_HEIGHT = 800, 800 15 | screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32) 16 | surface = pygame.Surface(screen.get_size()) 17 | surface = surface.convert() 18 | surface.fill((255,255,255)) 19 | clock = pygame.time.Clock() 20 | 21 | pygame.key.set_repeat(1, 40) 22 | 23 | GRIDSIZE=10 24 | GRID_WIDTH = SCREEN_WIDTH / GRIDSIZE 25 | GRID_HEIGHT = SCREEN_HEIGHT / GRIDSIZE 26 | UP = (0, -1) 27 | DOWN = (0, 1) 28 | LEFT = (-1, 0) 29 | RIGHT = (1, 0) 30 | BERRY_TYPES = 5 31 | 32 | screen.blit(surface, (0,0)) 33 | 34 | 35 | def draw_box(surf, color, pos): 36 | r = pygame.Rect((pos[0], pos[1]), (GRIDSIZE, GRIDSIZE)) 37 | pygame.draw.rect(surf, color, r) 38 | 39 | class Snake(object): 40 | def __init__(self): 41 | self.lose() 42 | self.color = (0,0,0) 43 | self.snap_time = 0 44 | 45 | 46 | def get_head_position(self): 47 | return self.positions[0] 48 | 49 | def lose(self): 50 | print('You have lost. The game will restart shortly. Press "q" to quit') 51 | time.sleep(2.5) 52 | self.length = 1 53 | self.positions = [((SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2))] 54 | self.direction = random.choice([UP, DOWN, LEFT, RIGHT]) 55 | 56 | def point(self, pt): 57 | if self.length > 1 and (pt[0] * -1, pt[1] * -1) == self.direction: 58 | return 59 | else: 60 | self.direction = pt 61 | 62 | def move(self): 63 | cur = self.positions[0] 64 | x, y = self.direction 65 | # if timer expires, set in_boost_snap to false 66 | cur_speed_time = time.time() 67 | if cur_speed_time - self.snap_time >= 5: 68 | speed = 1 69 | # print("timer is off " + str(cur_time) + " " + str(self.snap_time)) 70 | self.snap_time = 0 71 | else: 72 | speed = 2 73 | # print("timer is on " + str(cur_time) + str(self.snap_time)) 74 | 75 | new = (((cur[0]+(x*speed*GRIDSIZE)) % SCREEN_WIDTH), (cur[1]+(y*speed*GRIDSIZE)) % SCREEN_HEIGHT) 76 | if len(self.positions) > 2 and new in self.positions[2:]: 77 | self.lose() 78 | else: 79 | self.positions.insert(0, new) 80 | if len(self.positions) > self.length: 81 | self.positions.pop() 82 | 83 | def draw(self, surf): 84 | for p in self.positions: 85 | draw_box(surf, self.color, p) 86 | 87 | class Apple(object): 88 | def __init__(self): 89 | self.position = (0,0) 90 | self.color = (255,0,0) 91 | self.randomize() 92 | 93 | def randomize(self): 94 | self.position = (random.randint(0, GRID_WIDTH-1) * GRIDSIZE, random.randint(0, GRID_HEIGHT-1) * GRIDSIZE) 95 | 96 | def draw(self, surf): 97 | draw_box(surf, self.color, self.position) 98 | 99 | def check_eat_apple(snake, apple): 100 | if snake.get_head_position() == apple.position: 101 | snake.length += 1 102 | apple.randomize() 103 | 104 | class Blueberry(object): 105 | def __init__(self): 106 | self.position = (0,0) 107 | self.color = (0,0,255) 108 | self.randomize() 109 | 110 | def randomize(self): 111 | self.position = (random.randint(0, GRID_WIDTH-1) * GRIDSIZE, random.randint(0, GRID_HEIGHT-1) * GRIDSIZE) 112 | 113 | def draw(self, surf): 114 | draw_box(surf, self.color, self.position) 115 | 116 | def check_eat_blueberry(snake, Blueberry): 117 | if snake.get_head_position() == blueberry.position: 118 | #start timer for 5-10 seconds 119 | snake.snap_time = time.time() 120 | print("""You have eaten a blueberry. 121 | Your speed will be doubled for the next 5 seconds. 122 | _______________________________________________________""") 123 | time.sleep(1) 124 | snake.length += 5 125 | Blueberry.randomize() 126 | 127 | 128 | 129 | 130 | class Rock (object): 131 | def __init__(self): 132 | self.position = (0,0) 133 | self.color = (160,80,30) 134 | self.randomize() 135 | 136 | def randomize(self): 137 | self.position = (random.randint(0, GRID_WIDTH-1) * GRIDSIZE, 138 | random.randint(0, GRID_HEIGHT-1) * GRIDSIZE) 139 | 140 | def draw(self, surf): 141 | draw_box(surf, self.color, self.position) 142 | 143 | def check_smash_rock(snake, rock): 144 | if snake.get_head_position() == rock.position: 145 | snake.lose() 146 | 147 | 148 | class Thorns (object): 149 | def __init__(self): 150 | self.position = (0,0) 151 | self.color = (50,135,50) 152 | self.randomize() 153 | 154 | def randomize(self): 155 | self.position = (random.randint(0, GRID_WIDTH-1) * GRIDSIZE, 156 | random.randint(0, GRID_HEIGHT-1) * GRIDSIZE) 157 | 158 | def draw(self, surf): 159 | draw_box(surf, self.color, self.position) 160 | 161 | def check_smash_thorns(snake, thorns): 162 | if snake.get_head_position() == thorns.position: 163 | snake.lose() 164 | 165 | 166 | 167 | 168 | 169 | 170 | if __name__ == '__main__': 171 | #snake 172 | snake = Snake() 173 | 174 | #fruits 175 | apple = Apple() 176 | blueberry = Blueberry() 177 | #obstacles 178 | rock = Rock() 179 | thorns = Thorns() 180 | 181 | while True: 182 | for event in pygame.event.get(): 183 | if event.type == QUIT: 184 | pygame.quit() 185 | sys.exit() 186 | elif event.type == KEYDOWN: 187 | if event.key == K_UP or event.key == K_w: 188 | snake.point(UP) 189 | elif event.key == K_DOWN or event.key == K_s: 190 | snake.point(DOWN) 191 | elif event.key == K_LEFT or event.key == K_a: 192 | snake.point(LEFT) 193 | elif event.key == K_RIGHT or event.key == K_d: 194 | snake.point(RIGHT) 195 | elif event.key == K_q: 196 | sys.exit() 197 | 198 | 199 | surface.fill((255,255,255)) 200 | snake.move() 201 | 202 | #checking for collision 203 | check_eat_apple(snake, apple) 204 | check_eat_blueberry(snake, blueberry) 205 | check_smash_thorns(snake, thorns) 206 | check_smash_rock(snake, rock) 207 | 208 | #drawing everything 209 | snake.draw(surface) 210 | apple.draw(surface) 211 | blueberry.draw(surface) 212 | rock.draw(surface) 213 | thorns.draw(surface) 214 | 215 | #displaying the score 216 | font = pygame.font.Font(None, 36) 217 | text = font.render(str(snake.length), 1, (10, 10, 10)) 218 | textpos = text.get_rect() 219 | textpos.centerx = 20 220 | surface.blit(text, textpos) 221 | screen.blit(surface, (0,0)) 222 | 223 | #updating the screen 224 | pygame.display.flip() 225 | pygame.display.update() 226 | fpsClock.tick(FPS + snake.length/3) 227 | --------------------------------------------------------------------------------