├── Chapter01 ├── README.md ├── no_hello_world.py └── start_file.py ├── Chapter02 ├── README.md └── tic_tac_toe.py ├── Chapter03 ├── README.md ├── exceptionhandle.py ├── starter.py └── tictactoe.py ├── Chapter04 ├── README.md ├── boardcopy.py ├── packingkeyargs.py ├── tic-tac-toe_AI.py ├── tic_tac_toe_AI_start.py ├── unpackkeywordargs.py └── winner_AI.py ├── Chapter05 ├── README.md ├── curses_starter.py ├── keyboard_events.py ├── mouse_events.py ├── snake_final.py └── snake_starter.py ├── Chapter06 ├── Note ├── class_ex_2.py ├── classes_ex_1.py ├── constructor.py ├── decorator.py ├── encapsulation.py ├── encapsulation2.py ├── inheritance.py ├── method-overriding.py ├── multi-level-inheritance.py ├── setter.py ├── snake-game-OOP.py └── super.py ├── Chapter07 ├── Note ├── getter-setter7.py ├── property1.py ├── smart_multiply.py ├── using-property-method.py └── using-property.py ├── Chapter08 ├── Note ├── hexagon.py ├── keyboard-events.py ├── mouse-events.py ├── ontimer-star.py ├── star-color.py ├── turtle-for.py └── turtle-square.py ├── Chapter09 ├── Note ├── data-models-modified.py ├── data-models.py ├── new-data-model.py └── vector.py ├── Chapter10 ├── Note ├── ant.py ├── base.py ├── flappy.py ├── pong-update.py ├── pong.py └── snake.py ├── Chapter11 ├── Note ├── SnakeGameFinal.py ├── SnakeRect.py ├── apple.png ├── backbone.py ├── events.py ├── snakegameMainLoop.py └── snakehead.png ├── Chapter12 ├── Flappy_Bird │ ├── Note │ ├── background.png │ ├── bird.gif │ ├── bird_wing_down.png │ ├── bird_wing_up.png │ ├── flappybird.py │ ├── ground.png │ ├── pipe.png │ ├── pipe_body.png │ └── pipe_end.png ├── Note └── Sprites_Animation │ ├── Left1.png │ ├── Left2.png │ ├── Left3.png │ ├── Left4.png │ ├── Left5.png │ ├── Left6.png │ ├── Left7.png │ ├── Left8.png │ ├── Left9.png │ ├── Note │ ├── Right1.png │ ├── Right2.png │ ├── Right3.png │ ├── Right4.png │ ├── Right5.png │ ├── Right6.png │ ├── Right7.png │ ├── Right8.png │ ├── Right9.png │ ├── bg.jpg │ ├── sprite-animation.py │ └── standing.png ├── Chapter13 ├── Note └── tetris.py ├── Chapter14 ├── Note ├── draw.py └── draw_cube.py ├── Chapter15 ├── Note ├── characters.py ├── level.py ├── main.py ├── polygon.py └── res │ ├── Note │ ├── photos │ ├── Buttons.png │ ├── angry-birds-image.png │ ├── angry_birds.png │ ├── angry_birds_chrome_pigs_by_chinzapep-d5bnxdz.png │ ├── angry_birds_toons_sprites_by_jared33-d64u29w.png │ ├── background.png │ ├── background1.jpg │ ├── background2.jpg │ ├── background3.png │ ├── background4.png │ ├── buttons-image.png │ ├── column.png │ ├── full-sprite.png │ ├── gravity-zero.png │ ├── latest.png │ ├── pig_failed.png │ ├── red-bird.png │ ├── red-bird2.png │ ├── red-bird3.png │ ├── selected-buttons.png │ ├── sling-2.png │ ├── sling-3.png │ ├── sling.png │ ├── stars-edited.png │ ├── stars.png │ ├── walls.png │ ├── wood.png │ └── wood2.png │ └── sounds │ └── angry-birds.ogg ├── Chapter16 ├── App.py ├── Frog.py ├── Fullcode.py ├── Note ├── Player.py ├── frog-main.png ├── snake.png └── target.py ├── LICENSE └── README.md /Chapter01/README.md: -------------------------------------------------------------------------------- 1 | # Chapter One 2 | 3 | This is code for chapter 1 where we will cover: 4 | 5 | * Install python and took a tour on simple interfaces. 6 | * Write our first program "No hello world" 7 | -------------------------------------------------------------------------------- /Chapter01/no_hello_world.py: -------------------------------------------------------------------------------- 1 | print(input("Enter your Name: ")) 2 | 3 | # print and input is python inbuilt function, 4 | # You can directly use them in anywhere 5 | -------------------------------------------------------------------------------- /Chapter01/start_file.py: -------------------------------------------------------------------------------- 1 | print(4 + 5) # prints result of addition 2 | print(4 + 11) 3 | print("Hello world") # prints string hello world 4 | print(4 * 5) # prints result of multiplication 20 5 | print(4 / 5) # prints result of division 0.8 6 | -------------------------------------------------------------------------------- /Chapter02/README.md: -------------------------------------------------------------------------------- 1 | # Chapter Two 2 | 3 | This is code for chapter 2 where we will cover: 4 | 5 | * Create simple python game using concepts like variable and python in-built methods like input() and print() 6 | -------------------------------------------------------------------------------- /Chapter02/tic_tac_toe.py: -------------------------------------------------------------------------------- 1 | game_board = ['_'] * 9 2 | 3 | print(game_board[0] + '|' + game_board[1] + '|' + game_board[2]) 4 | print(game_board[3] + '|' + game_board[4] + '|' + game_board[5]) 5 | print(game_board[6] + '|' + game_board[7] + '|' + game_board[8]) 6 | 7 | while True: 8 | pos = input('Pick a number from 0-8') 9 | pos = int(pos) 10 | game_board[pos] = 'X' 11 | print(game_board[0] + '|' + game_board[1] + '|' + game_board[2]) 12 | print(game_board[3] + '|' + game_board[4] + '|' + game_board[5]) 13 | print(game_board[6] + '|' + game_board[7] + '|' + game_board[8]) 14 | -------------------------------------------------------------------------------- /Chapter03/README.md: -------------------------------------------------------------------------------- 1 | # Chapter Three 2 | 3 | This is code for chapter 3 where we will cover: 4 | 5 | * Conditionals 6 | * Looping 7 | * Exception Handling 8 | -------------------------------------------------------------------------------- /Chapter03/exceptionhandle.py: -------------------------------------------------------------------------------- 1 | choices = ['1', '2', '3', '4', '5', '6', '7', '8', '9'] 2 | while True: 3 | print('\n') 4 | print('|' + choices[0] + '|' + choices[1] + '|' + choices[2] + '|') 5 | print('----------') 6 | print('|' + choices[3] + '|' + choices[4] + '|' + choices[5] + '|') 7 | print('----------') 8 | print('|' + choices[6] + '|' + choices[7] + '|' + choices[8] + '|') 9 | # above code is to print board layouts 10 | 11 | try: 12 | choice = int(input("> ").strip()) 13 | except ValueError: 14 | print("Please enter only valid fields from board (0-8)") 15 | continue 16 | -------------------------------------------------------------------------------- /Chapter03/starter.py: -------------------------------------------------------------------------------- 1 | choices = ['1', '2', '3', '4', '5', '6', '7', '8', '9'] 2 | print('\n') 3 | print('|' + choices[0] + '|' + choices[1] + '|' + choices[2] + '|') 4 | print('----------') 5 | print('|' + choices[3] + '|' + choices[4] + '|' + choices[5] + '|') 6 | print('----------') 7 | print('|' + choices[6] + '|' + choices[7] + '|' + choices[8] + '|') 8 | -------------------------------------------------------------------------------- /Chapter03/tictactoe.py: -------------------------------------------------------------------------------- 1 | choices = ['1', '2', '3', '4', '5', '6', '7', '8', '9'] 2 | Is_Current_One = True 3 | won = False 4 | while not won: 5 | print('\n') 6 | print('|' + choices[0] + '|' + choices[1] + '|' + choices[2] + '|') 7 | print('----------') 8 | print('|' + choices[3] + '|' + choices[4] + '|' + choices[5] + '|') 9 | print('----------') 10 | print('|' + choices[6] + '|' + choices[7] + '|' + choices[8] + '|') 11 | # above code is to print board layouts 12 | if Is_Current_One: 13 | print("Player X") 14 | else: 15 | print("Player O") 16 | try: 17 | choice = int(input("> ").strip()) 18 | except ValueError: 19 | print("Please enter only valid fields from board (0-8)") 20 | continue 21 | 22 | if Is_Current_One: 23 | try: 24 | choices[choice - 1] = 'X' 25 | except IndexError: 26 | print("Please enter only valid fields from board (0-8)") 27 | else: 28 | try: 29 | choices[choice - 1] = 'O' 30 | except IndexError: 31 | print("Please enter only valid fields from board (0-8)") 32 | # code to toggle between True and False 33 | Is_Current_One = not Is_Current_One 34 | 35 | for pos_x in range(0, 3): 36 | pos_y = pos_x * 3 37 | 38 | # for row condition: 39 | if (choices[pos_y] == choices[(pos_y + 1)]) and ( 40 | choices[pos_y] == choices[(pos_y + 2)]): 41 | won = True 42 | 43 | # column condition: 44 | if (choices[pos_x] == choices[(pos_x + 3)]) and ( 45 | choices[pos_x] == choices[(pos_x + 6)]): 46 | won = True 47 | if ((choices[0] == choices[4] and choices[0] == choices[8]) 48 | or (choices[2] == choices[4] and choices[4] == choices[6])): 49 | won = True 50 | 51 | print("Player " + str(int(Is_Current_One + 1)) + " won, Congratulations!") 52 | -------------------------------------------------------------------------------- /Chapter04/README.md: -------------------------------------------------------------------------------- 1 | # Chapter Four 2 | 3 | This is code for chapter 4 where we will cover: 4 | 5 | * Data structures and Functions 6 | -------------------------------------------------------------------------------- /Chapter04/boardcopy.py: -------------------------------------------------------------------------------- 1 | def makeMove(board, current_player, move): 2 | board[move] = current_player 3 | 4 | 5 | def boardCopy(board): 6 | cloneBoard = [] 7 | for pos in board: 8 | cloneBoard.append(pos) 9 | 10 | return cloneBoard 11 | -------------------------------------------------------------------------------- /Chapter04/packingkeyargs.py: -------------------------------------------------------------------------------- 1 | def about(name, age, like): 2 | info = "I am {}. I am {} years old and I like {}. ".format(name, age, like) 3 | return info 4 | 5 | 6 | dictionary = {"name": "Ross", "age": 55, "like": "Python"} 7 | print(about(**dictionary)) 8 | -------------------------------------------------------------------------------- /Chapter04/tic-tac-toe_AI.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def printBoard(board): 5 | print(' | |') 6 | print(' ' + board[7] + ' | ' + board[8] + ' | ' + board[9]) 7 | print(' | |') 8 | print('----------') 9 | print(' | |') 10 | print(' ' + board[4] + ' | ' + board[5] + ' | ' + board[6]) 11 | print(' | |') 12 | print('----------') 13 | print(' | |') 14 | print(' ' + board[1] + ' | ' + board[2] + ' | ' + board[3]) 15 | print(' | |') 16 | 17 | 18 | def isWinner(board, current_player): 19 | return ((board[7] == current_player and board[8] == current_player 20 | and board[9] == current_player) 21 | or (board[4] == current_player and board[5] == current_player 22 | and board[6] == current_player) 23 | or (board[1] == current_player and board[2] == current_player 24 | and board[3] == current_player) 25 | or (board[7] == current_player and board[4] == current_player 26 | and board[1] == current_player) 27 | or (board[8] == current_player and board[5] == current_player 28 | and board[2] == current_player) 29 | or (board[9] == current_player and board[6] == current_player 30 | and board[3] == current_player) 31 | or (board[7] == current_player and board[5] == current_player 32 | and board[3] == current_player) 33 | or (board[9] == current_player and board[5] == current_player 34 | and board[1] == current_player)) 35 | 36 | 37 | def makeMove(board, current_player, move): 38 | board[move] = current_player 39 | 40 | 41 | def boardCopy(board): 42 | cloneBoard = [] 43 | for pos in board: 44 | cloneBoard.append(pos) 45 | 46 | return cloneBoard 47 | 48 | 49 | def isSpaceAvailable(board, move): 50 | return board[move] == ' ' 51 | 52 | 53 | def getRandomMove(board, moves): 54 | availableMoves = [] 55 | for move in moves: 56 | if isSpaceAvailable(board, move): 57 | availableMoves.append(move) 58 | 59 | if availableMoves.__len__() != 0: 60 | return random.choice(availableMoves) 61 | else: 62 | return None 63 | 64 | 65 | def makeComputerMove(board, computerPlayer): 66 | if computerPlayer == 'X': 67 | humanPlayer = 'O' 68 | else: 69 | humanPlayer = 'X' 70 | # part 1 71 | for pos in range(1, 10): 72 | # pos is for position of board layout 73 | clone = boardCopy(board) 74 | if isSpaceAvailable(clone, pos): 75 | makeMove(clone, computerPlayer, pos) 76 | if isWinner(clone, computerPlayer): 77 | return pos 78 | 79 | for pos in range(1, 10): 80 | clone = boardCopy(board) 81 | if isSpaceAvailable(clone, pos): 82 | makeMove(clone, humanPlayer, pos) 83 | if isWinner(clone, humanPlayer): 84 | return pos 85 | 86 | if isSpaceAvailable(board, 5): 87 | return 5 88 | 89 | move = getRandomMove(board, [1, 3, 7, 9]) 90 | if move is not None: 91 | return move 92 | 93 | # moves for remaining places ==> [2,4,6,8] 94 | return getRandomMove(board, [2, 4, 6, 8]) 95 | 96 | 97 | def makePlayerMove(board): 98 | move = ' ' 99 | while move not in '1 2 3 4 5 6 7 8 9'.split() or not isSpaceAvailable( 100 | board, int(move)): 101 | print('What is your next move? (choose between 1-9)') 102 | move = int(input().strip()) 103 | return move 104 | 105 | 106 | def main(): 107 | while True: 108 | board = [' '] * 10 109 | player, computer = 'X', 'O' 110 | turn = 'human' 111 | print("The " + turn + " will start the game") 112 | isGameRunning = True 113 | 114 | while isGameRunning: 115 | if turn == 'human': 116 | printBoard(board) 117 | move = makePlayerMove(board) 118 | makeMove(board, player, move) 119 | if isWinner(board, player): 120 | printBoard(board) 121 | print("You won the game!") 122 | isGameRunning = False 123 | else: 124 | turn = 'computer' 125 | else: 126 | move = makeComputerMove(board, computer) 127 | makeMove(board, computer, move) 128 | if isWinner(board, computer): 129 | printBoard(board) 130 | print('You loose!') 131 | isGameRunning = False 132 | else: 133 | turn = 'human' 134 | 135 | 136 | if __name__ == '__main__': 137 | main() # calling main function 138 | -------------------------------------------------------------------------------- /Chapter04/tic_tac_toe_AI_start.py: -------------------------------------------------------------------------------- 1 | def printBoard(board): 2 | print(' | |') 3 | print(' ' + board[7] + ' | ' + board[8] + ' | ' + board[9]) 4 | print(' | |') 5 | print('-----------') 6 | print(' | |') 7 | print(' ' + board[4] + ' | ' + board[5] + ' | ' + board[6]) 8 | print(' | |') 9 | print('-----------') 10 | print(' | |') 11 | print(' ' + board[1] + ' | ' + board[2] + ' | ' + board[3]) 12 | print(' | |') 13 | -------------------------------------------------------------------------------- /Chapter04/unpackkeywordargs.py: -------------------------------------------------------------------------------- 1 | def about(**kwargs): 2 | for key, value in kwargs.items(): 3 | print("{} is {}".format(key, value)) 4 | 5 | 6 | about(Python="Easy", Java="Hard") 7 | -------------------------------------------------------------------------------- /Chapter04/winner_AI.py: -------------------------------------------------------------------------------- 1 | def isWinner(board, current_player): 2 | return ((board[7] == current_player and board[8] == current_player 3 | and board[9] == current_player) 4 | or (board[4] == current_player and board[5] == current_player 5 | and board[6] == current_player) 6 | or (board[1] == current_player and board[2] == current_player 7 | and board[3] == current_player) 8 | or (board[7] == current_player and board[4] == current_player 9 | and board[1] == current_player) 10 | or (board[8] == current_player and board[5] == current_player 11 | and board[2] == current_player) 12 | or (board[9] == current_player and board[6] == current_player 13 | and board[3] == current_player) 14 | or (board[7] == current_player and board[5] == current_player 15 | and board[3] == current_player) 16 | or (board[9] == current_player and board[5] == current_player 17 | and board[1] == current_player)) 18 | -------------------------------------------------------------------------------- /Chapter05/README.md: -------------------------------------------------------------------------------- 1 | # Chapter Five 2 | 3 | This is code for chapter 5 where we will cover: 4 | 5 | * Learn curses by making snake game 6 | -------------------------------------------------------------------------------- /Chapter05/curses_starter.py: -------------------------------------------------------------------------------- 1 | import curses 2 | import time 3 | 4 | screen = curses.initscr() 5 | curses.noecho() 6 | curses.cbreak() 7 | screen.keypad(True) 8 | screen.addstr(5, 5, "Hello") 9 | screen.refresh() 10 | time.sleep(3) 11 | curses.endwin() 12 | -------------------------------------------------------------------------------- /Chapter05/keyboard_events.py: -------------------------------------------------------------------------------- 1 | import curses as c 2 | 3 | screen = c.initscr() 4 | 5 | win = c.newwin(20, 60, 0, 0) 6 | 7 | c.noecho() 8 | c.cbreak() 9 | screen.keypad(True) 10 | while True: 11 | char = screen.getch() 12 | if char == ord('q'): 13 | break 14 | if char == ord('p'): 15 | win.addstr(5, 10, "Hello world") 16 | win.refresh() 17 | 18 | # time.sleep(10) 19 | screen.endwin() 20 | -------------------------------------------------------------------------------- /Chapter05/mouse_events.py: -------------------------------------------------------------------------------- 1 | import curses as c 2 | import time 3 | 4 | 5 | def main(screen): 6 | c.curs_set(0) 7 | c.mousemask(1) 8 | 9 | inp = screen.getch() 10 | if inp == c.KEY_MOUSE: 11 | screen.addstr(17, 40, "Mouse is clicked") 12 | screen.refresh() 13 | 14 | screen.getch() 15 | time.sleep(10) 16 | 17 | 18 | c.wrapper(main) 19 | -------------------------------------------------------------------------------- /Chapter05/snake_final.py: -------------------------------------------------------------------------------- 1 | import curses as c 2 | from curses import KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT 3 | from random import randint 4 | 5 | 6 | def main(): 7 | 8 | c.initscr() 9 | win = c.newwin(20, 60, 0, 0) 10 | win.keypad(1) 11 | c.noecho() 12 | c.curs_set(0) 13 | win.border(0) 14 | win.nodelay(1) 15 | 16 | key = KEY_RIGHT # Initializing values 17 | score = 0 18 | 19 | snake = [[4, 10], [4, 9], [4, 8]] # Initial snake co-ordinates 20 | food = [10, 20] # First food co-ordinates 21 | 22 | win.addch(food[0], food[1], 'O') # Prints the food 23 | 24 | while key != 27: # While Esc key is not pressed 25 | win.border(0) 26 | win.addstr(0, 2, 'Score : ' + str(score) + ' ') # Printing 'Score' and 27 | win.addstr(0, 27, ' SNAKE ') # 'SNAKE' strings 28 | win.timeout( 29 | 100 30 | ) # Increases the speed of Snake as its length increases for speed 31 | 32 | prevKey = key # Previous key pressed 33 | event = win.getch() 34 | key = key if event == -1 else event 35 | 36 | if key not in [KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN, 37 | 27]: # If an invalid key is pressed 38 | key = prevKey 39 | 40 | # Calculates the new coordinates of the head of the snake. 41 | # NOTE: len(snake) increases. 42 | 43 | snake.insert(0, [ 44 | snake[0][0] + (key == KEY_DOWN and 1) + (key == KEY_UP and -1), 45 | snake[0][1] + (key == KEY_LEFT and -1) + (key == KEY_RIGHT and 1) 46 | ]) 47 | 48 | # If snake crosses the boundaries, make it enter from the other side 49 | if snake[0][0] == 0: 50 | snake[0][0] = 18 51 | if snake[0][1] == 0: 52 | snake[0][1] = 58 53 | if snake[0][0] == 19: 54 | snake[0][0] = 1 55 | if snake[0][1] == 59: 56 | snake[0][1] = 1 57 | 58 | if snake[0] in snake[1:]: 59 | break 60 | 61 | if snake[0] == food: 62 | food = [] 63 | # AFTER EATING EVERY FOOD SCORE = FOOD 64 | score += 1 65 | while food == []: 66 | food = [randint(1, 18), randint(1, 58)] 67 | if food in snake: 68 | food = [] 69 | win.addch(food[0], food[1], "O") 70 | else: 71 | last = snake.pop() 72 | win.addch(last[0], last[1], ' ') 73 | win.addch(snake[0][0], snake[0][1], 'X') 74 | 75 | c.endwin() 76 | 77 | 78 | if __name__ == '__main__': 79 | main() 80 | -------------------------------------------------------------------------------- /Chapter05/snake_starter.py: -------------------------------------------------------------------------------- 1 | import curses as c 2 | from curses import KEY_RIGHT, KEY_LEFT, KEY_UP, KEY_DOWN 3 | 4 | c.initscr() 5 | win = c.newwin(20, 60, 0, 0) 6 | win.keypad(1) 7 | c.noecho() 8 | c.curs_set(0) 9 | win.border(0) 10 | win.nodelay(1) 11 | 12 | snake = [[4, 10], [4, 9], [4, 8]] 13 | food = [10, 20] 14 | 15 | win.addch(food[0], food[1], 'O') 16 | 17 | c.endwin() 18 | 19 | key = KEY_RIGHT # default key 20 | 21 | # ASCII value of ESC is 27 22 | while key != 27: 23 | win.border(0) 24 | win.timeout(100) # speed for snake 25 | default_key = key 26 | event = win.getch() 27 | key = key if event == -1 else event 28 | if key not in [KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN, 27]: 29 | key = default_key 30 | -------------------------------------------------------------------------------- /Chapter06/Note: -------------------------------------------------------------------------------- 1 | This chapter will teach us about Object Oriented Programming and its important features like: 2 | 3 | 1. Encapsulation 4 | 2. Inheritance 5 | 3. Polymorphism 6 | 4. Method overriding 7 | 5. Method overloading will be taught in upcoming chapter 8 | -------------------------------------------------------------------------------- /Chapter06/class_ex_2.py: -------------------------------------------------------------------------------- 1 | class Bike: 2 | name = '' 3 | color= ' ' 4 | price = 0 5 | 6 | def info(self, name, color, price): 7 | self.name, self.color, self.price = name,color,price 8 | print("{}: {} and {}".format(self.name,self.color,self.price)) 9 | -------------------------------------------------------------------------------- /Chapter06/classes_ex_1.py: -------------------------------------------------------------------------------- 1 | class Bike: 2 | def ride_Left(self): 3 | print("Bike is turning to left") 4 | 5 | def ride_Right(self): 6 | print("Bike is turning to right") 7 | 8 | def Brake(self): 9 | print("Breaking......") 10 | 11 | suzuki = Bike() 12 | suzuki.ride_Left() 13 | -------------------------------------------------------------------------------- /Chapter06/constructor.py: -------------------------------------------------------------------------------- 1 | class Bike: 2 | def __init__(self,name,color,price): 3 | self.name = name 4 | self.color = color 5 | self.price = price 6 | 7 | def info(self): 8 | print("{}: {} and {}".format(self.name,self.color,self.price)) 9 | -------------------------------------------------------------------------------- /Chapter06/decorator.py: -------------------------------------------------------------------------------- 1 | class Person: 2 | def __init__(self,first,last): 3 | self.first = first 4 | self.last = last 5 | self.email = first + '.' + last + '@gmail.com' 6 | 7 | per1 = Person('Ross', 'Geller') 8 | 9 | per1.first = "Rachel" 10 | print(per1.first) 11 | 12 | print(per1.email) 13 | -------------------------------------------------------------------------------- /Chapter06/encapsulation.py: -------------------------------------------------------------------------------- 1 | class Bike: 2 | def __init__(self): 3 | self.__updateTech() 4 | def Ride(self): 5 | print("Riding...") 6 | def __updateTech(self): 7 | print("Updating your Bike..") 8 | -------------------------------------------------------------------------------- /Chapter06/encapsulation2.py: -------------------------------------------------------------------------------- 1 | class Bike: 2 | __name = " " 3 | __color = " " 4 | def __init__(self,name,color): 5 | self.__name = name 6 | self.__color = color 7 | def info(self): 8 | print("{} is of {} color".format(self.__name,self.__color)) 9 | -------------------------------------------------------------------------------- /Chapter06/inheritance.py: -------------------------------------------------------------------------------- 1 | class Bike: 2 | def __init__(self): 3 | print("Bike is starting..") 4 | def Ride(self): 5 | print("Riding...") 6 | 7 | class Suzuki(Bike): 8 | def __init__(self,name,color): 9 | self.name = name 10 | self.color = color 11 | def info(self): 12 | print("You are riding {} and it's color is {}".format(self.name,self.color)) 13 | -------------------------------------------------------------------------------- /Chapter06/method-overriding.py: -------------------------------------------------------------------------------- 1 | class Bird: 2 | def about(self): 3 | print("Species: Bird") 4 | def Dance(self): 5 | print("Not all but some birds can dance") 6 | 7 | class Peacock(Bird): 8 | def Dance(self): 9 | print("Peacock can dance") 10 | class Sparrow(Bird): 11 | def Dance(self): 12 | print("Sparrow can't dance") 13 | -------------------------------------------------------------------------------- /Chapter06/multi-level-inheritance.py: -------------------------------------------------------------------------------- 1 | class Mobile: 2 | def __init__(self): 3 | print("Mobile features: Camera, Phone, Applications") 4 | class Samsung(Mobile): 5 | def __init__(self): 6 | print("Samsung Company") 7 | super().__init__() 8 | class Samsung_Prime(Samsung): 9 | def __init__(self): 10 | print("Samsung latest Mobile") 11 | super().__init__() 12 | -------------------------------------------------------------------------------- /Chapter06/setter.py: -------------------------------------------------------------------------------- 1 | class Bike: 2 | __name = " " 3 | __color = " " 4 | def __init__(self,name,color): 5 | self.__name = name 6 | self.__color = color 7 | def setNewColor(self, color): 8 | self.__color = color 9 | def info(self): 10 | print("{} is of {} color".format(self.__name,self.__color)) 11 | -------------------------------------------------------------------------------- /Chapter06/snake-game-OOP.py: -------------------------------------------------------------------------------- 1 | 2 | import curses 3 | from curses import KEY_RIGHT, KEY_LEFT, KEY_DOWN, KEY_UP 4 | from random import randint 5 | 6 | WIDTH = 35 7 | HEIGHT = 20 8 | MAX_X = WIDTH - 2 9 | MAX_Y = HEIGHT - 2 10 | SNAKE_LENGTH = 5 11 | SNAKE_X = SNAKE_LENGTH + 1 12 | SNAKE_Y = 3 13 | TIMEOUT = 100 14 | 15 | class Snake(object): 16 | REV_DIR_MAP = { 17 | KEY_UP: KEY_DOWN, KEY_DOWN: KEY_UP, 18 | KEY_LEFT: KEY_RIGHT, KEY_RIGHT: KEY_LEFT, 19 | } 20 | 21 | def __init__(self, x, y, window): 22 | self.body_list = [] 23 | self.hit_score = 0 24 | self.timeout = TIMEOUT 25 | 26 | for i in range(SNAKE_LENGTH, 0, -1): 27 | self.body_list.append(Body(x - i, y)) 28 | 29 | self.body_list.append(Body(x, y, '#')) 30 | self.window = window 31 | self.direction = KEY_RIGHT 32 | self.last_head_coor = (x, y) 33 | self.direction_map = { 34 | KEY_UP: self.move_up, 35 | KEY_DOWN: self.move_down, 36 | KEY_LEFT: self.move_left, 37 | KEY_RIGHT: self.move_right 38 | } 39 | 40 | @property 41 | def score(self): 42 | return 'Score : {}'.format(self.hit_score) 43 | 44 | def add_body(self, body_list): 45 | self.body_list.extend(body_list) 46 | 47 | def eat_food(self, food): 48 | food.reset() 49 | body = Body(self.last_head_coor[0], self.last_head_coor[1]) 50 | self.body_list.insert(-1, body) 51 | self.hit_score += 1 52 | if self.hit_score % 3 == 0: 53 | self.timeout -= 5 54 | self.window.timeout(self.timeout) 55 | 56 | @property 57 | def collided(self): 58 | return any([body.coor == self.head.coor 59 | for body in self.body_list[:-1]]) 60 | 61 | def update(self): 62 | last_body = self.body_list.pop(0) 63 | last_body.x = self.body_list[-1].x 64 | last_body.y = self.body_list[-1].y 65 | self.body_list.insert(-1, last_body) 66 | self.last_head_coor = (self.head.x, self.head.y) 67 | self.direction_map[self.direction]() 68 | 69 | def change_direction(self, direction): 70 | if direction != Snake.REV_DIR_MAP[self.direction]: 71 | self.direction = direction 72 | 73 | def render(self): 74 | for body in self.body_list: 75 | self.window.addstr(body.y, body.x, body.char) 76 | 77 | @property 78 | def head(self): 79 | return self.body_list[-1] 80 | 81 | @property 82 | def coor(self): 83 | return self.head.x, self.head.y 84 | 85 | def move_up(self): 86 | self.head.y -= 1 87 | if self.head.y < 1: 88 | self.head.y = MAX_Y 89 | 90 | def move_down(self): 91 | self.head.y += 1 92 | if self.head.y > MAX_Y: 93 | self.head.y = 1 94 | 95 | def move_left(self): 96 | self.head.x -= 1 97 | if self.head.x < 1: 98 | self.head.x = MAX_X 99 | 100 | def move_right(self): 101 | self.head.x += 1 102 | if self.head.x > MAX_X: 103 | self.head.x = 1 104 | 105 | class Body(object): 106 | def __init__(self, x, y, char='#'): 107 | self.x = x 108 | self.y = y 109 | self.char = char 110 | 111 | @property 112 | def coor(self): 113 | return self.x, self.y 114 | 115 | class Food(object): 116 | def __init__(self, window, char='&'): 117 | self.x = randint(1, MAX_X) 118 | self.y = randint(1, MAX_Y) 119 | self.char = char 120 | self.window = window 121 | 122 | def render(self): 123 | self.window.addstr(self.y, self.x, self.char) 124 | 125 | def reset(self): 126 | self.x = randint(1, MAX_X) 127 | self.y = randint(1, MAX_Y) 128 | 129 | 130 | if __name__ == '__main__': 131 | curses.initscr() 132 | curses.beep() 133 | curses.beep() 134 | window = curses.newwin(HEIGHT, WIDTH, 0, 0) 135 | window.timeout(TIMEOUT) 136 | window.keypad(1) 137 | curses.noecho() 138 | curses.curs_set(0) 139 | window.border(0) 140 | 141 | snake = Snake(SNAKE_X, SNAKE_Y, window) 142 | food = Food(window, '*') 143 | 144 | while True: 145 | window.clear() 146 | window.border(0) 147 | snake.render() 148 | food.render() 149 | 150 | window.addstr(0, 5, snake.score) 151 | event = window.getch() 152 | 153 | if event == 27: 154 | break 155 | 156 | if event in [KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT]: 157 | snake.change_direction(event) 158 | 159 | if snake.head.x == food.x and snake.head.y == food.y: 160 | snake.eat_food(food) 161 | 162 | if event == 32: 163 | key = -1 164 | while key != 32: 165 | key = window.getch() 166 | 167 | snake.update() 168 | if snake.collided: 169 | break 170 | 171 | 172 | curses.endwin() 173 | -------------------------------------------------------------------------------- /Chapter06/super.py: -------------------------------------------------------------------------------- 1 | class Bike: 2 | def __init__(self): 3 | print("Bike is starting..") 4 | def Ride(self): 5 | print("Riding...") 6 | 7 | class Suzuki(Bike): 8 | def __init__(self,name,color): 9 | self.name = name 10 | self.color = color 11 | Bike().__init__() 12 | -------------------------------------------------------------------------------- /Chapter07/Note: -------------------------------------------------------------------------------- 1 | This chapter will teach students about List Comprehensions and Decorators 2 | -------------------------------------------------------------------------------- /Chapter07/getter-setter7.py: -------------------------------------------------------------------------------- 1 | class Speed: 2 | def __init__(self, speed = 0): 3 | self.set_speed(speed) 4 | 5 | def change_to_mile(self): 6 | return (self.get_speed*0.6213," miles") 7 | 8 | #new updates are made as follows using getter and setter 9 | def get_speed(self): 10 | return self._speed 11 | def set_speed(self, km): 12 | if km > 50: 13 | raise ValueError("You are liable to speed ticket") 14 | self._speed = km 15 | -------------------------------------------------------------------------------- /Chapter07/property1.py: -------------------------------------------------------------------------------- 1 | class Speed: 2 | def __init__(self, speed = 0): 3 | self.speed = speed 4 | 5 | def change_to_mile(self): 6 | return self.speed*0.6213," miles" 7 | -------------------------------------------------------------------------------- /Chapter07/smart_multiply.py: -------------------------------------------------------------------------------- 1 | def smart_multiply(func): 2 | def inner(a,b): 3 | if (a.isdigit() and b.isdigit()): 4 | a = int(a) 5 | b = int(b) 6 | print("multiplying ",a," with ",b) 7 | return func(a,b) 8 | else: 9 | print("Whoops!! Not valid multiplication") 10 | return 11 | return inner 12 | 13 | @smart_multiply 14 | def multiply(a,b): 15 | print(a*b) 16 | a = input("value of a: ") 17 | b = input("value of b: ") 18 | multiply(a,b) 19 | -------------------------------------------------------------------------------- /Chapter07/using-property-method.py: -------------------------------------------------------------------------------- 1 | class Speed: 2 | def __init__(self, speed = 0): 3 | self.speed = speed 4 | 5 | def change_to_mile(self): 6 | return (self.speed*0.6213," miles") 7 | 8 | def get_speed(self): 9 | return self._speed 10 | def set_speed(self, km): 11 | if km > 50: 12 | raise ValueError("You are liable to speeding ticket") 13 | self._speed = km 14 | 15 | #using property 16 | speed = property(get_speed,set_speed) 17 | -------------------------------------------------------------------------------- /Chapter07/using-property.py: -------------------------------------------------------------------------------- 1 | class Speed: 2 | def __init__(self, speed = 0): 3 | self.speed = speed 4 | 5 | def change_to_mile(self): 6 | return (self.speed*0.6213," miles") 7 | 8 | @property 9 | def speed(self): 10 | return self._speed 11 | 12 | @speed.setter 13 | def speed(self,km): 14 | if km > 50: 15 | raise ValueError("You are liable to speeding ticket") 16 | self._speed = km 17 | -------------------------------------------------------------------------------- /Chapter08/Note: -------------------------------------------------------------------------------- 1 | This chapter will teach us about turtle module. 2 | -------------------------------------------------------------------------------- /Chapter08/hexagon.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | 3 | hexagon = turtle.Turtle() 4 | 5 | num_of_sides = 6 6 | length_of_sides = 70 7 | angle = 360.0 / num_of_sides 8 | 9 | for i in range(num_of_sides): 10 | hexagon.forward(length_of_sides) 11 | hexagon.right(angle) 12 | 13 | turtle.done() 14 | -------------------------------------------------------------------------------- /Chapter08/keyboard-events.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | star = turtle.Turtle() 3 | def main(): 4 | for i in range(30): 5 | star.forward(100) 6 | star.right(144) 7 | turtle.onkeypress(main,"space") 8 | turtle.listen() 9 | -------------------------------------------------------------------------------- /Chapter08/mouse-events.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | pacman = turtle.Turtle() 3 | def move(x,y): 4 | pacman.forward(50) 5 | print(x,y) 6 | 7 | turtle.onclick(move) 8 | -------------------------------------------------------------------------------- /Chapter08/ontimer-star.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | star = turtle.Turtle() 3 | 4 | exit = False 5 | def main(): 6 | if not exit: 7 | star.forward(50) 8 | star.right(144) 9 | turtle.ontimer(main,500) 10 | main() 11 | 12 | -------------------------------------------------------------------------------- /Chapter08/star-color.py: -------------------------------------------------------------------------------- 1 | from turtle import * 2 | 3 | color('red', 'yellow') 4 | begin_fill() 5 | while True: 6 | forward(300) 7 | left(170) 8 | if abs(pos()) < 1: 9 | break 10 | end_fill() 11 | done() 12 | -------------------------------------------------------------------------------- /Chapter08/turtle-for.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | 3 | pacman = turtle.Turtle() 4 | for i in range(4): 5 | pacman.forward(50) 6 | pacman.right(90) 7 | 8 | turtle.done() 9 | -------------------------------------------------------------------------------- /Chapter08/turtle-square.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | 3 | pacman = turtle.Turtle() 4 | 5 | pacman.forward(50) 6 | pacman.right(90) # Rotate clockwise by 90 degrees 7 | 8 | pacman.forward(50) 9 | pacman.right(90) 10 | 11 | pacman.forward(50) 12 | pacman.right(90) 13 | 14 | pacman.forward(50) 15 | pacman.right(90) 16 | 17 | turtle.done() 18 | -------------------------------------------------------------------------------- /Chapter09/Note: -------------------------------------------------------------------------------- 1 | This chapter is about operator overloading, data models and vectors. 2 | -------------------------------------------------------------------------------- /Chapter09/data-models-modified.py: -------------------------------------------------------------------------------- 1 | class Base: 2 | def __init__(self, first): 3 | self.first = first 4 | 5 | def __add__(self, other): 6 | print(self.first + other.first) 7 | 8 | -------------------------------------------------------------------------------- /Chapter09/data-models.py: -------------------------------------------------------------------------------- 1 | class Base: 2 | def __init__(self, first): 3 | self.first = first 4 | 5 | def add(self, other): 6 | print(self.first + other) 7 | 8 | -------------------------------------------------------------------------------- /Chapter09/new-data-model.py: -------------------------------------------------------------------------------- 1 | class Base: 2 | def __new__(cls): 3 | print("This is __new__() magic method") 4 | obj = object.__new__(cls) 5 | return obj 6 | def __init__(self): 7 | print("This is __init__() magic method") 8 | self.info = "I love Python" 9 | -------------------------------------------------------------------------------- /Chapter09/vector.py: -------------------------------------------------------------------------------- 1 | class Vector(object): 2 | def __init__(self, x = 0.0, y = 0.0): 3 | self.x = x 4 | self.y = y 5 | def __str__(self): 6 | return "(%s, %s)"%(self.x, self.y) 7 | def __iadd__(self, other): 8 | if isinstance(other, Vector): 9 | self.x += other.x 10 | self.y += other.y 11 | else: 12 | self.x += other 13 | self.y += other 14 | return "(%s, %s)"%(self.x, self.y) 15 | 16 | def __isub__(self, other): 17 | if isinstance(other, Vector): 18 | self.x -= other.x 19 | self.y -= other.y 20 | else: 21 | self.x -= other 22 | self.y -= other 23 | return "(%s, %s)"%(self.x, self.y) 24 | 25 | def __imul__(self, other): 26 | if isinstance(other, Vector): 27 | self.x *= other.x 28 | self.y *= other.y 29 | else: 30 | self.x *= other 31 | self.y *= other 32 | return "(%s, %s)"%(self.x, self.y) 33 | 34 | def __itruediv__(self, other): 35 | if isinstance(other, Vector): 36 | self.x /= other.x 37 | self.y /= other.y 38 | else: 39 | self.x /= other 40 | self.y /= other 41 | return "(%s, %s)"%(self.x, self.y) 42 | -------------------------------------------------------------------------------- /Chapter10/Note: -------------------------------------------------------------------------------- 1 | This chapter is about Making games using turtle module. 2 | -------------------------------------------------------------------------------- /Chapter10/ant.py: -------------------------------------------------------------------------------- 1 | """Ant, simple animation demo. 2 | 3 | Exercises 4 | 5 | 1. Wrap ant around screen boundaries. 6 | 2. Make the ant leave a trail. 7 | 3. Change the ant color based on position. 8 | Hint: colormode(255); color(0, 100, 200) 9 | 10 | """ 11 | 12 | from random import * 13 | from turtle import * 14 | from base import vector 15 | 16 | ant = vector(0, 0) 17 | aim = vector(2, 0) 18 | 19 | def wrap(value): 20 | "Wrap value around -200 and 200." 21 | return value # TODO 22 | 23 | def draw(): 24 | "Move ant and draw screen." 25 | ant.move(aim) 26 | ant.x = wrap(ant.x) 27 | ant.y = wrap(ant.y) 28 | 29 | aim.move(random() - 0.5) 30 | aim.rotate(random() * 10 - 5) 31 | 32 | clear() 33 | goto(ant.x, ant.y) 34 | dot(10) 35 | 36 | if running: 37 | ontimer(draw, 100) 38 | 39 | setup(420, 420, 370, 0) 40 | hideturtle() 41 | tracer(False) 42 | up() 43 | running = True 44 | draw() 45 | done() 46 | -------------------------------------------------------------------------------- /Chapter10/base.py: -------------------------------------------------------------------------------- 1 | """Utilities 2 | 3 | """ 4 | # pylint: disable=no-member 5 | 6 | import collections 7 | import math 8 | import os 9 | 10 | 11 | 12 | def line(a, b, x, y): 13 | "Draw line from `(a, b)` to `(x, y)`." 14 | import turtle 15 | turtle.up() 16 | turtle.goto(a, b) 17 | turtle.down() 18 | turtle.goto(x, y) 19 | 20 | 21 | def square(x, y, size, name): 22 | """Draw square at `(x, y)` with side length `size` and fill color `name`. 23 | 24 | The square is oriented so the bottom left corner is at (x, y). 25 | 26 | """ 27 | import turtle 28 | turtle.up() 29 | turtle.goto(x, y) 30 | turtle.down() 31 | turtle.color(name) 32 | turtle.begin_fill() 33 | 34 | for count in range(4): 35 | turtle.forward(size) 36 | turtle.left(90) 37 | 38 | turtle.end_fill() 39 | 40 | 41 | class vector(collections.Sequence): 42 | """Two-dimensional vector. 43 | 44 | Vectors can be modified in-place. 45 | 46 | >>> v = vector(0, 1) 47 | >>> v.move(1) 48 | >>> v 49 | vector(1, 2) 50 | >>> v.rotate(90) 51 | >>> v 52 | vector(-2.0, 1.0) 53 | 54 | """ 55 | # pylint: disable=invalid-name 56 | PRECISION = 6 57 | 58 | __slots__ = ('_x', '_y', '_hash') 59 | 60 | def __init__(self, x, y): 61 | """Initialize vector with coordinates: x, y. 62 | 63 | >>> v = vector(1, 2) 64 | >>> v.x 65 | 1 66 | >>> v.y 67 | 2 68 | 69 | """ 70 | self._hash = None 71 | self._x = round(x, self.PRECISION) 72 | self._y = round(y, self.PRECISION) 73 | 74 | @property 75 | def x(self): 76 | """X-axis component of vector. 77 | 78 | >>> v = vector(1, 2) 79 | >>> v.x 80 | 1 81 | >>> v.x = 3 82 | >>> v.x 83 | 3 84 | 85 | """ 86 | return self._x 87 | 88 | @x.setter 89 | def x(self, value): 90 | if self._hash is not None: 91 | raise ValueError('cannot set x after hashing') 92 | self._x = round(value, self.PRECISION) 93 | 94 | @property 95 | def y(self): 96 | """Y-axis component of vector. 97 | 98 | >>> v = vector(1, 2) 99 | >>> v.y 100 | 2 101 | >>> v.y = 5 102 | >>> v.y 103 | 5 104 | 105 | """ 106 | return self._y 107 | 108 | @y.setter 109 | def y(self, value): 110 | if self._hash is not None: 111 | raise ValueError('cannot set y after hashing') 112 | self._y = round(value, self.PRECISION) 113 | 114 | def __hash__(self): 115 | """v.__hash__() -> hash(v) 116 | 117 | >>> v = vector(1, 2) 118 | >>> h = hash(v) 119 | >>> v.x = 2 120 | Traceback (most recent call last): 121 | ... 122 | ValueError: cannot set x after hashing 123 | 124 | """ 125 | if self._hash is None: 126 | pair = (self.x, self.y) 127 | self._hash = hash(pair) 128 | return self._hash 129 | 130 | def __len__(self): 131 | """v.__len__() -> len(v) 132 | 133 | >>> v = vector(1, 2) 134 | >>> len(v) 135 | 2 136 | 137 | """ 138 | return 2 139 | 140 | def __getitem__(self, index): 141 | """v.__getitem__(v, i) -> v[i] 142 | 143 | >>> v = vector(3, 4) 144 | >>> v[0] 145 | 3 146 | >>> v[1] 147 | 4 148 | >>> v[2] 149 | Traceback (most recent call last): 150 | ... 151 | IndexError 152 | 153 | """ 154 | if index == 0: 155 | return self.x 156 | elif index == 1: 157 | return self.y 158 | else: 159 | raise IndexError 160 | 161 | def copy(self): 162 | """Return copy of vector. 163 | 164 | >>> v = vector(1, 2) 165 | >>> w = v.copy() 166 | >>> v is w 167 | False 168 | 169 | """ 170 | type_self = type(self) 171 | return type_self(self.x, self.y) 172 | 173 | def __eq__(self, other): 174 | """v.__eq__(w) -> v == w 175 | 176 | >>> v = vector(1, 2) 177 | >>> w = vector(1, 2) 178 | >>> v == w 179 | True 180 | 181 | """ 182 | if isinstance(other, vector): 183 | return self.x == other.x and self.y == other.y 184 | return NotImplemented 185 | 186 | def __ne__(self, other): 187 | """v.__ne__(w) -> v != w 188 | 189 | >>> v = vector(1, 2) 190 | >>> w = vector(3, 4) 191 | >>> v != w 192 | True 193 | 194 | """ 195 | if isinstance(other, vector): 196 | return self.x != other.x or self.y != other.y 197 | return NotImplemented 198 | 199 | def __iadd__(self, other): 200 | """v.__iadd__(w) -> v += w 201 | 202 | >>> v = vector(1, 2) 203 | >>> w = vector(3, 4) 204 | >>> v += w 205 | >>> v 206 | vector(4, 6) 207 | >>> v += 1 208 | >>> v 209 | vector(5, 7) 210 | 211 | """ 212 | if self._hash is not None: 213 | raise ValueError('cannot add vector after hashing') 214 | elif isinstance(other, vector): 215 | self.x += other.x 216 | self.y += other.y 217 | else: 218 | self.x += other 219 | self.y += other 220 | return self 221 | 222 | def __add__(self, other): 223 | """v.__add__(w) -> v + w 224 | 225 | >>> v = vector(1, 2) 226 | >>> w = vector(3, 4) 227 | >>> v + w 228 | vector(4, 6) 229 | >>> v + 1 230 | vector(2, 3) 231 | >>> 2.0 + v 232 | vector(3.0, 4.0) 233 | 234 | """ 235 | copy = self.copy() 236 | return copy.__iadd__(other) 237 | 238 | __radd__ = __add__ 239 | 240 | def move(self, other): 241 | """Move vector by other (in-place). 242 | 243 | >>> v = vector(1, 2) 244 | >>> w = vector(3, 4) 245 | >>> v.move(w) 246 | >>> v 247 | vector(4, 6) 248 | >>> v.move(3) 249 | >>> v 250 | vector(7, 9) 251 | 252 | """ 253 | self.__iadd__(other) 254 | 255 | def __isub__(self, other): 256 | """v.__isub__(w) -> v -= w 257 | 258 | >>> v = vector(1, 2) 259 | >>> w = vector(3, 4) 260 | >>> v -= w 261 | >>> v 262 | vector(-2, -2) 263 | >>> v -= 1 264 | >>> v 265 | vector(-3, -3) 266 | 267 | """ 268 | if self._hash is not None: 269 | raise ValueError('cannot subtract vector after hashing') 270 | elif isinstance(other, vector): 271 | self.x -= other.x 272 | self.y -= other.y 273 | else: 274 | self.x -= other 275 | self.y -= other 276 | return self 277 | 278 | def __sub__(self, other): 279 | """v.__sub__(w) -> v - w 280 | 281 | >>> v = vector(1, 2) 282 | >>> w = vector(3, 4) 283 | >>> v - w 284 | vector(-2, -2) 285 | >>> v - 1 286 | vector(0, 1) 287 | 288 | """ 289 | copy = self.copy() 290 | return copy.__isub__(other) 291 | 292 | def __imul__(self, other): 293 | """v.__imul__(w) -> v *= w 294 | 295 | >>> v = vector(1, 2) 296 | >>> w = vector(3, 4) 297 | >>> v *= w 298 | >>> v 299 | vector(3, 8) 300 | >>> v *= 2 301 | >>> v 302 | vector(6, 16) 303 | 304 | """ 305 | if self._hash is not None: 306 | raise ValueError('cannot multiply vector after hashing') 307 | elif isinstance(other, vector): 308 | self.x *= other.x 309 | self.y *= other.y 310 | else: 311 | self.x *= other 312 | self.y *= other 313 | return self 314 | 315 | def __mul__(self, other): 316 | """v.__mul__(w) -> v * w 317 | 318 | >>> v = vector(1, 2) 319 | >>> w = vector(3, 4) 320 | >>> v * w 321 | vector(3, 8) 322 | >>> v * 2 323 | vector(2, 4) 324 | >>> 3.0 * v 325 | vector(3.0, 6.0) 326 | 327 | """ 328 | copy = self.copy() 329 | return copy.__imul__(other) 330 | 331 | __rmul__ = __mul__ 332 | 333 | def scale(self, other): 334 | """Scale vector by other (in-place). 335 | 336 | >>> v = vector(1, 2) 337 | >>> w = vector(3, 4) 338 | >>> v.scale(w) 339 | >>> v 340 | vector(3, 8) 341 | >>> v.scale(0.5) 342 | >>> v 343 | vector(1.5, 4.0) 344 | 345 | """ 346 | self.__imul__(other) 347 | 348 | def __itruediv__(self, other): 349 | """v.__itruediv__(w) -> v /= w 350 | 351 | >>> v = vector(2, 4) 352 | >>> w = vector(4, 8) 353 | >>> v /= w 354 | >>> v 355 | vector(0.5, 0.5) 356 | >>> v /= 2 357 | >>> v 358 | vector(0.25, 0.25) 359 | 360 | """ 361 | if self._hash is not None: 362 | raise ValueError('cannot divide vector after hashing') 363 | elif isinstance(other, vector): 364 | self.x /= other.x 365 | self.y /= other.y 366 | else: 367 | self.x /= other 368 | self.y /= other 369 | return self 370 | 371 | def __truediv__(self, other): 372 | """v.__truediv__(w) -> v / w 373 | 374 | >>> v = vector(1, 2) 375 | >>> w = vector(3, 4) 376 | >>> w / v 377 | vector(3.0, 2.0) 378 | >>> v / 2 379 | vector(0.5, 1.0) 380 | 381 | """ 382 | copy = self.copy() 383 | return copy.__itruediv__(other) 384 | 385 | def __neg__(self): 386 | """v.__neg__() -> -v 387 | 388 | >>> v = vector(1, 2) 389 | >>> -v 390 | vector(-1, -2) 391 | 392 | """ 393 | # pylint: disable=invalid-unary-operand-type 394 | copy = self.copy() 395 | copy.x = -copy.x 396 | copy.y = -copy.y 397 | return copy 398 | 399 | def __abs__(self): 400 | """v.__abs__() -> abs(v) 401 | 402 | >>> v = vector(3, 4) 403 | >>> abs(v) 404 | 5.0 405 | 406 | """ 407 | return (self.x ** 2 + self.y ** 2) ** 0.5 408 | 409 | def rotate(self, angle): 410 | """Rotate vector counter-clockwise by angle (in-place). 411 | 412 | >>> v = vector(1, 2) 413 | >>> v.rotate(90) 414 | >>> v == vector(-2, 1) 415 | True 416 | 417 | """ 418 | if self._hash is not None: 419 | raise ValueError('cannot rotate vector after hashing') 420 | radians = angle * math.pi / 180.0 421 | cosine = math.cos(radians) 422 | sine = math.sin(radians) 423 | x = self.x 424 | y = self.y 425 | self.x = x * cosine - y * sine 426 | self.y = y * cosine + x * sine 427 | 428 | def __repr__(self): 429 | """v.__repr__() -> repr(v) 430 | 431 | >>> v = vector(1, 2) 432 | >>> repr(v) 433 | 'vector(1, 2)' 434 | 435 | """ 436 | type_self = type(self) 437 | name = type_self.__name__ 438 | return '{}({!r}, {!r})'.format(name, self.x, self.y) 439 | -------------------------------------------------------------------------------- /Chapter10/flappy.py: -------------------------------------------------------------------------------- 1 | """Flappy, game inspired by Flappy Bird. 2 | 3 | Exercises 4 | 5 | 1. Keep score. 6 | 2. Vary the speed. 7 | 3. Vary the size of the balls. 8 | 4. Allow the bird to move forward and back. 9 | 10 | """ 11 | 12 | from random import * 13 | from turtle import * 14 | from base import vector 15 | 16 | bird = vector(0, 0) 17 | balls = [] 18 | 19 | def tap(x, y): 20 | "Move bird up in response to screen tap." 21 | up = vector(0, 30) 22 | bird.move(up) 23 | 24 | def inside(point): 25 | "Return True if point on screen." 26 | return -200 < point.x < 200 and -200 < point.y < 200 27 | 28 | def draw(alive): 29 | "Draw screen objects." 30 | clear() 31 | 32 | goto(bird.x, bird.y) 33 | 34 | if alive: 35 | dot(10, 'green') 36 | else: 37 | dot(10, 'red') 38 | 39 | for ball in balls: 40 | goto(ball.x, ball.y) 41 | dot(20, 'black') 42 | 43 | update() 44 | 45 | def move(): 46 | "Update object positions." 47 | bird.y -= 5 48 | 49 | for ball in balls: 50 | ball.x -= 3 51 | 52 | if randrange(10) == 0: 53 | y = randrange(-199, 199) 54 | ball = vector(199, y) 55 | balls.append(ball) 56 | 57 | while len(balls) > 0 and not inside(balls[0]): 58 | balls.pop(0) 59 | 60 | if not inside(bird): 61 | draw(False) 62 | return 63 | 64 | for ball in balls: 65 | if abs(ball - bird) < 15: 66 | print(abs(ball - bird)) 67 | draw(False) 68 | return 69 | 70 | draw(True) 71 | ontimer(move, 50) 72 | 73 | setup(420, 420, 370, 0) 74 | hideturtle() 75 | up() 76 | tracer(False) 77 | onscreenclick(tap) 78 | move() 79 | done() 80 | -------------------------------------------------------------------------------- /Chapter10/pong-update.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | 3 | wn = turtle.Screen() 4 | wn.title('Pong') 5 | wn.bgcolor('black') 6 | wn.setup(width=800, height=600) 7 | wn.tracer(0) 8 | 9 | # Paddle A 10 | paddle_a = turtle.Turtle() 11 | paddle_a.speed(0) 12 | paddle_a.shape('square') 13 | paddle_a.color('white') 14 | paddle_a.penup() 15 | paddle_a.goto(-350, 0) 16 | paddle_a.shapesize(5, 1) 17 | 18 | # Paddle B 19 | paddle_b = turtle.Turtle() 20 | paddle_b.speed(0) 21 | paddle_b.shape('square') 22 | paddle_b.color('white') 23 | paddle_b.penup() 24 | paddle_b.goto(350, 0) 25 | paddle_b.shapesize(5, 1) 26 | 27 | # Ball 28 | ball = turtle.Turtle() 29 | ball.speed(0) 30 | ball.shape('circle') 31 | ball.color('white') 32 | ball.penup() 33 | ball.dx = 0.15 34 | ball.dy = 0.15 35 | 36 | # Pen 37 | pen = turtle.Turtle() 38 | pen.speed(0) 39 | pen.color('white') 40 | pen.penup() 41 | pen.goto(0, 260) 42 | pen.write("Player A: 0 Player B: 0", align='center', font=('Courier', 24, 'bold')) 43 | pen.hideturtle() 44 | 45 | # Score 46 | score_a = 0 47 | score_b = 0 48 | 49 | def paddle_a_up(): 50 | y = paddle_a.ycor() 51 | y += 20 52 | paddle_a.sety(y) 53 | 54 | def paddle_b_up(): 55 | y = paddle_b.ycor() 56 | y += 20 57 | paddle_b.sety(y) 58 | 59 | def paddle_a_down(): 60 | y = paddle_a.ycor() 61 | y += -20 62 | paddle_a.sety(y) 63 | 64 | def paddle_b_down(): 65 | y = paddle_b.ycor() 66 | y += -20 67 | paddle_b.sety(y) 68 | 69 | # Keyboard binding 70 | wn.listen() 71 | wn.onkeypress(paddle_a_up, 'w') 72 | wn.onkeypress(paddle_a_down, 's') 73 | wn.onkeypress(paddle_b_up, 'Up') 74 | wn.onkeypress(paddle_b_down, 'Down') 75 | 76 | 77 | # Main game loop 78 | while True: 79 | wn.update() 80 | 81 | # Moving Ball 82 | ball.setx(ball.xcor() + ball.dx) 83 | ball.sety(ball.ycor() + ball.dy) 84 | 85 | # Border checking 86 | if ball.ycor() > 290 or ball.ycor() < -290: 87 | 88 | ball.dy *= -1 89 | 90 | if ball.xcor() > 390: 91 | 92 | ball.goto(0, 0) 93 | ball.dx *= -1 94 | score_a += 1 95 | pen.clear() 96 | pen.write("Player A: {} Player B: {}".format(score_a, score_b), align='center', font=('Courier', 24, 'bold')) 97 | 98 | if ball.xcor() < -390: 99 | 100 | ball.goto(0, 0) 101 | 102 | ball.dx *= -1 103 | score_b += 1 104 | pen.clear() 105 | pen.write("Player A: {} Player B: {}".format(score_a, score_b), align='center', font=('Courier', 24, 'bold')) 106 | 107 | # Paddle and ball collisions 108 | if (ball.xcor() > 340 and ball.xcor() < 350) and (ball.ycor() < paddle_b.ycor() + 60 and ball.ycor() > paddle_b.ycor() -60): 109 | 110 | ball.setx(340) 111 | ball.dx *= -1 112 | 113 | if (ball.xcor() < -340 and ball.xcor() > -350) and (ball.ycor() < paddle_a.ycor() + 60 and ball.ycor() > paddle_a.ycor() -60): 114 | 115 | ball.setx(-340) 116 | ball.dx *= -1 117 | -------------------------------------------------------------------------------- /Chapter10/pong.py: -------------------------------------------------------------------------------- 1 | """Pong, classic arcade game. 2 | 3 | Exercises 4 | 5 | 1. Change the colors. 6 | 2. What is the frame rate? Make it faster or slower. 7 | 3. Change the speed of the ball. 8 | 4. Change the size of the paddles. 9 | 5. Change how the ball bounces off walls. 10 | 6. How would you add a computer player? 11 | 6. Add a second ball. 12 | 13 | """ 14 | 15 | from random import choice, random 16 | from turtle import * 17 | from base import vector 18 | 19 | def value(): 20 | "Randomly generate value between (-5, -3) or (3, 5)." 21 | return (3 + random() * 2) * choice([1, -1]) 22 | 23 | ball = vector(0, 0) 24 | aim = vector(value(), value()) 25 | state = {1: 0, 2: 0} 26 | 27 | def move(player, change): 28 | "Move player position by change." 29 | state[player] += change 30 | 31 | def rectangle(x, y, width, height): 32 | "Draw rectangle at (x, y) with given width and height." 33 | up() 34 | goto(x, y) 35 | down() 36 | begin_fill() 37 | for count in range(2): 38 | forward(width) 39 | left(90) 40 | forward(height) 41 | left(90) 42 | end_fill() 43 | 44 | def draw(): 45 | "Draw game and move pong ball." 46 | clear() 47 | rectangle(-200, state[1], 10, 50) 48 | rectangle(190, state[2], 10, 50) 49 | 50 | ball.move(aim) 51 | x = ball.x 52 | y = ball.y 53 | 54 | up() 55 | goto(x, y) 56 | dot(10) 57 | update() 58 | 59 | if y < -200 or y > 200: 60 | aim.y = -aim.y 61 | 62 | if x < -185: 63 | low = state[1] 64 | high = state[1] + 50 65 | 66 | if low <= y <= high: 67 | aim.x = -aim.x 68 | else: 69 | return 70 | 71 | if x > 185: 72 | low = state[2] 73 | high = state[2] + 50 74 | 75 | if low <= y <= high: 76 | aim.x = -aim.x 77 | else: 78 | return 79 | 80 | ontimer(draw, 50) 81 | 82 | setup(420, 420, 370, 0) 83 | hideturtle() 84 | tracer(False) 85 | listen() 86 | onkey(lambda: move(1, 20), 'w') 87 | onkey(lambda: move(1, -20), 's') 88 | onkey(lambda: move(2, 20), 'i') 89 | onkey(lambda: move(2, -20), 'k') 90 | draw() 91 | done() 92 | -------------------------------------------------------------------------------- /Chapter10/snake.py: -------------------------------------------------------------------------------- 1 | """Snake, classic arcade game. 2 | 3 | Excercises 4 | 5 | 1. How do you make the snake faster or slower? 6 | 2. How can you make the snake go around the edges? 7 | 3. How would you move the food? 8 | 4. Change the snake to respond to arrow keys. 9 | 10 | """ 11 | 12 | from turtle import * 13 | from random import randrange 14 | from base import square, vector 15 | 16 | food = vector(0, 0) 17 | snake = [vector(10, 0)] 18 | aim = vector(0, -10) 19 | 20 | def change(x, y): 21 | "Change snake direction." 22 | aim.x = x 23 | aim.y = y 24 | 25 | def inside(head): 26 | "Return True if head inside boundaries." 27 | return -200 < head.x < 190 and -200 < head.y < 190 28 | 29 | def move(): 30 | "Move snake forward one segment." 31 | head = snake[-1].copy() 32 | head.move(aim) 33 | 34 | if not inside(head) or head in snake: 35 | square(head.x, head.y, 9, 'red') 36 | update() 37 | return 38 | 39 | snake.append(head) 40 | 41 | if head == food: 42 | print('Snake:', len(snake)) 43 | food.x = randrange(-15, 15) * 10 44 | food.y = randrange(-15, 15) * 10 45 | else: 46 | snake.pop(0) 47 | 48 | clear() 49 | 50 | for body in snake: 51 | square(body.x, body.y, 9, 'black') 52 | 53 | square(food.x, food.y, 9, 'green') 54 | update() 55 | ontimer(move, 100) 56 | 57 | setup(420, 420, 370, 0) 58 | hideturtle() 59 | tracer(False) 60 | listen() 61 | onkey(lambda: change(10, 0), 'Right') 62 | onkey(lambda: change(-10, 0), 'Left') 63 | onkey(lambda: change(0, 10), 'Up') 64 | onkey(lambda: change(0, -10), 'Down') 65 | move() 66 | done() 67 | -------------------------------------------------------------------------------- /Chapter11/Note: -------------------------------------------------------------------------------- 1 | This chapter is about Pygame module. 2 | SKILL 1: Readers will learn about how to make use of sprites to build 2D games. 3 | SKILL 2: Readers will learn to handle user key events with PyGame 4 | SKILL 3: Readers will learn to use Rect Objects to make objects in game 5 | SKILL 4: Readers will learn to make sprite animation with PyGame 6 | SKILL 5: Readers will learn about Color objects of PyGame 7 | SKILL 6: Readers will learn to handle different movements including diagonal movements. 8 | SKILL 7: Readers will learn to use GIMP to make our own game sprites. 9 | SKILL 8: Readers will learn to make interactive game screens i.e. menu and score screen 10 | SKILL 9: Readers will learn to convert Python file to exe file 11 | SKILL 10: Readers will learn about object alignment. 12 | -------------------------------------------------------------------------------- /Chapter11/SnakeGameFinal.py: -------------------------------------------------------------------------------- 1 | import pygame as game 2 | import time 3 | import random 4 | 5 | game.init() 6 | 7 | color_white = (255, 255, 255) 8 | color_black = (0, 0, 0) 9 | color_red = (255, 0, 0) 10 | green = (0, 155, 0) 11 | 12 | display_width = 800 13 | display_height = 600 14 | 15 | DisplayScreen = game.display.set_mode((display_width, display_height)) 16 | game.display.set_caption('') 17 | 18 | 19 | image = game.image.load('snakehead.png') 20 | appleimg = game.image.load('apple.png') 21 | 22 | objectClock = game.time.Clock() 23 | 24 | Width_Apple = 10 25 | pixel_size = 10 26 | FPS = 15 27 | 28 | arrow_key = "right" 29 | 30 | font_small = game.font.SysFont("comicsansms", 25) 31 | font_medium = game.font.SysFont("comicsansms", 50) 32 | font_large = game.font.SysFont("comicsansms", 80) 33 | 34 | 35 | def score(score): 36 | text = font_small.render("Score: " + str(score), True, color_black) 37 | DisplayScreen.blit(text, [0, 0]) 38 | 39 | 40 | def randAppleGen(): 41 | XpositionApple = round(random.randrange(0, display_width - Width_Apple)) # /10.0)*10.0 42 | YpositionApple = round(random.randrange(0, display_height - Width_Apple)) # /10.0)*10.0 43 | 44 | return XpositionApple, YpositionApple 45 | 46 | 47 | def intro_for_game(): 48 | intro_screen = True 49 | 50 | while intro_screen: 51 | 52 | for eachEvent in game.event.get(): 53 | if eachEvent.type == game.QUIT: 54 | game.quit() 55 | quit() 56 | 57 | if eachEvent.type == game.KEYDOWN: 58 | if eachEvent.key == game.K_c: 59 | intro_screen = False 60 | if eachEvent.key == game.K_q: 61 | game.quit() 62 | quit() 63 | 64 | DisplayScreen.fill(color_white) 65 | display_ScreenMessage("Welcome to drawSnake", 66 | green, 67 | -100, 68 | "large") 69 | display_ScreenMessage("", 70 | color_black, 71 | -30) 72 | 73 | display_ScreenMessage("", 74 | color_black, 75 | 10) 76 | 77 | display_ScreenMessage("Made by Python Programmers", 78 | color_black, 79 | 50) 80 | 81 | display_ScreenMessage("Press C to play or Q to quit.", 82 | color_red, 83 | 180) 84 | 85 | game.display.update() 86 | objectClock.tick(15) 87 | 88 | 89 | def drawSnake(pixel_size, snakeArray): 90 | if arrow_key == "right": 91 | head_of_snake = game.transform.rotate(image, 270) 92 | 93 | if arrow_key == "left": 94 | head_of_snake = game.transform.rotate(image, 90) 95 | 96 | if arrow_key == "up": 97 | head_of_snake = image 98 | 99 | if arrow_key == "down": 100 | head_of_snake = game.transform.rotate(image, 180) 101 | 102 | DisplayScreen.blit(head_of_snake, (snakeArray[-1][0], snakeArray[-1][1])) 103 | 104 | for eachSegment in snakeArray[:-1]: 105 | game.draw.rect(DisplayScreen, green, [eachSegment[0], eachSegment[1], pixel_size, pixel_size]) 106 | 107 | 108 | def objects_text(sample_text, sample_color, sample_size): 109 | if sample_size == "small": 110 | surface_for_text = font_small.render(sample_text, True, sample_color) 111 | elif sample_size == "medium": 112 | surface_for_text = font_medium.render(sample_text, True, sample_color) 113 | elif sample_size == "large": 114 | surface_for_text = font_large.render(sample_text, True, sample_color) 115 | 116 | return surface_for_text, surface_for_text.get_rect() 117 | 118 | 119 | def display_ScreenMessage(message, font_color, yDisplace=0, font_size="small"): 120 | textSurface, textRectShape = objects_text(message, font_color, font_size) 121 | textRectShape.center = (display_width / 2), (display_height / 2) + yDisplace 122 | DisplayScreen.blit(textSurface, textRectShape) 123 | 124 | 125 | def MainLoopForGame(): 126 | global arrow_key 127 | 128 | arrow_key = 'right' 129 | gameOver = False 130 | gameFinish = False 131 | 132 | change_x = display_width / 2 133 | change_y = display_height / 2 134 | 135 | lead_x_change = 10 136 | lead_y_change = 0 137 | 138 | snakeArray = [] 139 | snakeLength = 1 140 | 141 | XpositionApple, YpositionApple = randAppleGen() 142 | 143 | while not gameOver: 144 | 145 | while gameFinish == True: 146 | DisplayScreen.fill(color_white) 147 | display_ScreenMessage("Game over", 148 | color_red, 149 | yDisplace=-50, 150 | font_size="large") 151 | 152 | display_ScreenMessage("Press C to play again or Q to quit", 153 | color_red, 154 | 50, 155 | font_size="medium") 156 | game.display.update() 157 | 158 | for anyEvent in game.event.get(): 159 | if anyEvent.type == game.QUIT: 160 | gameFinish = False 161 | gameOver = True 162 | 163 | if anyEvent.type == game.KEYDOWN: 164 | if anyEvent.key == game.K_q: 165 | gameOver = True 166 | gameFinish = False 167 | if anyEvent.key == game.K_c: 168 | MainLoopForGame() 169 | 170 | for anyEvent in game.event.get(): 171 | if anyEvent.type == game.QUIT: 172 | gameOver = True 173 | if anyEvent.type == game.KEYDOWN: 174 | if anyEvent.key == game.K_LEFT: 175 | arrow_key = "left" 176 | lead_x_change = -pixel_size 177 | lead_y_change = 0 178 | elif anyEvent.key == game.K_RIGHT: 179 | arrow_key = "right" 180 | lead_x_change = pixel_size 181 | lead_y_change = 0 182 | elif anyEvent.key == game.K_UP: 183 | arrow_key = "up" 184 | lead_y_change = -pixel_size 185 | lead_x_change = 0 186 | elif anyEvent.key == game.K_DOWN: 187 | arrow_key = "down" 188 | lead_y_change = pixel_size 189 | lead_x_change = 0 190 | 191 | if change_x >= display_width or change_x < 0 or change_y >= display_height or change_y < 0: 192 | gameFinish = True 193 | 194 | change_x += lead_x_change 195 | change_y += lead_y_change 196 | 197 | DisplayScreen.fill(color_white) 198 | 199 | # game.draw.rect(DisplayScreen, color_red, [XpositionApple, YpositionApple, Width_Apple, Width_Apple]) 200 | 201 | DisplayScreen.blit(appleimg, (XpositionApple, YpositionApple)) 202 | 203 | head_of_Snake = [] 204 | head_of_Snake.append(change_x) 205 | head_of_Snake.append(change_y) 206 | snakeArray.append(head_of_Snake) 207 | 208 | if len(snakeArray) > snakeLength: 209 | del snakeArray[0] 210 | 211 | for eachPart in snakeArray[:-1]: 212 | if eachPart == head_of_Snake: 213 | gameFinish = True 214 | 215 | drawSnake(pixel_size, snakeArray) 216 | 217 | score(snakeLength - 1) 218 | 219 | game.display.update() 220 | 221 | if change_x > XpositionApple and change_x < XpositionApple + Width_Apple or change_x + pixel_size > XpositionApple and change_x + pixel_size < XpositionApple + Width_Apple: 222 | 223 | if change_y > YpositionApple and change_y < YpositionApple + Width_Apple: 224 | 225 | XpositionApple, YpositionApple = randAppleGen() 226 | snakeLength += 1 227 | 228 | elif change_y + pixel_size > YpositionApple and change_y + pixel_size < YpositionApple + Width_Apple: 229 | 230 | XpositionApple, YpositionApple = randAppleGen() 231 | snakeLength += 1 232 | 233 | objectClock.tick(FPS) 234 | 235 | game.quit() 236 | quit() 237 | 238 | 239 | intro_for_game() 240 | MainLoopForGame() 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | -------------------------------------------------------------------------------- /Chapter11/SnakeRect.py: -------------------------------------------------------------------------------- 1 | """ 2 | Code before making snake head image 3 | 4 | game.draw.rect(DisplayScreen, color_red, [XpositionApple, YpositionApple, Width_Apple, Width_Apple]) 5 | game.draw.rect(DisplayScreen, color_black, [change_x,change_y,pixel_size, pixel_size]) 6 | game.display.update() 7 | 8 | objectClock.tick(FPS) 9 | 10 | game.quit() 11 | quit() 12 | 13 | MainLoopForGame() 14 | 15 | 16 | 17 | """ 18 | -------------------------------------------------------------------------------- /Chapter11/apple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter11/apple.png -------------------------------------------------------------------------------- /Chapter11/backbone.py: -------------------------------------------------------------------------------- 1 | import pygame as game 2 | from sys import exit 3 | game.init() 4 | 5 | DisplayScreen = game.display.set_mode((850,650)) 6 | game.display.set_caption('The Snake Game') #game title 7 | 8 | game.display.update() 9 | 10 | gameOver = False 11 | 12 | while not gameOver: 13 | for anyEvent in game.event.get(): 14 | print(event) 15 | exit() 16 | 17 | game.quit() 18 | quit() 19 | -------------------------------------------------------------------------------- /Chapter11/events.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | 3 | pygame.init() 4 | screen = pygame.display.set_mode((400, 300)) 5 | done = False 6 | 7 | while not done: 8 | for event in pygame.event.get(): 9 | if event.type == pygame.QUIT: 10 | done = True 11 | pygame.draw.rect(screen, (0, 128, 0), pygame.Rect(30, 30, 60, 60)) 12 | pygame.display.flip() 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Chapter11/snakegameMainLoop.py: -------------------------------------------------------------------------------- 1 | def MainLoopForGame(): 2 | global arrow_key 3 | 4 | arrow_key = 'right' 5 | gameOver = False 6 | gameFinish = False 7 | 8 | change_x = display_width/2 9 | change_y = display_height/2 10 | 11 | lead_x_change = 10 12 | lead_y_change = 0 13 | 14 | snakeArray = [] 15 | snakeLength = 1 16 | 17 | XpositionApple,YpositionApple = randAppleGen() 18 | 19 | while not gameOver: 20 | 21 | while gameFinish == True: 22 | DisplayScreen.fill(color_white) 23 | 24 | game.display.update() 25 | 26 | for anyEvent in game.anyEvent.get(): 27 | 28 | if anyEvent.type == game.KEYDOWN: 29 | if anyEvent.key == game.K_q: 30 | gameOver = True 31 | gameFinish = False 32 | if anyEvent.key == game.K_c: 33 | MainLoopForGame() 34 | 35 | 36 | for anyEvent in game.anyEvent.get(): 37 | if anyEvent.type == game.QUIT: 38 | gameOver = True 39 | if anyEvent.type == game.KEYDOWN: 40 | if anyEvent.key == game.K_LEFT: 41 | arrow_key = "left" 42 | lead_x_change = -pixel_size 43 | lead_y_change = 0 44 | elif anyEvent.key == game.K_RIGHT: 45 | arrow_key = "right" 46 | lead_x_change = pixel_size 47 | lead_y_change = 0 48 | elif anyEvent.key == game.K_UP: 49 | arrow_key = "up" 50 | lead_y_change = -pixel_size 51 | lead_x_change = 0 52 | elif anyEvent.key == game.K_DOWN: 53 | arrow_key = "down" 54 | lead_y_change = pixel_size 55 | lead_x_change = 0 56 | -------------------------------------------------------------------------------- /Chapter11/snakehead.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter11/snakehead.png -------------------------------------------------------------------------------- /Chapter12/Flappy_Bird/Note: -------------------------------------------------------------------------------- 1 | Flappy Bird clone game 2 | -------------------------------------------------------------------------------- /Chapter12/Flappy_Bird/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Flappy_Bird/background.png -------------------------------------------------------------------------------- /Chapter12/Flappy_Bird/bird.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Flappy_Bird/bird.gif -------------------------------------------------------------------------------- /Chapter12/Flappy_Bird/bird_wing_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Flappy_Bird/bird_wing_down.png -------------------------------------------------------------------------------- /Chapter12/Flappy_Bird/bird_wing_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Flappy_Bird/bird_wing_up.png -------------------------------------------------------------------------------- /Chapter12/Flappy_Bird/flappybird.py: -------------------------------------------------------------------------------- 1 | import math 2 | import os 3 | from random import randint 4 | from collections import deque 5 | 6 | import pygame 7 | from pygame.locals import * 8 | 9 | 10 | Frame_Rate = 60 11 | ANIMATION_SPEED = 0.18 # pixels per millisecond 12 | WINDOW_WIDTH = 284 * 2 # BG image size: 284x512 px; tiled twice 13 | WINDOW_HEIGHT = 512 14 | 15 | 16 | class Bird(pygame.sprite.Sprite): 17 | """Represents the bird controlled by the player. 18 | 19 | The bird is the 'hero' of this game. The player can make it climb 20 | (ascend quickly), otherwise it sinks (descends more slowly). It must 21 | pass through the space in between pipes (for every pipe passed, one 22 | point is scored); if it crashes into a pipe, the game ends. 23 | 24 | Attributes: 25 | x: The bird's X coordinate. 26 | y: The bird's Y coordinate. 27 | msec_to_climb: The number of milliseconds left to climb, where a 28 | complete climb lasts Bird.CLIMB_DURATION milliseconds. 29 | 30 | Constants: 31 | WIDTH: The width, in pixels, of the bird's image. 32 | HEIGHT: The height, in pixels, of the bird's image. 33 | SINK_SPEED: With which speed, in pixels per millisecond, the bird 34 | descends in one second while not climbing. 35 | CLIMB_SPEED: With which speed, in pixels per millisecond, the bird 36 | ascends in one second while climbing, on average. See also the 37 | Bird.update docstring. 38 | CLIMB_DURATION: The number of milliseconds it takes the bird to 39 | execute a complete climb. 40 | """ 41 | 42 | WIDTH = HEIGHT = 30 43 | SINK_SPEED = 0.18 44 | CLIMB_SPEED = 0.3 45 | CLIMB_DURATION = 333.3 46 | 47 | def __init__(self, x, y, msec_to_climb, images): 48 | """Initialise a new Bird instance. 49 | 50 | Arguments: 51 | x: The bird's initial X coordinate. 52 | y: The bird's initial Y coordinate. 53 | msec_to_climb: The number of milliseconds left to climb, where a 54 | complete climb lasts Bird.CLIMB_DURATION milliseconds. Use 55 | this if you want the bird to make a (small?) climb at the 56 | very beginning of the game. 57 | images: A tuple containing the images used by this bird. It 58 | must contain the following images, in the following order: 59 | 0. image of the bird with its wing pointing upward 60 | 1. image of the bird with its wing pointing downward 61 | """ 62 | super(Bird, self).__init__() 63 | self.x, self.y = x, y 64 | self.msec_to_climb = msec_to_climb 65 | self._img_wingup, self._img_wingdown = images 66 | self._mask_wingup = pygame.mask.from_surface(self._img_wingup) 67 | self._mask_wingdown = pygame.mask.from_surface(self._img_wingdown) 68 | 69 | def update(self, delta_frames=1): 70 | """Update the bird's position. 71 | 72 | This function uses the cosine function to achieve a smooth climb: 73 | In the first and last few frames, the bird climbs very little, in the 74 | middle of the climb, it climbs a lot. 75 | One complete climb lasts CLIMB_DURATION milliseconds, during which 76 | the bird ascends with an average speed of CLIMB_SPEED px/ms. 77 | This Bird's msec_to_climb attribute will automatically be 78 | decreased accordingly if it was > 0 when this method was called. 79 | 80 | Arguments: 81 | delta_frames: The number of frames elapsed since this method was 82 | last called. 83 | """ 84 | if self.msec_to_climb > 0: 85 | frac_climb_done = 1 - self.msec_to_climb/Bird.CLIMB_DURATION 86 | self.y -= (Bird.CLIMB_SPEED * frames_to_msec(delta_frames) * 87 | (1 - math.cos(frac_climb_done * math.pi))) 88 | self.msec_to_climb -= frames_to_msec(delta_frames) 89 | else: 90 | self.y += Bird.SINK_SPEED * frames_to_msec(delta_frames) 91 | 92 | @property 93 | def image(self): 94 | """Get a Surface containing this bird's image. 95 | 96 | This will decide whether to return an image where the bird's 97 | visible wing is pointing upward or where it is pointing downward 98 | based on pygame.time.get_ticks(). This will animate the flapping 99 | bird, even though pygame doesn't support animated GIFs. 100 | """ 101 | if pygame.time.get_ticks() % 500 >= 250: 102 | return self._img_wingup 103 | else: 104 | return self._img_wingdown 105 | 106 | @property 107 | def mask(self): 108 | """Get a bitmask for use in collision detection. 109 | 110 | The bitmask excludes all pixels in self.image with a 111 | transparency greater than 127.""" 112 | if pygame.time.get_ticks() % 500 >= 250: 113 | return self._mask_wingup 114 | else: 115 | return self._mask_wingdown 116 | 117 | @property 118 | def rect(self): 119 | """Get the bird's position, width, and height, as a pygame.Rect.""" 120 | return Rect(self.x, self.y, Bird.WIDTH, Bird.HEIGHT) 121 | 122 | 123 | class PipePair(pygame.sprite.Sprite): 124 | """Represents an obstacle. 125 | 126 | A PipePair has a top and a bottom pipe, and only between them can 127 | the bird pass -- if it collides with either part, the game is over. 128 | 129 | Attributes: 130 | x: The PipePair's X position. This is a float, to make movement 131 | smoother. Note that there is no y attribute, as it will only 132 | ever be 0. 133 | image: A pygame.Surface which can be blitted to the display surface 134 | to display the PipePair. 135 | mask: A bitmask which excludes all pixels in self.image with a 136 | transparency greater than 127. This can be used for collision 137 | detection. 138 | top_pipe_pieces: The number of pieces, including the end piece, in the 139 | top pipe. 140 | bottom_pipe_pieces: The number of pieces, including the end piece, in 141 | the bottom pipe. 142 | 143 | Constants: 144 | WIDTH: The width, in pixels, of a pipe piece. Because a pipe is 145 | only one piece wide, this is also the width of a PipePair's 146 | image. 147 | HEIGHT_PIECE: The height, in pixels, of a pipe piece. 148 | ADD_INTERVAL: The interval, in milliseconds, in between adding new 149 | pipes. 150 | """ 151 | 152 | WIDTH = 80 153 | HEIGHT_PIECE = 32 154 | ADD_INTERVAL = 3000 155 | 156 | def __init__(self, end_image_pipe, body_image_pipe): 157 | """Initialises a new random PipePair. 158 | 159 | The new PipePair will automatically be assigned an x attribute of 160 | float(WINDOW_WIDTH - 1). 161 | 162 | Arguments: 163 | end_image_pipe: The image to use to represent a pipe's end piece. 164 | body_image_pipe: The image to use to represent one horizontal slice 165 | of a pipe's body. 166 | """ 167 | self.x = float(WINDOW_WIDTH - 1) 168 | self.score_counted = False 169 | 170 | self.image = pygame.Surface((PipePair.WIDTH, WINDOW_HEIGHT), SRCALPHA) 171 | self.image.convert() # speeds up blitting 172 | self.image.fill((0, 0, 0, 0)) 173 | total_pipe_body_pieces = int( 174 | (WINDOW_HEIGHT - # fill window from top to bottom 175 | 3 * Bird.HEIGHT - # make room for bird to fit through 176 | 3 * PipePair.HEIGHT_PIECE) / # 2 end pieces + 1 body piece 177 | PipePair.HEIGHT_PIECE # to get number of pipe pieces 178 | ) 179 | self.bottom_pipe_pieces = randint(1, total_pipe_body_pieces) 180 | self.top_pipe_pieces = total_pipe_body_pieces - self.bottom_pipe_pieces 181 | 182 | # bottom pipe 183 | for i in range(1, self.bottom_pipe_pieces + 1): 184 | piece_pos = (0, WINDOW_HEIGHT - i*PipePair.HEIGHT_PIECE) 185 | self.image.blit(body_image_pipe, piece_pos) 186 | bottom_pipe_end_y = WINDOW_HEIGHT - self.height_bottomPipe_px 187 | bottom_end_piece_pos = (0, bottom_pipe_end_y - PipePair.HEIGHT_PIECE) 188 | self.image.blit(end_image_pipe, bottom_end_piece_pos) 189 | 190 | # top pipe 191 | for i in range(self.top_pipe_pieces): 192 | self.image.blit(body_image_pipe, (0, i * PipePair.HEIGHT_PIECE)) 193 | top_pipe_end_y = self.height_topPipe_px 194 | self.image.blit(end_image_pipe, (0, top_pipe_end_y)) 195 | 196 | # compensate for added end pieces 197 | self.top_pipe_pieces += 1 198 | self.bottom_pipe_pieces += 1 199 | 200 | # for collision detection 201 | self.mask = pygame.mask.from_surface(self.image) 202 | 203 | @property 204 | def height_topPipe_px(self): 205 | """Get the top pipe's height, in pixels.""" 206 | return self.top_pipe_pieces * PipePair.HEIGHT_PIECE 207 | 208 | @property 209 | def height_bottomPipe_px(self): 210 | """Get the bottom pipe's height, in pixels.""" 211 | return self.bottom_pipe_pieces * PipePair.HEIGHT_PIECE 212 | 213 | @property 214 | def visible(self): 215 | """Get whether this PipePair on screen, visible to the player.""" 216 | return -PipePair.WIDTH < self.x < WINDOW_WIDTH 217 | 218 | @property 219 | def rect(self): 220 | """Get the Rect which contains this PipePair.""" 221 | return Rect(self.x, 0, PipePair.WIDTH, PipePair.HEIGHT_PIECE) 222 | 223 | def update(self, delta_frames=1): 224 | """Update the PipePair's position. 225 | 226 | Arguments: 227 | delta_frames: The number of frames elapsed since this method was 228 | last called. 229 | """ 230 | self.x -= ANIMATION_SPEED * frames_to_msec(delta_frames) 231 | 232 | def collides_with(self, bird): 233 | """Get whether the bird collides with a pipe in this PipePair. 234 | 235 | Arguments: 236 | bird: The Bird which should be tested for collision with this 237 | PipePair. 238 | """ 239 | return pygame.sprite.collide_mask(self, bird) 240 | 241 | 242 | def loading_Images(): 243 | """Load all images required by the game and return a dict of them. 244 | 245 | The returned dict has the following keys: 246 | game_background: The game's game_background image. 247 | WingUp: An image of the bird with its wing pointing upward. 248 | Use this and WingDown to create a flapping bird. 249 | WingDown: An image of the bird with its wing pointing downward. 250 | Use this and WingUp to create a flapping bird. 251 | endPipe: An image of a pipe's end piece (the slightly wider bit). 252 | Use this and bodyPipe to make pipes. 253 | bodyPipe: An image of a slice of a pipe's body. Use this and 254 | bodyPipe to make pipes. 255 | """ 256 | 257 | def loading_Image(img_file_name): 258 | """Return the loaded pygame image with the specified file name. 259 | 260 | This function looks for images in the game's images folder 261 | (./images/). All images are converted before being returned to 262 | speed up blitting. 263 | 264 | Arguments: 265 | img_file_name: The file name (including its extension, e.g. 266 | '.png') of the required image, without a file path. 267 | """ 268 | file_name = os.path.join('.', 'images', img_file_name) 269 | img = pygame.image.load(file_name) 270 | img.convert() 271 | return img 272 | 273 | return {'game_background': loading_Image('background.png'), 274 | 'endPipe': loading_Image('pipe_end.png'), 275 | 'bodyPipe': loading_Image('pipe_body.png'), 276 | # GIF file format is nor supported by pygame 277 | 'WingUp': loading_Image('bird_wing_up.png'), 278 | 'WingDown': loading_Image('bird_wing_down.png')} 279 | 280 | 281 | def frames_to_msec(frames, Frame_Rate=Frame_Rate): 282 | """Convert frames to milliseconds at the specified framerate. 283 | 284 | Arguments: 285 | frames: How many frames to convert to milliseconds. 286 | Frame_Rate: The framerate to use for conversion. Default: Frame_Rate. 287 | """ 288 | return 1000.0 * frames / Frame_Rate 289 | 290 | 291 | def msec_to_frames(milliseconds, Frame_Rate=Frame_Rate): 292 | """Convert milliseconds to frames at the specified framerate. 293 | 294 | Arguments: 295 | milliseconds: How many milliseconds to convert to frames. 296 | Frame_Rate: The framerate to use for conversion. Default: Frame_Rate. 297 | """ 298 | return Frame_Rate * milliseconds / 1000.0 299 | 300 | 301 | def main(): 302 | """The application's entry point. 303 | 304 | If someone executes this module (instead of importing it, for 305 | example), this function is called. 306 | """ 307 | 308 | pygame.init() 309 | 310 | display_surface = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT)) 311 | pygame.display.set_caption('Pygame Flappy Bird') 312 | 313 | clock = pygame.time.Clock() 314 | score_font = pygame.font.SysFont(None, 32, bold=True) # default font 315 | images = loading_Images() 316 | 317 | # the bird stays in the same x position, so bird.x is a constant 318 | # center bird on screen 319 | bird = Bird(50, int(WINDOW_HEIGHT/2 - Bird.HEIGHT/2), 2, 320 | (images['WingUp'], images['WingDown'])) 321 | 322 | pipes = deque() 323 | 324 | frame_clock = 0 # this counter is only incremented if the game isn't paused 325 | score = 0 326 | done = paused = False 327 | while not done: 328 | clock.tick(Frame_Rate) 329 | 330 | # Handle this 'manually'. If we used pygame.time.set_timer(), 331 | # pipe addition would be messed up when paused. 332 | if not (paused or frame_clock % msec_to_frames(PipePair.ADD_INTERVAL)): 333 | pp = PipePair(images['endPipe'], images['bodyPipe']) 334 | pipes.append(pp) 335 | 336 | for e in pygame.event.get(): 337 | if e.type == QUIT or (e.type == KEYUP and e.key == K_ESCAPE): 338 | done = True 339 | break 340 | elif e.type == KEYUP and e.key in (K_PAUSE, K_p): 341 | paused = not paused 342 | elif e.type == MOUSEBUTTONUP or (e.type == KEYUP and 343 | e.key in (K_UP, K_RETURN, K_SPACE)): 344 | bird.msec_to_climb = Bird.CLIMB_DURATION 345 | 346 | if paused: 347 | continue # don't draw anything 348 | 349 | # check for collisions 350 | 351 | 352 | for x in (0, WINDOW_WIDTH / 2): 353 | display_surface.blit(images['game_background'], (x, 0)) 354 | 355 | while pipes and not pipes[0].visible: 356 | pipes.popleft() 357 | 358 | for p in pipes: 359 | p.update() 360 | display_surface.blit(p.image, p.rect) 361 | 362 | bird.update() 363 | display_surface.blit(bird.image, bird.rect) 364 | 365 | # update and display score 366 | for p in pipes: 367 | if p.x + PipePair.WIDTH < bird.x and not p.score_counted: 368 | score += 1 369 | p.score_counted = True 370 | 371 | 372 | pygame.display.flip() 373 | frame_clock += 1 374 | print('Game over! Score: %i' % score) 375 | pygame.quit() 376 | 377 | 378 | if __name__ == '__main__': 379 | # If this module had been imported, __name__ would be 'flappybird'. 380 | # It was executed (e.g. by double-clicking the file), so call main. 381 | main() 382 | -------------------------------------------------------------------------------- /Chapter12/Flappy_Bird/ground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Flappy_Bird/ground.png -------------------------------------------------------------------------------- /Chapter12/Flappy_Bird/pipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Flappy_Bird/pipe.png -------------------------------------------------------------------------------- /Chapter12/Flappy_Bird/pipe_body.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Flappy_Bird/pipe_body.png -------------------------------------------------------------------------------- /Chapter12/Flappy_Bird/pipe_end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Flappy_Bird/pipe_end.png -------------------------------------------------------------------------------- /Chapter12/Note: -------------------------------------------------------------------------------- 1 | This chapter will teach you about character animation using sprites by making flappy bird game 2 | -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Left1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Left1.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Left2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Left2.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Left3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Left3.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Left4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Left4.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Left5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Left5.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Left6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Left6.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Left7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Left7.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Left8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Left8.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Left9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Left9.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Note: -------------------------------------------------------------------------------- 1 | How to use sprites for animation 2 | -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Right1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Right1.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Right2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Right2.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Right3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Right3.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Right4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Right4.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Right5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Right5.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Right6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Right6.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Right7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Right7.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Right8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Right8.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/Right9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/Right9.png -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/bg.jpg -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/sprite-animation.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | 3 | pygame.init() 4 | 5 | win = pygame.display.set_mode((500, 480)) 6 | 7 | 8 | walkRight = [pygame.image.load('Right1.png'), pygame.image.load('Right2.png'), pygame.image.load('Right3.png'), 9 | pygame.image.load('Right4.png'), pygame.image.load('Right5.png'), pygame.image.load('Right6.png'), 10 | pygame.image.load('Right7.png'), pygame.image.load('Right8.png'), pygame.image.load('Right9.png')] 11 | walkLeft = [pygame.image.load('Left1.png'), pygame.image.load('Left2.png'), pygame.image.load('Left3.png'), 12 | pygame.image.load('Left4.png'), pygame.image.load('Left5.png'), pygame.image.load('Left6.png'), 13 | pygame.image.load('Left7.png'), pygame.image.load('Left8.png'), pygame.image.load('Left9.png')] 14 | bg = pygame.image.load('bg.jpg') 15 | char = pygame.image.load('standing.png') 16 | 17 | x = 50 18 | y = 400 19 | width = 40 20 | height = 60 21 | vel = 5 22 | 23 | clock = pygame.time.Clock() 24 | 25 | 26 | left = False 27 | right = False 28 | walkCount = 0 29 | 30 | 31 | def Animation_Logic(): 32 | global walkCount 33 | 34 | win.blit(bg, (0, 0)) 35 | if walkCount + 1 >= 27: 36 | walkCount = 0 37 | 38 | if left: 39 | win.blit(walkLeft[walkCount // 3], (x, y)) 40 | walkCount += 1 41 | elif right: 42 | win.blit(walkRight[walkCount // 3], (x, y)) 43 | walkCount += 1 44 | else: 45 | win.blit(char, (x, y)) 46 | walkCount = 0 47 | 48 | pygame.display.update() 49 | 50 | 51 | finish = False 52 | 53 | while not finish: 54 | clock.tick(27) 55 | 56 | for event in pygame.event.get(): 57 | if event.type == pygame.QUIT: 58 | finish = True 59 | 60 | keys = pygame.key.get_pressed() 61 | 62 | if keys[pygame.K_LEFT] and x > vel: 63 | x -= vel 64 | left = True 65 | right = False 66 | 67 | elif keys[pygame.K_RIGHT] and x < 500 - vel - width: 68 | x += vel 69 | left = False 70 | right = True 71 | 72 | else: 73 | left = False 74 | right = False 75 | walkCount = 0 76 | 77 | 78 | 79 | Animation_Logic() 80 | 81 | pygame.quit() 82 | -------------------------------------------------------------------------------- /Chapter12/Sprites_Animation/standing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter12/Sprites_Animation/standing.png -------------------------------------------------------------------------------- /Chapter13/Note: -------------------------------------------------------------------------------- 1 | #making tetris game using python pygame 2 | -------------------------------------------------------------------------------- /Chapter13/tetris.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import random 3 | 4 | pygame.font.init() 5 | 6 | # GLOBALS VARS 7 | width = 800 8 | height = 700 9 | game_width = 300 # meaning 300 // 10 = 30 width per block 10 | game_height = 600 # meaning 600 // 20 = 30 height per block 11 | shape_size = 30 12 | 13 | top_left_x = (width - game_width) // 2 14 | top_left_y = height - game_height 15 | 16 | 17 | # SHAPE FORMATS 18 | 19 | S = [['.....', 20 | '.....', 21 | '..00.', 22 | '.00..', 23 | '.....'], 24 | ['.....', 25 | '..0..', 26 | '..00.', 27 | '...0.', 28 | '.....']] 29 | 30 | Z = [['.....', 31 | '.....', 32 | '.00..', 33 | '..00.', 34 | '.....'], 35 | ['.....', 36 | '..0..', 37 | '.00..', 38 | '.0...', 39 | '.....']] 40 | 41 | I = [['..0..', 42 | '..0..', 43 | '..0..', 44 | '..0..', 45 | '.....'], 46 | ['.....', 47 | '0000.', 48 | '.....', 49 | '.....', 50 | '.....']] 51 | 52 | O = [['.....', 53 | '.....', 54 | '.00..', 55 | '.00..', 56 | '.....']] 57 | 58 | J = [['.....', 59 | '.0...', 60 | '.000.', 61 | '.....', 62 | '.....'], 63 | ['.....', 64 | '..00.', 65 | '..0..', 66 | '..0..', 67 | '.....'], 68 | ['.....', 69 | '.....', 70 | '.000.', 71 | '...0.', 72 | '.....'], 73 | ['.....', 74 | '..0..', 75 | '..0..', 76 | '.00..', 77 | '.....']] 78 | 79 | L = [['.....', 80 | '...0.', 81 | '.000.', 82 | '.....', 83 | '.....'], 84 | ['.....', 85 | '..0..', 86 | '..0..', 87 | '..00.', 88 | '.....'], 89 | ['.....', 90 | '.....', 91 | '.000.', 92 | '.0...', 93 | '.....'], 94 | ['.....', 95 | '.00..', 96 | '..0..', 97 | '..0..', 98 | '.....']] 99 | 100 | T = [['.....', 101 | '..0..', 102 | '.000.', 103 | '.....', 104 | '.....'], 105 | ['.....', 106 | '..0..', 107 | '..00.', 108 | '..0..', 109 | '.....'], 110 | ['.....', 111 | '.....', 112 | '.000.', 113 | '..0..', 114 | '.....'], 115 | ['.....', 116 | '..0..', 117 | '.00..', 118 | '..0..', 119 | '.....']] 120 | 121 | game_objects = [S, Z, I, O, J, L, T] 122 | objects_color = [(0, 255, 0), (255, 0, 0), (0, 255, 255), (255, 255, 0), (255, 165, 0), (0, 0, 255), (128, 0, 128)] 123 | # index 0 - 6 represent shape 124 | 125 | 126 | class Shape(object): # * 127 | def __init__(self, column, row, shape): 128 | self.x = column 129 | self.y = row 130 | self.shape = shape 131 | self.color = objects_color[game_objects.index(shape)] 132 | self.rotation = 0 133 | 134 | 135 | def build_Grid(occupied={}): # * 136 | shapes_grid = [[(0,0,0) for _ in range(10)] for _ in range(20)] 137 | 138 | for row in range(len(shapes_grid)): 139 | for column in range(len(shapes_grid[row])): 140 | if (column, row) in occupied: 141 | piece = occupied[(column,row)] 142 | shapes_grid[row][column] = piece 143 | return shapes_grid 144 | 145 | 146 | def define_shape_position(shape_piece): 147 | positions = [] 148 | list_of_shapes = shape_piece.shape[shape_piece.rotation % len(shape_piece.shape)] 149 | 150 | for i, line in enumerate(list_of_shapes): 151 | row = list(line) 152 | for j, column in enumerate(row): 153 | if column == '0': 154 | positions.append((shape_piece.x + j, shape_piece.y + i)) 155 | 156 | for p, block_pos in enumerate(positions): 157 | positions[p] = (block_pos[0] - 2, block_pos[1] - 4) 158 | 159 | return positions 160 | 161 | 162 | def check_Moves(shape, grid): 163 | valid_pos = [[(j, i) for j in range(10) if grid[i][j] == (0,0,0)] for i in range(20)] 164 | valid_pos = [j for sub in valid_pos for j in sub] 165 | 166 | shape_pos = define_shape_position(shape) 167 | 168 | for eachPos in shape_pos: 169 | if eachPos not in valid_pos: 170 | if eachPos[1] > -1: 171 | return False 172 | return True 173 | 174 | 175 | def check_lost(positions): 176 | for pos in positions: 177 | x, y = pos 178 | if y < 1: 179 | return True 180 | 181 | return False 182 | 183 | 184 | def generate_Shapes(): 185 | return Shape(5, 0, random.choice(game_objects)) 186 | 187 | 188 | def draw_text_middle(surface, text, size, color): 189 | font = pygame.font.SysFont("comicsans", size, bold=True) 190 | label = font.render(text, 1, color) 191 | 192 | surface.blit(label, (top_left_x + game_width /2 - (label.get_width()/2), top_left_y + game_height/2 - label.get_height()/2)) 193 | 194 | 195 | def show_grid(screen_surface, grid): 196 | side_x = top_left_x 197 | side_y = top_left_y 198 | 199 | for eachRow in range(len(grid)): 200 | pygame.draw.line(screen_surface, (128,128,128), (side_x, side_y + eachRow*shape_size), (side_x+game_width, side_y+ eachRow*shape_size)) 201 | for eachCol in range(len(grid[eachRow])): 202 | pygame.draw.line(screen_surface, (128, 128, 128), (side_x + eachCol*shape_size, side_y),(side_x + eachCol*shape_size, side_y + game_height)) 203 | 204 | 205 | def delete_Row(grid, occupied): 206 | 207 | black_background_color = (0, 0, 0) 208 | number_of_rows_deleted = 0 209 | for i in range(len(grid)-1, -1, -1): 210 | eachRow = grid[i] 211 | if black_background_color not in eachRow: 212 | number_of_rows_deleted += 1 213 | index_of_deleted_rows = i 214 | for j in range(len(eachRow)): 215 | try: 216 | del occupied[(j,i)] 217 | except: 218 | continue 219 | 220 | if number_of_rows_deleted > 0: 221 | for position in sorted(list(occupied), key=lambda x: x[1])[::-1]: 222 | x, y = position 223 | if y < index_of_deleted_rows: 224 | newPos = (x, y + number_of_rows_deleted) 225 | occupied[newPos] = occupied.pop(position) 226 | 227 | return number_of_rows_deleted 228 | 229 | 230 | def draw_next_shape(shape, surface): 231 | font = pygame.font.SysFont('comicsans', 30) 232 | label = font.render('Next Shape', 1, (255,255,255)) 233 | 234 | sx = top_left_x + game_width + 50 235 | sy = top_left_y + game_height/2 - 100 236 | format = shape.shape[shape.rotation % len(shape.shape)] 237 | 238 | for i, line in enumerate(format): 239 | row = list(line) 240 | for j, column in enumerate(row): 241 | if column == '0': 242 | pygame.draw.rect(surface, shape.color, (sx + j*shape_size, sy + i*shape_size, shape_size, shape_size), 0) 243 | 244 | surface.blit(label, (sx + 10, sy - 30)) 245 | 246 | 247 | def update_score(nscore): 248 | score = max_score() 249 | 250 | with open('scores.txt', 'w') as f: 251 | if int(score) > nscore: 252 | f.write(str(score)) 253 | else: 254 | f.write(str(nscore)) 255 | 256 | 257 | def max_score(): 258 | with open('scores.txt', 'r') as f: 259 | lines = f.readlines() 260 | score = lines[0].strip() 261 | 262 | return score 263 | 264 | 265 | def create_Grid(screen_surface, grid_scene, score=0, last_score = 0): 266 | screen_surface.fill((0, 0, 0)) 267 | 268 | pygame.font.init() 269 | font = pygame.font.SysFont('comicsans', 60) 270 | label = font.render('Tetris', 1, (255, 255, 255)) 271 | 272 | screen_surface.blit(label, (top_left_x + game_width / 2 - (label.get_width() / 2), 30)) 273 | 274 | """ current score and last score are modifications to the game 275 | 276 | ----------------------------------------------------------------- 277 | 278 | """ 279 | # current score 280 | font = pygame.font.SysFont('comicsans', 30) 281 | label = font.render('Score: ' + str(score), 1, (255,255,255)) 282 | 283 | 284 | sx = top_left_x + game_width + 50 285 | sy = top_left_y + game_height/2 - 100 286 | 287 | screen_surface.blit(label, (sx + 20, sy + 160)) 288 | # last score 289 | label = font.render('High Score: ' + last_score, 1, (255,255,255)) 290 | 291 | sx = top_left_x - 200 292 | sy = top_left_y + 200 293 | 294 | screen_surface.blit(label, (sx + 20, sy + 160)) 295 | 296 | for i in range(len(grid_scene)): 297 | for j in range(len(grid_scene[i])): 298 | pygame.draw.rect(screen_surface, grid_scene[i][j], (top_left_x + j*shape_size, top_left_y + i*shape_size, shape_size, shape_size), 0) 299 | 300 | pygame.draw.rect(screen_surface, (255, 0, 0), (top_left_x, top_left_y, game_width, game_height), 5) 301 | 302 | show_grid(screen_surface, grid_scene) 303 | #pygame.display.update() 304 | 305 | 306 | def main(win): # * 307 | 308 | last_score = max_score() 309 | occupied = {} 310 | grid = build_Grid(occupied) 311 | 312 | change_shape = False 313 | done = False 314 | current_shape = generate_Shapes() 315 | next_shape = generate_Shapes() 316 | clock = pygame.time.Clock() 317 | 318 | timeforFall = 0 319 | speedforFall = 0.27 320 | level_time = 0 321 | score = 0 322 | 323 | while not done: 324 | grid = build_Grid(occupied) 325 | timeforFall += clock.get_rawtime() 326 | level_time += clock.get_rawtime() 327 | clock.tick() 328 | 329 | if timeforFall/1000 > speedforFall: 330 | timeforFall = 0 331 | current_shape.y += 1 332 | if not(check_Moves(current_shape, grid)) and current_shape.y > 0: 333 | current_shape.y -= 1 334 | change_shape = True 335 | 336 | for eachEvent in pygame.event.get(): 337 | if eachEvent.type == pygame.QUIT: 338 | done = True 339 | pygame.display.quit() 340 | 341 | if eachEvent.type == pygame.KEYDOWN: 342 | if eachEvent.key == pygame.K_LEFT: 343 | current_shape.x -= 1 344 | if not(check_Moves(current_shape, grid)): 345 | current_shape.x += 1 346 | if eachEvent.key == pygame.K_RIGHT: 347 | current_shape.x += 1 348 | if not(check_Moves(current_shape, grid)): 349 | current_shape.x -= 1 350 | if eachEvent.key == pygame.K_DOWN: 351 | current_shape.y += 1 352 | if not(check_Moves(current_shape, grid)): 353 | current_shape.y -= 1 354 | if eachEvent.key == pygame.K_UP: 355 | current_shape.rotation += 1 356 | if not(check_Moves(current_shape, grid)): 357 | current_shape.rotation -= 1 358 | 359 | position_of_shape = define_shape_position(current_shape) 360 | 361 | for i in range(len(position_of_shape)): 362 | x, y = position_of_shape[i] 363 | if y > -1: 364 | grid[y][x] = current_shape.color 365 | 366 | """will change piece """ 367 | if change_shape: 368 | for eachPos in position_of_shape: 369 | pos = (eachPos[0], eachPos[1]) 370 | occupied[pos] = current_shape.color 371 | current_shape = next_shape 372 | next_shape = generate_Shapes() 373 | change_shape = False 374 | score += delete_Row(grid, occupied) * 10 375 | 376 | create_Grid(win, grid, score, last_score) 377 | draw_next_shape(next_shape, win) 378 | pygame.display.update() 379 | 380 | """ optional check: whether lost or not""" 381 | if check_lost(occupied): 382 | draw_text_middle(win, "YOU LOST!", 80, (255,255,255)) 383 | pygame.display.update() 384 | pygame.time.delay(1500) 385 | run = False 386 | update_score(score) 387 | 388 | 389 | def Welcome_Screen(surface): # * 390 | done = False 391 | while not done: 392 | surface.fill((128,0, 128)) 393 | draw_text_middle(win, 'Press Any Key To Play Tetris!!', 60, (255,255,255)) 394 | pygame.display.update() 395 | for event in pygame.event.get(): 396 | if event.type == pygame.QUIT: 397 | done = True 398 | if event.type == pygame.KEYDOWN: 399 | main(surface) 400 | 401 | pygame.display.quit() 402 | 403 | 404 | win = pygame.display.set_mode((width, height)) 405 | pygame.display.set_caption('Tetris') 406 | Welcome_Screen(win) 407 | -------------------------------------------------------------------------------- /Chapter14/Note: -------------------------------------------------------------------------------- 1 | """ learn about python pyopenGL module""" 2 | -------------------------------------------------------------------------------- /Chapter14/draw.py: -------------------------------------------------------------------------------- 1 | from OpenGLContext import testingcontext 2 | BaseContext = testingcontext.getInteractive() 3 | from OpenGL.GL import * 4 | 5 | """ 6 | we have to install OpenGLContext module which will store all the states that 7 | are associated with the instances of OpenGL. 8 | If the context is destroyed then eventually OpenGL will be destroyed. 9 | 10 | """ 11 | 12 | 13 | class TriangleContext( BaseContext ): 14 | 15 | initialPosition = (0, 0, 0) 16 | 17 | #define render 18 | def Render(self, mode): 19 | 20 | """ Render triangle""" 21 | glDisable(GL_CULL_FACE) 22 | glTranslatef(-1.5, 0.0, -6.0) 23 | glBegin(GL_TRIANGLES) 24 | glVertex3f(0.0, 1.0, 0.0) 25 | glVertex3f(-1.0, -1.0, 0.0) 26 | glVertex3f(1.0, -1.0, 0.0) 27 | glEnd() 28 | 29 | if __name__ == "__main__": 30 | TriangleContext.ContextMainLoop() 31 | -------------------------------------------------------------------------------- /Chapter14/draw_cube.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | from pygame.locals import * 3 | from OpenGL.GL import * 4 | from OpenGL.GLU import * 5 | 6 | cube_Vertices = ( 7 | (1, -1, -1), 8 | (1, 1, -1), 9 | (-1, 1, -1), 10 | (-1, -1, -1), 11 | (1, -1, 1), 12 | (1, 1, 1), 13 | (-1, -1, 1), 14 | (-1, 1, 1), 15 | ) 16 | 17 | cube_Edges = ( 18 | (0,1), 19 | (0,3), 20 | (0,4), 21 | (2,1), 22 | (2,3), 23 | (2,7), 24 | (6,3), 25 | (6,4), 26 | (6,7), 27 | (5,1), 28 | (5,4), 29 | (5,7), 30 | ) 31 | 32 | cube_Surfaces = ( 33 | (0,1,2,3), 34 | (3,2,7,6), 35 | (6,7,5,4), 36 | (4,5,1,0), 37 | (1,5,7,2), 38 | (4,0,3,6) 39 | ) 40 | 41 | 42 | def renderCube(): 43 | glBegin(GL_QUADS) 44 | for eachSurface in cube_Surfaces: 45 | for eachVertex in eachSurface: 46 | glColor3fv((1, 1, 0)) #yellow color code 47 | glVertex3fv(cube_Surfaces[eachVertex]) 48 | glEnd() 49 | glBegin(GL_LINES) 50 | for eachEdge in cube_Edges: 51 | for eachVertex in eachEdge: 52 | glVertex3fv(cube_Vertices[eachVertex]) 53 | glEnd() 54 | 55 | def ActionHandler(): 56 | pygame.init() 57 | screen = (800, 500) 58 | pygame.display.set_mode(screen, DOUBLEBUF|OPENGL) #OPENGL is essential 59 | 60 | #1: ADD A CLIPPING TRANSFORMATION 61 | gluPerspective(85.0, (screen[0]/screen[1]), 0.1, 50) 62 | 63 | # 80.0 -> field view of camera 64 | #screen[0]/screen[1] -> aspect ration (width/height) 65 | #0.1 -> near clipping plane 66 | #50 -> far clipping plane 67 | glRotatef(18, 2, 0, 0) #start point 68 | while True: 69 | 70 | for anyEvent in pygame.event.get(): 71 | if anyEvent.type == pygame.QUIT: 72 | pygame.quit() 73 | quit() 74 | 75 | if anyEvent.type == pygame.MOUSEBUTTONDOWN: 76 | print(anyEvent) 77 | print(anyEvent.button) #printing mouse event 78 | 79 | #mouse button 4 and 5 are at the left side of the mouse 80 | #mouse button 4 is used as forward and backward navigation 81 | if anyEvent.button == 4: 82 | glTranslatef(0.0,0.0,1.0) #produces translation of (x, y, z) 83 | elif anyEvent.button == 5: 84 | glTranslatef(0.0,0.0,-1.0) 85 | 86 | glRotatef(1, 3, 1, 1) 87 | #The glRotatef is used to perform matrix transformation which performs a rotation 88 | #of counterclockwise with an angle of degree about origin through the point #provided as (x, y, z). 89 | #----------------------------------------------------------------- 90 | #indicates the buffer that needs to be cleared 91 | #GL_COLOR_BUFFER_BIT: enabled for color drawing 92 | #GL_DEPTH_BUFFER_BIT: depth buffer which needs to be cleared 93 | 94 | glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) 95 | 96 | #render cube 97 | renderCube() 98 | pygame.display.flip() 99 | pygame.time.wait(12) 100 | 101 | #call main function only externally 102 | ActionHandler() 103 | -------------------------------------------------------------------------------- /Chapter15/Note: -------------------------------------------------------------------------------- 1 | """ chapter 15: We will learn about Python pymunk module: Pythonic way of implementing 2d Physics in the simulating environment""" 2 | -------------------------------------------------------------------------------- /Chapter15/characters.py: -------------------------------------------------------------------------------- 1 | import pymunk as p 2 | from pymunk import Vec2d 3 | 4 | 5 | class RoundBird(): 6 | def __init__(self, distance, angle, x_pos, y_pos, space): 7 | weight = 5 8 | r = 12 #radius 9 | value_of_inertia = p.moment_for_circle(weight, 0, r, (0, 0)) 10 | obj_body = p.Body(weight, value_of_inertia) 11 | obj_body.position = x_pos, y_pos 12 | power_value = distance * 53 13 | impulse = power_value * Vec2d(1, 0) 14 | angle = -angle 15 | obj_body.apply_impulse_at_local_point(impulse.rotated(angle)) 16 | obj_shape = p.Circle(obj_body, r, (0, 0)) 17 | obj_shape.elasticity = 0.95 #bouncing angry bird 18 | obj_shape.friction = 1 #for roughness 19 | obj_shape.collision_type = 0 #for checking collisions later 20 | space.add(obj_body, obj_shape) 21 | #class RoundBird attribute ---- 22 | self.body = obj_body 23 | self.shape = obj_shape 24 | 25 | 26 | class RoundPig(): 27 | def __init__(self, x_pos, y_pos, space): 28 | self.life = 20 #life will be decreased after collision of pig with bird 29 | weight = 5 30 | r = 14 #radius 31 | value_of_inertia = p.moment_for_circle(weight, 0, r, (0, 0)) 32 | obj_body = p.Body(weight, value_of_inertia) #creates virtual space to render shape 33 | obj_body.position = x_pos, y_pos 34 | #add circle to obj body 35 | obj_shape = p.Circle(obj_body, r, (0, 0)) 36 | obj_shape.elasticity = 0.95 37 | obj_shape.friction = 1 38 | obj_shape.collision_type = 1 39 | space.add(obj_body, obj_shape) 40 | self.body = obj_body 41 | self.shape = obj_shape 42 | -------------------------------------------------------------------------------- /Chapter15/level.py: -------------------------------------------------------------------------------- 1 | from characters import RoundPig 2 | from polygon import Polygon 3 | 4 | 5 | class Level(): 6 | def __init__(self, pigs_no, columns_no, beams_no, obj_space): 7 | self.pigs = pigs_no 8 | self.columns = columns_no 9 | self.beams = beams_no 10 | self.space = obj_space 11 | self.number = 0 12 | self.total_number_of_birds = 4 13 | 14 | 15 | def build_0(self): 16 | 17 | pig_no_1 = RoundPig(980, 100, self.space) 18 | pig_no_2 = RoundPig(985, 182, self.space) 19 | self.pigs.append(pig_no_1) 20 | self.pigs.append(pig_no_2) 21 | p = (950, 80) 22 | self.columns.append(Polygon(p, 20, 85, self.space)) 23 | p = (1010, 80) 24 | self.columns.append(Polygon(p, 20, 85, self.space)) 25 | p = (980, 150) 26 | self.beams.append(Polygon(p, 85, 20, self.space)) 27 | p = (950, 200) 28 | self.columns.append(Polygon(p, 20, 85, self.space)) 29 | p = (1010, 200) 30 | self.columns.append(Polygon(p, 20, 85, self.space)) 31 | p = (980, 240) 32 | self.beams.append(Polygon(p, 85, 20, self.space)) 33 | self.number_of_birds = 4 34 | 35 | 36 | def build_1(self): 37 | """level 1""" 38 | pig = RoundPig(1000, 100, self.space) 39 | self.pigs.append(pig) 40 | p = (900, 80) 41 | self.columns.append(Polygon(p, 20, 85, self.space)) 42 | p = (850, 80) 43 | self.columns.append(Polygon(p, 20, 85, self.space)) 44 | p = (850, 150) 45 | self.columns.append(Polygon(p, 20, 85, self.space)) 46 | p = (1050, 150) 47 | self.columns.append(Polygon(p, 20, 85, self.space)) 48 | p = (1105, 210) 49 | self.beams.append(Polygon(p, 85, 20, self.space)) 50 | self.total_number_of_birds = 4 51 | 52 | 53 | def load_level(self): 54 | try: 55 | build_name = "build_"+str(self.number) 56 | getattr(self, build_name)() 57 | except AttributeError: 58 | self.number = 0 59 | build_name = "build_"+str(self.number) 60 | getattr(self, build_name)() 61 | -------------------------------------------------------------------------------- /Chapter15/main.py: -------------------------------------------------------------------------------- 1 | import math 2 | import time 3 | import pygame 4 | import pymunk 5 | from characters import RoundBird 6 | from level import Level 7 | 8 | 9 | pygame.init() 10 | screen = pygame.display.set_mode((1200, 650)) 11 | redbird = pygame.image.load( 12 | "../res/photos/red-bird3.png").convert_alpha() 13 | background_image = pygame.image.load( 14 | "../res/photos/background3.png").convert_alpha() 15 | sling_image = pygame.image.load( 16 | "../res/photos/sling-3.png").convert_alpha() 17 | full_sprite = pygame.image.load( 18 | "../res/photos/full-sprite.png").convert_alpha() 19 | rect_screen = pygame.Rect(181, 1050, 50, 50) 20 | cropped_image = full_sprite.subsurface(rect_screen).copy() 21 | pig_image = pygame.transform.scale(cropped_image, (30, 30)) #(30, 30) resulting height and width of pig 22 | 23 | clock = pygame.time.Clock() 24 | 25 | 26 | running = True 27 | 28 | #base code 29 | space_obj = pymunk.Space() 30 | space_obj.gravity = (0.0, -700.0) 31 | 32 | total_pig = [] 33 | total_birds = [] 34 | beams = [] 35 | columns = [] 36 | #color code 37 | WHITE = (255, 255, 255) 38 | RED = (255, 0, 0) 39 | BLACK = (0, 0, 0) 40 | BLUE = (0, 0, 255) 41 | 42 | 43 | 44 | 45 | mouse_distance = 0 46 | rope_length = 90 47 | 48 | angle = 0 49 | mouse_x_pos = 0 50 | mouse_y_pos = 0 51 | 52 | mouse_pressed = False 53 | time_of_release = 0 54 | 55 | initial_x_sling, initial_y_sling = 135, 450 56 | next_x_sling, next_y_sling = 160, 450 57 | 58 | 59 | 60 | # Static floor 61 | static_floor_body = pymunk.Body(body_type=pymunk.Body.STATIC) 62 | static_lines_first = [pymunk.Segment(static_floor_body, (0.0, 060.0), (1200.0, 060.0), 0.0)] 63 | static_lines_second = [pymunk.Segment(static_floor_body, (1200.0, 060.0), (1200.0, 800.0), 0.0)] 64 | 65 | #lets add elasticity and friction to surface 66 | for eachLine in static_lines_first: 67 | eachLine.elasticity = 0.95 68 | eachLine.friction = 1 69 | eachLine.collision_type = 3 70 | 71 | for eachLine in static_lines_second: 72 | eachLine.elasticity = 0.95 73 | eachLine.friction = 1 74 | eachLine.collision_type = 3 75 | space_obj.add(static_lines_first) 76 | 77 | 78 | def convert_to_pygame(pos): 79 | """ pymunk to pygame coordinates""" 80 | return int(pos.x), int(-pos.y+600) 81 | 82 | 83 | def vector(a, b): 84 | #return vector from points 85 | p = b[0] - a[0] 86 | q = b[1] - a[1] 87 | return (p, q) 88 | 89 | 90 | def unit_vector(v): 91 | 92 | mag = ((v[0]**2)+(v[1]**2))**0.5 93 | if mag == 0: 94 | mag = 0.000000000000001 95 | unit_p = v[0] / mag 96 | unit_q = v[1] / mag 97 | return (unit_p, unit_q) 98 | 99 | 100 | def distance(x0, y0, x1, y1): 101 | """distance between points""" 102 | dx = x1 - x0 103 | dy = y1 - y0 104 | dist = ((dx ** 2) + (dy ** 2)) ** 0.5 105 | return dist 106 | 107 | 108 | def load_music(): 109 | """Load the music""" 110 | song = '../res/sounds/angry-total_birds.ogg' 111 | pygame.mixer.music.load(song) 112 | pygame.mixer.music.play(-1) 113 | 114 | 115 | def sling_action(): 116 | """Set up sling behavior""" 117 | global mouse_distance 118 | global rope_length 119 | global angle 120 | global mouse_x_pos 121 | global mouse_y_pos 122 | 123 | #add code inside sling function 124 | # Fixing bird to the sling rope 125 | vec = vector((initial_x_sling, initial_y_sling), (mouse_x_pos, mouse_y_pos)) 126 | unit_vec = unit_vector(vec) 127 | uv_1 = unit_vec[0] 128 | uv_2 = unit_vec[1] 129 | mouse_distance = distance(initial_x_sling, initial_y_sling, mouse_x_pos, mouse_y_pos) #point at which currrent bird id 130 | fix_pos = (uv_1*rope_length+initial_x_sling, uv_2*rope_length+initial_y_sling) 131 | highest_length = 102 #when stretched 132 | 133 | #to make bird stay within rope 134 | x_redbird = mouse_x_pos - 20 135 | y_redbird = mouse_y_pos - 20 136 | if mouse_distance > rope_length: 137 | pux, puy = fix_pos 138 | pux -= 20 139 | puy -= 20 140 | first_pos = pux, puy 141 | screen.blit(redbird, first_pos) 142 | second_pos = (uv_1*highest_length+initial_x_sling, uv_2*highest_length+initial_y_sling) #current position 143 | pygame.draw.line(screen, (255, 0, 0), (next_x_sling, next_y_sling), second_pos, 5) #catapult rope 144 | screen.blit(redbird, first_pos) 145 | pygame.draw.line(screen, (255, 0, 0), (initial_x_sling, initial_y_sling), second_pos, 5) #ANOTHER SIDE of catapult 146 | else: 147 | #when not fully stretched 148 | mouse_distance += 10 149 | third_pos = (uv_1*mouse_distance+initial_x_sling, uv_2*mouse_distance+initial_y_sling) 150 | pygame.draw.line(screen, (0, 0, 0), (next_x_sling, next_y_sling), third_pos, 5) 151 | screen.blit(redbird, (x_redbird, y_redbird)) 152 | pygame.draw.line(screen, (0, 0, 0), (initial_x_sling, initial_y_sling), third_pos, 5) 153 | # Angle of impulse 154 | 155 | change_in_y = mouse_y_pos - initial_y_sling 156 | change_in_x = mouse_x_pos - initial_x_sling 157 | if change_in_x == 0: 158 | dx = 0.00000000000001 159 | angle = math.atan((float(change_in_y))/change_in_x) 160 | 161 | 162 | """ collision handler post solve methods""" 163 | 164 | def post_solve_bird_pig(arbiter, space_obj, _): 165 | """Action to perform after collision between bird and pig""" 166 | 167 | object1, object2 = arbiter.shapes #Arbiter class obj 168 | bird_body = object1.body 169 | pig_body = object2.body 170 | bird_position = convert_to_pygame(bird_body.position) 171 | pig_position = convert_to_pygame(pig_body.position) 172 | radius = 30 173 | pygame.draw.circle(screen, (255, 0, 0), bird_position, radius, 4) #screen => pygame surface 174 | pygame.draw.circle(screen, RED, pig_position, radius, 4) 175 | #removal of pig 176 | removed_pigs_after_sling = [] 177 | for pig in total_pig: 178 | if pig_body == pig.body: 179 | pig.life -= 20 #decrease life 180 | removed_pigs_after_sling.append(pig) 181 | 182 | for eachPig in removed_pigs_after_sling: 183 | space_obj.remove(eachPig.shape, eachPig.shape.body) 184 | total_pig.remove(eachPig) 185 | 186 | 187 | def post_solve_bird_wood(arbiter, space_obj, _): 188 | """Action to perform after collision between bird and wood structure""" 189 | #removing polygon 190 | removed_poly = [] 191 | if arbiter.total_impulse.length > 1100: 192 | object1, object2 = arbiter.shapes 193 | for Each_column in columns: 194 | if object2 == Each_column.shape: 195 | removed_poly.append(Each_column) 196 | for Each_beam in beams: 197 | if object2 == Each_beam.shape: 198 | removed_poly.append(Each_beam) 199 | for Each_poly in removed_poly: 200 | if Each_poly in columns: 201 | columns.remove(Each_poly) 202 | if Each_poly in beams: 203 | beams.remove(Each_poly) 204 | space_obj.remove(object2, object2.body) 205 | #you can also remove bird if you want 206 | 207 | 208 | def post_solve_pig_wood(arbiter, space_obj, _): 209 | """Action to perform after collision between pig and wood""" 210 | removed_pigs = [] 211 | if arbiter.total_impulse.length > 700: 212 | pig_shape, wood_shape = arbiter.shapes 213 | for pig in total_pig: 214 | if pig_shape == pig.shape: 215 | pig.life -= 20 216 | 217 | if pig.life <= 0: #when life is 0 218 | removed_pigs.append(pig) 219 | for Each_pig in removed_pigs: 220 | space_obj.remove(Each_pig.shape, Each_pig.shape.body) 221 | total_pig.remove(Each_pig) 222 | 223 | 224 | # bird and total_pig 225 | space_obj.add_collision_handler(0, 1).post_solve=post_solve_bird_pig 226 | # bird and wood 227 | space_obj.add_collision_handler(0, 2).post_solve=post_solve_bird_wood 228 | # pig and wood 229 | space_obj.add_collision_handler(1, 2).post_solve=post_solve_pig_wood 230 | #load_music() 231 | level = Level(total_pig, columns, beams, space_obj) 232 | level.number = 0 233 | level.load_level() 234 | 235 | while running: 236 | # Input handling 237 | for event in pygame.event.get(): 238 | if event.type == pygame.QUIT: 239 | running = False 240 | elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: 241 | running = False 242 | 243 | if (pygame.mouse.get_pressed()[0] and mouse_x_pos > 100 and 244 | mouse_x_pos < 250 and mouse_y_pos > 370 and mouse_y_pos < 550): 245 | mouse_pressed = True 246 | if (event.type == pygame.MOUSEBUTTONUP and 247 | event.button == 1 and mouse_pressed): 248 | # Release new bird 249 | mouse_pressed = False 250 | if level.number_of_birds > 0: 251 | level.number_of_birds -= 1 252 | time_of_release = time.time()*1000 253 | x_initial = 154 254 | y_initial = 156 255 | 256 | 257 | if mouse_distance > rope_length: 258 | mouse_distance = rope_length 259 | if mouse_x_pos < initial_x_sling+5: 260 | bird = RoundBird(mouse_distance, angle, x_initial, y_initial, space_obj) 261 | total_birds.append(bird) 262 | else: 263 | bird = RoundBird(-mouse_distance, angle, x_initial, y_initial, space_obj) 264 | total_birds.append(bird) 265 | if level.number_of_birds == 0: 266 | game_finish_time = time.time() 267 | 268 | mouse_x_pos, mouse_y_pos = pygame.mouse.get_pos() 269 | # Draw background 270 | screen.fill((130, 200, 100)) 271 | screen.blit(background_image, (0, -50)) 272 | # Draw first part of the sling 273 | rect = pygame.Rect(50, 0, 70, 220) 274 | screen.blit(sling_image, (138, 420), rect) 275 | # Draw the trail left behind 276 | 277 | if level.number_of_birds > 0: 278 | for i in range(level.number_of_birds-1): 279 | x = 100 - (i*35) 280 | screen.blit(redbird, (x, 508)) 281 | 282 | 283 | # Draw sling behavior 284 | if mouse_pressed and level.number_of_birds > 0: 285 | sling_action() 286 | else: #blit bird when no stretch 287 | if time.time()*1000 - time_of_release > 300 and level.number_of_birds > 0: 288 | screen.blit(redbird, (130, 426)) 289 | 290 | removed_bird_after_sling = [] 291 | removed_pigs_after_sling = [] 292 | #counter += 1 293 | # Draw total_birds 294 | for bird in total_birds: 295 | if bird.shape.body.position.y < 0: 296 | removed_bird_after_sling.append(bird) 297 | p = convert_to_pygame(bird.shape.body.position) 298 | x, y = p 299 | x -= 22 300 | y -= 20 301 | screen.blit(redbird, (x, y)) 302 | pygame.draw.circle(screen, BLUE, 303 | p, int(bird.shape.radius), 2) 304 | 305 | 306 | # Remove total_birds and total_pig 307 | for bird in removed_bird_after_sling: 308 | space_obj.remove(bird.shape, bird.shape.body) 309 | total_birds.remove(bird) 310 | for pig in removed_pigs_after_sling: 311 | space_obj.remove(pig.shape, pig.shape.body) 312 | total_pig.remove(pig) 313 | 314 | 315 | #life = 0 316 | # Draw total_pig 317 | for Each_pig in total_pig: 318 | 319 | pig = Each_pig.shape 320 | if pig.body.position.y < 0: 321 | removed_pigs_after_sling.append(pig) 322 | 323 | pos = convert_to_pygame(pig.body.position) #pos is tuple 324 | x_pos, y_pos = pos 325 | 326 | angle_degrees = math.degrees(pig.body.angle) 327 | 328 | pig_rotated_img = pygame.transform.rotate(pig_image, angle_degrees) #small random rotation within wooden frame 329 | width,height = pig_rotated_img.get_size() 330 | x_pos -= width*0.5 331 | y_pos -= height*0.5 332 | screen.blit(pig_rotated_img, (x_pos, y_pos)) 333 | pygame.draw.circle(screen, BLUE, pos, int(pig.radius), 2) 334 | 335 | 336 | # Draw columns and Beams 337 | for column in columns: 338 | column.draw_poly('columns', screen) 339 | for beam in beams: 340 | beam.draw_poly('beams', screen) 341 | 342 | 343 | # Update simulation 344 | """ check URL:http://www.pymunk.org/en/latest/_modules/pymunk/space.html """ 345 | 346 | time_step_change = 1.0/50.0/2. 347 | for x in range(2): 348 | space_obj.step(time_step_change) # make two updates per frame for better stability 349 | # Drawing second part of the sling 350 | rect_for_sling = pygame.Rect(0, 0, 60, 200) 351 | screen.blit(sling_image, (120, 420), rect_for_sling) 352 | 353 | 354 | pygame.display.flip() 355 | clock.tick(50) 356 | 357 | -------------------------------------------------------------------------------- /Chapter15/polygon.py: -------------------------------------------------------------------------------- 1 | import pymunk as pym 2 | from pymunk import Vec2d 3 | import pygame as pg 4 | import math 5 | 6 | 7 | class Polygon(): 8 | def __init__(self, position, length, height, space, mass=5.0): 9 | value_moment = 1000 10 | body_obj = pym.Body(mass, value_moment) 11 | body_obj.position = Vec2d(position) 12 | shape_obj = pym.Poly.create_box(body_obj, (length, height)) 13 | shape_obj.color = (0, 0, 255) 14 | shape_obj.friction = 0.5 15 | shape_obj.collision_type = 2 #adding to check collision later 16 | space.add(body_obj, shape_obj) 17 | self.body = body_obj 18 | self.shape = shape_obj 19 | wood_photo = pg.image.load("../res/photos/wood.png").convert_alpha() 20 | wood2_photo = pg.image.load("../res/photos/wood2.png").convert_alpha() 21 | rect_wood = pg.Rect(251, 357, 86, 22) 22 | self.beam_image = wood_photo.subsurface(rect_wood).copy() 23 | rect_wood2 = pg.Rect(16, 252, 22, 84) 24 | self.column_image = wood2_photo.subsurface(rect_wood2).copy() 25 | 26 | def convert_to_pygame(self, pos): 27 | """Convert pymunk to pygame coordinates""" 28 | return int(pos.x), int(-pos.y+610) 29 | 30 | def draw_poly(self, element, screen): 31 | """Draw beams and columns""" 32 | polygon = self.shape 33 | 34 | if element == 'beams': 35 | pos = polygon.body.position 36 | pos = Vec2d(self.convert_to_pygame(pos)) 37 | angle_degrees = math.degrees(polygon.body.angle) 38 | rotated_beam = pg.transform.rotate(self.beam_image, 39 | angle_degrees) 40 | offset = Vec2d(rotated_beam.get_size()) / 2. 41 | pos = pos - offset 42 | final_pos = pos 43 | screen.blit(rotated_beam, (final_pos.x, final_pos.y)) 44 | if element == 'columns': 45 | pos = polygon.body.position 46 | pos = Vec2d(self.convert_to_pygame(pos)) 47 | angle_degrees = math.degrees(polygon.body.angle) + 180 48 | rotated_column = pg.transform.rotate(self.column_image, 49 | angle_degrees) 50 | offset = Vec2d(rotated_column.get_size()) / 2. 51 | pos = pos - offset 52 | final_pos = pos 53 | screen.blit(rotated_column, (final_pos.x, final_pos.y)) 54 | -------------------------------------------------------------------------------- /Chapter15/res/Note: -------------------------------------------------------------------------------- 1 | """Resources file of assets for angry bird""" 2 | -------------------------------------------------------------------------------- /Chapter15/res/photos/Buttons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/Buttons.png -------------------------------------------------------------------------------- /Chapter15/res/photos/angry-birds-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/angry-birds-image.png -------------------------------------------------------------------------------- /Chapter15/res/photos/angry_birds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/angry_birds.png -------------------------------------------------------------------------------- /Chapter15/res/photos/angry_birds_chrome_pigs_by_chinzapep-d5bnxdz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/angry_birds_chrome_pigs_by_chinzapep-d5bnxdz.png -------------------------------------------------------------------------------- /Chapter15/res/photos/angry_birds_toons_sprites_by_jared33-d64u29w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/angry_birds_toons_sprites_by_jared33-d64u29w.png -------------------------------------------------------------------------------- /Chapter15/res/photos/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/background.png -------------------------------------------------------------------------------- /Chapter15/res/photos/background1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/background1.jpg -------------------------------------------------------------------------------- /Chapter15/res/photos/background2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/background2.jpg -------------------------------------------------------------------------------- /Chapter15/res/photos/background3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/background3.png -------------------------------------------------------------------------------- /Chapter15/res/photos/background4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/background4.png -------------------------------------------------------------------------------- /Chapter15/res/photos/buttons-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/buttons-image.png -------------------------------------------------------------------------------- /Chapter15/res/photos/column.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/column.png -------------------------------------------------------------------------------- /Chapter15/res/photos/full-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/full-sprite.png -------------------------------------------------------------------------------- /Chapter15/res/photos/gravity-zero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/gravity-zero.png -------------------------------------------------------------------------------- /Chapter15/res/photos/latest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/latest.png -------------------------------------------------------------------------------- /Chapter15/res/photos/pig_failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/pig_failed.png -------------------------------------------------------------------------------- /Chapter15/res/photos/red-bird.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/red-bird.png -------------------------------------------------------------------------------- /Chapter15/res/photos/red-bird2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/red-bird2.png -------------------------------------------------------------------------------- /Chapter15/res/photos/red-bird3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/red-bird3.png -------------------------------------------------------------------------------- /Chapter15/res/photos/selected-buttons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/selected-buttons.png -------------------------------------------------------------------------------- /Chapter15/res/photos/sling-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/sling-2.png -------------------------------------------------------------------------------- /Chapter15/res/photos/sling-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/sling-3.png -------------------------------------------------------------------------------- /Chapter15/res/photos/sling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/sling.png -------------------------------------------------------------------------------- /Chapter15/res/photos/stars-edited.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/stars-edited.png -------------------------------------------------------------------------------- /Chapter15/res/photos/stars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/stars.png -------------------------------------------------------------------------------- /Chapter15/res/photos/walls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/walls.png -------------------------------------------------------------------------------- /Chapter15/res/photos/wood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/wood.png -------------------------------------------------------------------------------- /Chapter15/res/photos/wood2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/photos/wood2.png -------------------------------------------------------------------------------- /Chapter15/res/sounds/angry-birds.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter15/res/sounds/angry-birds.ogg -------------------------------------------------------------------------------- /Chapter16/App.py: -------------------------------------------------------------------------------- 1 | class App: 2 | Width = 800 3 | Height = 600 4 | player = 0 5 | Frog = 0 6 | 7 | def __init__(self): 8 | self._running = True 9 | self.surface = None 10 | self._image_surf = None 11 | self._Frog_surf = None 12 | self.game = Game() 13 | self.player = Player(5) 14 | self.Frog = Frog(8, 5) 15 | self.computer = Computer(5) 16 | 17 | def loader(self): 18 | pygame.init() 19 | self.surface = pygame.display.set_mode((self.Width, self.Height), pygame.HWSURFACE) 20 | 21 | self._running = True 22 | self._image_surf = pygame.image.load("snake.png").convert() 23 | self._Frog_surf = pygame.image.load("frog-main.png").convert() 24 | 25 | def on_event(self, event): 26 | if event.type == QUIT: 27 | self._running = False 28 | 29 | def main(self): 30 | self.computer.target(self.Frog.x, self.Frog.y) 31 | self.player.update() 32 | self.computer.update() 33 | 34 | # does snake eat Frog? 35 | for i in range(0, self.player.length): 36 | if self.game.checkCollision(self.Frog.x, self.Frog.y, self.player.x[i], self.player.y[i], 44): 37 | self.Frog.x = randint(2, 9) * 44 38 | self.Frog.y = randint(2, 9) * 44 39 | self.player.length = self.player.length + 1 40 | 41 | # does computer eat Frog? 42 | for i in range(0, self.player.length): 43 | if self.game.checkCollision(self.Frog.x, self.Frog.y, self.computer.x[i], self.computer.y[i], 44): 44 | self.Frog.x = randint(2, 9) * 44 45 | self.Frog.y = randint(2, 9) * 44 46 | #to increase length 47 | # self.computer.length = self.computer.length + 1 48 | 49 | # does snake collide with itself? 50 | for i in range(2, self.player.length): 51 | if self.game.checkCollision(self.player.x[0], self.player.y[0], self.player.x[i], self.player.y[i], 40): 52 | print( "You lose! ") 53 | exit(0) 54 | 55 | pass 56 | 57 | def renderer(self): 58 | self.surface.fill((0, 0, 0)) 59 | self.player.draw(self.surface, self._image_surf) 60 | self.Frog.draw(self.surface, self._Frog_surf) 61 | self.computer.draw(self.surface, self._image_surf) 62 | pygame.display.flip() 63 | 64 | def on_cleanup(self): 65 | pygame.quit() 66 | 67 | def handler(self): 68 | if self.loader() == False: 69 | self._running = False 70 | 71 | while (self._running): 72 | pygame.event.pump() 73 | keys = pygame.key.get_pressed() 74 | 75 | if (keys[K_RIGHT]): 76 | self.player.moveRight() 77 | 78 | if (keys[K_LEFT]): 79 | self.player.moveLeft() 80 | 81 | if (keys[K_UP]): 82 | self.player.moveUp() 83 | 84 | if (keys[K_DOWN]): 85 | self.player.moveDown() 86 | 87 | if (keys[K_ESCAPE]): 88 | self._running = False 89 | 90 | self.main() 91 | self.renderer() 92 | 93 | time.sleep(50.0 / 1000.0); 94 | self.on_cleanup() 95 | 96 | 97 | if __name__ == "__main__": 98 | main = App() 99 | main.handler() 100 | -------------------------------------------------------------------------------- /Chapter16/Frog.py: -------------------------------------------------------------------------------- 1 | from pygame.locals import * 2 | from random import randint 3 | import pygame 4 | import time 5 | from operator import * 6 | 7 | 8 | class Frog: 9 | x = 0 10 | y = 0 11 | size = 44 12 | 13 | def __init__(self, x, y): 14 | self.x = x * self.size 15 | self.y = y * self.size 16 | 17 | def draw(self, surface, image): 18 | surface.blit(image, (self.x, self.y)) 19 | -------------------------------------------------------------------------------- /Chapter16/Fullcode.py: -------------------------------------------------------------------------------- 1 | from pygame.locals import * 2 | from random import randint 3 | import pygame 4 | import time 5 | from operator import * 6 | 7 | class Player: 8 | x = [0] 9 | y = [0] 10 | size = 44 11 | direction = 0 12 | length = 3 13 | 14 | MaxAllowedMove = 2 15 | updateMove = 0 16 | 17 | def __init__(self, length): 18 | self.length = length 19 | for i in range(0, 2000): 20 | self.x.append(-100) 21 | self.y.append(-100) 22 | 23 | # initial positions, no collision. 24 | self.x[0] = 1 * 44 25 | self.x[0] = 2 * 44 26 | 27 | def update(self): 28 | 29 | self.updateMove = self.updateMove + 1 30 | if gt(self.updateMove, self.MaxAllowedMove): 31 | 32 | # update previous positions 33 | for i in range(self.length - 1, 0, -1): 34 | self.x[i] = self.x[i - 1] 35 | self.y[i] = self.y[i - 1] 36 | 37 | # update position of head of snake 38 | if self.direction == 0: 39 | self.x[0] = self.x[0] + self.size 40 | if self.direction == 1: 41 | self.x[0] = self.x[0] - self.size 42 | if self.direction == 2: 43 | self.y[0] = self.y[0] - self.size 44 | if self.direction == 3: 45 | self.y[0] = self.y[0] + self.size 46 | 47 | self.updateMove = 0 48 | 49 | def moveRight(self): 50 | self.direction = 0 51 | 52 | def moveLeft(self): 53 | self.direction = 1 54 | 55 | def moveUp(self): 56 | self.direction = 2 57 | 58 | def moveDown(self): 59 | self.direction = 3 60 | 61 | def draw(self, surface, image): 62 | for i in range(0, self.length): 63 | surface.blit(image, (self.x[i], self.y[i])) 64 | 65 | 66 | 67 | class Computer: 68 | x = [0] 69 | y = [0] 70 | size = 44 71 | direction = 0 72 | length = 3 73 | 74 | MaxAllowedMove = 2 75 | updateMove = 0 76 | 77 | def __init__(self, length): 78 | self.length = length 79 | for i in range(0, 2000): 80 | self.x.append(-100) 81 | self.y.append(-100) 82 | 83 | # initial positions, no collision. 84 | self.x[0] = 1 * 44 85 | self.y[0] = 4 * 44 86 | 87 | def update(self): 88 | 89 | self.updateMove = self.updateMove + 1 90 | if gt(self.updateMove, self.MaxAllowedMove): 91 | 92 | # update previous positions 93 | for i in range(self.length - 1, 0, -1): 94 | self.x[i] = self.x[i - 1] 95 | self.y[i] = self.y[i - 1] 96 | 97 | # update position of head of snake 98 | if self.direction == 0: 99 | self.x[0] = self.x[0] + self.size 100 | if self.direction == 1: 101 | self.x[0] = self.x[0] - self.size 102 | if self.direction == 2: 103 | self.y[0] = self.y[0] - self.size 104 | if self.direction == 3: 105 | self.y[0] = self.y[0] + self.size 106 | 107 | self.updateMove = 0 108 | 109 | def moveRight(self): 110 | self.direction = 0 111 | 112 | def moveLeft(self): 113 | self.direction = 1 114 | 115 | def moveUp(self): 116 | self.direction = 2 117 | 118 | def moveDown(self): 119 | self.direction = 3 120 | 121 | def target(self, dx, dy): 122 | if gt(self.x[0] , dx): 123 | 124 | self.moveLeft() 125 | 126 | if lt(self.x[0] , dx): 127 | self.moveRight() 128 | 129 | if self.x[0] == dx: 130 | if lt(self.y[0] , dy): 131 | self.moveDown() 132 | 133 | if gt(self.y[0] , dy): 134 | self.moveUp() 135 | 136 | def draw(self, surface, image): 137 | for i in range(0, self.length): 138 | surface.blit(image, (self.x[i], self.y[i])) 139 | 140 | 141 | class Game: 142 | def checkCollision(self, x1, y1, x2, y2, blockSize): 143 | if ge(x1 , x2) and le(x1 , x2 + blockSize): 144 | if ge(y1 , y2) and le(y1, y2 + blockSize): 145 | return True 146 | return False 147 | 148 | 149 | class Frog: 150 | x = 0 151 | y = 0 152 | size = 44 153 | 154 | def __init__(self, x, y): 155 | self.x = x * self.size 156 | self.y = y * self.size 157 | 158 | def draw(self, surface, image): 159 | surface.blit(image, (self.x, self.y)) 160 | 161 | 162 | class App: 163 | Width = 800 164 | Height = 600 165 | player = 0 166 | Frog = 0 167 | 168 | def __init__(self): 169 | self._running = True 170 | self.surface = None 171 | self._image_surf = None 172 | self._Frog_surf = None 173 | self.game = Game() 174 | self.player = Player(5) 175 | self.Frog = Frog(8, 5) 176 | self.computer = Computer(5) 177 | 178 | def loader(self): 179 | pygame.init() 180 | self.surface = pygame.display.set_mode((self.Width, self.Height), pygame.HWSURFACE) 181 | 182 | self._running = True 183 | self._image_surf = pygame.image.load("snake.png").convert() 184 | self._Frog_surf = pygame.image.load("frog-main.png").convert() 185 | 186 | def on_event(self, event): 187 | if event.type == QUIT: 188 | self._running = False 189 | 190 | def main(self): 191 | self.computer.target(self.Frog.x, self.Frog.y) 192 | self.player.update() 193 | self.computer.update() 194 | 195 | # does snake eat Frog? 196 | for i in range(0, self.player.length): 197 | if self.game.checkCollision(self.Frog.x, self.Frog.y, self.player.x[i], self.player.y[i], 44): 198 | self.Frog.x = randint(2, 9) * 44 199 | self.Frog.y = randint(2, 9) * 44 200 | self.player.length = self.player.length + 1 201 | 202 | # does computer eat Frog? 203 | for i in range(0, self.player.length): 204 | if self.game.checkCollision(self.Frog.x, self.Frog.y, self.computer.x[i], self.computer.y[i], 44): 205 | self.Frog.x = randint(2, 9) * 44 206 | self.Frog.y = randint(2, 9) * 44 207 | #to increase length 208 | # self.computer.length = self.computer.length + 1 209 | 210 | # does snake collide with itself? 211 | for i in range(2, self.player.length): 212 | if self.game.checkCollision(self.player.x[0], self.player.y[0], self.player.x[i], self.player.y[i], 40): 213 | print( "You lose! ") 214 | exit(0) 215 | 216 | pass 217 | 218 | def renderer(self): 219 | self.surface.fill((0, 0, 0)) 220 | self.player.draw(self.surface, self._image_surf) 221 | self.Frog.draw(self.surface, self._Frog_surf) 222 | self.computer.draw(self.surface, self._image_surf) 223 | pygame.display.flip() 224 | 225 | def on_cleanup(self): 226 | pygame.quit() 227 | 228 | def handler(self): 229 | if self.loader() == False: 230 | self._running = False 231 | 232 | while (self._running): 233 | pygame.event.pump() 234 | keys = pygame.key.get_pressed() 235 | 236 | if (keys[K_RIGHT]): 237 | self.player.moveRight() 238 | 239 | if (keys[K_LEFT]): 240 | self.player.moveLeft() 241 | 242 | if (keys[K_UP]): 243 | self.player.moveUp() 244 | 245 | if (keys[K_DOWN]): 246 | self.player.moveDown() 247 | 248 | if (keys[K_ESCAPE]): 249 | self._running = False 250 | 251 | self.main() 252 | self.renderer() 253 | 254 | time.sleep(50.0 / 1000.0); 255 | self.on_cleanup() 256 | 257 | 258 | if __name__ == "__main__": 259 | main = App() 260 | main.handler() 261 | -------------------------------------------------------------------------------- /Chapter16/Note: -------------------------------------------------------------------------------- 1 | """ This chapter will teach you about adding intelligent player into your games""" 2 | We will define target for such artificial player and icentivize them to take a move that is similar as compared to human being 3 | Main aim this chapter is to create a game that will be more competetive and fun 4 | -------------------------------------------------------------------------------- /Chapter16/Player.py: -------------------------------------------------------------------------------- 1 | class Player: 2 | x = [0] 3 | y = [0] 4 | size = 44 5 | direction = 0 6 | length = 3 7 | 8 | MaxAllowedMove = 2 9 | updateMove = 0 10 | 11 | def __init__(self, length): 12 | self.length = length 13 | for i in range(0, 2000): 14 | self.x.append(-100) 15 | self.y.append(-100) 16 | 17 | # initial positions, no collision. 18 | self.x[0] = 1 * 44 19 | self.x[0] = 2 * 44 20 | 21 | def update(self): 22 | 23 | self.updateMove = self.updateMove + 1 24 | if gt(self.updateMove, self.MaxAllowedMove): 25 | 26 | # update previous positions 27 | for i in range(self.length - 1, 0, -1): 28 | self.x[i] = self.x[i - 1] 29 | self.y[i] = self.y[i - 1] 30 | 31 | # update position of head of snake 32 | if self.direction == 0: 33 | self.x[0] = self.x[0] + self.size 34 | if self.direction == 1: 35 | self.x[0] = self.x[0] - self.size 36 | if self.direction == 2: 37 | self.y[0] = self.y[0] - self.size 38 | if self.direction == 3: 39 | self.y[0] = self.y[0] + self.size 40 | 41 | self.updateMove = 0 42 | 43 | def moveRight(self): 44 | self.direction = 0 45 | 46 | def moveLeft(self): 47 | self.direction = 1 48 | 49 | def moveUp(self): 50 | self.direction = 2 51 | 52 | def moveDown(self): 53 | self.direction = 3 54 | 55 | def draw(self, surface, image): 56 | for i in range(0, self.length): 57 | surface.blit(image, (self.x[i], self.y[i])) 58 | 59 | -------------------------------------------------------------------------------- /Chapter16/frog-main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter16/frog-main.png -------------------------------------------------------------------------------- /Chapter16/snake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Python-by-building-games/e6045d0456ede27f71e449d3c73f3f001f278ae2/Chapter16/snake.png -------------------------------------------------------------------------------- /Chapter16/target.py: -------------------------------------------------------------------------------- 1 | def target(self, dx, dy): 2 | if gt(self.x[0] , dx): 3 | 4 | self.moveLeft() 5 | 6 | if lt(self.x[0] , dx): 7 | self.moveRight() 8 | 9 | if self.x[0] == dx: 10 | if lt(self.y[0] , dy): 11 | self.moveDown() 12 | 13 | if gt(self.y[0] , dy): 14 | self.moveUp() 15 | 16 | 17 | def draw(self, surface, image): 18 | for item in range(0, self.length): 19 | surface.blit(image, (self.x[item], self.y[item])) 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Learning Python by Building Games 2 | 3 | Book Name 4 | 5 | This is the code repository for [Learning Python by Building Games](https://www.packtpub.com/game-development/learning-python-by-building-games?utm_source=github&utm_medium=repository&utm_campaign=9781789802986), published by Packt. 6 | 7 | **A beginner's guide to Python programming and game development** 8 | 9 | ## What is this book about? 10 | A fun and interactive way to get started with the Python language and its libraries is by getting hands-on with game development. 11 | Learning Python by Building Games brings you the best of both worlds. The book will first introduce you to Python fundamentals, which you will then use to develop a basic game. You’ll gradually explore the different Python libraries best suited for game development such as Pygame, Pyglet, and PyOpenGL. From building game characters through to using 3D animation techniques, you’ll discover how to create an aesthetic game environment. In addition to this, you’ll focus on game physics to give your effects a realistic feel, complete with movements and collisions. The book will also cover how you can use particle systems to simulate phenomena such as an explosion or smoke. In later chapters, you will gain insights into object-oriented programming by modifying a snake game, along with exploring GUI programming to build a user interface with Python’s turtle module. 12 | 13 | This book covers the following exciting features: 14 | * Explore core Python concepts by understanding Python libraries 15 | * Build your first 2D game using Python scripting 16 | * Understand concepts such as decorators and properties in the Python ecosystem 17 | * Create animations and movements by building a Flappy Bird-like game 18 | * Design game objects and characters using Pygame, PyOpenGL, and Pymunk 19 | 20 | If you feel this book is for you, get your [copy](https://www.amazon.com/dp/1789802989) today! 21 | 22 | https://www.packtpub.com/ 24 | 25 | 26 | ## Instructions and Navigations 27 | All of the code is organized into folders. For example, Chapter02. 28 | 29 | The code will look like the following: 30 | ``` 31 | n = int(input("Enter any number")) 32 | for i in range(1,100): 33 | if i == n: 34 | print(i) 35 | break 36 | ``` 37 | 38 | **Following is what you need for this book:** 39 | If you are completely new to Python or game programming and want to develop your programming skills, then this book is for you. The book also acts as a refresher for those who already have experience of using Python and want to learn how to build exciting games. 40 | 41 | With the following software and hardware list you can run all code files present in the book (Chapter 1-16). 42 | 43 | ### Software and Hardware List 44 | 45 | | Chapter | Software required | OS required | 46 | | -------- | --------------------------------------------------| -----------------------------------| 47 | | 1 | Open Source Python installer version | Windows, Mac OS X, and Linux (Any) | 48 | | | 3.5+ is required | | 49 | | 1 | Open Source IDLE (Python pre-installed) | Windows, Mac OS X, and Linux (Any) | 50 | | 2 | Python version 3.5+ | Windows, Mac OS X, and Linux (Any) | 51 | | 3 to 4 | Python IDLE (comes preinstalled with python) | Windows, Mac OS X, and Linux (Any) | 52 | | 5 | Open Source Curses Library[version 2.0+] | Windows, Mac OS X, and Linux (Any) | 53 | | 6 to 7 | Python IDLE (comes preinstalled with python) | Windows, Mac OS X, and Linux (Any) | 54 | | 8 | Python IDLE (comes preinstalled with python)/ | Windows, Mac OS X, and Linux (Any) | 55 | | | turtle library (comes prebuilt) | | 56 | | 9 to 10 | Python IDLE (comes preinstalled with python) | Windows, Mac OS X, and Linux (Any) | 57 | | 11 | Pycharm IDE Community Version 2018-2019.2+ | Windows, Mac OS X, and Linux (Any) | 58 | | 11 to 13 | Pygame Library version 1.9.6[Python version 3.5+] | Windows, Mac OS X, and Linux (Any) | 59 | | 14 | PyopenGL library version 3.1.0 | Windows, Mac OS X, and Linux (Any) | 60 | | 15 | Pycharm IDE Community Version 2018-2019.2+ | Windows, Mac OS X, and Linux (Any) | 61 | | 15 | Pymunk Library version 5.5.0 | Windows, Mac OS X, and Linux (Any) | 62 | | 16 | Pygame Library version 1.9.6[Python version 3.5+] | Windows, Mac OS X, and Linux (Any) | 63 | 64 | 65 | ## Code in Action 66 | 67 | Click on the following link to see the Code in Action: 68 | 69 | [http://bit.ly/2oE9mHV](http://bit.ly/2oE9mHV) 70 | 71 | ### Related products 72 | * Hands-On Deep Learning for Games [[Packt]](https://www.packtpub.com/game-development/hands-deep-learning-games?utm_source=github&utm_medium=repository&utm_campaign=9781788994071) [[Amazon]](https://www.amazon.com/dp/1788994078) 73 | 74 | * Expert Python Programming - Third Edition [[Packt]](https://www.packtpub.com/application-development/expert-python-programming-third-edition?utm_source=github&utm_medium=repository&utm_campaign=9781789808896) [[Amazon]](https://www.amazon.com/dp/1789808898) 75 | 76 | ## Get to Know the Author 77 | **Sachin Kafle** 78 | is a computer engineer from Tribhuvan University, Nepal, and a programming instructor currently living in Kathmandu. He is the founder of Bitfourstack Technologies, a software company that provides services including automation for real-time problems in businesses. One of his courses, named Python Game Development, is the best seller on many e-learning websites. His interests lie in software development and integration practices in the areas of computation and quantitative fields of trade. He has been utilizing his expertise in Python, C, Java, and C# by teaching since 2012. He has been a source of motivation to younger people, and even his peers, regardless of their educational background, who are embarking on their journey in programming. 79 | 80 | 81 | 82 | ### Suggestions and Feedback 83 | [Click here](https://docs.google.com/forms/d/e/1FAIpQLSdy7dATC6QmEL81FIUuymZ0Wy9vH1jHkvpY57OiMeKGqib_Ow/viewform) if you have any feedback or suggestions. 84 | --------------------------------------------------------------------------------